ey-deploy 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/ey-deploy.rb CHANGED
@@ -14,6 +14,26 @@ require 'configuration'
14
14
 
15
15
  module EY
16
16
  def self.node
17
- @node ||= JSON.parse(`sudo cat /etc/chef/dna.json`)
17
+ @node ||= deep_indifferentize(JSON.parse(dna_json))
18
18
  end
19
+
20
+ def self.dna_json
21
+ @dna_json ||= `sudo cat /etc/chef/dna.json`
22
+ end
23
+
24
+ private
25
+ def self.deep_indifferentize(thing)
26
+ if thing.kind_of?(Hash)
27
+ indifferent_hash = Thor::CoreExt::HashWithIndifferentAccess.new
28
+ thing.each do |k, v|
29
+ indifferent_hash[k] = deep_indifferentize(v)
30
+ end
31
+ indifferent_hash
32
+ elsif thing.kind_of?(Array)
33
+ thing.map {|x| deep_indifferentize(x)}
34
+ else
35
+ thing
36
+ end
37
+ end
38
+
19
39
  end
data/lib/ey-deploy/cli.rb CHANGED
@@ -93,7 +93,7 @@ module EY
93
93
  "#{config.user}@#{server.hostname}:#{remote_gem_file}",
94
94
  ]))
95
95
  server.run("sudo #{gem_binary} uninstall -a -x ey-deploy 2>/dev/null")
96
- server.run("sudo #{gem_binary} install '#{remote_gem_file}'")
96
+ server.run("sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
97
97
  end
98
98
  end
99
99
  end
@@ -16,9 +16,19 @@ module EY
16
16
  create_revision_file
17
17
  bundle
18
18
  symlink_configs
19
+
20
+ callback(:before_migrate)
19
21
  migrate
22
+ callback(:after_migrate)
23
+
24
+ callback(:before_symlink)
20
25
  symlink
26
+ callback(:after_symlink)
27
+
28
+ callback(:before_restart)
21
29
  restart
30
+ callback(:after_restart)
31
+
22
32
  cleanup
23
33
 
24
34
  puts "~> finalizing deploy"
@@ -37,7 +47,6 @@ module EY
37
47
  puts "~> Restarting app servers"
38
48
  puts "~> restarting app: #{c.latest_release}"
39
49
  roles :app_master, :app, :solo do
40
- callback(:before_restart)
41
50
  restart_command = case c.stack
42
51
  when "nginx_unicorn"
43
52
  sudo("/etc/init.d/unicorn_#{c.app} deploy")
@@ -46,7 +55,6 @@ module EY
46
55
  when "nginx_passenger", "apache_passenger"
47
56
  sudo("touch #{c.latest_release}/tmp/restart.txt")
48
57
  end
49
- callback(:after_restart)
50
58
  end
51
59
  end
52
60
 
@@ -79,7 +87,6 @@ module EY
79
87
  def migrate
80
88
  roles :app_master, :solo do
81
89
  if c.migrate?
82
- callback(:before_migrate)
83
90
  puts "~> migrating"
84
91
  cmd = "cd #{c.latest_release} && #{c.framework_envs} #{c.migration_command}"
85
92
  puts "~> Migrating: #{cmd}"
@@ -119,7 +126,6 @@ module EY
119
126
 
120
127
  # task
121
128
  def symlink(release_to_link=c.latest_release)
122
- callback(:before_symlink)
123
129
  puts "~> symlinking code"
124
130
  begin
125
131
  sudo "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
@@ -130,10 +136,10 @@ module EY
130
136
  end
131
137
  end
132
138
 
133
- def callback(what, roles=@roles)
139
+ def callback(what)
134
140
  if File.exist?("#{c.latest_release}/deploy/#{what}.rb")
135
141
  eysd_path = $0 # invoke others just like we were invoked
136
- EY::Server.from_roles(roles).each do |server|
142
+ EY::Server.all.each do |server|
137
143
  server.run("#{eysd_path} hook '#{what}' --app '#{config.app}' --release-path #{config.release_path}")
138
144
  end
139
145
  end
@@ -24,6 +24,7 @@ module EY
24
24
  class CallbackContext
25
25
  def initialize(hook_runner, config)
26
26
  @hook_runner, @configuration = hook_runner, config
27
+ @node = node
27
28
  end
28
29
 
29
30
  def method_missing(meth, *args, &blk)
@@ -45,6 +46,34 @@ module EY
45
46
  def sudo(cmd)
46
47
  system(@hook_runner.prepare_sudo(cmd))
47
48
  end
49
+
50
+ # convenience functions for running on certain instance types
51
+ def on_app_master(&blk) on_roles(%w[solo app_master], &blk) end
52
+ def on_app_servers(&blk) on_roles(%w[solo app_master app], &blk) end
53
+ def on_db_master(&blk) on_roles(%w[solo db_master], &blk) end
54
+ def on_db_slaves(&blk) on_roles(%w[db_slave], &blk) end
55
+ def on_db_servers(&blk) on_roles(%w[solo db_master db_slave], &blk) end
56
+ def on_app_servers_and_utilities(&blk) on_roles(%w[solo app_master app util], &blk) end
57
+
58
+ def on_utilities(*names, &blk)
59
+ names.flatten!
60
+ on_roles(%w[util]) do
61
+ blk.call if names.empty? || names.include?(current_name)
62
+ end
63
+ end
64
+
65
+ private
66
+ def on_roles(desired_roles)
67
+ yield if desired_roles.include?(current_role.to_s)
68
+ end
69
+
70
+ def current_role
71
+ node[:instance_role]
72
+ end
73
+
74
+ def current_name
75
+ node[:name]
76
+ end
48
77
  end
49
78
 
50
79
  end
@@ -1,3 +1,3 @@
1
1
  module EY
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -1,6 +1,13 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- describe "deploy hook's context" do
3
+ describe "the deploy-hook API" do
4
+ before(:all) do
5
+ module EY
6
+ def self.dna_json=(j) @dna_json = j; @node = nil end
7
+ end
8
+ EY.dna_json = {}.to_json
9
+ end
10
+
4
11
  before(:each) do
5
12
  @hook_runner = EY::DeployHook.new(options)
6
13
  @callback_context = EY::DeployHook::CallbackContext.new(@hook_runner, @hook_runner.config)
@@ -20,7 +27,7 @@ describe "deploy hook's context" do
20
27
  @callback_context.instance_eval(&blk)
21
28
  end
22
29
 
23
- context "the #run method" do
30
+ context "#run" do
24
31
  it "is available" do
25
32
  run_hook { respond_to?(:run) }.should be_true
26
33
  end
@@ -40,7 +47,7 @@ describe "deploy hook's context" do
40
47
  end
41
48
  end
42
49
 
43
- context "the #sudo method" do
50
+ context "#sudo" do
44
51
  it "is available" do
45
52
  run_hook { respond_to?(:sudo) }.should be_true
46
53
  end
@@ -64,6 +71,35 @@ describe "deploy hook's context" do
64
71
  end
65
72
  end
66
73
 
74
+ context "the @node ivar" do
75
+ before(:each) do
76
+ EY.dna_json = {
77
+ 'instance_role' => 'solo',
78
+ 'applications' => {
79
+ 'myapp' => {
80
+ 'type' => 'rails',
81
+ 'branch' => 'master',
82
+ }
83
+ }
84
+ }.to_json
85
+ end
86
+
87
+ it "is available" do
88
+ run_hook { @node.nil? }.should be_false
89
+ end
90
+
91
+ it "has indifferent access" do
92
+ run_hook { @node[:instance_role] }.should == 'solo'
93
+ run_hook { @node['instance_role'] }.should == 'solo'
94
+ end
95
+
96
+ it "has deep indifferent access" do
97
+ run_hook { @node['applications']['myapp']['type'] }.should == 'rails'
98
+ run_hook { @node[:applications]['myapp'][:type] }.should == 'rails'
99
+ run_hook { @node[:applications][:myapp][:type] }.should == 'rails'
100
+ end
101
+ end
102
+
67
103
  context "the @configuration ivar" do
68
104
  it "is available" do
69
105
  run_hook { @configuration.nil? }.should be_false
@@ -92,4 +128,76 @@ describe "deploy hook's context" do
92
128
  end
93
129
  end
94
130
  end
131
+
132
+ context "has methods to run code only on certain instances" do
133
+ def scenarios
134
+ [
135
+ {:instance_role => 'solo'},
136
+ {:instance_role => 'app_master'},
137
+ {:instance_role => 'app'},
138
+ {:instance_role => 'db_master'},
139
+ {:instance_role => 'db_slave'},
140
+ {:instance_role => 'util', :name => "alpha"},
141
+ {:instance_role => 'util', :name => "beta"},
142
+ {:instance_role => 'util', :name => "gamma"},
143
+ ]
144
+ end
145
+
146
+ def where_code_runs_with(method, *args)
147
+ scenarios.map do |s|
148
+ EY.dna_json = s.to_json
149
+
150
+ if run_hook { send(method, *args) { 'ran!'} } == 'ran!'
151
+ result = s[:instance_role]
152
+ result << "_#{s[:name]}" if s[:name]
153
+ result
154
+ end
155
+ end.compact
156
+ end
157
+
158
+ it "#on_app_master runs on app masters and solos" do
159
+ where_code_runs_with(:on_app_master).should == %w(solo app_master)
160
+ end
161
+
162
+ it "#on_app_servers runs on app masters, app slaves, and solos" do
163
+ where_code_runs_with(:on_app_servers).should == %w(solo app_master app)
164
+ end
165
+
166
+ it "#on_db_master runs on DB masters and solos" do
167
+ where_code_runs_with(:on_db_master).should == %w(solo db_master)
168
+ end
169
+
170
+ it "#on_db_slaves runs on DB slaves only (not solos or masters)" do
171
+ where_code_runs_with(:on_db_slaves).should == %w(db_slave)
172
+ end
173
+
174
+ it "#on_db_servers runs on DB masters, DB slaves, and solos" do
175
+ where_code_runs_with(:on_db_servers).should == %w(solo db_master db_slave)
176
+ end
177
+
178
+ it "#on_app_servers_and_utilities does what it says on the tin" do
179
+ where_code_runs_with(:on_app_servers_and_utilities).should ==
180
+ %w(solo app_master app util_alpha util_beta util_gamma)
181
+ end
182
+
183
+ it "#on_utilities() runs on all utility instances" do
184
+ where_code_runs_with(:on_utilities).should ==
185
+ %w(util_alpha util_beta util_gamma)
186
+ end
187
+
188
+ it "#on_utilities('sometype') runs on only utilities of type 'sometype'" do
189
+ where_code_runs_with(:on_utilities, 'alpha').should == %w(util_alpha)
190
+ end
191
+
192
+ it "#on_utilities('type1', 'type2') runs on utilities of both types" do
193
+ where_code_runs_with(:on_utilities, 'alpha', 'beta').should ==
194
+ %w(util_alpha util_beta)
195
+ end
196
+
197
+ it "#on_utilities can be invoked with (['a', 'b']) or ('a', 'b')" do
198
+ where_code_runs_with(:on_utilities, %w[alpha beta]).should ==
199
+ where_code_runs_with(:on_utilities, 'alpha', 'beta')
200
+ end
201
+
202
+ end
95
203
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 1
9
- version: 0.3.1
8
+ - 2
9
+ version: 0.3.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - EY Cloud Team
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-18 00:00:00 -07:00
17
+ date: 2010-05-26 00:00:00 -07:00
18
18
  default_executable: eysd
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency