chef 0.7.10 → 0.7.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of chef might be problematic. Click here for more details.

Files changed (70) hide show
  1. data/distro/debian/etc/init.d/chef-client +175 -0
  2. data/distro/debian/etc/init.d/chef-indexer +175 -0
  3. data/distro/debian/etc/init.d/chef-server +120 -0
  4. data/distro/debian/man/man1/chef-indexer.1 +42 -0
  5. data/distro/debian/man/man1/chef-server.1 +108 -0
  6. data/distro/debian/man/man8/chef-client.8 +61 -0
  7. data/distro/debian/man/man8/chef-solo.8 +58 -0
  8. data/distro/redhat/etc/chef/client.rb +16 -0
  9. data/distro/redhat/etc/chef/indexer.rb +10 -0
  10. data/distro/redhat/etc/chef/server.rb +22 -0
  11. data/distro/redhat/etc/init.d/chef-client +74 -0
  12. data/distro/redhat/etc/init.d/chef-indexer +76 -0
  13. data/distro/redhat/etc/init.d/chef-server +77 -0
  14. data/lib/chef.rb +1 -1
  15. data/lib/chef/client.rb +33 -8
  16. data/lib/chef/compile.rb +34 -2
  17. data/lib/chef/cookbook.rb +29 -2
  18. data/lib/chef/cookbook_loader.rb +61 -49
  19. data/lib/chef/couchdb.rb +7 -3
  20. data/lib/chef/mixin/command.rb +67 -32
  21. data/lib/chef/mixin/convert_to_class_name.rb +48 -0
  22. data/lib/chef/mixin/find_preferred_file.rb +5 -14
  23. data/lib/chef/mixin/from_file.rb +14 -0
  24. data/lib/chef/mixin/generate_url.rb +2 -1
  25. data/lib/chef/mixin/recipe_definition_dsl_core.rb +77 -0
  26. data/lib/chef/platform.rb +1 -1
  27. data/lib/chef/provider.rb +63 -2
  28. data/lib/chef/provider/cron.rb +75 -25
  29. data/lib/chef/provider/deploy.rb +281 -0
  30. data/lib/chef/provider/deploy/revision.rb +70 -0
  31. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  32. data/lib/chef/provider/git.rb +194 -0
  33. data/lib/chef/provider/group.rb +2 -2
  34. data/lib/chef/provider/group/gpasswd.rb +50 -0
  35. data/lib/chef/provider/group/groupadd.rb +2 -16
  36. data/lib/chef/provider/group/usermod.rb +57 -0
  37. data/lib/chef/provider/ifconfig.rb +3 -3
  38. data/lib/chef/provider/mount.rb +0 -4
  39. data/lib/chef/provider/mount/mount.rb +2 -2
  40. data/lib/chef/provider/package.rb +2 -2
  41. data/lib/chef/provider/package/apt.rb +4 -4
  42. data/lib/chef/provider/package/dpkg.rb +9 -13
  43. data/lib/chef/provider/package/freebsd.rb +6 -6
  44. data/lib/chef/provider/package/macports.rb +4 -4
  45. data/lib/chef/provider/package/portage.rb +3 -3
  46. data/lib/chef/provider/package/rpm.rb +4 -4
  47. data/lib/chef/provider/package/rubygems.rb +10 -4
  48. data/lib/chef/provider/package/yum.rb +6 -6
  49. data/lib/chef/provider/remote_file.rb +14 -7
  50. data/lib/chef/provider/service.rb +8 -2
  51. data/lib/chef/provider/service/freebsd.rb +1 -1
  52. data/lib/chef/provider/service/init.rb +8 -63
  53. data/lib/chef/provider/service/redhat.rb +2 -2
  54. data/lib/chef/provider/service/simple.rb +115 -0
  55. data/lib/chef/provider/subversion.rb +145 -0
  56. data/lib/chef/provider/template.rb +2 -0
  57. data/lib/chef/provider/user.rb +2 -2
  58. data/lib/chef/recipe.rb +9 -75
  59. data/lib/chef/resource.rb +131 -7
  60. data/lib/chef/resource/cron.rb +36 -0
  61. data/lib/chef/resource/deploy.rb +360 -0
  62. data/lib/chef/resource/deploy_revision.rb +35 -0
  63. data/lib/chef/resource/git.rb +36 -0
  64. data/lib/chef/resource/group.rb +2 -0
  65. data/lib/chef/resource/scm.rb +129 -0
  66. data/lib/chef/resource/subversion.rb +33 -0
  67. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  68. data/lib/chef/resource_collection.rb +32 -4
  69. data/lib/chef/runner.rb +35 -28
  70. metadata +40 -11
@@ -1,5 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
3
4
  # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
@@ -19,6 +20,7 @@
19
20
  require 'chef/mixin/params_validate'
20
21
  require 'chef/mixin/check_helper'
21
22
  require 'chef/mixin/language'
23
+ require 'chef/mixin/convert_to_class_name'
22
24
  require 'chef/resource_collection'
23
25
  require 'chef/node'
24
26
 
@@ -28,8 +30,9 @@ class Chef
28
30
  include Chef::Mixin::CheckHelper
29
31
  include Chef::Mixin::ParamsValidate
30
32
  include Chef::Mixin::Language
33
+ include Chef::Mixin::ConvertToClassName
31
34
 
32
- attr_accessor :actions, :params, :provider, :updated, :allowed_actions, :collection, :cookbook_name, :recipe_name
35
+ attr_accessor :actions, :params, :provider, :updated, :allowed_actions, :collection, :cookbook_name, :recipe_name, :enclosing_provider
33
36
  attr_reader :resource_name, :source_line, :node
34
37
 
35
38
  def initialize(name, collection=nil, node=nil)
@@ -58,6 +61,17 @@ class Chef
58
61
  @source_line = ::File.expand_path(@source_line) if @source_line
59
62
  end
60
63
  end
64
+
65
+ # If an unknown method is invoked, determine whether the enclosing Provider's
66
+ # lexical scope can fulfill the request. E.g. This happens when the Resource's
67
+ # block invokes new_resource.
68
+ def method_missing(method_symbol, *args, &block)
69
+ if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
70
+ enclosing_provider.send(method_symbol, *args, &block)
71
+ else
72
+ raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
73
+ end
74
+ end
61
75
 
62
76
  def load_prior_resource
63
77
  begin
@@ -83,9 +97,14 @@ class Chef
83
97
  end
84
98
 
85
99
  def provider(arg=nil)
100
+ klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
101
+ lookup_provider_constant(arg)
102
+ else
103
+ arg
104
+ end
86
105
  set_or_return(
87
106
  :provider,
88
- arg,
107
+ klass,
89
108
  :kind_of => [ Class ]
90
109
  )
91
110
  end
@@ -192,12 +211,12 @@ class Chef
192
211
  results.to_json(*a)
193
212
  end
194
213
 
195
- def self.json_create(o)
196
- resource = self.new(o["instance_vars"]["@name"])
197
- o["instance_vars"].each do |k,v|
198
- resource.instance_variable_set(k.to_sym, v)
214
+ def to_hash
215
+ instance_vars = Hash.new
216
+ self.instance_variables.each do |iv|
217
+ instance_vars[iv.sub(/^@/,'').to_sym] = self.instance_variable_get(iv) unless iv == "@collection"
199
218
  end
200
- resource
219
+ instance_vars
201
220
  end
202
221
 
203
222
  def only_if(arg=nil, &blk)
@@ -224,7 +243,112 @@ class Chef
224
243
  provider.send("action_#{action}")
225
244
  end
226
245
 
246
+ class << self
247
+
248
+ def json_create(o)
249
+ resource = self.new(o["instance_vars"]["@name"])
250
+ o["instance_vars"].each do |k,v|
251
+ resource.instance_variable_set(k.to_sym, v)
252
+ end
253
+ resource
254
+ end
255
+
256
+ include Chef::Mixin::ConvertToClassName
257
+
258
+ def attribute(attr_name, validation_opts={})
259
+ # This atrocity is the only way to support 1.8 and 1.9 at the same time
260
+ # When you're ready to drop 1.8 support, do this:
261
+ # define_method attr_name.to_sym do |arg=nil|
262
+ # etc.
263
+ shim_method=<<-SHIM
264
+ def #{attr_name}(arg=nil)
265
+ _set_or_return_#{attr_name}(arg)
266
+ end
267
+ SHIM
268
+ class_eval(shim_method)
269
+
270
+ define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
271
+ set_or_return(attr_name.to_sym, arg, validation_opts)
272
+ end
273
+ end
274
+
275
+ def build_from_file(cookbook_name, filename)
276
+ rname = filename_to_qualified_string(cookbook_name, filename)
277
+
278
+ new_resource_class = Class.new self do |cls|
279
+
280
+ # default initialize method that ensures that when initialize is finally
281
+ # wrapped (see below), super is called in the event that the resource
282
+ # definer does not implement initialize
283
+ def initialize(name, collection=nil, node=nil)
284
+ super(name, collection, node)
285
+ end
286
+
287
+ @actions_to_create = []
288
+
289
+ class << cls
290
+ include Chef::Mixin::FromFile
291
+
292
+ def actions_to_create
293
+ @actions_to_create
294
+ end
295
+
296
+ define_method(:actions) do |*action_names|
297
+ actions_to_create.push(*action_names)
298
+ end
299
+ end
300
+
301
+ # load resource definition from file
302
+ cls.class_from_file(filename)
303
+
304
+ # create a new constructor that wraps the old one and adds the actions
305
+ # specified in the DSL
306
+ old_init = instance_method(:initialize)
307
+
308
+ define_method(:initialize) do |name, *optional_args|
309
+ collection = optional_args.shift
310
+ node = optional_args.shift
311
+ @resource_name = rname.to_sym
312
+ old_init.bind(self).call(name, collection, node)
313
+ allowed_actions.push(self.class.actions_to_create).flatten!
314
+ end
315
+ end
316
+
317
+ # register new class as a Chef::Resource
318
+ class_name = convert_to_class_name(rname)
319
+ Chef::Resource.const_set(class_name, new_resource_class)
320
+ Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
321
+
322
+ new_resource_class
323
+ end
324
+
325
+ # Resources that want providers namespaced somewhere other than
326
+ # Chef::Provider can set the namespace with +provider_base+
327
+ # Ex:
328
+ # class MyResource < Chef::Resource
329
+ # provider_base Chef::Provider::Deploy
330
+ # # ...other stuff
331
+ # end
332
+ def provider_base(arg=nil)
333
+ @provider_base ||= arg
334
+ @provider_base ||= Chef::Provider
335
+ end
336
+
337
+ end
338
+
227
339
  private
340
+
341
+ def lookup_provider_constant(name)
342
+ begin
343
+ self.class.provider_base.const_get(convert_to_class_name(name.to_s))
344
+ rescue NameError => e
345
+ if e.to_s =~ /#{self.class.provider_base.to_s}/
346
+ raise ArgumentError, "No provider found to match '#{name}'"
347
+ else
348
+ raise e
349
+ end
350
+ end
351
+ end
228
352
 
229
353
  def check_timing(timing)
230
354
  unless timing == :delayed || timing == :immediate || timing == :immediately
@@ -34,6 +34,10 @@ class Chef
34
34
  @weekday = "*"
35
35
  @command = nil
36
36
  @user = "root"
37
+ @mailto = nil
38
+ @path = nil
39
+ @shell = nil
40
+ @home = nil
37
41
  end
38
42
 
39
43
  def minute(arg=nil)
@@ -121,6 +125,38 @@ class Chef
121
125
  )
122
126
  end
123
127
 
128
+ def mailto(arg=nil)
129
+ set_or_return(
130
+ :mailto,
131
+ arg,
132
+ :kind_of => String
133
+ )
134
+ end
135
+
136
+ def path(arg=nil)
137
+ set_or_return(
138
+ :path,
139
+ arg,
140
+ :kind_of => String
141
+ )
142
+ end
143
+
144
+ def home(arg=nil)
145
+ set_or_return(
146
+ :home,
147
+ arg,
148
+ :kind_of => String
149
+ )
150
+ end
151
+
152
+ def shell(arg=nil)
153
+ set_or_return(
154
+ :shell,
155
+ arg,
156
+ :kind_of => String
157
+ )
158
+ end
159
+
124
160
  def command(arg=nil)
125
161
  set_or_return(
126
162
  :command,
@@ -0,0 +1,360 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ # EX:
20
+ # deploy "/my/deploy/dir" do
21
+ # repo "git@github.com/whoami/project"
22
+ # revision "abc123" # or "HEAD" or "TAG_for_1.0" or (subversion) "1234"
23
+ # user "deploy_ninja"
24
+ # enable_submodules true
25
+ # migrate true
26
+ # migration_command "rake db:migrate"
27
+ # environment "RAILS_ENV" => "production", "OTHER_ENV" => "foo"
28
+ # shallow_clone true
29
+ # action :deploy # or :rollback
30
+ # restart_command "touch tmp/restart.txt"
31
+ # git_ssh_wrapper "wrap-ssh4git.sh"
32
+ # scm_provider Chef::Provider::Git # is the default, for svn: Chef::Provider::Subversion
33
+ # svn_username "whoami"
34
+ # svn_password "supersecret"
35
+ # end
36
+
37
+ require "chef/resource/scm"
38
+
39
+ class Chef
40
+ class Resource
41
+
42
+ # Deploy: Deploy apps from a source control repository.
43
+ #
44
+ # Callbacks:
45
+ # Callbacks can be a block or a string. If given a block, the code
46
+ # is evaluated as an embedded recipe, and run at the specified
47
+ # point in the deploy process. If given a string, the string is taken as
48
+ # a path to a callback file/recipe. Paths are evaluated relative to the
49
+ # release directory. Callback files can contain chef code (resources, etc.)
50
+ #
51
+ class Deploy < Chef::Resource
52
+
53
+ provider_base Chef::Provider::Deploy
54
+
55
+ def initialize(name, collection=nil, node=nil)
56
+ super(name, collection, node)
57
+ @resource_name = :deploy
58
+ @deploy_to = name
59
+ @environment = nil
60
+ @repository_cache = 'cached-copy'
61
+ @copy_exclude = []
62
+ @purge_before_symlink = %w{log tmp/pids public/system}
63
+ @create_dirs_before_symlink = %w{tmp public config}
64
+ @symlink_before_migrate = {"config/database.yml" => "config/database.yml"}
65
+ @symlinks = {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}
66
+ @revision = 'HEAD'
67
+ @action = :deploy
68
+ @migrate = false
69
+ @remote = "origin"
70
+ @enable_submodules = false
71
+ @shallow_clone = false
72
+ @force_deploy = false
73
+ @scm_provider = Chef::Provider::Git
74
+ @provider = Chef::Provider::Deploy::Timestamped
75
+ @allowed_actions.push(:deploy, :rollback)
76
+ end
77
+
78
+ # where the checked out/cloned code goes
79
+ def destination
80
+ @destination ||= shared_path + "/#{@repository_cache}/"
81
+ end
82
+
83
+ # where shared stuff goes, i.e., logs, tmp, etc. goes here
84
+ def shared_path
85
+ @shared_path ||= @deploy_to + "/shared"
86
+ end
87
+
88
+ # where the deployed version of your code goes
89
+ def current_path
90
+ @current_path ||= @deploy_to + "/current"
91
+ end
92
+
93
+ def depth
94
+ @shallow_clone ? "5" : nil
95
+ end
96
+
97
+ # note: deploy_to is your application "meta-root."
98
+ def deploy_to(arg=nil)
99
+ set_or_return(
100
+ :deploy_to,
101
+ arg,
102
+ :kind_of => [ String ]
103
+ )
104
+ end
105
+
106
+ def repo(arg=nil)
107
+ set_or_return(
108
+ :repo,
109
+ arg,
110
+ :kind_of => [ String ]
111
+ )
112
+ end
113
+ alias :repository :repo
114
+
115
+ def remote(arg=nil)
116
+ set_or_return(
117
+ :remote,
118
+ arg,
119
+ :kind_of => [ String ]
120
+ )
121
+ end
122
+
123
+ def role(arg=nil)
124
+ set_or_return(
125
+ :role,
126
+ arg,
127
+ :kind_of => [ String ]
128
+ )
129
+ end
130
+
131
+ def restart_command(arg=nil, &block)
132
+ arg ||= block
133
+ set_or_return(
134
+ :restart_command,
135
+ arg,
136
+ :kind_of => [ String, Proc ]
137
+ )
138
+ end
139
+ alias :restart :restart_command
140
+
141
+ def migrate(arg=nil)
142
+ set_or_return(
143
+ :migrate,
144
+ arg,
145
+ :kind_of => [ TrueClass, FalseClass ]
146
+ )
147
+ end
148
+
149
+ def migration_command(arg=nil)
150
+ set_or_return(
151
+ :migration_command,
152
+ arg,
153
+ :kind_of => [ String ]
154
+ )
155
+ end
156
+
157
+ def user(arg=nil)
158
+ set_or_return(
159
+ :user,
160
+ arg,
161
+ :kind_of => [ String ]
162
+ )
163
+ end
164
+
165
+ def group(arg=nil)
166
+ set_or_return(
167
+ :group,
168
+ arg,
169
+ :kind_of => [ String ]
170
+ )
171
+ end
172
+
173
+ def enable_submodules(arg=nil)
174
+ set_or_return(
175
+ :enable_submodules,
176
+ arg,
177
+ :kind_of => [ TrueClass, FalseClass ]
178
+ )
179
+ end
180
+
181
+ def shallow_clone(arg=nil)
182
+ set_or_return(
183
+ :shallow_clone,
184
+ arg,
185
+ :kind_of => [ TrueClass, FalseClass ]
186
+ )
187
+ end
188
+
189
+ def repository_cache(arg=nil)
190
+ set_or_return(
191
+ :repository_cache,
192
+ arg,
193
+ :kind_of => [ String ]
194
+ )
195
+ end
196
+
197
+ def copy_exclude(arg=nil)
198
+ set_or_return(
199
+ :copy_exclude,
200
+ arg,
201
+ :kind_of => [ String ]
202
+ )
203
+ end
204
+
205
+ def revision(arg=nil)
206
+ set_or_return(
207
+ :revision,
208
+ arg,
209
+ :kind_of => [ String ]
210
+ )
211
+ end
212
+ alias :branch :revision
213
+
214
+ def git_ssh_wrapper(arg=nil)
215
+ set_or_return(
216
+ :git_ssh_wrapper,
217
+ arg,
218
+ :kind_of => [ String ]
219
+ )
220
+ end
221
+ alias :ssh_wrapper :git_ssh_wrapper
222
+
223
+ def svn_username(arg=nil)
224
+ set_or_return(
225
+ :svn_username,
226
+ arg,
227
+ :kind_of => [ String ]
228
+ )
229
+ end
230
+
231
+ def svn_password(arg=nil)
232
+ set_or_return(
233
+ :svn_password,
234
+ arg,
235
+ :kind_of => [ String ]
236
+ )
237
+ end
238
+
239
+ def svn_arguments(arg=nil)
240
+ set_or_return(
241
+ :svn_arguments,
242
+ arg,
243
+ :kind_of => [ String ]
244
+ )
245
+ end
246
+
247
+ # Shall we run the deploy even if the code has not changed?
248
+ def force_deploy(arg=nil)
249
+ set_or_return(
250
+ :force_deploy,
251
+ arg,
252
+ :kind_of => [ TrueClass, FalseClass ]
253
+ )
254
+ end
255
+
256
+ def scm_provider(arg=nil)
257
+ set_or_return(
258
+ :scm_provider,
259
+ arg,
260
+ :kind_of => [ Class ]
261
+ )
262
+ end
263
+
264
+ def environment(arg=nil)
265
+ if arg.is_a?(String)
266
+ Chef::Log.info "Setting RAILS_ENV, RACK_ENV, and MERB_ENV to `#{arg}'"
267
+ Chef::Log.warn "[DEPRECATED] please modify your deploy recipe or attributes to set the environment using a hash"
268
+ arg = {"RAILS_ENV"=>arg,"MERB_ENV"=>arg,"RACK_ENV"=>arg}
269
+ end
270
+ set_or_return(
271
+ :environment,
272
+ arg,
273
+ :kind_of => [ Hash ]
274
+ )
275
+ end
276
+
277
+ # An array of paths, relative to your app's root, to be purged from a
278
+ # SCM clone/checkout before symlinking. Use this to get rid of files and
279
+ # directories you want to be shared between releases.
280
+ # Default: ["log", "tmp/pids", "public/system"]
281
+ def purge_before_symlink(arg=nil)
282
+ set_or_return(
283
+ :purge_before_symlink,
284
+ arg,
285
+ :kind_of => Array
286
+ )
287
+ end
288
+
289
+ # An array of paths, relative to your app's root, where you expect dirs to
290
+ # exist before symlinking. This runs after #purge_before_symlink, so you
291
+ # can use this to recreate dirs that you had previously purged.
292
+ # For example, if you plan to use a shared directory for pids, and you
293
+ # want it to be located in $APP_ROOT/tmp/pids, you could purge tmp,
294
+ # then specify tmp here so that the tmp directory will exist when you
295
+ # symlink the pids directory in to the current release.
296
+ # Default: ["tmp", "public", "config"]
297
+ def create_dirs_before_symlink(arg=nil)
298
+ set_or_return(
299
+ :create_dirs_before_symlink,
300
+ arg,
301
+ :kind_of => Array
302
+ )
303
+ end
304
+
305
+ # A Hash of shared/dir/path => release/dir/path. This attribute determines
306
+ # which files and dirs in the shared directory get symlinked to the current
307
+ # release directory, and where they go. If you have a directory
308
+ # $shared/pids that you would like to symlink as $current_release/tmp/pids
309
+ # you specify it as "pids" => "tmp/pids"
310
+ # Default {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}
311
+ def symlinks(arg=nil)
312
+ set_or_return(
313
+ :symlinks,
314
+ arg,
315
+ :kind_of => Hash
316
+ )
317
+ end
318
+
319
+ # A Hash of shared/dir/path => release/dir/path. This attribute determines
320
+ # which files in the shared directory get symlinked to the current release
321
+ # directory and where they go. Unlike map_shared_files, these are symlinked
322
+ # *before* any migration is run.
323
+ # For a rails/merb app, this is used to link in a known good database.yml
324
+ # (with the production db password) before running migrate.
325
+ # Default {"config/database.yml" => "config/database.yml"}
326
+ def symlink_before_migrate(arg=nil)
327
+ set_or_return(
328
+ :symlink_before_migrate,
329
+ arg,
330
+ :kind_of => Hash
331
+ )
332
+ end
333
+
334
+ # Callback fires before migration is run.
335
+ def before_migrate(arg=nil, &block)
336
+ arg ||= block
337
+ set_or_return(:before_migrate, arg, :kind_of => [Proc, String])
338
+ end
339
+
340
+ # Callback fires before symlinking
341
+ def before_symlink(arg=nil, &block)
342
+ arg ||= block
343
+ set_or_return(:before_symlink, arg, :kind_of => [Proc, String])
344
+ end
345
+
346
+ # Callback fires before restart
347
+ def before_restart(arg=nil, &block)
348
+ arg ||= block
349
+ set_or_return(:before_restart, arg, :kind_of => [Proc, String])
350
+ end
351
+
352
+ # Callback fires after restart
353
+ def after_restart(arg=nil, &block)
354
+ arg ||= block
355
+ set_or_return(:after_restart, arg, :kind_of => [Proc, String])
356
+ end
357
+
358
+ end
359
+ end
360
+ end