chef 12.0.0.alpha.0 → 12.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -5
  3. data/lib/chef/api_client.rb +1 -1
  4. data/lib/chef/application.rb +16 -8
  5. data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
  6. data/lib/chef/chef_fs/command_line.rb +1 -1
  7. data/lib/chef/chef_fs/file_system.rb +1 -1
  8. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  9. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +3 -3
  10. data/lib/chef/chef_fs/file_system/cookbook_file.rb +2 -2
  11. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -2
  12. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -4
  13. data/lib/chef/config.rb +6 -5
  14. data/lib/chef/config_fetcher.rb +1 -1
  15. data/lib/chef/cookbook/cookbook_version_loader.rb +126 -43
  16. data/lib/chef/cookbook/metadata.rb +102 -53
  17. data/lib/chef/cookbook/syntax_check.rb +1 -1
  18. data/lib/chef/cookbook_loader.rb +62 -14
  19. data/lib/chef/cookbook_site_streaming_uploader.rb +12 -1
  20. data/lib/chef/cookbook_version.rb +13 -4
  21. data/lib/chef/data_bag.rb +28 -15
  22. data/lib/chef/data_bag_item.rb +5 -7
  23. data/lib/chef/digester.rb +5 -9
  24. data/lib/chef/dsl/recipe.rb +14 -0
  25. data/lib/chef/encrypted_data_bag_item.rb +1 -0
  26. data/lib/chef/encrypted_data_bag_item/assertions.rb +57 -0
  27. data/lib/chef/encrypted_data_bag_item/decryptor.rb +52 -28
  28. data/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb +37 -0
  29. data/lib/chef/encrypted_data_bag_item/encryption_failure.rb +22 -0
  30. data/lib/chef/encrypted_data_bag_item/encryptor.rb +79 -8
  31. data/lib/chef/environment.rb +1 -3
  32. data/lib/chef/exceptions.rb +18 -3
  33. data/lib/chef/formatters/base.rb +7 -0
  34. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
  35. data/lib/chef/handler/json_file.rb +0 -1
  36. data/lib/chef/http/json_output.rb +1 -1
  37. data/lib/chef/json_compat.rb +24 -6
  38. data/lib/chef/knife/bootstrap.rb +2 -2
  39. data/lib/chef/knife/client_delete.rb +1 -1
  40. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  41. data/lib/chef/knife/cookbook_site_list.rb +1 -1
  42. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  43. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  44. data/lib/chef/knife/cookbook_site_show.rb +3 -3
  45. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  46. data/lib/chef/knife/core/node_editor.rb +2 -3
  47. data/lib/chef/knife/core/ui.rb +2 -2
  48. data/lib/chef/knife/deps.rb +2 -3
  49. data/lib/chef/mixin/shell_out.rb +1 -1
  50. data/lib/chef/mixin/windows_architecture_helper.rb +1 -0
  51. data/lib/chef/node.rb +1 -2
  52. data/lib/chef/platform/provider_mapping.rb +33 -6
  53. data/lib/chef/provider.rb +0 -2
  54. data/lib/chef/provider/cookbook_file/content.rb +1 -1
  55. data/lib/chef/provider/cron.rb +11 -0
  56. data/lib/chef/provider/deploy.rb +3 -2
  57. data/lib/chef/provider/deploy/revision.rb +2 -2
  58. data/lib/chef/provider/env.rb +1 -1
  59. data/lib/chef/provider/env/windows.rb +5 -9
  60. data/lib/chef/provider/file.rb +84 -33
  61. data/lib/chef/provider/git.rb +2 -1
  62. data/lib/chef/provider/group/aix.rb +17 -2
  63. data/lib/chef/provider/group/dscl.rb +27 -9
  64. data/lib/chef/provider/group/pw.rb +8 -1
  65. data/lib/chef/provider/http_request.rb +4 -4
  66. data/lib/chef/provider/log.rb +4 -14
  67. data/lib/chef/provider/mount/mount.rb +2 -2
  68. data/lib/chef/provider/package/ips.rb +17 -23
  69. data/lib/chef/provider/package/paludis.rb +2 -2
  70. data/lib/chef/provider/package/rpm.rb +2 -2
  71. data/lib/chef/provider/package/rubygems.rb +2 -0
  72. data/lib/chef/provider/package/yum.rb +2 -0
  73. data/lib/chef/provider/package/zypper.rb +1 -1
  74. data/lib/chef/provider/remote_file/cache_control_data.rb +2 -2
  75. data/lib/chef/provider/service/windows.rb +87 -21
  76. data/lib/chef/provider/user/aix.rb +95 -0
  77. data/lib/chef/provider/user/dscl.rb +544 -156
  78. data/lib/chef/provider/user/useradd.rb +1 -0
  79. data/lib/chef/providers.rb +1 -0
  80. data/lib/chef/resource.rb +4 -3
  81. data/lib/chef/resource/freebsd_package.rb +10 -2
  82. data/lib/chef/resource/paludis_package.rb +1 -0
  83. data/lib/chef/resource/scm.rb +10 -0
  84. data/lib/chef/resource/user.rb +27 -0
  85. data/lib/chef/resource/windows_service.rb +53 -0
  86. data/lib/chef/resource_collection.rb +23 -12
  87. data/lib/chef/resource_reporter.rb +10 -10
  88. data/lib/chef/resources.rb +1 -0
  89. data/lib/chef/role.rb +3 -3
  90. data/lib/chef/run_list.rb +6 -3
  91. data/lib/chef/user.rb +1 -1
  92. data/lib/chef/util/diff.rb +1 -2
  93. data/lib/chef/version.rb +1 -1
  94. data/lib/chef/version_constraint.rb +4 -4
  95. data/spec/data/cookbooks/angrybash/metadata.rb +2 -0
  96. data/spec/data/cookbooks/apache2/metadata.rb +2 -0
  97. data/spec/data/cookbooks/borken/metadata.rb +2 -0
  98. data/spec/data/cookbooks/ignorken/metadata.rb +2 -0
  99. data/spec/data/cookbooks/java/metadata.rb +2 -0
  100. data/spec/data/cookbooks/name-mismatch-versionnumber/README.md +4 -0
  101. data/spec/data/cookbooks/name-mismatch-versionnumber/metadata.rb +8 -0
  102. data/spec/data/cookbooks/name-mismatch-versionnumber/recipes/default.rb +8 -0
  103. data/spec/data/cookbooks/openldap/files/default/remotedir/not_a_template.erb +2 -0
  104. data/spec/data/cookbooks/preseed/metadata.rb +2 -0
  105. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/README.md +4 -0
  106. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/metadata.rb +13 -0
  107. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/recipes/default.rb +8 -0
  108. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/README.md +4 -0
  109. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/metadata.rb +10 -0
  110. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/recipes/default.rb +8 -0
  111. data/spec/data/mac_users/10.7-8.plist.xml +559 -0
  112. data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
  113. data/spec/data/mac_users/10.7.plist.xml +559 -0
  114. data/spec/data/mac_users/10.7.shadow.xml +11 -0
  115. data/spec/data/mac_users/10.8.plist.xml +559 -0
  116. data/spec/data/mac_users/10.8.shadow.xml +21 -0
  117. data/spec/data/mac_users/10.9.plist.xml +560 -0
  118. data/spec/data/mac_users/10.9.shadow.xml +21 -0
  119. data/spec/data/object_loader/environments/test.json +2 -0
  120. data/spec/data/object_loader/environments/test_json_class.json +2 -0
  121. data/spec/data/object_loader/nodes/test.json +2 -0
  122. data/spec/data/object_loader/nodes/test_json_class.json +2 -0
  123. data/spec/data/object_loader/roles/test.json +2 -0
  124. data/spec/data/object_loader/roles/test_json_class.json +2 -0
  125. data/spec/functional/resource/bff_spec.rb +1 -1
  126. data/spec/functional/resource/cron_spec.rb +20 -1
  127. data/spec/functional/resource/env_spec.rb +137 -0
  128. data/spec/functional/resource/group_spec.rb +7 -5
  129. data/spec/functional/resource/remote_file_spec.rb +12 -1
  130. data/spec/functional/resource/user/dscl_spec.rb +198 -0
  131. data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +175 -37
  132. data/spec/integration/client/client_spec.rb +6 -4
  133. data/spec/integration/client/ipv6_spec.rb +16 -14
  134. data/spec/integration/knife/chef_fs_data_store_spec.rb +57 -46
  135. data/spec/integration/knife/chef_repo_path_spec.rb +105 -78
  136. data/spec/integration/knife/chef_repository_file_system_spec.rb +100 -84
  137. data/spec/integration/knife/chefignore_spec.rb +76 -46
  138. data/spec/integration/knife/common_options_spec.rb +16 -21
  139. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -3
  140. data/spec/integration/knife/delete_spec.rb +66 -46
  141. data/spec/integration/knife/deps_spec.rb +145 -94
  142. data/spec/integration/knife/diff_spec.rb +176 -110
  143. data/spec/integration/knife/download_spec.rb +229 -133
  144. data/spec/integration/knife/list_spec.rb +62 -54
  145. data/spec/integration/knife/raw_spec.rb +24 -9
  146. data/spec/integration/knife/redirection_spec.rb +2 -2
  147. data/spec/integration/knife/serve_spec.rb +2 -2
  148. data/spec/integration/knife/show_spec.rb +32 -26
  149. data/spec/integration/knife/upload_spec.rb +308 -165
  150. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +10 -8
  151. data/spec/integration/solo/solo_spec.rb +22 -11
  152. data/spec/spec_helper.rb +3 -0
  153. data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
  154. data/spec/support/platform_helpers.rb +12 -0
  155. data/spec/support/shared/functional/file_resource.rb +10 -0
  156. data/spec/support/shared/integration/chef_zero_support.rb +130 -0
  157. data/spec/support/shared/integration/integration_helper.rb +100 -98
  158. data/spec/support/shared/integration/knife_support.rb +0 -1
  159. data/spec/support/shared/unit/provider/file.rb +6 -4
  160. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +10 -1
  161. data/spec/unit/api_client/registration_spec.rb +83 -74
  162. data/spec/unit/application_spec.rb +32 -9
  163. data/spec/unit/cookbook/cookbook_version_loader_spec.rb +179 -0
  164. data/spec/unit/cookbook/metadata_spec.rb +190 -150
  165. data/spec/unit/cookbook/syntax_check_spec.rb +3 -2
  166. data/spec/unit/cookbook_loader_spec.rb +114 -53
  167. data/spec/unit/{cookbook_site_streaming_uploader.rb → cookbook_site_streaming_uploader_spec.rb} +21 -1
  168. data/spec/unit/data_bag_spec.rb +88 -13
  169. data/spec/unit/deprecation_spec.rb +1 -2
  170. data/spec/unit/encrypted_data_bag_item_spec.rb +145 -9
  171. data/spec/unit/environment_spec.rb +1 -1
  172. data/spec/unit/formatters/base_spec.rb +48 -0
  173. data/spec/unit/json_compat_spec.rb +48 -17
  174. data/spec/unit/knife/client_delete_spec.rb +4 -4
  175. data/spec/unit/knife/client_show_spec.rb +15 -5
  176. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -1
  177. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  178. data/spec/unit/knife/data_bag_from_file_spec.rb +0 -2
  179. data/spec/unit/knife/data_bag_show_spec.rb +23 -14
  180. data/spec/unit/knife/node_show_spec.rb +32 -15
  181. data/spec/unit/knife/role_show_spec.rb +59 -0
  182. data/spec/unit/platform_spec.rb +10 -0
  183. data/spec/unit/provider/deploy_spec.rb +4 -0
  184. data/spec/unit/provider/env_spec.rb +19 -0
  185. data/spec/unit/provider/git_spec.rb +22 -2
  186. data/spec/unit/provider/group/dscl_spec.rb +38 -1
  187. data/spec/unit/provider/group/pw_spec.rb +2 -2
  188. data/spec/unit/provider/http_request_spec.rb +8 -8
  189. data/spec/unit/provider/log_spec.rb +33 -53
  190. data/spec/unit/provider/mount/mount_spec.rb +12 -3
  191. data/spec/unit/provider/package/ips_spec.rb +96 -63
  192. data/spec/unit/provider/package/paludis_spec.rb +5 -5
  193. data/spec/unit/provider/package/rpm_spec.rb +12 -0
  194. data/spec/unit/provider/package/zypper_spec.rb +28 -16
  195. data/spec/unit/provider/service/windows_spec.rb +77 -17
  196. data/spec/unit/provider/user/dscl_spec.rb +659 -264
  197. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  198. data/spec/unit/recipe_spec.rb +41 -0
  199. data/spec/unit/resource/scm_spec.rb +11 -0
  200. data/spec/unit/resource/user_spec.rb +4 -0
  201. data/spec/unit/resource/windows_service_spec.rb +46 -0
  202. data/spec/unit/resource_collection_spec.rb +33 -0
  203. data/spec/unit/resource_reporter_spec.rb +48 -0
  204. data/spec/unit/resource_spec.rb +9 -2
  205. data/spec/unit/role_spec.rb +6 -0
  206. data/spec/unit/version_constraint_spec.rb +28 -0
  207. metadata +61 -4
@@ -41,7 +41,7 @@ class Chef
41
41
  confirm "Do you really want to unshare the cookbook #{@cookbook_name}"
42
42
 
43
43
  begin
44
- rest.delete_rest "http://cookbooks.opscode.com/api/v1/cookbooks/#{@name_args[0]}"
44
+ rest.delete_rest "https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}"
45
45
  rescue Net::HTTPServerException => e
46
46
  raise e unless e.message =~ /Forbidden/
47
47
  ui.error "Forbidden: You must be the maintainer of #{@cookbook_name} to unshare it."
@@ -42,8 +42,8 @@ class Chef
42
42
  end
43
43
 
44
44
  def updated?
45
- pristine_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(node), :create_additions => false)
46
- updated_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@updated_node), :create_additions => false)
45
+ pristine_copy = Chef::JSONCompat.parse(Chef::JSONCompat.to_json(node))
46
+ updated_copy = Chef::JSONCompat.parse(Chef::JSONCompat.to_json(@updated_node))
47
47
  unless pristine_copy == updated_copy
48
48
  updated_properties = %w{name normal chef_environment run_list default override automatic}.reject do |key|
49
49
  pristine_copy[key] == updated_copy[key]
@@ -107,4 +107,3 @@ class Chef
107
107
  end
108
108
  end
109
109
  end
110
-
@@ -195,8 +195,8 @@ class Chef
195
195
  # We wouldn't have to do these shenanigans if all the editable objects
196
196
  # implemented to_hash, or if to_json against a hash returned a string
197
197
  # with stable key order.
198
- object_parsed_again = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(object), :create_additions => false)
199
- output_parsed_again = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(output), :create_additions => false)
198
+ object_parsed_again = Chef::JSONCompat.parse(Chef::JSONCompat.to_json(object))
199
+ output_parsed_again = Chef::JSONCompat.parse(Chef::JSONCompat.to_json(output))
200
200
  if object_parsed_again != output_parsed_again
201
201
  output.save
202
202
  self.msg("Saved #{output}")
@@ -77,7 +77,7 @@ class Chef
77
77
  return entry.chef_object.metadata.dependencies.keys.map { |cookbook| "/cookbooks/#{cookbook}" }
78
78
 
79
79
  elsif entry.parent && entry.parent.path == '/nodes'
80
- node = JSON.parse(entry.read, :create_additions => false)
80
+ node = Chef::JSONCompat.parse(entry.read)
81
81
  result = []
82
82
  if node['chef_environment'] && node['chef_environment'] != '_default'
83
83
  result << "/environments/#{node['chef_environment']}.json"
@@ -88,7 +88,7 @@ class Chef
88
88
  result
89
89
 
90
90
  elsif entry.parent && entry.parent.path == '/roles'
91
- role = JSON.parse(entry.read, :create_additions => false)
91
+ role = Chef::JSONCompat.parse(entry.read)
92
92
  result = []
93
93
  if role['run_list']
94
94
  dependencies_from_runlist(role['run_list']).each do |dependency|
@@ -138,4 +138,3 @@ class Chef
138
138
  end
139
139
  end
140
140
  end
141
-
@@ -33,7 +33,7 @@ class Chef
33
33
 
34
34
  def shell_out(*command_args)
35
35
  cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
36
- cmd.live_stream = io_for_live_stream
36
+ cmd.live_stream ||= io_for_live_stream
37
37
  cmd.run_command
38
38
  cmd
39
39
  end
@@ -18,6 +18,7 @@
18
18
 
19
19
 
20
20
  require 'chef/exceptions'
21
+ require 'chef/platform/query_helpers'
21
22
  require 'win32/api' if Chef::Platform.windows?
22
23
  require 'chef/win32/api/process' if Chef::Platform.windows?
23
24
  require 'chef/win32/api/error' if Chef::Platform.windows?
@@ -181,7 +181,6 @@ class Chef
181
181
  attributes.override
182
182
  end
183
183
 
184
-
185
184
  def override_attrs
186
185
  attributes.override
187
186
  end
@@ -416,7 +415,7 @@ class Chef
416
415
 
417
416
  # Serialize this object as a hash
418
417
  def to_json(*a)
419
- for_json.to_json(*a)
418
+ Chef::JSONCompat.to_json(for_json, *a)
420
419
  end
421
420
 
422
421
  def for_json
@@ -142,11 +142,14 @@ class Chef
142
142
  },
143
143
  :centos => {
144
144
  :default => {
145
- :service => Chef::Provider::Service::Redhat,
145
+ :service => Chef::Provider::Service::Systemd,
146
146
  :cron => Chef::Provider::Cron,
147
147
  :package => Chef::Provider::Package::Yum,
148
148
  :mdadm => Chef::Provider::Mdadm,
149
149
  :ifconfig => Chef::Provider::Ifconfig::Redhat
150
+ },
151
+ "< 7" => {
152
+ :service => Chef::Provider::Service::Redhat
150
153
  }
151
154
  },
152
155
  :amazon => {
@@ -159,19 +162,25 @@ class Chef
159
162
  },
160
163
  :scientific => {
161
164
  :default => {
162
- :service => Chef::Provider::Service::Redhat,
165
+ :service => Chef::Provider::Service::Systemd,
163
166
  :cron => Chef::Provider::Cron,
164
167
  :package => Chef::Provider::Package::Yum,
165
168
  :mdadm => Chef::Provider::Mdadm
169
+ },
170
+ "< 7" => {
171
+ :service => Chef::Provider::Service::Redhat
166
172
  }
167
173
  },
168
174
  :fedora => {
169
175
  :default => {
170
- :service => Chef::Provider::Service::Redhat,
176
+ :service => Chef::Provider::Service::Systemd,
171
177
  :cron => Chef::Provider::Cron,
172
178
  :package => Chef::Provider::Package::Yum,
173
179
  :mdadm => Chef::Provider::Mdadm,
174
180
  :ifconfig => Chef::Provider::Ifconfig::Redhat
181
+ },
182
+ "< 15" => {
183
+ :service => Chef::Provider::Service::Redhat
175
184
  }
176
185
  },
177
186
  :opensuse => {
@@ -196,19 +205,25 @@ class Chef
196
205
  },
197
206
  :oracle => {
198
207
  :default => {
199
- :service => Chef::Provider::Service::Redhat,
208
+ :service => Chef::Provider::Service::Systemd,
200
209
  :cron => Chef::Provider::Cron,
201
210
  :package => Chef::Provider::Package::Yum,
202
211
  :mdadm => Chef::Provider::Mdadm
212
+ },
213
+ "< 7" => {
214
+ :service => Chef::Provider::Service::Redhat
203
215
  }
204
216
  },
205
217
  :redhat => {
206
218
  :default => {
207
- :service => Chef::Provider::Service::Redhat,
219
+ :service => Chef::Provider::Service::Systemd,
208
220
  :cron => Chef::Provider::Cron,
209
221
  :package => Chef::Provider::Package::Yum,
210
222
  :mdadm => Chef::Provider::Mdadm,
211
223
  :ifconfig => Chef::Provider::Ifconfig::Redhat
224
+ },
225
+ "< 7" => {
226
+ :service => Chef::Provider::Service::Systemd
212
227
  }
213
228
  },
214
229
  :ibm_powerkvm => {
@@ -229,6 +244,15 @@ class Chef
229
244
  :ifconfig => Chef::Provider::Ifconfig::Redhat
230
245
  }
231
246
  },
247
+ :parallels => {
248
+ :default => {
249
+ :service => Chef::Provider::Service::Redhat,
250
+ :cron => Chef::Provider::Cron,
251
+ :package => Chef::Provider::Package::Yum,
252
+ :mdadm => Chef::Provider::Mdadm,
253
+ :ifconfig => Chef::Provider::Ifconfig::Redhat
254
+ }
255
+ },
232
256
  :gentoo => {
233
257
  :default => {
234
258
  :package => Chef::Provider::Package::Portage,
@@ -365,7 +389,8 @@ class Chef
365
389
  :mount => Chef::Provider::Mount::Aix,
366
390
  :ifconfig => Chef::Provider::Ifconfig::Aix,
367
391
  :cron => Chef::Provider::Cron::Aix,
368
- :package => Chef::Provider::Package::Aix
392
+ :package => Chef::Provider::Package::Aix,
393
+ :user => Chef::Provider::User::Aix
369
394
  }
370
395
  },
371
396
  :exherbo => {
@@ -523,6 +548,8 @@ class Chef
523
548
  if platforms.has_key?(args[:platform])
524
549
  if platforms[args[:platform]].has_key?(:default)
525
550
  platforms[args[:platform]][:default][args[:resource].to_sym] = args[:provider]
551
+ elsif args[:platform] == :default
552
+ platforms[:default][args[:resource].to_sym] = args[:provider]
526
553
  else
527
554
  platforms[args[:platform]] = { :default => { args[:resource].to_sym => args[:provider] } }
528
555
  end
@@ -19,14 +19,12 @@
19
19
 
20
20
  require 'chef/mixin/from_file'
21
21
  require 'chef/mixin/convert_to_class_name'
22
- require 'chef/dsl/recipe'
23
22
  require 'chef/mixin/enforce_ownership_and_permissions'
24
23
  require 'chef/mixin/why_run'
25
24
  require 'chef/mixin/shell_out'
26
25
 
27
26
  class Chef
28
27
  class Provider
29
- include Chef::DSL::Recipe
30
28
  include Chef::Mixin::WhyRun
31
29
  include Chef::Mixin::ShellOut
32
30
 
@@ -28,7 +28,7 @@ class Chef
28
28
 
29
29
  def file_for_provider
30
30
  cookbook = run_context.cookbook_collection[resource_cookbook]
31
- file_cache_location = cookbook.preferred_filename_on_disk_location(run_context.node, :files, @new_resource.source, @new_resource.path)
31
+ file_cache_location = cookbook.preferred_filename_on_disk_location(run_context.node, :files, @new_resource.source)
32
32
  if file_cache_location.nil?
33
33
  nil
34
34
  else
@@ -118,6 +118,12 @@ class Chef
118
118
  when ENV_PATTERN
119
119
  crontab << line unless cron_found
120
120
  next
121
+ when SPECIAL_PATTERN
122
+ if cron_found
123
+ cron_found = false
124
+ crontab << newcron
125
+ next
126
+ end
121
127
  when CRON_PATTERN
122
128
  if cron_found
123
129
  cron_found = false
@@ -163,6 +169,11 @@ class Chef
163
169
  next
164
170
  when ENV_PATTERN
165
171
  next if cron_found
172
+ when SPECIAL_PATTERN
173
+ if cron_found
174
+ cron_found = false
175
+ next
176
+ end
166
177
  when CRON_PATTERN
167
178
  if cron_found
168
179
  cron_found = false
@@ -21,7 +21,7 @@ require "chef/mixin/from_file"
21
21
  require "chef/monkey_patches/fileutils"
22
22
  require "chef/provider/git"
23
23
  require "chef/provider/subversion"
24
- require 'chef/dsl/recipe'
24
+ require "chef/dsl/recipe"
25
25
 
26
26
  class Chef
27
27
  class Provider
@@ -31,7 +31,7 @@ class Chef
31
31
  include Chef::Mixin::FromFile
32
32
  include Chef::Mixin::Command
33
33
 
34
- attr_reader :scm_provider, :release_path, :previous_release_path
34
+ attr_reader :scm_provider, :release_path, :shared_path, :previous_release_path
35
35
 
36
36
  def initialize(new_resource, run_context)
37
37
  super(new_resource, run_context)
@@ -53,6 +53,7 @@ class Chef
53
53
  def load_current_resource
54
54
  @scm_provider.load_current_resource
55
55
  @release_path = @new_resource.deploy_to + "/releases/#{release_slug}"
56
+ @shared_path = @new_resource.shared_path
56
57
  end
57
58
 
58
59
  def sudo(command,&block)
@@ -90,14 +90,14 @@ class Chef
90
90
 
91
91
  def load_cache
92
92
  begin
93
- Chef::JSONCompat.from_json(Chef::FileCache.load("revision-deploys/#{new_resource.name}"))
93
+ Chef::JSONCompat.parse(Chef::FileCache.load("revision-deploys/#{new_resource.name}"))
94
94
  rescue Chef::Exceptions::FileNotFound
95
95
  sorted_releases_from_filesystem
96
96
  end
97
97
  end
98
98
 
99
99
  def save_cache(cache)
100
- Chef::FileCache.store("revision-deploys/#{new_resource.name}", cache.to_json)
100
+ Chef::FileCache.store("revision-deploys/#{new_resource.name}", Chef::JSONCompat.to_json(cache))
101
101
  cache
102
102
  end
103
103
 
@@ -143,7 +143,7 @@ class Chef
143
143
  def modify_env
144
144
  if @new_resource.delim
145
145
  #e.g. add to PATH
146
- @new_resource.value << @new_resource.delim << @current_resource.value
146
+ @new_resource.value(@new_resource.value + @new_resource.delim + @current_resource.value)
147
147
  end
148
148
  create_env
149
149
  end
@@ -51,17 +51,13 @@ class Chef
51
51
  return obj ? obj.variablevalue : nil
52
52
  end
53
53
 
54
- def find_env(environment_variables, key_name)
55
- environment_variables.find do | environment_variable |
56
- environment_variable['name'].downcase == key_name
57
- end
58
- end
59
-
60
54
  def env_obj(key_name)
61
55
  wmi = WmiLite::Wmi.new
62
- environment_variables = wmi.instances_of('Win32_Environment')
63
- existing_variable = find_env(environment_variables, key_name)
64
- existing_variable.nil? ? nil : existing_variable.wmi_ole_object
56
+ # Note that by design this query is case insensitive with regard to key_name
57
+ environment_variables = wmi.query("select * from Win32_Environment where name = '#{key_name}'")
58
+ if environment_variables && environment_variables.length > 0
59
+ environment_variables[0].wmi_ole_object
60
+ end
65
61
  end
66
62
 
67
63
  #see: http://msdn.microsoft.com/en-us/library/ms682653%28VS.85%29.aspx
@@ -56,6 +56,10 @@ class Chef
56
56
 
57
57
  attr_reader :deployment_strategy
58
58
 
59
+ attr_accessor :needs_creating
60
+ attr_accessor :needs_unlinking
61
+ attr_accessor :managing_symlink
62
+
59
63
  def initialize(new_resource, run_context)
60
64
  @content_class ||= Chef::Provider::File::Content
61
65
  if new_resource.respond_to?(:atomic_update)
@@ -69,22 +73,47 @@ class Chef
69
73
  end
70
74
 
71
75
  def load_current_resource
76
+ # true if there is a symlink and we need to manage what it points at
77
+ @managing_symlink = file_class.symlink?(new_resource.path) && ( new_resource.manage_symlink_source || new_resource.manage_symlink_source.nil? )
78
+
79
+ # true if there is a non-file thing in the way that we need to unlink first
80
+ @needs_unlinking =
81
+ if ::File.exist?(new_resource.path)
82
+ if managing_symlink?
83
+ !symlink_to_real_file?(new_resource.path)
84
+ else
85
+ !real_file?(new_resource.path)
86
+ end
87
+ else
88
+ false
89
+ end
90
+
91
+ # true if we are going to be creating a new file
92
+ @needs_creating = !::File.exist?(new_resource.path) || needs_unlinking?
93
+
72
94
  # Let children resources override constructing the @current_resource
73
- @current_resource ||= Chef::Resource::File.new(@new_resource.name)
74
- @current_resource.path(@new_resource.path)
75
- if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
95
+ @current_resource ||= Chef::Resource::File.new(new_resource.name)
96
+ current_resource.path(new_resource.path)
97
+
98
+ if !needs_creating?
99
+ # we are updating an existing file
76
100
  if managing_content?
77
- Chef::Log.debug("#{@new_resource} checksumming file at #{@new_resource.path}.")
78
- @current_resource.checksum(checksum(@current_resource.path))
101
+ Chef::Log.debug("#{new_resource} checksumming file at #{new_resource.path}.")
102
+ current_resource.checksum(checksum(current_resource.path))
103
+ else
104
+ # if the file does not exist or is not a file, then the checksum is invalid/pointless
105
+ current_resource.checksum(nil)
79
106
  end
80
- load_resource_attributes_from_file(@current_resource)
107
+ load_resource_attributes_from_file(current_resource)
81
108
  end
82
- @current_resource
109
+
110
+ current_resource
83
111
  end
84
112
 
85
113
  def define_resource_requirements
86
114
  # deep inside FAC we have to assert requirements, so call FACs hook to set that up
87
115
  access_controls.define_resource_requirements
116
+
88
117
  # Make sure the parent directory exists, otherwise fail. For why-run assume it would have been created.
89
118
  requirements.assert(:create, :create_if_missing, :touch) do |a|
90
119
  parent_directory = ::File.dirname(@new_resource.path)
@@ -94,7 +123,7 @@ class Chef
94
123
  end
95
124
 
96
125
  # Make sure the file is deletable if it exists, otherwise fail.
97
- if ::File.exists?(@new_resource.path)
126
+ if ::File.exist?(@new_resource.path)
98
127
  requirements.assert(:delete) do |a|
99
128
  a.assertion { ::File.writable?(@new_resource.path) }
100
129
  a.failure_message(Chef::Exceptions::InsufficientPermissions,"File #{@new_resource.path} exists but is not writable so it cannot be deleted")
@@ -114,6 +143,8 @@ class Chef
114
143
  end
115
144
 
116
145
  def action_create
146
+ do_generate_content
147
+ do_validate_content
117
148
  do_unlink
118
149
  do_create_file
119
150
  do_contents_changes
@@ -123,10 +154,10 @@ class Chef
123
154
  end
124
155
 
125
156
  def action_create_if_missing
126
- if ::File.exists?(@new_resource.path)
127
- Chef::Log.debug("#{@new_resource} exists at #{@new_resource.path} taking no action.")
128
- else
157
+ unless ::File.exist?(@new_resource.path)
129
158
  action_create
159
+ else
160
+ Chef::Log.debug("#{@new_resource} exists at #{@new_resource.path} taking no action.")
130
161
  end
131
162
  end
132
163
 
@@ -275,6 +306,15 @@ class Chef
275
306
  !file_class.symlink?(path) && ::File.file?(path)
276
307
  end
277
308
 
309
+ # like real_file? that follows (sane) symlinks
310
+ def symlink_to_real_file?(path)
311
+ begin
312
+ real_file?(::File.realpath(path))
313
+ rescue Errno::ELOOP, Errno::ENOENT
314
+ false
315
+ end
316
+ end
317
+
278
318
  # Similar to File.exist?, but also returns true in the case that the
279
319
  # named file is a broken symlink.
280
320
  def l_exist?(path)
@@ -290,41 +330,42 @@ class Chef
290
330
  end
291
331
  end
292
332
 
333
+ def do_generate_content
334
+ # referencing the tempfile magically causes content to be generated
335
+ tempfile
336
+ end
337
+
338
+ def tempfile_checksum
339
+ @tempfile_checksum ||= checksum(tempfile.path)
340
+ end
341
+
342
+ def do_validate_content
343
+ if new_resource.checksum && tempfile && ( new_resource.checksum != tempfile_checksum )
344
+ raise Chef::Exceptions::ChecksumMismatch.new(short_cksum(new_resource.checksum), short_cksum(tempfile_checksum))
345
+ end
346
+ end
347
+
293
348
  def do_unlink
294
- @file_unlinked = false
295
349
  if @new_resource.force_unlink
296
- if l_exist?(@new_resource.path) && !real_file?(@new_resource.path)
350
+ if needs_unlinking?
297
351
  # unlink things that aren't normal files
298
352
  description = "unlink #{file_type_string(@new_resource.path)} at #{@new_resource.path}"
299
353
  converge_by(description) do
300
354
  unlink(@new_resource.path)
301
355
  end
302
- @current_resource.checksum = nil
303
- @file_unlinked = true
304
356
  end
305
357
  end
306
358
  end
307
359
 
308
- def file_unlinked?
309
- @file_unlinked == true
310
- end
311
-
312
360
  def do_create_file
313
- @file_created = false
314
- if !::File.exists?(@new_resource.path) || file_unlinked?
361
+ if needs_creating?
315
362
  converge_by("create new file #{@new_resource.path}") do
316
363
  deployment_strategy.create(@new_resource.path)
317
364
  Chef::Log.info("#{@new_resource} created file #{@new_resource.path}")
318
365
  end
319
- @file_created = true
320
366
  end
321
367
  end
322
368
 
323
- # do_contents_changes needs to know if do_create_file created a file or not
324
- def file_created?
325
- @file_created == true
326
- end
327
-
328
369
  def do_backup(file = nil)
329
370
  Chef::Util::Backup.new(@new_resource, file).backup!
330
371
  end
@@ -334,7 +375,7 @@ class Chef
334
375
  end
335
376
 
336
377
  def update_file_contents
337
- do_backup unless file_created?
378
+ do_backup unless needs_creating?
338
379
  deployment_strategy.deploy(tempfile.path, ::File.realpath(@new_resource.path))
339
380
  Chef::Log.info("#{@new_resource} updated file contents #{@new_resource.path}")
340
381
  if managing_content?
@@ -353,7 +394,7 @@ class Chef
353
394
  # the file? on the next line suppresses the case in why-run when we have a not-file here that would have otherwise been removed
354
395
  if ::File.file?(@new_resource.path) && contents_changed?
355
396
  description = [ "update content in file #{@new_resource.path} from \
356
- #{short_cksum(@current_resource.checksum)} to #{short_cksum(checksum(tempfile.path))}" ]
397
+ #{short_cksum(@current_resource.checksum)} to #{short_cksum(tempfile_checksum)}" ]
357
398
 
358
399
  # Hide the diff output if the resource is marked as a sensitive resource
359
400
  if @new_resource.sensitive
@@ -361,7 +402,7 @@ class Chef
361
402
  description << "suppressed sensitive resource"
362
403
  else
363
404
  diff.diff(@current_resource.path, tempfile.path)
364
- @new_resource.diff( diff.for_reporting ) unless file_created?
405
+ @new_resource.diff( diff.for_reporting ) unless needs_creating?
365
406
  description << diff.for_output
366
407
  end
367
408
 
@@ -401,11 +442,11 @@ class Chef
401
442
 
402
443
  def contents_changed?
403
444
  Chef::Log.debug "calculating checksum of #{tempfile.path} to compare with #{@current_resource.checksum}"
404
- checksum(tempfile.path) != @current_resource.checksum
445
+ tempfile_checksum != @current_resource.checksum
405
446
  end
406
447
 
407
448
  def tempfile
408
- content.tempfile
449
+ @tempfile ||= content.tempfile
409
450
  end
410
451
 
411
452
  def short_cksum(checksum)
@@ -414,7 +455,6 @@ class Chef
414
455
  end
415
456
 
416
457
  def load_resource_attributes_from_file(resource)
417
-
418
458
  if Chef::Platform.windows?
419
459
  # This is a work around for CHEF-3554.
420
460
  # OC-6534: is tracking the real fix for this workaround.
@@ -426,6 +466,17 @@ class Chef
426
466
  acl_scanner.set_all!
427
467
  end
428
468
 
469
+ def managing_symlink?
470
+ !!@managing_symlink
471
+ end
472
+
473
+ def needs_creating?
474
+ !!@needs_creating
475
+ end
476
+
477
+ def needs_unlinking?
478
+ !!@needs_unlinking
479
+ end
429
480
  end
430
481
  end
431
482
  end