engineyard-serverside 2.6.19 → 2.7.0.pre

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.
Files changed (27) hide show
  1. data/lib/engineyard-serverside/callbacks.rb +11 -0
  2. data/lib/engineyard-serverside/callbacks/collection.rb +17 -0
  3. data/lib/engineyard-serverside/callbacks/collection/base.rb +94 -0
  4. data/lib/engineyard-serverside/callbacks/collection/combined.rb +45 -0
  5. data/lib/engineyard-serverside/callbacks/collection/deploy_hooks.rb +21 -0
  6. data/lib/engineyard-serverside/callbacks/collection/service_hooks.rb +17 -0
  7. data/lib/engineyard-serverside/callbacks/collection/service_hooks/collection.rb +24 -0
  8. data/lib/engineyard-serverside/callbacks/collection/service_hooks/combined.rb +40 -0
  9. data/lib/engineyard-serverside/callbacks/distributor.rb +23 -0
  10. data/lib/engineyard-serverside/callbacks/distributor/base.rb +38 -0
  11. data/lib/engineyard-serverside/callbacks/distributor/executable.rb +19 -0
  12. data/lib/engineyard-serverside/callbacks/distributor/executable/runnable.rb +41 -0
  13. data/lib/engineyard-serverside/callbacks/distributor/executable/unrunnable.rb +19 -0
  14. data/lib/engineyard-serverside/callbacks/distributor/ruby.rb +59 -0
  15. data/lib/engineyard-serverside/callbacks/distributor/ruby/distributor.rb +57 -0
  16. data/lib/engineyard-serverside/callbacks/hooks.rb +0 -0
  17. data/lib/engineyard-serverside/callbacks/hooks/app.rb +17 -0
  18. data/lib/engineyard-serverside/callbacks/hooks/base.rb +39 -0
  19. data/lib/engineyard-serverside/callbacks/hooks/service.rb +24 -0
  20. data/lib/engineyard-serverside/callbacks/service_hook.rb +20 -0
  21. data/lib/engineyard-serverside/deploy.rb +7 -45
  22. data/lib/engineyard-serverside/deploy_hook.rb +20 -83
  23. data/lib/engineyard-serverside/deploy_hook/callback_context.rb +77 -0
  24. data/lib/engineyard-serverside/paths.rb +9 -0
  25. data/lib/engineyard-serverside/version.rb +1 -1
  26. metadata +187 -193
  27. checksums.yaml +0 -7
@@ -0,0 +1,57 @@
1
+ require 'engineyard-serverside/callbacks/distributor/base'
2
+
3
+ require 'escape'
4
+
5
+ module EY
6
+ module Serverside
7
+ module Callbacks
8
+ module Distributor
9
+ module Ruby
10
+
11
+ class Distributor < Base
12
+ def distribute
13
+ shell.status "Running deploy hook: #{hook}.rb"
14
+
15
+ runner.run escaped_command(hook) do |server, cmd|
16
+ instance_args = [
17
+ '--current-roles', server.roles.to_a.join(' ')
18
+ ]
19
+
20
+ if server.name
21
+ instance_args.push('--current-name')
22
+ instance_args.push(server.name.to_s)
23
+ end
24
+
25
+ instance_args.push('--config')
26
+ instance_args.push(config.to_json)
27
+
28
+ cmd << " " << Escape.shell_command(instance_args)
29
+ end
30
+ end
31
+
32
+ private
33
+ def escaped_command(hook)
34
+ Escape.shell_command(command_for(hook.callback_name))
35
+ end
36
+ def command_for(hook_name)
37
+ cmd = [
38
+ About.binary,
39
+ 'hook', hook_name.to_s,
40
+ '--app', config.app,
41
+ '--environment-name', config.environment_name,
42
+ '--account-name', config.account_name,
43
+ '--release-path', paths.active_release.to_s,
44
+ '--framework-env', config.framework_env.to_s
45
+ ]
46
+
47
+ cmd.push('--verbose') if config.verbose
48
+
49
+ cmd
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
File without changes
@@ -0,0 +1,17 @@
1
+ require 'engineyard-serverside/callbacks/hooks/base'
2
+
3
+ module EY
4
+ module Serverside
5
+ module Callbacks
6
+ module Hooks
7
+
8
+ class App < Base
9
+ def to_s
10
+ "deploy/#{callback_name}"
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ require 'pathname'
2
+
3
+ module EY
4
+ module Serverside
5
+ module Callbacks
6
+ module Hooks
7
+
8
+ class Base
9
+ attr_reader :path, :callback_name, :flavor
10
+
11
+ def initialize(file_path)
12
+ @path = Pathname.new(file_path)
13
+
14
+ filename = path.basename
15
+
16
+ callback = filename.basename('.rb')
17
+
18
+ @flavor = filename == callback ? :executable : :ruby
19
+
20
+ @callback_name = callback.to_s.to_sym
21
+ end
22
+
23
+ def matches?(callback)
24
+ callback_name == callback
25
+ end
26
+
27
+ def read
28
+ path.read
29
+ end
30
+
31
+ def to_s
32
+ raise "Unimplemented"
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ require 'engineyard-serverside/callbacks/hooks/base'
2
+
3
+ module EY
4
+ module Serverside
5
+ module Callbacks
6
+ module Hooks
7
+
8
+ class Service < Base
9
+ attr_reader :service_name
10
+
11
+ def initialize(file_path)
12
+ super
13
+ @service_name = path.dirname.basename.to_s
14
+ end
15
+
16
+ def to_s
17
+ "service/#{service_name}/#{callback_name}"
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'pathname'
2
+
3
+ require 'engineyard-serverside/callbacks/base_hook'
4
+
5
+ module EY
6
+ module Serverside
7
+ module Callbacks
8
+
9
+ class ServiceHook < BaseHook
10
+ attr_reader :service_name
11
+
12
+ def initialize(file_path)
13
+ super
14
+ @service_name = path.dirname.basename.to_s
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -5,6 +5,7 @@ require 'engineyard-serverside/rails_assets'
5
5
  require 'engineyard-serverside/maintenance'
6
6
  require 'engineyard-serverside/dependency_manager'
7
7
  require 'engineyard-serverside/dependency_manager/legacy_helpers'
8
+ require 'engineyard-serverside/callbacks'
8
9
 
9
10
  module EY
10
11
  module Serverside
@@ -450,27 +451,9 @@ defaults:
450
451
  end
451
452
 
452
453
  def callback(what)
454
+ load_callbacks
453
455
  @callbacks_reached ||= true
454
-
455
- if paths.deploy_hook(what).exist?
456
- shell.status "Running deploy hook: deploy/#{what}.rb"
457
- run Escape.shell_command(base_callback_command_for(what)) do |server, cmd|
458
- per_instance_args = []
459
- per_instance_args << '--current-roles' << server.roles.to_a.join(' ')
460
- per_instance_args << '--current-name' << server.name.to_s if server.name
461
- per_instance_args << '--config' << config.to_json
462
- cmd << " " << Escape.shell_command(per_instance_args)
463
- end
464
- elsif paths.executable_deploy_hook(what).executable?
465
- shell.status "Running deploy hook: deploy/#{what}"
466
- run [About.hook_executor, what.to_s].join(' ') do |server, cmd|
467
- cmd = hook_env_vars(server).reject{|k,v| v.nil?}.map{|k,v|
468
- "#{k}=#{Escape.shell_command([v])}"
469
- }.join(' ') + ' ' + config.framework_envs + ' ' + cmd
470
- end
471
- elsif paths.executable_deploy_hook(what).exist?
472
- shell.warning "Skipping possible deploy hook deploy/#{what} because it is not executable."
473
- end
456
+ @callbacks_collection.distribute(self, what)
474
457
  end
475
458
 
476
459
  def source
@@ -480,31 +463,6 @@ defaults:
480
463
 
481
464
  protected
482
465
 
483
- def base_callback_command_for(what)
484
- cmd = [About.binary, 'hook', what.to_s]
485
- cmd << '--app' << config.app
486
- cmd << '--environment-name' << config.environment_name
487
- cmd << '--account-name' << config.account_name
488
- cmd << '--release-path' << paths.active_release.to_s
489
- cmd << '--framework-env' << config.framework_env.to_s
490
- cmd << '--verbose' if config.verbose
491
- cmd
492
- end
493
-
494
- def hook_env_vars(server)
495
- {
496
- 'EY_DEPLOY_ACCOUNT_NAME' => config.account_name,
497
- 'EY_DEPLOY_APP' => config.app,
498
- 'EY_DEPLOY_CONFIG' => config.to_json,
499
- 'EY_DEPLOY_CURRENT_ROLES' => server.roles.to_a.join(' '),
500
- 'EY_DEPLOY_CURRENT_NAME' => server.name ? server.name.to_s : nil,
501
- 'EY_DEPLOY_ENVIRONMENT_NAME' => config.environment_name,
502
- 'EY_DEPLOY_FRAMEWORK_ENV' => config.framework_env.to_s,
503
- 'EY_DEPLOY_RELEASE_PATH' => paths.active_release.to_s,
504
- 'EY_DEPLOY_VERBOSE' => (config.verbose ? '1' : '0'),
505
- }
506
- end
507
-
508
466
  # FIXME: Legacy method, warn and remove.
509
467
  def serverside_bin
510
468
  About.binary
@@ -554,6 +512,10 @@ defaults:
554
512
  def compile_assets
555
513
  RailsAssets.detect_and_compile(config, shell, self)
556
514
  end
515
+
516
+ def load_callbacks
517
+ @callbacks_collection ||= Callbacks.load(paths)
518
+ end
557
519
  end # DeployBase
558
520
 
559
521
  class Deploy < DeployBase
@@ -1,4 +1,6 @@
1
1
  require 'engineyard-serverside/shell/helpers'
2
+ require 'engineyard-serverside/deploy_hook/callback_context'
3
+ require 'engineyard-serverside/callbacks'
2
4
  require 'rbconfig'
3
5
 
4
6
  module EY
@@ -10,36 +12,32 @@ module EY
10
12
  @config, @shell, @hook_name = config, shell, hook_name
11
13
  end
12
14
 
13
- def hook_path
14
- config.paths.deploy_hook(hook_name)
15
- end
16
-
17
- def callback_context
18
- @context ||= CallbackContext.new(config, shell, hook_path)
19
- end
20
-
21
15
  def call
22
- if hook_path.exist?
16
+ hooks.each do |hook|
23
17
  Dir.chdir(config.paths.active_release.to_s) do
24
- if desc = syntax_error(hook_path)
25
- hook_name = hook_path.basename
18
+ if desc = syntax_error(hook.path)
19
+ hook_name = hook.path.basename
26
20
  abort "*** [Error] Invalid Ruby syntax in hook: #{hook_name} ***\n*** #{desc.chomp} ***"
27
21
  else
28
- eval_hook(hook_path.read)
22
+ eval_hook(hook.read, hook.path)
29
23
  end
30
24
  end
31
25
  end
32
26
  end
33
27
 
34
- def eval_hook(code)
35
- display_deprecation_warnings(code)
36
- callback_context.instance_eval(code)
28
+ def eval_hook(code, hook_path = nil)
29
+ hook_path ||= config.paths.deploy_hook(hook_name)
30
+ shell.info "Executing #{hook_path} ..."
31
+ display_deprecation_warnings(code, hook_path)
32
+ CallbackContext.
33
+ new(config, shell, hook_path).
34
+ instance_eval(code)
37
35
  rescue Exception => exception
38
36
  display_hook_error(exception, code, hook_path)
39
37
  raise exception
40
38
  end
41
39
 
42
- def display_deprecation_warnings(code)
40
+ def display_deprecation_warnings(code, hook_path)
43
41
  if code =~ /@configuration/
44
42
  shell.warning("Use of `@configuration` in deploy hooks is deprecated.\nPlease use `config`, which provides access to the same object.\n\tin #{hook_path}")
45
43
  end
@@ -68,73 +66,12 @@ Please fix this error before retrying.
68
66
  output unless output =~ /Syntax OK/
69
67
  end
70
68
 
71
- class CallbackContext
72
- include EY::Serverside::Shell::Helpers
73
-
74
- attr_reader :shell, :hook_path
75
-
76
- def initialize(config, shell, hook_path)
77
- @configuration = config
78
- @configuration.set_framework_envs
79
- @shell = shell
80
- @node = config.node
81
- @hook_path = hook_path
82
- end
83
-
84
- def config
85
- @configuration
86
- end
87
-
88
- def inspect
89
- "#<DeployHook::CallbackContext #{hook_path.inspect}>"
90
- end
91
-
92
- def method_missing(meth, *args, &blk)
93
- if @configuration.respond_to?(meth)
94
- shell.warning "Use of `#{meth}` (via method_missing) is deprecated in favor of `config.#{meth}` for improved error messages and compatibility.\n\tin #{hook_path}"
95
- @configuration.send(meth, *args, &blk)
96
- else
97
- super
98
- end
99
- end
100
-
101
- def respond_to?(*a)
102
- @configuration.respond_to?(*a) || super
103
- end
104
-
105
- def run(cmd)
106
- shell.logged_system(Escape.shell_command(["sh", "-l", "-c", cmd])).success?
107
- end
108
-
109
- def run!(cmd)
110
- run(cmd) or raise("run!: Command failed. #{cmd}")
111
- end
112
-
113
- def sudo(cmd)
114
- shell.logged_system(Escape.shell_command(["sudo", "sh", "-l", "-c", cmd])).success?
115
- end
116
-
117
- def sudo!(cmd)
118
- sudo(cmd) or raise("sudo!: Command failed. #{cmd}")
119
- end
120
-
121
- # convenience functions for running on certain instance types
122
- def on_app_master(&blk) on_roles(%w[solo app_master], &blk) end
123
- def on_app_servers(&blk) on_roles(%w[solo app_master app], &blk) end
124
- def on_app_servers_and_utilities(&blk) on_roles(%w[solo app_master app util], &blk) end
125
-
126
- def on_utilities(*names, &blk)
127
- names.flatten!
128
- on_roles(%w[util]) do
129
- blk.call if names.empty? || names.include?(config.current_name)
130
- end
131
- end
132
-
133
- private
134
- def on_roles(desired_roles)
135
- yield if desired_roles.any? { |role| config.current_roles.include?(role) }
136
- end
137
-
69
+ private
70
+ def hooks
71
+ @hooks ||= Callbacks.
72
+ load(config.paths).
73
+ matching(hook_name.to_s).
74
+ select {|hook| hook.flavor == :ruby}
138
75
  end
139
76
 
140
77
  end
@@ -0,0 +1,77 @@
1
+ require 'engineyard-serverside/shell/helpers'
2
+
3
+ module EY
4
+ module Serverside
5
+ class DeployHook
6
+
7
+ class CallbackContext
8
+ include EY::Serverside::Shell::Helpers
9
+
10
+ attr_reader :shell, :hook_path
11
+
12
+ def initialize(config, shell, hook_path)
13
+ @configuration = config
14
+ @configuration.set_framework_envs
15
+ @shell = shell
16
+ @node = config.node
17
+ @hook_path = hook_path
18
+ end
19
+
20
+ def config
21
+ @configuration
22
+ end
23
+
24
+ def inspect
25
+ "#<DeployHook::CallbackContext #{hook_path.inspect}>"
26
+ end
27
+
28
+ def method_missing(meth, *args, &blk)
29
+ if @configuration.respond_to?(meth)
30
+ shell.warning "Use of `#{meth}` (via method_missing) is deprecated in favor of `config.#{meth}` for improved error messages and compatibility.\n\tin #{hook_path}"
31
+ @configuration.send(meth, *args, &blk)
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ def respond_to?(*a)
38
+ @configuration.respond_to?(*a) || super
39
+ end
40
+
41
+ def run(cmd)
42
+ shell.logged_system(Escape.shell_command(["sh", "-l", "-c", cmd])).success?
43
+ end
44
+
45
+ def run!(cmd)
46
+ run(cmd) or raise("run!: Command failed. #{cmd}")
47
+ end
48
+
49
+ def sudo(cmd)
50
+ shell.logged_system(Escape.shell_command(["sudo", "sh", "-l", "-c", cmd])).success?
51
+ end
52
+
53
+ def sudo!(cmd)
54
+ sudo(cmd) or raise("sudo!: Command failed. #{cmd}")
55
+ end
56
+
57
+ # convenience functions for running on certain instance types
58
+ def on_app_master(&blk) on_roles(%w[solo app_master], &blk) end
59
+ def on_app_servers(&blk) on_roles(%w[solo app_master app], &blk) end
60
+ def on_app_servers_and_utilities(&blk) on_roles(%w[solo app_master app util], &blk) end
61
+
62
+ def on_utilities(*names, &blk)
63
+ names.flatten!
64
+ on_roles(%w[util]) do
65
+ blk.call if names.empty? || names.include?(config.current_name)
66
+ end
67
+ end
68
+
69
+ private
70
+ def on_roles(desired_roles)
71
+ yield if desired_roles.any? { |role| config.current_roles.include?(role) }
72
+ end
73
+ end
74
+
75
+ end
76
+ end
77
+ end