From 01ecb029cd1a0c7f5306f3a7fb135cb6c23b908c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Charlier?= Date: Mon, 4 Jun 2012 11:04:26 -0700 Subject: [PATCH] Implement individual server pipelines This commit adds the ability to specify individual pipelines per storage server. This allows users to specify their own custom pipelines to determine how they implement the middlewares for their storage instances. --- manifests/storage/all.pp | 14 +++++--- manifests/storage/server.pp | 39 ++++++++++++++++------- spec/classes/swift_storage_all_spec.rb | 14 +++++--- spec/defines/swift_storage_server_spec.rb | 21 +++++++++--- 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/manifests/storage/all.pp b/manifests/storage/all.pp index 46837685..e24ae4c6 100644 --- a/manifests/storage/all.pp +++ b/manifests/storage/all.pp @@ -17,10 +17,13 @@ # class swift::storage::all( $storage_local_net_ip, - $devices = '/srv/node', - $object_port = '6000', - $container_port = '6001', - $account_port = '6002' + $devices = '/srv/node', + $object_port = '6000', + $container_port = '6001', + $account_port = '6002', + $object_pipeline = undef, + $container_pipeline = undef, + $account_pipeline = undef ) { class { 'swift::storage': @@ -35,15 +38,18 @@ class swift::storage::all( swift::storage::server { $account_port: type => 'account', config_file_path => 'account-server.conf', + pipeline => $account_pipeline, } swift::storage::server { $container_port: type => 'container', config_file_path => 'container-server.conf', + pipeline => $container_pipeline, } swift::storage::server { $object_port: type => 'object', config_file_path => 'object-server.conf', + pipeline => $object_pipeline, } } diff --git a/manifests/storage/server.pp b/manifests/storage/server.pp index 102a6ff3..d59ccf6b 100644 --- a/manifests/storage/server.pp +++ b/manifests/storage/server.pp @@ -6,23 +6,26 @@ define swift::storage::server( $type, $storage_local_net_ip, - $devices = '/srv/node', - $owner = 'swift', - $group = 'swift', - $max_connections = 25, - $pipeline = ["${type}-server"], - $mount_check = 'false', - $user = 'swift', - $workers = '1', - $concurrency = $::processorcount, + $devices = '/srv/node', + $owner = 'swift', + $group = 'swift', + $max_connections = 25, + $pipeline = ["${type}-server"], + $mount_check = 'false', + $user = 'swift', + $workers = '1', + $concurrency = $::processorcount, + $replicator_concurrency = $concurrency, + $updater_concurrency = $concurrency, + $reaper_concurrency = $concurrency, # this parameters needs to be specified after type and name - $config_file_path = "${type}-server/${name}.conf" + $config_file_path = "${type}-server/${name}.conf" ) { # TODO if array does not include type-server, warn if( (is_array($pipeline) and ! member($pipeline, "${type}-server")) or - $pipline != "${type}-server" + $pipeline != "${type}-server" ) { warning("swift storage server ${type} must specify ${type}-server") } @@ -32,6 +35,7 @@ define swift::storage::server( validate_re($name, '^\d+$') validate_re($type, '^object|container|account$') + validate_array($pipeline) # TODO - validate that name is an integer $bind_port = $name @@ -52,10 +56,23 @@ define swift::storage::server( mode => 640, } + $required_middlewares = split( + inline_template( + "<%= + (pipeline - ['${type}-server']).collect do |x| + 'Swift::Storage::Filter::' + x + '[${type}]' + end.join(',') + %>"), ',') + # you can now add your custom fragments at the user level concat::fragment { "swift-${type}-${name}": target => "/etc/swift/${config_file_path}", content => template("swift/${type}-server.conf.erb"), order => '00', + # require classes for each of the elements of the pipeline + # this is to ensure the user gets reasonable elements if he + # does not specify the backends for every specified element of + # the pipeline + before => $required_middlewares, } } diff --git a/spec/classes/swift_storage_all_spec.rb b/spec/classes/swift_storage_all_spec.rb index 96ca079c..37771b5f 100644 --- a/spec/classes/swift_storage_all_spec.rb +++ b/spec/classes/swift_storage_all_spec.rb @@ -40,7 +40,10 @@ describe 'swift::storage::all' do :storage_local_net_ip => '10.0.0.1', :object_port => '7000', :container_port => '7001', - :account_port => '7002' + :account_port => '7002', + :object_pipeline => ["1", "2"], + :container_pipeline => ["3", "4"], + :account_pipeline => ["5", "6"], } ].each do |param_set| @@ -76,15 +79,18 @@ describe 'swift::storage::all' do it { should contain_swift__storage__server(param_hash[:account_port]).with( {:type => 'account', - :config_file_path => 'account-server.conf'}.merge(storage_server_defaults) + :config_file_path => 'account-server.conf', + :pipeline => param_hash[:account_pipeline] || 'account-server' }.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) + :config_file_path => 'object-server.conf', + :pipeline => param_hash[:object_pipeline] || 'object-server' }.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) + :config_file_path => 'container-server.conf', + :pipeline => param_hash[:container_pipeline] || 'container-server' }.merge(storage_server_defaults) )} it { should contain_class('rsync::server').with( diff --git a/spec/defines/swift_storage_server_spec.rb b/spec/defines/swift_storage_server_spec.rb index 2d0ceb8a..561e48a1 100644 --- a/spec/defines/swift_storage_server_spec.rb +++ b/spec/defines/swift_storage_server_spec.rb @@ -70,7 +70,7 @@ describe 'swift::storage::server' do :mount_check => true, :concurrency => 5, :workers => 7, - :pipeline => 'foo' + :pipeline => ['foo'] }.each do |k,v| describe "when #{k} is set" do let :params do req_params.merge({k => v}) end @@ -78,10 +78,23 @@ describe 'swift::storage::server' do .with_content(/^#{k.to_s}\s*=\s*#{v}\s*$/) } end - describe "when pipline is passed an array" do - let :params do req_params.merge({:pipeline => [1,2,3]}) end + end + describe "when pipeline is passed an array" do + let :params do req_params.merge({:pipeline => [1,2,3]}) end + it { should contain_file(fragment_file).with({ + :content => /^pipeline\s*=\s*1 2 3\s*$/, + :before => ["Swift::Storage::Filter::1[#{t}]", "Swift::Storage::Filter::2[#{t}]", "Swift::Storage::Filter::3[#{t}]"] + })} + end + describe "when pipeline is not passed an array" do + let :params do req_params.merge({:pipeline => 'not an array'}) end + it "should fail" do + expect do + subject + end.should raise_error(Puppet::Error, /is not an Array/) + end + end it { should contain_file(fragment_file) \ - .with_content(/^pipeline\s*=\s*1 2 3\s*$/) } end end