chef 12.0.0.alpha.0-x86-mingw32 → 12.0.0.alpha.1-x86-mingw32

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 (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60e7ed5e2729a9e7c21acfa95d07e43638d78730
4
- data.tar.gz: 3ece05335bad2e82332cd470ce29ee001ec99810
3
+ metadata.gz: d09796613f1004fd31743d62e30f2b6e10741d8e
4
+ data.tar.gz: deee29276799d1858418b4850c69d4955548468e
5
5
  SHA512:
6
- metadata.gz: c71f624aacf29771b168d4d03ede5d1c1dc9eeb4e0975d1e067593d6b90725b19b162be6c834725271266a49148ad7c6e0f17a19440c3696c10624e5ea7708a5
7
- data.tar.gz: 74084acfde35c719290511363cec2ff6f243a4a47b6d32c72fac162969db2466d4fbf2c5ff7be31dcd438a525443d2f12ea2f1f65b8e73c3f17a4c24f3fdde18
6
+ metadata.gz: 27c7d1868381141741cb793d3e6c5859b3e5ac2f0fd049be3fdbe0bbfd90d71f213a5f6563bebbfdfd80c429db40eb9d88fddfaa8717428ebb9484cf4677e729
7
+ data.tar.gz: f4797ef8e7782d0a8a1fcffb6d92ca316c79a77e93b498069ea8fb28fb0260867f4d3a654934228a9638520265cc101df623d59ea11a5c8c69cc3c74e00a0daf
@@ -11,9 +11,7 @@ We utilize **Github Issues** for issue tracking and contributions. You can contr
11
11
 
12
12
  We have a 3 step process that utilizes **Github Issues**:
13
13
 
14
- 1. Sign our
15
- [Individual Contributor License Agreement (CLA)](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
16
- or [Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856) online once.
14
+ 1. Sign or be added to an existing [Contributor License Agreement (CLA)](https://supermarket.getchef.com/become-a-contributor).
17
15
  2. Create a Github Pull Request.
18
16
  3. Do [Code Review](#cr) with the **Chef Engineering Team** or **Chef Core Committers** on the pull request.
19
17
 
@@ -83,10 +81,10 @@ To make a good faith effort to ensure these criteria are met, Chef requires an I
83
81
  It only takes a few minutes to complete a CLA, and you retain the copyright to your contribution.
84
82
 
85
83
  You can complete our
86
- [Individual CLA](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L) online.
84
+ [Individual CLA](https://supermarket.getchef.com/icla-signatures/new) online.
87
85
  If you're contributing on behalf of your employer and they retain the copyright for your works,
88
86
  have your employer fill out our
89
- [Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856) instead.
87
+ [Corporate CLA](https://supermarket.getchef.com/ccla-signatures/new) instead.
90
88
 
91
89
  ### Chef Obvious Fix Policy
92
90
 
@@ -121,7 +121,7 @@ class Chef
121
121
  #
122
122
  # @return [String] the JSON string.
123
123
  def to_json(*a)
124
- to_hash.to_json(*a)
124
+ Chef::JSONCompat.to_json(to_hash, *a)
125
125
  end
126
126
 
127
127
  def self.json_create(o)
@@ -73,7 +73,6 @@ class Chef::Application
73
73
  end
74
74
  end
75
75
 
76
-
77
76
  # Parse configuration (options and config file)
78
77
  def configure_chef
79
78
  parse_options
@@ -219,30 +218,39 @@ class Chef::Application
219
218
  # Set ENV['http_proxy']
220
219
  def configure_http_proxy
221
220
  if http_proxy = Chef::Config[:http_proxy]
222
- env['http_proxy'] = configure_proxy("http", http_proxy,
223
- Chef::Config[:http_proxy_user], Chef::Config[:http_proxy_pass])
221
+ http_proxy_string = configure_proxy("http", http_proxy,
222
+ Chef::Config[:http_proxy_user], Chef::Config[:http_proxy_pass])
223
+ env['http_proxy'] = http_proxy_string unless env['http_proxy']
224
+ env['HTTP_PROXY'] = http_proxy_string unless env['HTTP_PROXY']
224
225
  end
225
226
  end
226
227
 
227
228
  # Set ENV['https_proxy']
228
229
  def configure_https_proxy
229
230
  if https_proxy = Chef::Config[:https_proxy]
230
- env['https_proxy'] = configure_proxy("https", https_proxy,
231
- Chef::Config[:https_proxy_user], Chef::Config[:https_proxy_pass])
231
+ https_proxy_string = configure_proxy("https", https_proxy,
232
+ Chef::Config[:https_proxy_user], Chef::Config[:https_proxy_pass])
233
+ env['https_proxy'] = https_proxy_string unless env['https_proxy']
234
+ env['HTTPS_PROXY'] = https_proxy_string unless env['HTTPS_PROXY']
232
235
  end
233
236
  end
234
237
 
235
238
  # Set ENV['ftp_proxy']
236
239
  def configure_ftp_proxy
237
240
  if ftp_proxy = Chef::Config[:ftp_proxy]
238
- env['ftp_proxy'] = configure_proxy("ftp", ftp_proxy,
241
+ ftp_proxy_string = configure_proxy("ftp", ftp_proxy,
239
242
  Chef::Config[:ftp_proxy_user], Chef::Config[:ftp_proxy_pass])
243
+ env['ftp_proxy'] = ftp_proxy_string unless env['ftp_proxy']
244
+ env['FTP_PROXY'] = ftp_proxy_string unless env['FTP_PROXY']
240
245
  end
241
246
  end
242
247
 
243
248
  # Set ENV['no_proxy']
244
249
  def configure_no_proxy
245
- env['no_proxy'] = Chef::Config[:no_proxy] if Chef::Config[:no_proxy]
250
+ if Chef::Config[:no_proxy]
251
+ env['no_proxy'] = Chef::Config[:no_proxy] unless env['no_proxy']
252
+ env['NO_PROXY'] = Chef::Config[:no_proxy] unless env['NO_PROXY']
253
+ end
246
254
  end
247
255
 
248
256
  # Builds a proxy uri. Examples:
@@ -256,7 +264,7 @@ class Chef::Application
256
264
  # pass = password
257
265
  def configure_proxy(scheme, path, user, pass)
258
266
  begin
259
- path = "#{scheme}://#{path}" unless path.start_with?(scheme)
267
+ path = "#{scheme}://#{path}" unless path.include?('://')
260
268
  # URI.split returns the following parts:
261
269
  # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
262
270
  parts = URI.split(URI.encode(path))
@@ -269,7 +269,7 @@ class Chef
269
269
 
270
270
  # Create a little Chef::ChefFS memory filesystem with the data
271
271
  cookbook_fs = Chef::ChefFS::FileSystem::MemoryRoot.new('uploading')
272
- cookbook = JSON.parse(data, :create_additions => false)
272
+ cookbook = Chef::JSONCompat.parse(data)
273
273
  cookbook.each_pair do |key, value|
274
274
  if value.is_a?(Array)
275
275
  value.each do |file|
@@ -251,7 +251,7 @@ class Chef
251
251
  end
252
252
 
253
253
  def self.canonicalize_json(json_text)
254
- parsed_json = JSON.parse(json_text, :create_additions => false)
254
+ parsed_json = Chef::JSONCompat.parse(json_text)
255
255
  sorted_json = sort_keys(parsed_json)
256
256
  JSON.pretty_generate(sorted_json)
257
257
  end
@@ -369,7 +369,7 @@ class Chef
369
369
  end
370
370
  else
371
371
  if dest_entry.dir?
372
- ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n") if ui
372
+ ui.error("File #{src_path} is a regular file while file #{dest_path} is a directory\n") if ui
373
373
  return
374
374
  else
375
375
 
@@ -37,7 +37,7 @@ class Chef
37
37
 
38
38
  def write(file_contents)
39
39
  # ACL writes are fun.
40
- acls = data_handler.normalize(JSON.parse(file_contents, :create_additions => false), self)
40
+ acls = data_handler.normalize(Chef::JSONCompat.parse(file_contents), self)
41
41
  PERMISSIONS.each do |permission|
42
42
  begin
43
43
  rest.put("#{api_path}/#{permission}", { permission => acls[permission] })
@@ -41,7 +41,7 @@ class Chef
41
41
 
42
42
  def chef_object
43
43
  begin
44
- return data_handler.chef_object(JSON.parse(read, :create_additions => false))
44
+ return data_handler.chef_object(Chef::JSONCompat.parse(read))
45
45
  rescue
46
46
  Chef::Log.error("Could not read #{path_for_printing} into a Chef object: #{$!}")
47
47
  end
@@ -60,10 +60,10 @@ class Chef
60
60
  end
61
61
 
62
62
  def minimize(file_contents, entry)
63
- object = JSONCompat.from_json(file_contents, :create_additions => false)
63
+ object = Chef::JSONCompat.from_json(file_contents)
64
64
  object = data_handler.normalize(object, entry)
65
65
  object = data_handler.minimize(object, entry)
66
- JSONCompat.to_json_pretty(object)
66
+ Chef::JSONCompat.to_json_pretty(object)
67
67
  end
68
68
 
69
69
  def children
@@ -18,7 +18,7 @@
18
18
 
19
19
  require 'chef/chef_fs/file_system/base_fs_object'
20
20
  require 'chef/http/simple'
21
- require 'digest/md5'
21
+ require 'openssl'
22
22
 
23
23
  class Chef
24
24
  module ChefFS
@@ -74,7 +74,7 @@ class Chef
74
74
  private
75
75
 
76
76
  def calc_checksum(value)
77
- Digest::MD5.hexdigest(value)
77
+ OpenSSL::Digest::MD5.hexdigest(value)
78
78
  end
79
79
  end
80
80
  end
@@ -61,8 +61,8 @@ class Chef
61
61
 
62
62
  def create_child(name, file_contents)
63
63
  begin
64
- object = JSON.parse(file_contents, :create_additions => false)
65
- rescue JSON::ParserError => e
64
+ object = Chef::JSONCompat.parse(file_contents)
65
+ rescue Chef::Exceptions::JSON::ParseError => e
66
66
  raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Parse error reading JSON creating child '#{name}': #{e}"
67
67
  end
68
68
 
@@ -128,8 +128,8 @@ class Chef
128
128
  value = minimize_value(value)
129
129
  value_json = Chef::JSONCompat.to_json_pretty(value)
130
130
  begin
131
- other_value = JSON.parse(other_value_json, :create_additions => false)
132
- rescue JSON::ParserError => e
131
+ other_value = Chef::JSONCompat.parse(other_value_json)
132
+ rescue Chef::Exceptions::JSON::ParseError => e
133
133
  Chef::Log.warn("Parse error reading #{other.path_for_printing} as JSON: #{e}")
134
134
  return [ nil, value_json, other_value_json ]
135
135
  end
@@ -145,8 +145,8 @@ class Chef
145
145
 
146
146
  def write(file_contents)
147
147
  begin
148
- object = JSON.parse(file_contents, :create_additions => false)
149
- rescue JSON::ParserError => e
148
+ object = Chef::JSONCompat.parse(file_contents)
149
+ rescue Chef::Exceptions::JSON::ParseError => e
150
150
  raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Parse error reading JSON: #{e}"
151
151
  end
152
152
 
@@ -432,7 +432,8 @@ class Chef
432
432
  # format. Version "2" is available which adds encrypt-then-mac protection.
433
433
  # To maintain compatibility, versions other than 1 must be opt-in.
434
434
  #
435
- # Set this to `2` if you have chef-client 11.6.0+ in your infrastructure:
435
+ # Set this to `2` if you have chef-client 11.6.0+ in your infrastructure.
436
+ # Set this to `3` if you have chef-client 11.?.0+, ruby 2 and OpenSSL >= 1.0.1 in your infrastructure. (TODO)
436
437
  default :data_bag_encrypt_version, 1
437
438
 
438
439
  # When reading data bag items, any supported version is accepted. However,
@@ -455,15 +456,15 @@ class Chef
455
456
  default :validation_client_name, "chef-validator"
456
457
 
457
458
  # When creating a new client via the validation_client account, Chef 11
458
- # servers allow the client to generate a key pair locally and sent the
459
+ # servers allow the client to generate a key pair locally and send the
459
460
  # public key to the server. This is more secure and helps offload work from
460
461
  # the server, enhancing scalability. If enabled and the remote server
461
462
  # implements only the Chef 10 API, client registration will not work
462
463
  # properly.
463
464
  #
464
- # The default value is `false` (Server generates client keys). Set to
465
- # `true` to enable client-side key generation.
466
- default(:local_key_generation) { false }
465
+ # The default value is `true`. Set to `false` to disable client-side key
466
+ # generation (server generates client keys).
467
+ default(:local_key_generation) { true }
467
468
 
468
469
  # Zypper package provider gpg checks. Set to true to enable package
469
470
  # gpg signature checking. This will be default in the
@@ -18,7 +18,7 @@ class Chef
18
18
  config_data = read_config
19
19
  begin
20
20
  Chef::JSONCompat.from_json(config_data)
21
- rescue FFI_Yajl::ParseError => error
21
+ rescue Chef::Exceptions::JSON::ParseError => error
22
22
  Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2)
23
23
  end
24
24
  end
@@ -18,21 +18,29 @@ class Chef
18
18
 
19
19
  UPLOADED_COOKBOOK_VERSION_FILE = ".uploaded-cookbook-version.json".freeze
20
20
 
21
- attr_reader :cookbook_name
22
21
  attr_reader :cookbook_settings
23
22
  attr_reader :cookbook_paths
24
23
  attr_reader :metadata_filenames
25
24
  attr_reader :frozen
26
25
  attr_reader :uploaded_cookbook_version_file
27
26
 
27
+ attr_reader :cookbook_path
28
+
29
+ # The cookbook's name as inferred from its directory.
30
+ attr_reader :inferred_cookbook_name
31
+
32
+ attr_reader :metadata_error
33
+
28
34
  def initialize(path, chefignore=nil)
29
35
  @cookbook_path = File.expand_path( path ) # cookbook_path from which this was loaded
30
36
  # We keep a list of all cookbook paths that have been merged in
31
- @cookbook_paths = [ @cookbook_path ]
32
- @cookbook_name = File.basename( path )
37
+ @cookbook_paths = [ cookbook_path ]
38
+
39
+ @inferred_cookbook_name = File.basename( path )
33
40
  @chefignore = chefignore
34
- @metadata = Hash.new
41
+ @metadata = nil
35
42
  @relative_path = /#{Regexp.escape(@cookbook_path)}\/(.+)$/
43
+ @metadata_loaded = false
36
44
  @cookbook_settings = {
37
45
  :attribute_filenames => {},
38
46
  :definition_filenames => {},
@@ -46,9 +54,29 @@ class Chef
46
54
  }
47
55
 
48
56
  @metadata_filenames = []
57
+ @metadata_error = nil
58
+ end
59
+
60
+ # Load the cookbook. Raises an error if the cookbook_path given to the
61
+ # constructor doesn't point to a valid cookbook.
62
+ def load!
63
+ file_paths_map = load
64
+
65
+ if empty?
66
+ raise Exceptions::CookbookNotFoundInRepo, "The directory #{cookbook_path} does not contain a cookbook"
67
+ end
68
+ file_paths_map
49
69
  end
50
70
 
51
- def load_cookbooks
71
+ # Load the cookbook. Does not raise an error if given a non-cookbook
72
+ # directory as the cookbook_path. This behavior is provided for
73
+ # compatibility, it is recommended to use #load! instead.
74
+ def load
75
+ metadata # force lazy evaluation to occur
76
+
77
+ # re-raise any exception that occurred when reading the metadata
78
+ raise_metadata_error!
79
+
52
80
  load_as(:attribute_filenames, 'attributes', '*.rb')
53
81
  load_as(:definition_filenames, 'definitions', '*.rb')
54
82
  load_as(:recipe_filenames, 'recipes', '*.rb')
@@ -61,31 +89,37 @@ class Chef
61
89
 
62
90
  remove_ignored_files
63
91
 
64
- if File.exists?(File.join(@cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE))
65
- @uploaded_cookbook_version_file = File.join(@cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE)
92
+ if empty?
93
+ Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
94
+ end
95
+ @cookbook_settings
96
+ end
97
+
98
+ alias :load_cookbooks :load
99
+
100
+ def metadata_filenames
101
+ return @metadata_filenames unless @metadata_filenames.empty?
102
+ if File.exists?(File.join(cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE))
103
+ @uploaded_cookbook_version_file = File.join(cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE)
66
104
  end
67
105
 
68
- if File.exists?(File.join(@cookbook_path, "metadata.rb"))
69
- @metadata_filenames << File.join(@cookbook_path, "metadata.rb")
70
- elsif File.exists?(File.join(@cookbook_path, "metadata.json"))
71
- @metadata_filenames << File.join(@cookbook_path, "metadata.json")
106
+ if File.exists?(File.join(cookbook_path, "metadata.rb"))
107
+ @metadata_filenames << File.join(cookbook_path, "metadata.rb")
108
+ elsif File.exists?(File.join(cookbook_path, "metadata.json"))
109
+ @metadata_filenames << File.join(cookbook_path, "metadata.json")
72
110
  elsif @uploaded_cookbook_version_file
73
111
  @metadata_filenames << @uploaded_cookbook_version_file
74
112
  end
75
113
 
76
114
  # Set frozen based on .uploaded-cookbook-version.json
77
115
  set_frozen
78
-
79
- if empty?
80
- Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
81
- end
82
- @cookbook_settings
116
+ @metadata_filenames
83
117
  end
84
118
 
85
119
  def cookbook_version
86
120
  return nil if empty?
87
121
 
88
- Chef::CookbookVersion.new(@cookbook_name.to_sym, *@cookbook_paths).tap do |c|
122
+ Chef::CookbookVersion.new(cookbook_name, *cookbook_paths).tap do |c|
89
123
  c.attribute_filenames = cookbook_settings[:attribute_filenames].values
90
124
  c.definition_filenames = cookbook_settings[:definition_filenames].values
91
125
  c.recipe_filenames = cookbook_settings[:recipe_filenames].values
@@ -95,16 +129,32 @@ class Chef
95
129
  c.resource_filenames = cookbook_settings[:resource_filenames].values
96
130
  c.provider_filenames = cookbook_settings[:provider_filenames].values
97
131
  c.root_filenames = cookbook_settings[:root_filenames].values
98
- c.metadata_filenames = @metadata_filenames
99
- c.metadata = metadata(c)
132
+ c.metadata_filenames = metadata_filenames
133
+ c.metadata = metadata
134
+
100
135
  c.freeze_version if @frozen
101
136
  end
102
137
  end
103
138
 
139
+ def cookbook_name
140
+ # The `name` attribute is now required in metadata, so
141
+ # inferred_cookbook_name generally should not be used. Per CHEF-2923,
142
+ # we have to not raise errors in cookbook metadata immediately, so that
143
+ # users can still `knife cookbook upload some-cookbook` when an
144
+ # unrelated cookbook has an error in its metadata. This situation
145
+ # could prevent us from reading the `name` attribute from the metadata
146
+ # entirely, but the name is used as a hash key in CookbookLoader, so we
147
+ # fall back to the inferred name here.
148
+ (metadata.name || @inferred_cookbook_name).to_sym
149
+ end
150
+
104
151
  # Generates the Cookbook::Metadata object
105
- def metadata(cookbook_version)
106
- @metadata = Chef::Cookbook::Metadata.new(cookbook_version)
107
- @metadata_filenames.each do |metadata_file|
152
+ def metadata
153
+ return @metadata unless @metadata.nil?
154
+
155
+ @metadata = Chef::Cookbook::Metadata.new
156
+
157
+ metadata_filenames.each do |metadata_file|
108
158
  case metadata_file
109
159
  when /\.rb$/
110
160
  apply_ruby_metadata(metadata_file)
@@ -116,51 +166,75 @@ class Chef
116
166
  raise RuntimeError, "Invalid metadata file: #{metadata_file} for cookbook: #{cookbook_version}"
117
167
  end
118
168
  end
169
+
170
+ @metadata
171
+
172
+ # Rescue errors so that users can upload cookbooks via `knife cookbook
173
+ # upload` even if some cookbooks in their chef-repo have errors in
174
+ # their metadata. We only rescue StandardError because you have to be
175
+ # doing something *really* terrible to raise an exception that inherits
176
+ # directly from Exception in your metadata.rb file.
177
+ rescue StandardError => e
178
+ @metadata_error = e
119
179
  @metadata
120
180
  end
121
181
 
182
+ def raise_metadata_error!
183
+ raise @metadata_error unless @metadata_error.nil?
184
+ # Metadata won't be valid if the cookbook is empty. If the cookbook is
185
+ # actually empty, a metadata error here would be misleading, so don't
186
+ # raise it (if called by #load!, a different error is raised).
187
+ if !empty? && !metadata.valid?
188
+ message = "Cookbook loaded at path(s) [#{@cookbook_paths.join(', ')}] has invalid metadata: #{metadata.errors.join('; ')}"
189
+ raise Exceptions::MetadataNotValid, message
190
+ end
191
+ false
192
+ end
193
+
122
194
  def empty?
123
- @cookbook_settings.values.all? { |files_hash| files_hash.empty? } && @metadata_filenames.size == 0
195
+ cookbook_settings.values.all? { |files_hash| files_hash.empty? } && metadata_filenames.size == 0
124
196
  end
125
197
 
126
198
  def merge!(other_cookbook_loader)
127
199
  other_cookbook_settings = other_cookbook_loader.cookbook_settings
128
- @cookbook_settings.each do |file_type, file_list|
200
+ cookbook_settings.each do |file_type, file_list|
129
201
  file_list.merge!(other_cookbook_settings[file_type])
130
202
  end
131
- @metadata_filenames.concat(other_cookbook_loader.metadata_filenames)
203
+ metadata_filenames.concat(other_cookbook_loader.metadata_filenames)
132
204
  @cookbook_paths += other_cookbook_loader.cookbook_paths
133
205
  @frozen = true if other_cookbook_loader.frozen
206
+ @metadata = nil # reset metadata so it gets reloaded and all metadata files applied.
207
+ self
134
208
  end
135
209
 
136
210
  def chefignore
137
- @chefignore ||= Chefignore.new(File.basename(@cookbook_path))
211
+ @chefignore ||= Chefignore.new(File.basename(cookbook_path))
138
212
  end
139
213
 
140
214
  def load_root_files
141
- Dir.glob(File.join(@cookbook_path, '*'), File::FNM_DOTMATCH).each do |file|
215
+ Dir.glob(File.join(cookbook_path, '*'), File::FNM_DOTMATCH).each do |file|
142
216
  next if File.directory?(file)
143
217
  next if File.basename(file) == UPLOADED_COOKBOOK_VERSION_FILE
144
- @cookbook_settings[:root_filenames][file[@relative_path, 1]] = file
218
+ cookbook_settings[:root_filenames][file[@relative_path, 1]] = file
145
219
  end
146
220
  end
147
221
 
148
222
  def load_recursively_as(category, category_dir, glob)
149
- file_spec = File.join(@cookbook_path, category_dir, '**', glob)
223
+ file_spec = File.join(cookbook_path, category_dir, '**', glob)
150
224
  Dir.glob(file_spec, File::FNM_DOTMATCH).each do |file|
151
225
  next if File.directory?(file)
152
- @cookbook_settings[category][file[@relative_path, 1]] = file
226
+ cookbook_settings[category][file[@relative_path, 1]] = file
153
227
  end
154
228
  end
155
229
 
156
230
  def load_as(category, *path_glob)
157
- Dir[File.join(@cookbook_path, *path_glob)].each do |file|
158
- @cookbook_settings[category][file[@relative_path, 1]] = file
231
+ Dir[File.join(cookbook_path, *path_glob)].each do |file|
232
+ cookbook_settings[category][file[@relative_path, 1]] = file
159
233
  end
160
234
  end
161
235
 
162
236
  def remove_ignored_files
163
- @cookbook_settings.each_value do |file_list|
237
+ cookbook_settings.each_value do |file_list|
164
238
  file_list.reject! do |relative_path, full_path|
165
239
  chefignore.ignored?(relative_path)
166
240
  end
@@ -170,8 +244,8 @@ class Chef
170
244
  def apply_ruby_metadata(file)
171
245
  begin
172
246
  @metadata.from_file(file)
173
- rescue JSON::ParserError
174
- Chef::Log.error("Error evaluating metadata.rb for #@cookbook_name in " + file)
247
+ rescue Chef::Exceptions::JSON::ParseError
248
+ Chef::Log.error("Error evaluating metadata.rb for #@inferred_cookbook_name in " + file)
175
249
  raise
176
250
  end
177
251
  end
@@ -179,18 +253,27 @@ class Chef
179
253
  def apply_json_metadata(file)
180
254
  begin
181
255
  @metadata.from_json(IO.read(file))
182
- rescue JSON::ParserError
183
- Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
256
+ rescue Chef::Exceptions::JSON::ParseError
257
+ Chef::Log.error("Couldn't parse cookbook metadata JSON for #@inferred_cookbook_name in " + file)
184
258
  raise
185
259
  end
186
260
  end
187
261
 
188
262
  def apply_json_cookbook_version_metadata(file)
189
263
  begin
190
- data = Chef::JSONCompat.from_json(IO.read(file), :create_additions => false)
264
+ data = Chef::JSONCompat.parse(IO.read(file))
191
265
  @metadata.from_hash(data['metadata'])
192
- rescue JSON::ParserError
193
- Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
266
+ # the JSON cookbok metadata file is only used by chef-zero.
267
+ # The Chef Server API currently does not enforce that the metadata
268
+ # have a `name` field, but that will cause an error when attempting
269
+ # to load the cookbook. To keep compatibility, we fake it by setting
270
+ # the metadata name from the cookbook version object's name.
271
+ #
272
+ # This behavior can be removed if/when Chef Server enforces that the
273
+ # metadata contains a name key.
274
+ @metadata.name(data['cookbook_name']) unless data['metadata'].key?('name')
275
+ rescue Chef::Exceptions::JSON::ParseError
276
+ Chef::Log.error("Couldn't parse cookbook metadata JSON for #@inferred_cookbook_name in " + file)
194
277
  raise
195
278
  end
196
279
  end
@@ -198,10 +281,10 @@ class Chef
198
281
  def set_frozen
199
282
  if uploaded_cookbook_version_file
200
283
  begin
201
- data = Chef::JSONCompat.from_json(IO.read(uploaded_cookbook_version_file), :create_additions => false)
284
+ data = Chef::JSONCompat.parse(IO.read(uploaded_cookbook_version_file))
202
285
  @frozen = data['frozen?']
203
- rescue JSON::ParserError
204
- Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in #{uploaded_cookbook_version_file}")
286
+ rescue Chef::Exceptions::JSON::ParseError
287
+ Chef::Log.error("Couldn't parse cookbook metadata JSON for #@inferred_cookbook_name in #{uploaded_cookbook_version_file}")
205
288
  raise
206
289
  end
207
290
  end