chef_cap 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ group :development do
6
6
  gem "wirble"
7
7
  gem "gemcutter"
8
8
  gem "autotest"
9
+ gem "ruby-debug19"
9
10
  end
data/README.rdoc CHANGED
@@ -72,6 +72,8 @@ Optional JSON keys:
72
72
 
73
73
  { "environments": { ENVIRONMENT: { "role_order": { FIRST_ROLE: [OTHER_ROLES] } } } }
74
74
  { "environments": { ENVIRONMENT: { "environment_settings": ENV_HASH } } }
75
+ { "rollback_run_list": [] }
76
+ { "deploy_recipe": "[some_cookbook]::[some_recipe]" }
75
77
 
76
78
 
77
79
  == REQUIREMENTS
@@ -1,3 +1,3 @@
1
1
  module ChefCap
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
data/recipes/chef_cap.rb CHANGED
@@ -25,7 +25,6 @@ if ChefDnaParser.parsed["environments"]
25
25
  ChefDnaParser.parsed["environments"].each_key do |environment|
26
26
  next if environment == "default"
27
27
  environment_hash = ChefDnaParser.parsed["environments"][environment]
28
-
29
28
  set :environments, environments.merge(environment => environment_hash)
30
29
 
31
30
  desc "Set server roles for the #{environment} environment"
@@ -208,35 +207,56 @@ namespace :chef do
208
207
 
209
208
  set "node_hash_for_#{channel[:host].gsub(/\./, "_")}", json_to_modify
210
209
  put json_to_modify.to_json, "/tmp/chef-cap-#{rails_env}-#{channel[:host]}.json", :mode => "0600"
210
+
211
+ rollback_json = json_to_modify.dup
212
+ rollback_json["run_list"] = rollback_json["rollback_run_list"] || []
213
+ set "node_hash_for_#{channel[:host].gsub(/\./, "_")}_rollback", rollback_json
214
+ put rollback_json.to_json, "/tmp/chef-cap-#{rails_env}-#{channel[:host]}-rollback.json", :mode => "0600"
211
215
  end
212
216
  end
213
-
214
- chef.run_chef_solo
217
+ transaction { chef.run_chef_solo }
215
218
  end
216
219
 
217
- task :run_chef_solo do
218
- debug_flag = ENV['QUIET'] ? '' : '-l debug'
219
- 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}"
220
-
221
- hosts_that_have_run = []
222
- unless role_order.empty?
223
- role_order.each do |role, dependent_roles|
224
- role_hosts = (find_servers(:roles => [role.to_sym]).map(&:host) - hosts_that_have_run).uniq
225
- dependent_hosts = (find_servers(:roles => dependent_roles.map(&:to_sym)).map(&:host) - role_hosts - hosts_that_have_run).uniq
226
-
227
- if role_hosts.any?
228
- sudo(run_chef_solo, :hosts => role_hosts)
229
- hosts_that_have_run += role_hosts
230
- end
231
- if dependent_hosts.any?
232
- sudo(run_chef_solo, :hosts => dependent_hosts)
233
- hosts_that_have_run += dependent_hosts
220
+ task :setup_to_run_chef_solo do
221
+ set :debug_flag, ENV['QUIET'] ? '' : '-l debug'
222
+ exec_chef_solo = "env PATH=$PATH:/usr/sbin `cat #{rvm_bin_path}` default exec chef-solo -c /tmp/chef-cap-solo-#{rails_env}.rb #{debug_flag}"
223
+ set :run_chef_solo_deploy_command, "#{exec_chef_solo} -j /tmp/chef-cap-#{rails_env}-`hostname`.json"
224
+ set :run_chef_solo_rollback_command, "#{exec_chef_solo} -j /tmp/chef-cap-#{rails_env}-`hostname`-rollback.json"
225
+ set :run_chef_solo_block, { :block => lambda { |command_to_run|
226
+ hosts_that_have_run = []
227
+ unless role_order.empty?
228
+ role_order.each do |role, dependent_roles|
229
+ role_hosts = (find_servers(:roles => [role.to_sym]).map(&:host) - hosts_that_have_run).uniq
230
+ dependent_hosts = (find_servers(:roles => dependent_roles.map(&:to_sym)).map(&:host) - role_hosts - hosts_that_have_run).uniq
231
+ if role_hosts.any?
232
+ sudo(command_to_run, :hosts => role_hosts)
233
+ hosts_that_have_run += role_hosts
234
+ end
235
+ if dependent_hosts.any?
236
+ sudo(command_to_run, :hosts => dependent_hosts)
237
+ hosts_that_have_run += dependent_hosts
238
+ end
234
239
  end
240
+ else
241
+ sudo(command_to_run)
235
242
  end
236
- else
237
- sudo(run_chef_solo)
238
- end
243
+ } } # Because capistrano automatically calls lambdas on reference which means you can't pass it an argument.
244
+ end
245
+
246
+ task :rollback_pre_hook do
247
+ end
239
248
 
249
+ task :rollback_post_hook do
250
+ end
251
+
252
+ task :run_chef_solo do
253
+ chef.setup_to_run_chef_solo
254
+ on_rollback do
255
+ chef.rollback_pre_hook
256
+ run_chef_solo_block[:block].call(run_chef_solo_rollback_command)
257
+ chef.rollback_post_hook
258
+ end
259
+ run_chef_solo_block[:block].call(run_chef_solo_deploy_command)
240
260
  end
241
261
 
242
262
  desc "Remove all chef-cap files from /tmp"
@@ -98,14 +98,26 @@ def unset(key)
98
98
  end
99
99
 
100
100
  def set(key, value)
101
- key.to_s.gsub!(/\.|-/, '_')
101
+ defined_key = key.to_s.gsub(/\.|-/, '_')
102
+ accessor_key = "key_#{defined_key}".to_sym
103
+ @variables ||= {}
104
+ @variables[accessor_key] = value
102
105
  self.instance_eval(<<-EOS)
103
- def #{key}
104
- #{value.inspect}
106
+ def #{defined_key.to_s}
107
+ @variables[#{accessor_key}]
105
108
  end
106
109
  EOS
110
+ end
111
+
112
+ def set(key, value)
113
+ key.to_s.gsub!(/\.|-/, '_')
107
114
  @variables ||= {}
108
- @variables[key] = value
115
+ @variables[key.to_sym] = value
116
+ self.instance_eval(<<-EOS)
117
+ def #{key.to_s}
118
+ @variables['#{key}'.to_sym]
119
+ end
120
+ EOS
109
121
  end
110
122
 
111
123
  def cap_variable
@@ -129,6 +141,14 @@ def current_description
129
141
  @task_description
130
142
  end
131
143
 
144
+ def transaction(&block)
145
+ yield
146
+ end
147
+
148
+ def on_rollback(&block)
149
+ # ignore for now
150
+ end
151
+
132
152
  def namespace(name, &block)
133
153
  @namespaces ||= {}
134
154
  @namespaces[name] = true
@@ -418,23 +418,11 @@ describe "chef_cap" do
418
418
 
419
419
  chef_cap.parallel_sessions.each do |server_session|
420
420
  if server_session.things_that_were_set.keys.include? "node_hash_for_localhost"
421
- server_session.things_that_were_set["node_hash_for_localhost"].should == {
422
- "environments" => {"some_env"=>{ "rails_env" => "myenv",
423
- "servers"=>[ {"hostname"=>"localhost", "roles"=>["role1", "role2"] }, {"hostname"=>"otherhost.com", "roles"=>["role1"]}]}},
424
- "chef" => {"root"=>"path_to_cookbooks", "version"=>"0.1982.1234"},
425
- "run_list" => ["foo", "bar"],
426
- "environment" => {"rails_env" => "myenv", "roles" => ["role1", "role2"], "servers"=>[ {"primary" => [], "hostname"=>"localhost", "roles"=>["role1", "role2"] },
427
- {"primary" => [], "hostname"=>"otherhost.com", "roles"=>["role1"]}]},
428
- "roles" => {"role1" => {"run_list"=>["foo"]}, "role2"=>{"run_list"=>["foo", "bar"]}}}
421
+ server_session.things_that_were_set["node_hash_for_localhost"]["environment"]["roles"].should == ["role1", "role2"]
422
+ server_session.things_that_were_set["node_hash_for_localhost"]["run_list"].should == ["foo", "bar"]
429
423
  elsif server_session.things_that_were_set.keys.include? "node_hash_for_otherhost"
430
- server_session.things_that_were_set["node_hash_for_otherhost"].should == {
431
- "environments" => {"some_env"=>{ "rails_env" => "myenv",
432
- "servers"=>[{"hostname"=>"localhost", "roles"=>["role1", "role2"]}, {"hostname"=>"otherhost.com", "roles"=>["role1"]}]}},
433
- "chef"=>{"root"=>"path_to_cookbooks"},
434
- "run_list"=>["foo"],
435
- "environment"=>{"rails_env" => "myenv", "roles" => ["role1"], "servers"=>[{"primary" => [], "hostname"=>"localhost", "roles"=>["role1", "role2"]},
436
- {"primary" => [], "hostname"=>"otherhost.com", "roles"=>["role1"]}]},
437
- "roles"=>{"role1"=>{"run_list"=>["foo"]}, "role2"=>{"run_list"=>["foo", "bar"]}}}
424
+ server_session.things_that_were_set["node_hash_for_otherhost"]["environment"]["roles"].should == ["role1"]
425
+ server_session.things_that_were_set["node_hash_for_otherhost"]["run_list"].should == ["foo"]
438
426
  end
439
427
  end
440
428
  end
@@ -520,6 +508,7 @@ describe "chef_cap" do
520
508
 
521
509
  chef_cap.cap_task[:some_env].should_not be_nil
522
510
  chef_cap.cap_task[:some_env].call
511
+ chef_cap.cap_task["chef:setup_to_run_chef_solo"].call
523
512
  end
524
513
 
525
514
  it "invokes chef-solo on db hosts then app and web only hosts" do
@@ -557,6 +546,7 @@ describe "chef_cap" do
557
546
 
558
547
  chef_cap.cap_task[:some_env].should_not be_nil
559
548
  chef_cap.cap_task[:some_env].call
549
+ chef_cap.cap_task["chef:setup_to_run_chef_solo"].call
560
550
  end
561
551
 
562
552
 
@@ -608,6 +598,7 @@ describe "chef_cap" do
608
598
 
609
599
  chef_cap.cap_task[:some_env].should_not be_nil
610
600
  chef_cap.cap_task[:some_env].call
601
+ chef_cap.cap_task["chef:setup_to_run_chef_solo"].call
611
602
  end
612
603
 
613
604
  it "invokes chef-solo on dep0 then dep1 and dep2 then finally dep3" do
@@ -658,6 +649,7 @@ describe "chef_cap" do
658
649
 
659
650
  chef_cap.cap_task[:some_env].should_not be_nil
660
651
  chef_cap.cap_task[:some_env].call
652
+ chef_cap.cap_task["chef:setup_to_run_chef_solo"].call
661
653
  end
662
654
 
663
655
  it "invokes chef-solo on dep0 then dep1 and dep2 then finally dep3" do
@@ -1004,6 +996,7 @@ describe "chef_cap" do
1004
996
  it "shoves the value into the node json alongside branch" do
1005
997
  ENV['rev'] = "123"
1006
998
  ENV['branch'] = "somebranch"
999
+ chef_cap.stub(:system).and_return(true)
1007
1000
  chef_cap.stub!(:put => "stubbed")
1008
1001
  chef_cap.stub!(:upload => "stubbed")
1009
1002
  chef_cap.stub!(:sudo => "stubbed")
@@ -1012,19 +1005,10 @@ describe "chef_cap" do
1012
1005
  chef_cap.parallel_mocks << proc { |server_session|
1013
1006
  server_session.stub!(:put => "stubbed")
1014
1007
  server_session.stub!(:sudo => "stubbed")
1015
- server_session.should_receive(:set).with("node_hash_for_localhost",
1016
- {
1017
- "chef"=>{"root"=>"path_to_cookbooks"},
1018
- "environments" => { "some_env"=>{"servers"=>[{"hostname"=>"localhost", "roles"=>["role1", "role2"]}]}},
1019
- "shared"=>{"foo"=>"bar"},
1020
- "foo"=>"bar",
1021
- "something"=>"other",
1022
- "environment"=> {"revision"=>"123", "branch" => "somebranch",
1023
- "roles" => ["role1"],
1024
- "servers"=>[{"primary" => [], "hostname"=>"localhost", "roles"=>["role1", "role2"]}]},
1025
- "roles"=>{"role1"=>{"something"=>"other"}},
1026
- "run_list"=>nil
1027
- })
1008
+ server_session.should_receive(:set) do |key, value|
1009
+ value["environment"]["revision"].should == "123"
1010
+ value["environment"]["branch"].should == "somebranch"
1011
+ end.twice
1028
1012
  }
1029
1013
  chef_cap.cap_task["chef:deploy"].call
1030
1014
  end
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.3.2
4
+ version: 0.3.3
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-12-21 00:00:00.000000000Z
12
+ date: 2011-12-29 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
16
- requirement: &2153316960 !ruby/object:Gem::Requirement
16
+ requirement: &2157107720 !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: *2153316960
24
+ version_requirements: *2157107720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-rails
27
- requirement: &2153316420 !ruby/object:Gem::Requirement
27
+ requirement: &2157107140 !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: *2153316420
35
+ version_requirements: *2157107140
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: -2180159314980717012
94
+ hash: -4226372811426833892
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
@@ -100,10 +100,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
100
  version: '0'
101
101
  segments:
102
102
  - 0
103
- hash: -2180159314980717012
103
+ hash: -4226372811426833892
104
104
  requirements: []
105
105
  rubyforge_project:
106
- rubygems_version: 1.8.11
106
+ rubygems_version: 1.8.12
107
107
  signing_key:
108
108
  specification_version: 3
109
109
  summary: capistrano + chef-solo == chef_cap"