Decouple storage server types from each other

Previously, all of the storage server types
(account, container, proxy) were always
configured to be installed on the same node.

It often makes sense to only have the account and
container together, and to put the object server on
a different node. (or its possible that other
configurations make sense)

This commit refactors the swift module so that
each of the types of nodes can be built
independently of each other.
This commit is contained in:
Dan Bode 2012-03-02 20:01:49 -08:00
parent 530ed65ea9
commit 5083e19bc4
15 changed files with 426 additions and 196 deletions

View File

@ -3,7 +3,8 @@
# same as what I have been using
# to build swift in my environment (which is based on vagrant)
#
$proxy_local_net_ip='127.0.0.1'
$swift_local_net_ip='127.0.0.1'
$swift_shared_secret='changeme'
Exec { logoutput => true }
@ -13,7 +14,7 @@ package { 'curl': ensure => present }
class { 'ssh::server::install': }
class { 'memcached':
listen_ip => $proxy_local_net_ip,
listen_ip => $swift_local_net_ip,
}
class { 'swift':
@ -22,6 +23,12 @@ class { 'swift':
package_ensure => latest,
}
# === Configure Storage
class { 'swift::storage':
storage_local_net_ip => $swift_local_net_ip
}
# create xfs partitions on a loopback device and mounts them
swift::storage::loopback { ['1', '2', '3']:
require => Class['swift'],
@ -34,22 +41,22 @@ Swift::Storage::Node {
mnt_base_dir => '/srv/node',
weight => 1,
manage_ring => true,
storage_local_net_ip => '127.0.0.1',
storage_local_net_ip => $swift_local_net_ip,
}
swift::storage::node { '1':
zone => 1,
require => Swift::Storage::Loopback[1],
zone => 1,
require => Swift::Storage::Loopback[1],
}
swift::storage::node { '2':
zone => 2,
require => Swift::Storage::Loopback[2],
zone => 2,
require => Swift::Storage::Loopback[2],
}
swift::storage::node { '3':
zone => 3,
require => Swift::Storage::Loopback[3],
zone => 3,
require => Swift::Storage::Loopback[3],
}
class { 'swift::ringbuilder':
@ -59,7 +66,6 @@ class { 'swift::ringbuilder':
require => Class['swift'],
}
class { 'swift::storage': }
# TODO should I enable swath in the default config?
class { 'swift::proxy':

View File

@ -65,6 +65,7 @@ node 'swift_storage_3' {
#
node 'swift_proxy' {
# TODO this should not be recommended
class { 'role_swift_ringbuilder': }
class { 'role_swift_proxy':
require => Class['role_swift_ringbuilder'],
@ -128,11 +129,6 @@ class role_swift_proxy inherits role_swift {
class role_swift_storage inherits role_swift {
class { 'swift::storage':
storage_local_net_ip => $swift_local_net_ip,
devices => '/srv/node',
}
# create xfs partitions on a loopback device and mount them
swift::storage::loopback { '1':
base_dir => '/srv/loopback-device',
@ -140,6 +136,15 @@ class role_swift_storage inherits role_swift {
require => Class['swift'],
}
# install all swift storage servers together
class { 'swift::storage::all':
storage_local_net_ip => $swift_local_net_ip,
}
# TODO I need to wrap these in a define so that
# mcollective can collect that define
# these exported resources write ring config
# resources into the database so that they can be
# consumed by the ringbuilder role
@ -155,6 +160,7 @@ class role_swift_storage inherits role_swift {
weight => 1,
}
# TODO should device be changed to volume
@@ring_account_device { "${swift_local_net_ip}:6002":
zone => $swift_zone,
device_name => 1,

View File

@ -1,25 +1,12 @@
#
# Configures a swift storage node to host servers for object,
# container, and accounts.
# Configures dependencies that are common for all storage
# types.
# - installs an rsync server
# - installs required packages
#
# Includes:
# installing an rsync server
# installs storeage packages (object,account,containers)
# == Parameters
# [*storeage_local_net_ip*] ip address that the swift servers should
# bind to. Optional. Defaults to 127.0.0.1 .
# TODO - should this default to 0.0.0.0 ?
# [*package_ensure*] The desired ensure state of the swift storage packages.
# Optional. Defaults to present.
# [*devices*] The path where the managed volumes can be found.
# This assumes that all servers use the same path.
# Optional. Defaults to /srv/node/
# [*object_port*] Port where object storage server should be hosted.
# Optional. Defaults to 6000.
# [*container_port*] Port where the container storage server should be hosted.
# Optional. Defaults to 6001.
# [*account_port*] Port where the account storage server should be hosted.
# Optional. Defaults to 6002.
# bind to. Required.
# == Dependencies
#
# == Examples
@ -33,107 +20,16 @@
# Copyright 2011 Puppetlabs Inc, unless otherwise noted.
#
class swift::storage(
$package_ensure = 'present',
# TODO - should this default to 0.0.0.0?
$storage_local_net_ip = '127.0.0.1',
$devices = '/srv/node',
$object_port = '6000',
$container_port = '6001',
$account_port = '6002'
$storage_local_net_ip
) inherits swift {
class{ 'rsync::server':
use_xinetd => false,
address => $storage_local_net_ip,
}
Service {
ensure => running,
enable => true,
hasstatus => true,
subscribe => Service['rsync'],
}
File {
owner => 'swift',
group => 'swift',
}
Swift::Storage::Server {
devices => $devices,
storage_local_net_ip => $storage_local_net_ip,
address => $storage_local_net_ip,
}
# package dependencies
package { ['xfsprogs', 'parted']:
ensure => 'present'
}
package { 'swift-account':
ensure => $package_ensure,
}
swift::storage::server { $account_port:
type => 'account',
config_file_path => 'account-server.conf',
}
file { '/etc/swift/account-server/':
ensure => directory,
}
service { 'swift-account':
provider => 'upstart',
}
# container server configuration
package { 'swift-container':
ensure => $package_ensure,
}
swift::storage::server { $container_port:
type => 'container',
config_file_path => 'container-server.conf',
}
file { '/etc/swift/container-server/':
ensure => directory,
}
service { 'swift-container':
provider => 'upstart',
}
# object server configuration
package { 'swift-object':
ensure => $package_ensure,
}
swift::storage::server { $object_port:
type => 'object',
config_file_path => 'object-server.conf',
}
file { '/etc/swift/object-server/':
ensure => directory,
}
service { 'swift-object':
provider => 'upstart',
}
# TODO this should be removed when the upstart packages are fixed.
define upstart() {
file { "/etc/init/swift-${name}.conf":
mode => '0644',
owner => 'root',
group => 'root',
source => "puppet:///modules/swift/swift-${name}.conf.upstart",
before => Service["swift-${name}"],
}
}
swift::storage::upstart { ['object', 'container', 'account']: }
}

View File

@ -0,0 +1,7 @@
class swift::storage::account(
$package_ensure = 'present'
) {
swift::storage::generic { 'account':
package_ensure => $package_ensure,
}
}

49
manifests/storage/all.pp Normal file
View File

@ -0,0 +1,49 @@
#
# configures all storage types
# on the same node
#
# [*storeage_local_net_ip*] ip address that the swift servers should
# bind to. Required
# [*devices*] The path where the managed volumes can be found.
# This assumes that all servers use the same path.
# Optional. Defaults to /srv/node/
# [*object_port*] Port where object storage server should be hosted.
# Optional. Defaults to 6000.
# [*container_port*] Port where the container storage server should be hosted.
# Optional. Defaults to 6001.
# [*account_port*] Port where the account storage server should be hosted.
# Optional. Defaults to 6002.
#
#
class swift::storage::all(
$storage_local_net_ip,
$devices = '/srv/node',
$object_port = '6000',
$container_port = '6001',
$account_port = '6002'
) {
class { 'swift::storage':
storage_local_net_ip => $storage_local_net_ip,
}
Swift::Storage::Server {
devices => $devices,
storage_local_net_ip => $storage_local_net_ip,
}
swift::storage::server { $account_port:
type => 'account',
config_file_path => 'account-server.conf',
}
swift::storage::server { $container_port:
type => 'container',
config_file_path => 'container-server.conf',
}
swift::storage::server { $object_port:
type => 'object',
config_file_path => 'object-server.conf',
}
}

View File

@ -0,0 +1,7 @@
class swift::storage::container(
$package_ensure = 'present'
) {
swift::storage::generic { 'container':
package_ensure => $package_ensure
}
}

View File

@ -0,0 +1,59 @@
# Creates the files packages and services that are
# needed to deploy each type of storage server.
#
# == Parameters
# [*package_ensure*] The desired ensure state of the swift storage packages.
# Optional. Defaults to present.
# [*service_provider*] The provider to use for the service
#
# == Dependencies
# Requires Class[swift::storage]
# == Examples
#
# == Authors
#
# Dan Bode dan@puppetlabs.com
#
# == Copyright
#
# Copyright 2011 Puppetlabs Inc, unless otherwise noted.
define swift::storage::generic(
$package_ensure = 'present',
$service_provider = 'upstart'
) {
Class['swift::storage'] -> Swift::Storage::Generic[$name]
validate_re($name, '^object|container|account$')
package { "swift-${name}":
ensure => $package_ensure,
}
file { "/etc/swift/${name}-server/":
ensure => directory,
owner => 'swift',
group => 'swift',
}
service { "swift-${name}":
ensure => running,
enable => true,
hasstatus => true,
provider => $service_provider,
subscribe => Service['rsync'],
}
swift::storage::generic::upstart { $name: }
}
# TODO this should be removed when the upstart packages are fixed.
define swift::storage::generic::upstart() {
file { "/etc/init/swift-${name}.conf":
mode => '0644',
owner => 'root',
group => 'root',
source => "puppet:///modules/swift/swift-${name}.conf.upstart",
before => Service["swift-${name}"],
}
}

View File

@ -0,0 +1,7 @@
class swift::storage::object(
$package_ensure = 'present'
) {
swift::storage::generic { 'object':
package_ensure => $package_ensure
}
}

View File

@ -14,6 +14,8 @@ define swift::storage::server(
$config_file_path = "${type}-server/${name}.conf"
) {
include "swift::storage::$type"
validate_re($name, '^\d+$')
validate_re($type, '^object|container|account$')
# TODO - validate that name is an integer

View File

@ -0,0 +1,27 @@
require 'spec_helper'
describe 'swift::storage::account' do
let :pre_condition do
"class { 'ssh::server::install': }
class { 'swift': swift_hash_suffix => 'foo' }
class { 'swift::storage': storage_local_net_ip => '10.0.0.1' }"
end
let :default_params do
{:package_ensure => 'present'}
end
[{},
{:package_ensure => 'latest'}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
it { should contain_swift__storage__generic('account').with_package_ensure(param_hash[:package_ensure]) }
end
end
end

View File

@ -0,0 +1,95 @@
require 'spec_helper'
describe 'swift::storage::all' do
# TODO I am not testing the upstart code b/c it should be temporary
let :pre_condition do
"class { 'swift': swift_hash_suffix => 'changeme' }
include ssh::server::install
"
end
let :default_params do
{
:devices => '/srv/node',
:object_port => '6000',
:container_port => '6001',
:account_port => '6002'
}
end
describe 'when an internal network ip is not specified' do
it 'should fail' do
expect do
subject
end.should raise_error(Puppet::Error, /Must pass storage_local_net_ip/)
end
end
[{ :storage_local_net_ip => '127.0.0.1' },
{
:devices => '/tmp/node',
:storage_local_net_ip => '10.0.0.1',
:object_port => '7000',
:container_port => '7001',
:account_port => '7002'
}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
['xfsprogs', 'parted'].each do |present_package|
it { should contain_package(present_package).with_ensure('present') }
end
['object', 'container', 'account'].each do |type|
it { should contain_package("swift-#{type}").with_ensure('present') }
it { should contain_service("swift-#{type}").with(
{:provider => 'upstart',
:ensure => 'running',
:enable => true,
:hasstatus => true,
:subscribe => 'Service[rsync]'}
)}
it { should contain_file("/etc/swift/#{type}-server/").with(
{:ensure => 'directory',
:owner => 'swift',
:group => 'swift'}
)}
end
let :storage_server_defaults do
{:devices => param_hash[:devices],
:storage_local_net_ip => param_hash[:storage_local_net_ip]
}
end
it { should contain_swift__storage__server(param_hash[:account_port]).with(
{:type => 'account',
:config_file_path => 'account-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_swift__storage__server(param_hash[:object_port]).with(
{:type => 'object',
:config_file_path => 'object-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_swift__storage__server(param_hash[:container_port]).with(
{:type => 'container',
:config_file_path => 'container-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_class('rsync::server').with(
{:use_xinetd => false,
:address => param_hash[:storage_local_net_ip]
}
)}
end
end
end

View File

@ -0,0 +1,27 @@
require 'spec_helper'
describe 'swift::storage::container' do
let :pre_condition do
"class { 'ssh::server::install': }
class { 'swift': swift_hash_suffix => 'foo' }
class { 'swift::storage': storage_local_net_ip => '10.0.0.1' }"
end
let :default_params do
{:package_ensure => 'present'}
end
[{},
{:package_ensure => 'latest'}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
it { should contain_swift__storage__generic('container').with_package_ensure(param_hash[:package_ensure]) }
end
end
end

View File

@ -0,0 +1,27 @@
require 'spec_helper'
describe 'swift::storage::object' do
let :pre_condition do
"class { 'ssh::server::install': }
class { 'swift': swift_hash_suffix => 'foo' }
class { 'swift::storage': storage_local_net_ip => '10.0.0.1' }"
end
let :default_params do
{:package_ensure => 'present'}
end
[{},
{:package_ensure => 'latest'}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
it { should contain_swift__storage__generic('object').with_package_ensure(param_hash[:package_ensure]) }
end
end
end

View File

@ -3,88 +3,41 @@ require 'spec_helper'
describe 'swift::storage' do
# TODO I am not testing the upstart code b/c it should be temporary
let :pre_condition do
"class { 'swift': swift_hash_suffix => 'changeme' }
include ssh::server::install
"
end
let :default_params do
{
:package_ensure => 'present',
:storage_local_net_ip => '127.0.0.1',
:devices => '/srv/node',
:object_port => '6000',
:container_port => '6001',
:account_port => '6002'
}
end
[{},
{
:package_ensure => 'latest',
:devices => '/tmp/node',
:storage_local_net_ip => '10.0.0.1',
:object_port => '7000',
:container_port => '7001',
:account_port => '7002'
}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
describe 'when required classes are specified' do
let :pre_condition do
"class { 'swift': swift_hash_suffix => 'changeme' }
include ssh::server::install
"
end
describe 'when the local net ip is specified' do
let :params do
param_set
{
:storage_local_net_ip => '127.0.0.1',
}
end
['xfsprogs', 'parted'].each do |present_package|
it { should contain_package(present_package).with_ensure('present') }
end
['object', 'container', 'account'].each do |type|
it { should contain_package("swift-#{type}").with_ensure(param_hash[:package_ensure]) }
it { should contain_service("swift-#{type}").with(
{:provider => 'upstart',
:ensure => 'running',
:enable => true,
:hasstatus => true,
:subscribe => 'Service[rsync]'}
)}
it { should contain_file("/etc/swift/#{type}-server/").with(
{:ensure => 'directory',
:owner => 'swift',
:group => 'swift'}
)}
end
let :storage_server_defaults do
{:devices => param_hash[:devices],
:storage_local_net_ip => param_hash[:storage_local_net_ip]
}
end
it { should contain_swift__storage__server(param_hash[:account_port]).with(
{:type => 'account',
:config_file_path => 'account-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_swift__storage__server(param_hash[:object_port]).with(
{:type => 'object',
:config_file_path => 'object-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_swift__storage__server(param_hash[:container_port]).with(
{:type => 'container',
:config_file_path => 'container-server.conf'}.merge(storage_server_defaults)
)}
it { should contain_class('rsync::server').with(
{:use_xinetd => false,
:address => param_hash[:storage_local_net_ip]
:address => params[:storage_local_net_ip]
}
)}
end
describe 'when local net ip is not specified' do
it 'should fail' do
expect do
subject
end.should raise_error(Puppet::Error, /Must pass storage_local_net_ip/)
end
end
end
describe 'when the dependencies are not specified' do
it 'should fail' do
expect { subject }.should raise_error(Puppet::Error)
end
end
end

View File

@ -0,0 +1,62 @@
require 'spec_helper'
describe 'swift::storage::generic' do
let :title do
'account'
end
let :pre_condition do
"class { 'ssh::server::install': }
class { 'swift': swift_hash_suffix => 'foo' }
class { 'swift::storage': storage_local_net_ip => '10.0.0.1' }"
end
let :default_params do
{:package_ensure => 'present',
:service_provider => 'upstart'}
end
describe 'with an invalid title' do
let :title do
'foo'
end
it 'should fail' do
expect do
subject
end.should raise_error(Puppet::Error, /does not match/)
end
end
['account', 'object', 'container'].each do |t|
[{},
{:package_ensure => 'latest',
:service_provider => 'init'}
].each do |param_set|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
let :title do
t
end
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
it { should contain_package("swift-#{t}").with_ensure(param_hash[:package_ensure]) }
it { should contain_service("swift-#{t}").with(
:ensure => 'running',
:enable => true,
:hasstatus => true,
:provider => param_hash[:service_provider],
:subscribe => 'Service[rsync]'
)}
it { should contain_file("/etc/swift/#{t}-server/").with(
:ensure => 'directory',
:owner => 'swift',
:group => 'swift'
)}
end
# TODO - I do not want to add tests for the upstart stuff
# I need to check the tickets and see if this stuff is fixed
end
end
end