chef_cap 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module ChefCap
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.6"
3
3
  end
@@ -32,7 +32,12 @@ if ChefDnaParser.parsed["environments"]
32
32
  task environment.to_sym do
33
33
  set :environment_settings, environment_hash
34
34
  set :rails_env, environment_hash["rails_env"] || environment
35
- set :role_order, environment_hash["role_order"] || {}
35
+ if environment_hash["role_order"]
36
+ set :role_order, environment_hash["role_order"]
37
+ else
38
+ set(:role_order, {}) unless defined?(role_order)
39
+ end
40
+
36
41
  default_environment["RAILS_ENV"] = rails_env
37
42
 
38
43
  ChefCapHelper.parse_hash(environment_hash)
@@ -203,13 +208,20 @@ namespace :chef do
203
208
  debug_flag = ENV['QUIET'] ? '' : '-l debug'
204
209
  run_chef_solo = "env PATH=$PATH:/usr/sbin `cat #{rvm_bin_path}` default exec chef-solo -c /tmp/chef-cap-solo-#{rails_env}.rb -j /tmp/chef-cap-#{rails_env}-`hostname`.json #{debug_flag}"
205
210
 
211
+ hosts_that_have_run = []
206
212
  unless role_order.empty?
207
213
  role_order.each do |role, dependent_roles|
208
- role_hosts = find_servers(:roles => [role.to_sym]).map(&:host)
209
- dependent_hosts = find_servers(:roles => dependent_roles.map(&:to_sym)).map(&:host) - role_hosts
214
+ role_hosts = (find_servers(:roles => [role.to_sym]).map(&:host) - hosts_that_have_run).uniq
215
+ dependent_hosts = (find_servers(:roles => dependent_roles.map(&:to_sym)).map(&:host) - role_hosts - hosts_that_have_run).uniq
210
216
 
211
- sudo(run_chef_solo, :hosts => role_hosts) if role_hosts.any?
212
- sudo(run_chef_solo, :hosts => dependent_hosts) if dependent_hosts.any?
217
+ if role_hosts.any?
218
+ sudo(run_chef_solo, :hosts => role_hosts)
219
+ hosts_that_have_run += role_hosts
220
+ end
221
+ if dependent_hosts.any?
222
+ sudo(run_chef_solo, :hosts => dependent_hosts)
223
+ hosts_that_have_run += dependent_hosts
224
+ end
213
225
  end
214
226
  else
215
227
  sudo(run_chef_solo)
@@ -6,17 +6,18 @@ class ChefCapHelper
6
6
 
7
7
  def parse_hash(hash, prefix = nil)
8
8
  hash.each do |key, value|
9
+ key = [prefix, key].compact.join("_").to_sym
9
10
  if value.is_a? Hash
10
- parse_hash(value, [prefix, key].compact.join("_"))
11
+ parse_hash(value, key)
12
+ end
13
+ next if key == :ssh_options # skip restricted variables
14
+
15
+ unless value.nil?
16
+ debug("Setting #{key.inspect} => #{value.inspect}")
17
+ ChefCapConfiguration.configuration.set key, value
11
18
  else
12
- key = [prefix, key].compact.join("_").to_sym
13
- unless value.nil?
14
- debug("Setting #{key.inspect} => #{value.inspect}")
15
- ChefCapConfiguration.configuration.set key, value
16
- else
17
- debug("Unsetting #{key.inspect} => #{value.inspect}")
18
- ChefCapConfiguration.configuration.unset key
19
- end
19
+ debug("Unsetting #{key.inspect} => #{value.inspect}")
20
+ ChefCapConfiguration.configuration.unset key
20
21
  end
21
22
  end
22
23
  end
@@ -12,6 +12,7 @@ describe ChefCapHelper do
12
12
 
13
13
  context "given a prefix" do
14
14
  it "should call itself recursively" do
15
+ @configuration.should_receive(:set).with(:prefix_somehash, {"somekey" => "somevalue"})
15
16
  @configuration.should_receive(:set).with(:prefix_somehash_somekey, "somevalue")
16
17
  ChefCapHelper.parse_hash({"somehash" => {"somekey" => "somevalue"}}, "prefix")
17
18
  end
@@ -19,6 +20,7 @@ describe ChefCapHelper do
19
20
 
20
21
  context "given no prefix" do
21
22
  it "should call itself recursively" do
23
+ @configuration.should_receive(:set).with(:somehash, {"somekey" => "somevalue"})
22
24
  @configuration.should_receive(:set).with(:somehash_somekey, "somevalue")
23
25
  ChefCapHelper.parse_hash({"somehash" => {"somekey" => "somevalue"}})
24
26
  end
@@ -17,8 +17,6 @@ def find_servers(options = {})
17
17
  @servers[role][:servers].each do |server|
18
18
  servers << TestCapServer.new(server)
19
19
  end
20
- else
21
- raise ArgumentError, "unknown role `#{role}'" unless roles.include?(role)
22
20
  end
23
21
  end
24
22
  servers
@@ -67,7 +65,7 @@ def roles
67
65
  role_klass.instance_eval(<<-EOS)
68
66
  def servers
69
67
  role_servers = []
70
- #{cap_role[key.to_sym][:servers].inspect}.each do |server_hostname|
68
+ #{(cap_role[key.to_sym] || {})[:servers].inspect}.each do |server_hostname|
71
69
  host = TestCapServer.new
72
70
  host.instance_eval(<<-EOH)
73
71
  def host
@@ -565,6 +565,109 @@ describe "chef_cap" do
565
565
  chef_cap.cap_task["chef:run_chef_solo"].call
566
566
  end
567
567
  end
568
+
569
+ context "with multiple dependent roles" do
570
+ before do
571
+ @test_dna = <<-JS
572
+ {
573
+ "chef": {
574
+ "root": "path_to_cookbooks"
575
+ },
576
+ "environments": {
577
+ "some_env": {
578
+ "rails_env": "myenv",
579
+ "role_order": { "dep0": ["dep1", "dep2"], "dep1": ["dep3"] },
580
+ "servers": [
581
+ {
582
+ "hostname": "dep0host",
583
+ "roles": ["dep0"]
584
+ },
585
+ {
586
+ "hostname": "dep1host",
587
+ "roles": ["dep1"]
588
+ },
589
+ {
590
+ "hostname": "dep2host",
591
+ "roles": ["dep2"]
592
+ },
593
+ {
594
+ "hostname": "dep3host",
595
+ "roles": ["dep3"]
596
+ }
597
+ ]
598
+ }
599
+ },
600
+ "roles": {
601
+ "dep0": { "run_list": [] },
602
+ "dep1": { "run_list": [] },
603
+ "dep2": { "run_list": [] },
604
+ "dep3": { "run_list": [] }
605
+ }
606
+ }
607
+ JS
608
+
609
+ chef_cap.cap_task[:some_env].should_not be_nil
610
+ chef_cap.cap_task[:some_env].call
611
+ end
612
+
613
+ it "invokes chef-solo on dep0 then dep1 and dep2 then finally dep3" do
614
+ chef_cap.cap_servers.should_not be_empty
615
+
616
+ chef_cap.should_receive(:sudo).ordered.with(anything, :hosts => ["dep0host"]).and_return("mocked")
617
+ chef_cap.should_receive(:sudo).ordered.with(anything, :hosts => ["dep1host", "dep2host"]).and_return("mocked")
618
+ chef_cap.should_receive(:sudo).ordered.with(anything, :hosts => ["dep3host"]).and_return("mocked")
619
+ chef_cap.cap_task["chef:run_chef_solo"].call
620
+ end
621
+
622
+ end
623
+
624
+ context "with multiple roles where some required role host is missing" do
625
+ before do
626
+ @test_dna = <<-JS
627
+ {
628
+ "chef": {
629
+ "root": "path_to_cookbooks"
630
+ },
631
+ "environments": {
632
+ "defaults": {
633
+ "role_order": { "dep0": ["dep1"], "dep1": ["dep2", "dep3"] }
634
+ },
635
+ "some_env": {
636
+ "rails_env": "myenv",
637
+ "servers": [
638
+ {
639
+ "hostname": "dep0host",
640
+ "roles": ["dep0"]
641
+ },
642
+ {
643
+ "hostname": "dep2host",
644
+ "roles": ["dep2", "dep3"]
645
+ }
646
+ ]
647
+ }
648
+ },
649
+ "roles": {
650
+ "dep0": { "run_list": [] },
651
+ "dep1": { "run_list": [] },
652
+ "dep2": { "run_list": [] },
653
+ "dep3": { "run_list": [] }
654
+ }
655
+ }
656
+ JS
657
+
658
+ chef_cap.cap_task[:some_env].should_not be_nil
659
+ chef_cap.cap_task[:some_env].call
660
+ end
661
+
662
+ it "invokes chef-solo on dep0 then dep1 and dep2 then finally dep3" do
663
+ chef_cap.cap_servers.should_not be_empty
664
+
665
+ chef_cap.should_receive(:sudo).ordered.with(anything, :hosts => ["dep0host"]).and_return("mocked")
666
+ chef_cap.should_receive(:sudo).ordered.with(anything, :hosts => ["dep2host"]).and_return("mocked")
667
+ chef_cap.cap_task["chef:run_chef_solo"].call
668
+ end
669
+
670
+ end
568
671
  end
569
672
 
570
673
  describe "merging roles with shared" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef_cap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-17 00:00:00.000000000Z
12
+ date: 2011-12-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
16
- requirement: &2153395380 !ruby/object:Gem::Requirement
16
+ requirement: &2151806800 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.5.5
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2153395380
24
+ version_requirements: *2151806800
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-rails
27
- requirement: &2153394260 !ruby/object:Gem::Requirement
27
+ requirement: &2151804840 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '2.1'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2153394260
35
+ version_requirements: *2151804840
36
36
  description: chef_cap uses chef"s JSON config format to drive both capistrano and
37
37
  chef-solo"
38
38
  email:
@@ -91,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
91
  version: '0'
92
92
  segments:
93
93
  - 0
94
- hash: 3095980632773080420
94
+ hash: -2863680832922122832
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
100
  version: '0'
101
101
  segments:
102
102
  - 0
103
- hash: 3095980632773080420
103
+ hash: -2863680832922122832
104
104
  requirements: []
105
105
  rubyforge_project:
106
106
  rubygems_version: 1.8.11