chef 0.10.4 → 0.10.6.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/distro/common/html/chef-client.8.html +9 -4
  2. data/distro/common/html/chef-expander.8.html +4 -4
  3. data/distro/common/html/chef-expanderctl.8.html +4 -4
  4. data/distro/common/html/chef-server-webui.8.html +4 -4
  5. data/distro/common/html/chef-server.8.html +4 -4
  6. data/distro/common/html/chef-solo.8.html +4 -4
  7. data/distro/common/html/chef-solr.8.html +6 -4
  8. data/distro/common/html/knife-bootstrap.1.html +13 -11
  9. data/distro/common/html/knife-client.1.html +4 -4
  10. data/distro/common/html/knife-configure.1.html +4 -4
  11. data/distro/common/html/knife-cookbook-site.1.html +7 -5
  12. data/distro/common/html/knife-cookbook.1.html +10 -8
  13. data/distro/common/html/knife-data-bag.1.html +4 -4
  14. data/distro/common/html/knife-environment.1.html +4 -4
  15. data/distro/common/html/knife-exec.1.html +4 -4
  16. data/distro/common/html/knife-index.1.html +4 -4
  17. data/distro/common/html/knife-node.1.html +5 -26
  18. data/distro/common/html/knife-role.1.html +4 -4
  19. data/distro/common/html/knife-search.1.html +9 -8
  20. data/distro/common/html/knife-ssh.1.html +10 -10
  21. data/distro/common/html/knife-status.1.html +4 -4
  22. data/distro/common/html/knife-tag.1.html +4 -4
  23. data/distro/common/html/knife.1.html +36 -10
  24. data/distro/common/html/shef.1.html +4 -4
  25. data/distro/common/man/man1/knife-bootstrap.1 +18 -10
  26. data/distro/common/man/man1/knife-client.1 +1 -1
  27. data/distro/common/man/man1/knife-configure.1 +1 -1
  28. data/distro/common/man/man1/knife-cookbook-site.1 +10 -2
  29. data/distro/common/man/man1/knife-cookbook.1 +10 -5
  30. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  31. data/distro/common/man/man1/knife-environment.1 +1 -1
  32. data/distro/common/man/man1/knife-exec.1 +1 -1
  33. data/distro/common/man/man1/knife-index.1 +1 -1
  34. data/distro/common/man/man1/knife-node.1 +2 -22
  35. data/distro/common/man/man1/knife-role.1 +1 -1
  36. data/distro/common/man/man1/knife-search.1 +8 -5
  37. data/distro/common/man/man1/knife-ssh.1 +17 -12
  38. data/distro/common/man/man1/knife-status.1 +1 -1
  39. data/distro/common/man/man1/knife-tag.1 +1 -1
  40. data/distro/common/man/man1/knife.1 +50 -9
  41. data/distro/common/man/man1/shef.1 +1 -1
  42. data/distro/common/man/man8/chef-client.8 +21 -1
  43. data/distro/common/man/man8/chef-expander.8 +1 -1
  44. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  45. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  46. data/distro/common/man/man8/chef-server.8 +1 -1
  47. data/distro/common/man/man8/chef-solo.8 +1 -1
  48. data/distro/common/man/man8/chef-solr.8 +9 -1
  49. data/distro/common/markdown/man1/knife-bootstrap.mkd +9 -5
  50. data/distro/common/markdown/man1/knife-cookbook-site.mkd +5 -1
  51. data/distro/common/markdown/man1/knife-cookbook.mkd +7 -4
  52. data/distro/common/markdown/man1/knife-node.mkd +1 -19
  53. data/distro/common/markdown/man1/knife-search.mkd +5 -4
  54. data/distro/common/markdown/man1/knife-ssh.mkd +8 -0
  55. data/distro/common/markdown/man1/knife.mkd +39 -8
  56. data/distro/common/markdown/man8/chef-client.mkd +10 -0
  57. data/distro/common/markdown/man8/chef-solr.mkd +5 -1
  58. data/distro/debian/etc/init.d/chef-client +48 -38
  59. data/distro/redhat/etc/init.d/chef-client +6 -2
  60. data/lib/chef/checksum.rb +9 -24
  61. data/lib/chef/checksum/storage.rb +18 -0
  62. data/lib/chef/checksum/storage/filesystem.rb +56 -0
  63. data/lib/chef/config.rb +6 -2
  64. data/lib/chef/cookbook/syntax_check.rb +1 -1
  65. data/lib/chef/cookbook_version.rb +37 -9
  66. data/lib/chef/file_access_control.rb +1 -1
  67. data/lib/chef/handler.rb +21 -0
  68. data/lib/chef/knife/bootstrap.rb +3 -1
  69. data/lib/chef/knife/bootstrap/archlinux-gems.erb +10 -0
  70. data/lib/chef/knife/bootstrap/centos5-gems.erb +13 -2
  71. data/lib/chef/knife/bootstrap/fedora13-gems.erb +10 -0
  72. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +10 -0
  73. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +10 -0
  74. data/lib/chef/knife/client_create.rb +13 -7
  75. data/lib/chef/knife/client_delete.rb +0 -2
  76. data/lib/chef/knife/client_edit.rb +0 -3
  77. data/lib/chef/knife/client_list.rb +0 -1
  78. data/lib/chef/knife/client_reregister.rb +2 -3
  79. data/lib/chef/knife/client_show.rb +0 -1
  80. data/lib/chef/knife/configure.rb +1 -1
  81. data/lib/chef/knife/configure_client.rb +0 -2
  82. data/lib/chef/knife/cookbook_create.rb +12 -12
  83. data/lib/chef/knife/cookbook_delete.rb +2 -0
  84. data/lib/chef/knife/cookbook_download.rb +9 -6
  85. data/lib/chef/knife/cookbook_list.rb +1 -6
  86. data/lib/chef/knife/cookbook_metadata.rb +8 -8
  87. data/lib/chef/knife/cookbook_site_list.rb +4 -2
  88. data/lib/chef/knife/cookbook_test.rb +1 -1
  89. data/lib/chef/knife/core/bootstrap_context.rb +9 -0
  90. data/lib/chef/knife/core/generic_presenter.rb +8 -1
  91. data/lib/chef/knife/core/node_presenter.rb +30 -0
  92. data/lib/chef/knife/core/ui.rb +8 -3
  93. data/lib/chef/knife/data_bag_create.rb +2 -5
  94. data/lib/chef/knife/data_bag_from_file.rb +2 -6
  95. data/lib/chef/knife/node_show.rb +8 -3
  96. data/lib/chef/knife/role_create.rb +2 -2
  97. data/lib/chef/knife/role_from_file.rb +12 -5
  98. data/lib/chef/knife/search.rb +1 -1
  99. data/lib/chef/knife/ssh.rb +20 -3
  100. data/lib/chef/mixin/command/windows.rb +1 -1
  101. data/lib/chef/platform.rb +24 -0
  102. data/lib/chef/provider/deploy.rb +93 -17
  103. data/lib/chef/provider/file.rb +5 -1
  104. data/lib/chef/provider/group/groupadd.rb +11 -1
  105. data/lib/chef/provider/ifconfig.rb +66 -5
  106. data/lib/chef/provider/package.rb +41 -5
  107. data/lib/chef/provider/package/apt.rb +10 -0
  108. data/lib/chef/provider/package/yum.rb +59 -14
  109. data/lib/chef/provider/remote_directory.rb +0 -1
  110. data/lib/chef/provider/service/debian.rb +2 -2
  111. data/lib/chef/provider/service/invokercd.rb +35 -0
  112. data/lib/chef/provider/service/windows.rb +92 -83
  113. data/lib/chef/resource.rb +4 -1
  114. data/lib/chef/resource/deploy.rb +9 -0
  115. data/lib/chef/resource/group.rb +8 -0
  116. data/lib/chef/resource/ifconfig.rb +12 -2
  117. data/lib/chef/resource/package.rb +1 -1
  118. data/lib/chef/resource/service.rb +1 -10
  119. data/lib/chef/shef/shef_session.rb +2 -1
  120. data/lib/chef/shell_out.rb +0 -1
  121. data/lib/chef/shell_out/windows.rb +508 -52
  122. data/lib/chef/solr_query/solr_http_request.rb +19 -5
  123. data/lib/chef/tasks/chef_repo.rake +9 -5
  124. data/lib/chef/version.rb +1 -1
  125. metadata +414 -453
@@ -53,6 +53,36 @@ class Chef
53
53
  # output formats for displaying node data
54
54
  class NodePresenter < GenericPresenter
55
55
 
56
+ def format(data)
57
+ if parse_format_option == :json
58
+ summarize_json(data)
59
+ else
60
+ super
61
+ end
62
+ end
63
+
64
+ def summarize_json(data)
65
+ if data.kind_of?(Chef::Node)
66
+ node = data
67
+ result = {}
68
+
69
+ result["name"] = node.name
70
+ result["chef_environment"] = node.chef_environment
71
+ result["run_list"] = node.run_list
72
+ result["normal"] = node.normal_attrs
73
+
74
+ if config[:long_output]
75
+ result["default"] = node.default_attrs
76
+ result["override"] = node.override_attrs
77
+ result["automatic"] = node.automatic_attrs
78
+ end
79
+
80
+ Chef::JSONCompat.to_json_pretty(result)
81
+ else
82
+ Chef::JSONCompat.to_json_pretty(data)
83
+ end
84
+ end
85
+
56
86
  # Converts a Chef::Node object to a string suitable for output to a
57
87
  # terminal. If config[:medium_output] or config[:long_output] are set
58
88
  # the volume of output is adjusted accordingly. Uses colors if enabled
@@ -66,19 +66,24 @@ class Chef
66
66
 
67
67
  alias :info :msg
68
68
 
69
+ # Prints a msg to stderr. Used for warn, error, and fatal.
70
+ def err(message)
71
+ stderr.puts message
72
+ end
73
+
69
74
  # Print a warning message
70
75
  def warn(message)
71
- msg("#{color('WARNING:', :yellow, :bold)} #{message}")
76
+ err("#{color('WARNING:', :yellow, :bold)} #{message}")
72
77
  end
73
78
 
74
79
  # Print an error message
75
80
  def error(message)
76
- msg("#{color('ERROR:', :red, :bold)} #{message}")
81
+ err("#{color('ERROR:', :red, :bold)} #{message}")
77
82
  end
78
83
 
79
84
  # Print a message describing a fatal error.
80
85
  def fatal(message)
81
- msg("#{color('FATAL:', :red, :bold)} #{message}")
86
+ err("#{color('FATAL:', :red, :bold)} #{message}")
82
87
  end
83
88
 
84
89
  def color(string, *colors)
@@ -50,7 +50,7 @@ class Chef
50
50
 
51
51
  def use_encryption
52
52
  if config[:secret] && config[:secret_file]
53
- stdout.puts "please specify only one of --secret, --secret-file"
53
+ ui.fatal("please specify only one of --secret, --secret-file")
54
54
  exit(1)
55
55
  end
56
56
  config[:secret] || config[:secret_file]
@@ -61,7 +61,7 @@ class Chef
61
61
 
62
62
  if @data_bag_name.nil?
63
63
  show_usage
64
- stdout.puts("You must specify a data bag name")
64
+ ui.fatal("You must specify a data bag name")
65
65
  exit 1
66
66
  end
67
67
 
@@ -91,6 +91,3 @@ class Chef
91
91
  end
92
92
  end
93
93
  end
94
-
95
-
96
-
@@ -53,7 +53,7 @@ class Chef
53
53
 
54
54
  def use_encryption
55
55
  if config[:secret] && config[:secret_file]
56
- stdout.puts "please specify only one of --secret, --secret-file"
56
+ ui.fatal("please specify only one of --secret, --secret-file")
57
57
  exit(1)
58
58
  end
59
59
  config[:secret] || config[:secret_file]
@@ -65,7 +65,7 @@ class Chef
65
65
 
66
66
  def run
67
67
  if @name_args.size != 2
68
- stdout.puts opt_parser
68
+ ui.msg(opt_parser)
69
69
  exit(1)
70
70
  end
71
71
  @data_bag, @item_path = @name_args[0], @name_args[1]
@@ -85,7 +85,3 @@ class Chef
85
85
  end
86
86
  end
87
87
  end
88
-
89
-
90
-
91
-
@@ -32,12 +32,12 @@ class Chef
32
32
 
33
33
  banner "knife node show NODE (options)"
34
34
 
35
- attrs_to_show = []
35
+ @attrs_to_show = []
36
36
  option :attribute,
37
37
  :short => "-a [ATTR]",
38
38
  :long => "--attribute [ATTR]",
39
- :proc => lambda {|val| attrs_to_show << val},
40
- :description => "Show only one attribute"
39
+ :proc => lambda {|val| @attrs_to_show << val},
40
+ :description => "Show one or more attributes"
41
41
 
42
42
  option :run_list,
43
43
  :short => "-r",
@@ -61,6 +61,11 @@ class Chef
61
61
 
62
62
  node = Chef::Node.load(@node_name)
63
63
  output(format_for_display(node))
64
+ self.class.attrs_to_show = []
65
+ end
66
+
67
+ def self.attrs_to_show=(attrs)
68
+ @attrs_to_show = attrs
64
69
  end
65
70
  end
66
71
  end
@@ -30,8 +30,8 @@ class Chef
30
30
  banner "knife role create ROLE (options)"
31
31
 
32
32
  option :description,
33
- :short => "-d",
34
- :long => "--description",
33
+ :short => "-d DESC",
34
+ :long => "--description DESC",
35
35
  :description => "The role description"
36
36
 
37
37
  def run
@@ -28,20 +28,27 @@ class Chef
28
28
  require 'chef/json_compat'
29
29
  end
30
30
 
31
- banner "knife role from file FILE (options)"
31
+ banner "knife role from file FILE [FILE..] (options)"
32
32
 
33
33
  def loader
34
34
  @loader ||= Knife::Core::ObjectLoader.new(Chef::Role, ui)
35
35
  end
36
36
 
37
+ option :all,
38
+ :short => "-a",
39
+ :long => "--all",
40
+ :description => "Upload all roles, rather than just a single role"
41
+
37
42
  def run
38
- updated = loader.load_from("roles", @name_args[0])
43
+ @name_args.each do |arg|
44
+ updated = loader.load_from("roles", arg)
39
45
 
40
- updated.save
46
+ updated.save
41
47
 
42
- output(format_for_display(updated)) if config[:print_after]
48
+ output(format_for_display(updated)) if config[:print_after]
43
49
 
44
- ui.info("Updated Role #{updated.name}!")
50
+ ui.info("Updated Role #{updated.name}!")
51
+ end
45
52
  end
46
53
 
47
54
  end
@@ -51,7 +51,7 @@ class Chef
51
51
  :short => "-R INT",
52
52
  :long => "--rows INT",
53
53
  :description => "The number of rows to return",
54
- :default => 20,
54
+ :default => 1000,
55
55
  :proc => lambda { |i| i.to_i }
56
56
 
57
57
  option :attribute,
@@ -83,6 +83,7 @@ class Chef
83
83
  :default => false
84
84
 
85
85
  def session
86
+ config[:on_error] ||= :skip
86
87
  ssh_error_handler = Proc.new do |server|
87
88
  if config[:manual]
88
89
  node_name = server.host
@@ -91,8 +92,14 @@ class Chef
91
92
  node_name = n if format_for_display(n)[config[:attribute]] == server.host
92
93
  end
93
94
  end
94
- ui.warn "Failed to connect to #{node_name} -- #{$!.class.name}: #{$!.message}"
95
- $!.backtrace.each { |l| Chef::Log.debug(l) }
95
+ case config[:on_error]
96
+ when :skip
97
+ ui.warn "Failed to connect to #{node_name} -- #{$!.class.name}: #{$!.message}"
98
+ $!.backtrace.each { |l| Chef::Log.debug(l) }
99
+ when :raise
100
+ #Net::SSH::Multi magic to force exception to be re-raised.
101
+ throw :go, :raise
102
+ end
96
103
  end
97
104
 
98
105
  @session ||= Net::SSH::Multi.start(:concurrent_connections => config[:concurrency], :on_error => ssh_error_handler)
@@ -265,7 +272,7 @@ class Chef
265
272
  end.join(" \\; ")
266
273
  end
267
274
 
268
- tmux_name = "'knife ssh #{@name_args[0]}'"
275
+ tmux_name = "'knife ssh #{@name_args[0].gsub(/:/,'=')}'"
269
276
  begin
270
277
  server = session.servers_for.first
271
278
  cmd = ["tmux new-session -d -s #{tmux_name}",
@@ -307,6 +314,14 @@ class Chef
307
314
  "fqdn").strip
308
315
  end
309
316
 
317
+ def csshx
318
+ csshx_cmd = "csshX"
319
+ session.servers_for.each do |server|
320
+ csshx_cmd << " #{server.user ? "#{server.user}@#{server.host}" : server.host}"
321
+ end
322
+ exec(csshx_cmd)
323
+ end
324
+
310
325
  def configure_user
311
326
  config[:ssh_user] = (config[:ssh_user] ||
312
327
  Chef::Config[:knife][:ssh_user])
@@ -337,6 +352,8 @@ class Chef
337
352
  tmux
338
353
  when "macterm"
339
354
  macterm
355
+ when "csshx"
356
+ csshx
340
357
  else
341
358
  ssh_command(@name_args[1..-1].join(" "))
342
359
  end
@@ -35,7 +35,7 @@ class Chef
35
35
 
36
36
  #XXX :user, :group, :environment support?
37
37
 
38
- Open4.popen4(cmd) do |stdin,stdout,stderr,cid|
38
+ Open3.popen3(cmd) do |stdin,stdout,stderr,cid|
39
39
  if b
40
40
  if args[:waitlast]
41
41
  b[cid, stdin, stdout, stderr]
@@ -182,6 +182,30 @@ class Chef
182
182
  }
183
183
  },
184
184
  :solaris => {},
185
+ :openindiana => {
186
+ :default => {
187
+ :service => Chef::Provider::Service::Solaris,
188
+ :package => Chef::Provider::Package::Solaris,
189
+ :cron => Chef::Provider::Cron::Solaris,
190
+ :group => Chef::Provider::Group::Usermod
191
+ }
192
+ },
193
+ :opensolaris => {
194
+ :default => {
195
+ :service => Chef::Provider::Service::Solaris,
196
+ :package => Chef::Provider::Package::Solaris,
197
+ :cron => Chef::Provider::Cron::Solaris,
198
+ :group => Chef::Provider::Group::Usermod
199
+ }
200
+ },
201
+ :nexentacore => {
202
+ :default => {
203
+ :service => Chef::Provider::Service::Solaris,
204
+ :package => Chef::Provider::Package::Solaris,
205
+ :cron => Chef::Provider::Cron::Solaris,
206
+ :group => Chef::Provider::Group::Usermod
207
+ }
208
+ },
185
209
  :solaris2 => {
186
210
  :default => {
187
211
  :service => Chef::Provider::Service::Solaris,
@@ -28,7 +28,7 @@ class Chef
28
28
  include Chef::Mixin::FromFile
29
29
  include Chef::Mixin::Command
30
30
 
31
- attr_reader :scm_provider, :release_path
31
+ attr_reader :scm_provider, :release_path, :previous_release_path
32
32
 
33
33
  def initialize(new_resource, run_context)
34
34
  super(new_resource, run_context)
@@ -59,23 +59,35 @@ class Chef
59
59
  end
60
60
 
61
61
  def action_deploy
62
- if all_releases.include?(release_path)
63
- if all_releases[-1] == release_path
62
+ save_release_state
63
+
64
+ if deployed?(release_path)
65
+ if current_release?(release_path)
64
66
  Chef::Log.debug("#{@new_resource} is the latest version")
65
67
  else
66
68
  action_rollback
67
69
  end
68
70
  else
69
- deploy
70
- @new_resource.updated_by_last_action(true)
71
+
72
+ with_rollback_on_error do
73
+ deploy
74
+ @new_resource.updated_by_last_action(true)
75
+ end
71
76
  end
72
77
  end
73
78
 
74
79
  def action_force_deploy
75
- if all_releases.include?(release_path)
80
+ if deployed?(release_path)
81
+ Chef::Log.info("Already deployed app at #{release_path}, forcing.")
76
82
  FileUtils.rm_rf(release_path)
77
83
  Chef::Log.info("#{@new_resource} forcing deploy of already deployed app at #{release_path}")
78
84
  end
85
+
86
+ # Alternatives:
87
+ # * Move release_path directory before deploy and move it back when error occurs
88
+ # * Rollback to previous commit
89
+ # * Do nothing - because deploy is force, it will be retried in short time
90
+ # Because last is simpliest, keep it
79
91
  deploy
80
92
  @new_resource.updated_by_last_action(true)
81
93
  end
@@ -92,10 +104,8 @@ class Chef
92
104
  releases_to_nuke = [ all_releases.last ]
93
105
  end
94
106
 
95
- Chef::Log.info "#{@new_resource} rolling back to previous release #{release_path}"
96
- symlink
97
- Chef::Log.info "#{@new_resource} restarting with previous release"
98
- restart
107
+ rollback
108
+
99
109
  releases_to_nuke.each do |i|
100
110
  Chef::Log.info "#{@new_resource} removing release: #{i}"
101
111
  FileUtils.rm_rf i
@@ -106,6 +116,7 @@ class Chef
106
116
 
107
117
  def deploy
108
118
  enforce_ownership
119
+ verify_directories_exist
109
120
  update_cached_repo
110
121
  copy_cached_repo
111
122
  install_gems
@@ -121,6 +132,13 @@ class Chef
121
132
  Chef::Log.info "#{@new_resource} deployed to #{@new_resource.deploy_to}"
122
133
  end
123
134
 
135
+ def rollback
136
+ Chef::Log.info "#{@new_resource} rolling back to previous release #{release_path}"
137
+ symlink
138
+ Chef::Log.info "#{@new_resource} restarting with previous release"
139
+ restart
140
+ end
141
+
124
142
  def callback(what, callback_code=nil)
125
143
  @collection = Chef::ResourceCollection.new
126
144
  case callback_code
@@ -218,6 +236,11 @@ class Chef
218
236
  Chef::Log.info("#{@new_resource} set group to #{@new_resource.group}") if @new_resource.group
219
237
  end
220
238
 
239
+ def verify_directories_exist
240
+ create_dir_unless_exists(@new_resource.deploy_to)
241
+ create_dir_unless_exists(@new_resource.shared_path)
242
+ end
243
+
221
244
  def link_current_release_to_production
222
245
  FileUtils.rm_f(@new_resource.current_path)
223
246
  begin
@@ -244,20 +267,17 @@ class Chef
244
267
  def link_tempfiles_to_current_release
245
268
  dirs_info = @new_resource.create_dirs_before_symlink.join(",")
246
269
  @new_resource.create_dirs_before_symlink.each do |dir|
247
- begin
248
- FileUtils.mkdir_p(release_path + "/#{dir}")
249
- rescue => e
250
- raise Chef::Exceptions::FileNotFound.new("Cannot create directory #{dir}: #{e.message}")
251
- end
270
+ create_dir_unless_exists(release_path + "/#{dir}")
252
271
  end
253
272
  Chef::Log.info("#{@new_resource} created directories before symlinking #{dirs_info}")
254
273
 
255
274
  links_info = @new_resource.symlinks.map { |src, dst| "#{src} => #{dst}" }.join(", ")
256
275
  @new_resource.symlinks.each do |src, dest|
276
+ create_dir_unless_exists(::File.join(@new_resource.shared_path, src))
257
277
  begin
258
- FileUtils.ln_sf(@new_resource.shared_path + "/#{src}", release_path + "/#{dest}")
278
+ FileUtils.ln_sf(::File.join(@new_resource.shared_path, src), ::File.join(release_path, dest))
259
279
  rescue => e
260
- raise Chef::Exceptions::FileNotFound.new("Cannot symlink shared data #{@new_resource.shared_path}/#{src} to #{release_path}/#{dest}: #{e.message}")
280
+ raise Chef::Exceptions::FileNotFound.new("Cannot symlink shared data #{::File.join(@new_resource.shared_path, src)} to #{::File.join(release_path, dest)}: #{e.message}")
261
281
  end
262
282
  end
263
283
  Chef::Log.info("#{@new_resource} linked shared paths into current release: #{links_info}")
@@ -338,6 +358,62 @@ class Chef
338
358
  end
339
359
  end
340
360
 
361
+ def create_dir_unless_exists(dir)
362
+ if ::File.directory?(dir)
363
+ Chef::Log.debug "#{@new_resource} not creating #{dir} because it already exists"
364
+ return false
365
+ end
366
+
367
+ begin
368
+ FileUtils.mkdir_p(dir)
369
+ Chef::Log.debug "#{@new_resource} created directory #{dir}"
370
+ if @new_resource.user
371
+ FileUtils.chown(@new_resource.user, nil, dir)
372
+ Chef::Log.debug("#{@new_resource} set user to #{@new_resource.user} for #{dir}")
373
+ end
374
+ if @new_resource.group
375
+ FileUtils.chown(nil, @new_resource.group, dir)
376
+ Chef::Log.debug("#{@new_resource} set group to #{@new_resource.group} for #{dir}")
377
+ end
378
+ rescue => e
379
+ raise Chef::Exceptions::FileNotFound.new("Cannot create directory #{dir}: #{e.message}")
380
+ end
381
+ end
382
+
383
+ def with_rollback_on_error
384
+ yield
385
+ rescue ::Exception => e
386
+ if @new_resource.rollback_on_error
387
+ Chef::Log.warn "Error on deploying #{release_path}: #{e.message}"
388
+ failed_release = release_path
389
+
390
+ if previous_release_path
391
+ @release_path = previous_release_path
392
+ rollback
393
+ end
394
+
395
+ Chef::Log.info "Removing failed deploy #{failed_release}"
396
+ FileUtils.rm_rf failed_release
397
+ release_deleted(failed_release)
398
+ end
399
+
400
+ raise
401
+ end
402
+
403
+ def save_release_state
404
+ if ::File.exists?(@new_resource.current_path)
405
+ release = ::File.readlink(@new_resource.current_path)
406
+ @previous_release_path = release if ::File.exists?(release)
407
+ end
408
+ end
409
+
410
+ def deployed?(release)
411
+ all_releases.include?(release)
412
+ end
413
+
414
+ def current_release?(release)
415
+ @previous_release_path == release
416
+ end
341
417
  end
342
418
  end
343
419
  end