ey-deploy 0.4.1 → 0.5.0

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.
@@ -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: