ey-deploy 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,28 +10,32 @@ module EY
10
10
  exit(1)
11
11
  end
12
12
 
13
- method_option :migrate, :type => :string,
14
- :desc => "Run migrations with this deploy",
15
- :aliases => ["-m"]
13
+ method_option :migrate, :type => :string,
14
+ :desc => "Run migrations with this deploy",
15
+ :aliases => ["-m"]
16
16
 
17
- method_option :branch, :type => :string,
18
- :desc => "Branch to deploy from, defaults to master",
19
- :aliases => ["-b"]
17
+ method_option :branch, :type => :string,
18
+ :desc => "Branch to deploy from, defaults to master",
19
+ :aliases => ["-b"]
20
20
 
21
- method_option :repo, :type => :string,
22
- :desc => "Remote repo to deploy",
23
- :aliases => ["-r"]
21
+ method_option :repo, :type => :string,
22
+ :desc => "Remote repo to deploy",
23
+ :aliases => ["-r"]
24
24
 
25
- method_option :app, :type => :string,
26
- :required => true,
27
- :desc => "Application to deploy",
28
- :aliases => ["-a"]
25
+ method_option :app, :type => :string,
26
+ :required => true,
27
+ :desc => "Application to deploy",
28
+ :aliases => ["-a"]
29
29
 
30
- method_option :config, :type => :string,
31
- :desc => "Additional configuration"
30
+ method_option :config, :type => :string,
31
+ :desc => "Additional configuration"
32
+
33
+ method_option :instances, :type => :array,
34
+ :desc => "Instances in cluster"
32
35
 
33
36
  desc "deploy", "Deploy code from /data/<app>"
34
37
  def deploy(default_task=:deploy)
38
+ EY::Server.all = parse_instances(options[:instances])
35
39
  invoke :propagate
36
40
  EY::Deploy.run(options.merge("default_task" => default_task))
37
41
  end
@@ -44,6 +48,13 @@ module EY
44
48
  method_option :release_path, :type => :string,
45
49
  :desc => "Value for #release_path in hooks (mostly for internal coordination)",
46
50
  :aliases => ["-r"]
51
+
52
+ method_option :current_role, :type => :string,
53
+ :desc => "Value for #current_role in hooks"
54
+
55
+ method_option :current_name, :type => :string,
56
+ :desc => "Value for #current_name in hooks"
57
+
47
58
  desc "hook [NAME]", "Run a particular deploy hook"
48
59
  def hook(hook_name)
49
60
  EY::DeployHook.new(options).run(hook_name)
@@ -77,5 +88,15 @@ module EY
77
88
  server.run("sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
78
89
  end
79
90
  end
91
+
92
+ private
93
+
94
+ def parse_instances(instance_strings)
95
+ instance_strings.map do |s|
96
+ tuple = s.split(/,/)
97
+ {:hostname => tuple[0], :role => tuple[1], :name => tuple[2]}
98
+ end
99
+ end
100
+
80
101
  end
81
102
  end
@@ -198,7 +198,11 @@ module EY
198
198
  @callbacks_reached ||= true
199
199
  if File.exist?("#{c.latest_release}/deploy/#{what}.rb")
200
200
  eysd_path = $0 # invoke others just like we were invoked
201
- run "#{eysd_path} hook '#{what}' --app '#{config.app}' --release-path #{config.release_path}"
201
+ run "#{eysd_path} hook '#{what}' --app '#{config.app}' --release-path #{config.release_path}" do |server, cmd|
202
+ cmd << " --current-role '#{server.role}'"
203
+ cmd << " --current-name '#{server.name}'" if server.name
204
+ cmd
205
+ end
202
206
  end
203
207
  end
204
208
 
@@ -9,7 +9,7 @@ module EY
9
9
  end
10
10
 
11
11
  def callback_context
12
- @context ||= CallbackContext.new(self, config)
12
+ @context ||= CallbackContext.new(config)
13
13
  end
14
14
 
15
15
  def run(hook)
@@ -22,8 +22,8 @@ module EY
22
22
  end
23
23
 
24
24
  class CallbackContext
25
- def initialize(hook_runner, config)
26
- @hook_runner, @configuration = hook_runner, config
25
+ def initialize(config)
26
+ @configuration = config
27
27
  @node = node
28
28
  end
29
29
 
@@ -40,11 +40,11 @@ module EY
40
40
  end
41
41
 
42
42
  def run(cmd)
43
- system(@hook_runner.prepare_run(cmd))
43
+ system(Escape.shell_command(["sh", "-l", "-c", cmd]))
44
44
  end
45
45
 
46
46
  def sudo(cmd)
47
- system(@hook_runner.prepare_sudo(cmd))
47
+ system(Escape.shell_command(["sudo", "sh", "-l", "-c", cmd]))
48
48
  end
49
49
 
50
50
  # convenience functions for running on certain instance types
@@ -67,13 +67,6 @@ module EY
67
67
  yield if desired_roles.include?(current_role.to_s)
68
68
  end
69
69
 
70
- def current_role
71
- node[:instance_role]
72
- end
73
-
74
- def current_name
75
- node[:name]
76
- end
77
70
  end
78
71
 
79
72
  end
@@ -5,6 +5,11 @@ module EY
5
5
  class Server < Struct.new(:hostname, :role, :name)
6
6
  include VerboseSystem
7
7
 
8
+ def initialize(*fields)
9
+ super
10
+ self.role = self.role.to_sym
11
+ end
12
+
8
13
  def self.config=(config)
9
14
  @@config = config
10
15
  end
@@ -24,41 +29,20 @@ module EY
24
29
  end
25
30
  end
26
31
 
27
- def self.all
28
- @servers ||= ([current] << app_slaves << db_master << db_slaves << utils).flatten.compact
29
- end
30
-
31
- def self.current
32
- @current ||= new(open("http://169.254.169.254/latest/meta-data/local-hostname").read, EY.node["instance_role"].to_sym)
32
+ def self.from_hash(h)
33
+ new(h[:hostname], h[:role], h[:name])
33
34
  end
34
35
 
35
- def self.app_slaves
36
- @app_slaves ||= Array(EY.node["members"]).map do |slave|
37
- new(slave, :app)
38
- end.reject do |server|
39
- server.hostname == current.hostname
40
- end
41
- end
42
-
43
- def self.db_master
44
- return @db_master if @db_master
45
- if EY.node["instance_role"] == "solo"
46
- @db_master = nil
47
- else
48
- @db_master = EY.node["db_host"] && new(EY.node["db_host"], :db_master)
49
- end
36
+ def self.all
37
+ @all
50
38
  end
51
39
 
52
- def self.db_slaves
53
- EY.node["db_slaves"].map do |slave|
54
- new(slave, :db_slave)
55
- end
40
+ def self.all=(server_hashes)
41
+ @all = server_hashes.map { |s| from_hash(s) }
56
42
  end
57
43
 
58
- def self.utils
59
- EY.node["utility_instances"].map do |server|
60
- new(server["hostname"], :util, server["name"])
61
- end
44
+ def self.current
45
+ all.find {|s| s.local? }
62
46
  end
63
47
 
64
48
  def local?
@@ -36,12 +36,12 @@ module EY
36
36
  end
37
37
  end
38
38
 
39
- def run(cmd)
40
- run_on_roles { prepare_run cmd }
39
+ def run(cmd, &blk)
40
+ run_on_roles(cmd, &blk)
41
41
  end
42
42
 
43
- def sudo(cmd)
44
- run_on_roles { prepare_sudo cmd }
43
+ def sudo(cmd, &blk)
44
+ run_on_roles(cmd, %w[sudo sh -l -c], &blk)
45
45
  end
46
46
 
47
47
  def prepare_run(command)
@@ -54,10 +54,10 @@ module EY
54
54
 
55
55
  private
56
56
 
57
- def run_on_roles
58
- cmd = yield
57
+ def run_on_roles(cmd, wrapper=%w[sh -l -c])
59
58
  EY::Server.from_roles(@roles).inject(false) do |acc, server|
60
- failure = !server.run(cmd)
59
+ to_run = block_given? ? yield(server, cmd.dup) : cmd
60
+ failure = !server.run(Escape.shell_command(wrapper + [to_run]))
61
61
  acc || failure
62
62
  end && raise(EY::RemoteFailure)
63
63
  end
@@ -1,3 +1,3 @@
1
1
  module EY
2
- VERSION = '0.4.1'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -2,14 +2,14 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe "the deploy-hook API" do
4
4
  before(:each) do
5
- @hook_runner = EY::DeployHook.new(options)
6
- @callback_context = EY::DeployHook::CallbackContext.new(@hook_runner, @hook_runner.config)
5
+ hook = EY::DeployHook.new(options)
6
+ @callback_context = EY::DeployHook::CallbackContext.new(hook.config)
7
7
  end
8
8
 
9
9
  def run_hook(options={}, &blk)
10
10
  raise ArgumentError unless block_given?
11
11
  options.each do |k, v|
12
- @hook_runner.config.configuration[k] = v # ugh
12
+ @callback_context.configuration[k] = v
13
13
  end
14
14
 
15
15
  # The hooks on the filesystem are run by passing a string to
@@ -138,7 +138,8 @@ describe "the deploy-hook API" do
138
138
 
139
139
  def where_code_runs_with(method, *args)
140
140
  scenarios.map do |s|
141
- EY.dna_json = s.to_json
141
+ @callback_context.configuration[:current_role] = s[:instance_role]
142
+ @callback_context.configuration[:current_name] = s[:name]
142
143
 
143
144
  if run_hook { send(method, *args) { 'ran!'} } == 'ran!'
144
145
  result = s[:instance_role]
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
8
- - 1
9
- version: 0.4.1
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - EY Cloud Team
@@ -14,23 +14,25 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-16 00:00:00 -07:00
17
+ date: 2010-06-17 00:00:00 -07:00
18
18
  default_executable: eysd
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
21
+ prerelease: false
22
+ name: rake
23
+ requirement: &id001 !ruby/object:Gem::Requirement
22
24
  requirements:
23
25
  - - ">="
24
26
  - !ruby/object:Gem::Version
25
27
  segments:
26
28
  - 0
27
29
  version: "0"
28
- name: rake
29
- prerelease: false
30
- requirement: *id001
31
30
  type: :runtime
31
+ version_requirements: *id001
32
32
  - !ruby/object:Gem::Dependency
33
- version_requirements: &id002 !ruby/object:Gem::Requirement
33
+ prerelease: false
34
+ name: escape
35
+ requirement: &id002 !ruby/object:Gem::Requirement
34
36
  requirements:
35
37
  - - ">="
36
38
  - !ruby/object:Gem::Version
@@ -39,22 +41,20 @@ dependencies:
39
41
  - 0
40
42
  - 4
41
43
  version: 0.0.4
42
- name: escape
43
- prerelease: false
44
- requirement: *id002
45
44
  type: :runtime
45
+ version_requirements: *id002
46
46
  - !ruby/object:Gem::Dependency
47
- version_requirements: &id003 !ruby/object:Gem::Requirement
47
+ prerelease: false
48
+ name: json
49
+ requirement: &id003 !ruby/object:Gem::Requirement
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
51
53
  segments:
52
54
  - 0
53
55
  version: "0"
54
- name: json
55
- prerelease: false
56
- requirement: *id003
57
56
  type: :runtime
57
+ version_requirements: *id003
58
58
  description:
59
59
  email: cloud@engineyard.com
60
60
  executables: