chef 12.4.3-universal-mingw32 → 12.5.1-universal-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 (320) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +21 -25
  3. data/Gemfile +46 -0
  4. data/README.md +4 -4
  5. data/Rakefile +4 -110
  6. data/bin/chef-service-manager +3 -1
  7. data/distro/common/html/knife_cookbook_site.html +18 -18
  8. data/distro/common/man/man1/knife-cookbook-site.1 +11 -11
  9. data/lib/chef.rb +1 -1
  10. data/lib/chef/application.rb +1 -1
  11. data/lib/chef/application/apply.rb +19 -1
  12. data/lib/chef/application/client.rb +11 -5
  13. data/lib/chef/application/knife.rb +2 -2
  14. data/lib/chef/application/solo.rb +1 -1
  15. data/lib/chef/application/windows_service_manager.rb +19 -12
  16. data/lib/chef/chef_class.rb +46 -0
  17. data/lib/chef/chef_fs/config.rb +22 -24
  18. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +3 -1
  19. data/lib/chef/chef_fs/file_pattern.rb +4 -15
  20. data/lib/chef/chef_fs/file_system/acl_dir.rb +3 -4
  21. data/lib/chef/chef_fs/file_system/acls_dir.rb +5 -1
  22. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +0 -5
  23. data/lib/chef/chef_fs/file_system/base_fs_object.rb +5 -2
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +2 -9
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +2 -9
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +10 -17
  27. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -12
  28. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +15 -11
  29. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +8 -2
  30. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +4 -4
  31. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +1 -1
  32. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -11
  33. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +3 -5
  34. data/lib/chef/chef_fs/file_system/environments_dir.rb +1 -1
  35. data/lib/chef/chef_fs/file_system/file_system_entry.rb +7 -4
  36. data/lib/chef/chef_fs/file_system/memory_dir.rb +2 -3
  37. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +15 -0
  38. data/lib/chef/chef_fs/file_system/nodes_dir.rb +1 -1
  39. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +2 -2
  40. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +4 -9
  41. data/lib/chef/chef_fs/knife.rb +35 -7
  42. data/lib/chef/chef_fs/path_utils.rb +65 -34
  43. data/lib/chef/client.rb +2 -3
  44. data/lib/chef/config.rb +34 -2
  45. data/lib/chef/{mixin/wstring.rb → constants.rb} +9 -13
  46. data/lib/chef/cookbook/metadata.rb +25 -3
  47. data/lib/chef/cookbook/synchronizer.rb +1 -1
  48. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  49. data/lib/chef/cookbook_version.rb +3 -3
  50. data/lib/chef/delayed_evaluator.rb +21 -0
  51. data/lib/chef/deprecation/mixin/template.rb +1 -2
  52. data/lib/chef/deprecation/provider/cookbook_file.rb +1 -1
  53. data/lib/chef/deprecation/provider/file.rb +1 -1
  54. data/lib/chef/deprecation/provider/remote_directory.rb +52 -0
  55. data/lib/chef/deprecation/provider/remote_file.rb +1 -2
  56. data/lib/chef/deprecation/provider/template.rb +1 -1
  57. data/lib/chef/deprecation/warnings.rb +3 -4
  58. data/lib/chef/dsl/reboot_pending.rb +3 -2
  59. data/lib/chef/dsl/recipe.rb +26 -7
  60. data/lib/chef/dsl/resources.rb +2 -2
  61. data/lib/chef/event_dispatch/base.rb +51 -22
  62. data/lib/chef/event_dispatch/dispatcher.rb +21 -6
  63. data/lib/chef/event_dispatch/dsl.rb +64 -0
  64. data/lib/chef/exceptions.rb +28 -1
  65. data/lib/chef/file_content_management/tempfile.rb +1 -1
  66. data/lib/chef/formatters/base.rb +3 -0
  67. data/lib/chef/formatters/doc.rb +56 -6
  68. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +36 -0
  69. data/lib/chef/formatters/minimal.rb +2 -2
  70. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +3 -1
  71. data/lib/chef/http/http_request.rb +1 -1
  72. data/lib/chef/knife.rb +35 -55
  73. data/lib/chef/knife/bootstrap.rb +41 -0
  74. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +1 -0
  75. data/lib/chef/knife/bootstrap/client_builder.rb +16 -0
  76. data/lib/chef/knife/bootstrap/templates/README.md +3 -4
  77. data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
  78. data/lib/chef/knife/cookbook_create.rb +1 -1
  79. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  80. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  81. data/lib/chef/knife/cookbook_site_share.rb +6 -6
  82. data/lib/chef/knife/cookbook_site_unshare.rb +2 -2
  83. data/lib/chef/knife/core/bootstrap_context.rb +12 -4
  84. data/lib/chef/knife/core/custom_manifest_loader.rb +69 -0
  85. data/lib/chef/knife/core/gem_glob_loader.rb +138 -0
  86. data/lib/chef/knife/core/hashed_command_loader.rb +80 -0
  87. data/lib/chef/knife/core/node_presenter.rb +24 -1
  88. data/lib/chef/knife/core/object_loader.rb +1 -0
  89. data/lib/chef/knife/core/subcommand_loader.rb +131 -146
  90. data/lib/chef/knife/node_run_list_remove.rb +12 -1
  91. data/lib/chef/knife/null.rb +10 -0
  92. data/lib/chef/knife/rehash.rb +62 -0
  93. data/lib/chef/knife/search.rb +3 -3
  94. data/lib/chef/knife/ssh.rb +52 -30
  95. data/lib/chef/knife/ssl_check.rb +3 -2
  96. data/lib/chef/knife/user_edit.rb +1 -2
  97. data/lib/chef/local_mode.rb +5 -0
  98. data/lib/chef/log.rb +5 -1
  99. data/lib/chef/mixin/deprecation.rb +8 -8
  100. data/lib/chef/mixin/params_validate.rb +362 -135
  101. data/lib/chef/mixin/template.rb +48 -0
  102. data/lib/chef/mixin/which.rb +1 -1
  103. data/lib/chef/mixin/wide_string.rb +72 -0
  104. data/lib/chef/mixin/windows_architecture_helper.rb +15 -39
  105. data/lib/chef/mixin/windows_env_helper.rb +4 -1
  106. data/lib/chef/monkey_patches/webrick-utils.rb +51 -0
  107. data/lib/chef/monkey_patches/win32/registry.rb +72 -0
  108. data/lib/chef/node.rb +116 -3
  109. data/lib/chef/node_map.rb +2 -2
  110. data/lib/chef/platform/handler_map.rb +0 -5
  111. data/lib/chef/platform/provider_mapping.rb +5 -6
  112. data/lib/chef/platform/query_helpers.rb +46 -4
  113. data/lib/chef/platform/rebooter.rb +1 -1
  114. data/lib/chef/platform/service_helpers.rb +30 -32
  115. data/lib/chef/policy_builder.rb +1 -8
  116. data/lib/chef/policy_builder/dynamic.rb +186 -0
  117. data/lib/chef/policy_builder/expand_node_object.rb +30 -15
  118. data/lib/chef/policy_builder/policyfile.rb +155 -18
  119. data/lib/chef/property.rb +568 -0
  120. data/lib/chef/provider.rb +222 -13
  121. data/lib/chef/provider/batch.rb +8 -0
  122. data/lib/chef/provider/deploy.rb +5 -7
  123. data/lib/chef/provider/directory.rb +14 -2
  124. data/lib/chef/provider/dsc_resource.rb +5 -9
  125. data/lib/chef/provider/group/pw.rb +1 -1
  126. data/lib/chef/provider/ifconfig.rb +2 -2
  127. data/lib/chef/provider/lwrp_base.rb +1 -75
  128. data/lib/chef/provider/mount.rb +7 -3
  129. data/lib/chef/provider/package.rb +1 -1
  130. data/lib/chef/provider/package/dpkg.rb +5 -11
  131. data/lib/chef/provider/package/rpm.rb +2 -2
  132. data/lib/chef/provider/package/rubygems.rb +1 -1
  133. data/lib/chef/provider/package/windows/msi.rb +2 -2
  134. data/lib/chef/provider/package/yum.rb +17 -5
  135. data/lib/chef/provider/powershell_script.rb +59 -23
  136. data/lib/chef/provider/registry_key.rb +5 -5
  137. data/lib/chef/provider/remote_directory.rb +190 -102
  138. data/lib/chef/provider/service.rb +12 -2
  139. data/lib/chef/provider/service/aix.rb +1 -1
  140. data/lib/chef/provider/service/debian.rb +3 -5
  141. data/lib/chef/provider/service/freebsd.rb +1 -1
  142. data/lib/chef/provider/service/gentoo.rb +3 -3
  143. data/lib/chef/provider/service/init.rb +3 -3
  144. data/lib/chef/provider/service/insserv.rb +2 -4
  145. data/lib/chef/provider/service/invokercd.rb +2 -4
  146. data/lib/chef/provider/service/macosx.rb +5 -1
  147. data/lib/chef/provider/service/openbsd.rb +2 -1
  148. data/lib/chef/provider/service/redhat.rb +52 -16
  149. data/lib/chef/provider/service/simple.rb +2 -2
  150. data/lib/chef/provider/service/systemd.rb +3 -5
  151. data/lib/chef/provider/service/upstart.rb +4 -6
  152. data/lib/chef/provider/subversion.rb +13 -7
  153. data/lib/chef/provider/template/content.rb +16 -6
  154. data/lib/chef/provider/user/solaris.rb +32 -4
  155. data/lib/chef/provider/windows_script.rb +3 -5
  156. data/lib/chef/provider_resolver.rb +2 -2
  157. data/lib/chef/recipe.rb +1 -8
  158. data/lib/chef/resource.rb +563 -90
  159. data/lib/chef/resource/action_class.rb +83 -0
  160. data/lib/chef/resource/chef_gem.rb +3 -3
  161. data/lib/chef/resource/deploy.rb +8 -2
  162. data/lib/chef/resource/dsc_script.rb +2 -0
  163. data/lib/chef/resource/file/verification.rb +7 -1
  164. data/lib/chef/resource/lwrp_base.rb +1 -7
  165. data/lib/chef/resource/registry_key.rb +1 -1
  166. data/lib/chef/resource/service.rb +10 -2
  167. data/lib/chef/resource/subversion.rb +5 -0
  168. data/lib/chef/resource/windows_script.rb +6 -2
  169. data/lib/chef/resource/yum_package.rb +10 -1
  170. data/lib/chef/resource_resolver.rb +3 -3
  171. data/lib/chef/run_context.rb +402 -83
  172. data/lib/chef/run_list/versioned_recipe_list.rb +15 -0
  173. data/lib/chef/run_lock.rb +30 -21
  174. data/lib/chef/util/powershell/ps_credential.rb +4 -0
  175. data/lib/chef/util/windows.rb +0 -32
  176. data/lib/chef/util/windows/net_group.rb +85 -106
  177. data/lib/chef/util/windows/net_use.rb +35 -71
  178. data/lib/chef/util/windows/net_user.rb +0 -1
  179. data/lib/chef/util/windows/volume.rb +19 -19
  180. data/lib/chef/version.rb +3 -3
  181. data/lib/chef/win32/api.rb +1 -0
  182. data/lib/chef/win32/api/file.rb +20 -0
  183. data/lib/chef/win32/api/net.rb +163 -43
  184. data/lib/chef/win32/api/registry.rb +51 -0
  185. data/lib/chef/win32/api/system.rb +23 -0
  186. data/lib/chef/win32/api/unicode.rb +0 -43
  187. data/lib/chef/win32/crypto.rb +2 -1
  188. data/lib/chef/win32/file.rb +28 -3
  189. data/lib/chef/win32/mutex.rb +1 -2
  190. data/lib/chef/win32/net.rb +162 -8
  191. data/lib/chef/win32/process.rb +13 -0
  192. data/lib/chef/win32/registry.rb +35 -30
  193. data/lib/chef/win32/security.rb +1 -1
  194. data/lib/chef/win32/security/token.rb +1 -1
  195. data/lib/chef/win32/system.rb +62 -0
  196. data/lib/chef/win32/unicode.rb +7 -2
  197. data/lib/chef/win32/version.rb +0 -4
  198. data/lib/chef/workstation_config_loader.rb +3 -158
  199. data/spec/data/cookbooks/openldap/templates/default/helpers.erb +14 -0
  200. data/spec/data/cookbooks/openldap/templates/default/nested_openldap_partials.erb +1 -0
  201. data/spec/data/cookbooks/openldap/templates/default/nested_partial.erb +1 -0
  202. data/spec/data/dsc_lcm.pfx +0 -0
  203. data/spec/data/run_context/cookbooks/include/recipes/default.rb +24 -0
  204. data/spec/data/run_context/cookbooks/include/recipes/includee.rb +3 -0
  205. data/spec/functional/dsl/reboot_pending_spec.rb +33 -43
  206. data/spec/functional/knife/cookbook_delete_spec.rb +17 -7
  207. data/spec/functional/knife/ssh_spec.rb +16 -0
  208. data/spec/functional/rebooter_spec.rb +1 -1
  209. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  210. data/spec/functional/resource/dsc_resource_spec.rb +2 -0
  211. data/spec/functional/resource/dsc_script_spec.rb +91 -2
  212. data/spec/functional/resource/group_spec.rb +67 -44
  213. data/spec/functional/resource/{powershell_spec.rb → powershell_script_spec.rb} +107 -18
  214. data/spec/functional/resource/windows_service_spec.rb +1 -1
  215. data/spec/functional/run_lock_spec.rb +368 -189
  216. data/spec/functional/win32/{registry_helper_spec.rb → registry_spec.rb} +16 -23
  217. data/spec/functional/win32/service_manager_spec.rb +2 -2
  218. data/spec/integration/client/client_spec.rb +51 -0
  219. data/spec/integration/knife/chef_repo_path_spec.rb +13 -11
  220. data/spec/integration/knife/download_spec.rb +4 -0
  221. data/spec/integration/knife/list_spec.rb +8 -0
  222. data/spec/integration/knife/upload_spec.rb +1 -1
  223. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -16
  224. data/spec/integration/recipes/remote_directory.rb +74 -0
  225. data/spec/integration/recipes/resource_action_spec.rb +363 -0
  226. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +423 -0
  227. data/spec/integration/recipes/resource_load_spec.rb +206 -0
  228. data/spec/spec_helper.rb +9 -0
  229. data/spec/support/platform_helpers.rb +13 -0
  230. data/spec/support/shared/context/win32.rb +34 -0
  231. data/spec/support/shared/functional/win32_service.rb +2 -1
  232. data/spec/support/shared/functional/windows_script.rb +63 -26
  233. data/spec/support/shared/unit/mock_shellout.rb +46 -0
  234. data/spec/support/shared/unit/provider/file.rb +10 -4
  235. data/spec/unit/application/client_spec.rb +16 -3
  236. data/spec/unit/application/knife_spec.rb +2 -2
  237. data/spec/unit/application/solo_spec.rb +4 -3
  238. data/spec/unit/chef_class_spec.rb +23 -4
  239. data/spec/unit/chef_fs/path_util_spec.rb +108 -0
  240. data/spec/unit/client_spec.rb +6 -1
  241. data/spec/unit/config_spec.rb +31 -0
  242. data/spec/unit/cookbook/metadata_spec.rb +23 -3
  243. data/spec/unit/cookbook/syntax_check_spec.rb +3 -0
  244. data/spec/unit/deprecation_spec.rb +3 -6
  245. data/spec/unit/dsl/reboot_pending_spec.rb +12 -6
  246. data/spec/unit/event_dispatch/dispatcher_spec.rb +65 -3
  247. data/spec/unit/event_dispatch/dsl_spec.rb +83 -0
  248. data/spec/unit/formatters/doc_spec.rb +32 -0
  249. data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +26 -0
  250. data/spec/unit/json_compat_spec.rb +4 -3
  251. data/spec/unit/knife/bootstrap/client_builder_spec.rb +27 -0
  252. data/spec/unit/knife/bootstrap_spec.rb +55 -3
  253. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  254. data/spec/unit/knife/core/bootstrap_context_spec.rb +21 -4
  255. data/spec/unit/knife/core/custom_manifest_loader_spec.rb +41 -0
  256. data/spec/unit/knife/core/gem_glob_loader_spec.rb +210 -0
  257. data/spec/unit/knife/core/hashed_command_loader_spec.rb +93 -0
  258. data/spec/unit/knife/core/subcommand_loader_spec.rb +16 -192
  259. data/spec/unit/knife/node_run_list_remove_spec.rb +17 -0
  260. data/spec/unit/knife/ssl_check_spec.rb +4 -0
  261. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +10 -10
  262. data/spec/unit/mixin/params_validate_spec.rb +4 -2
  263. data/spec/unit/mixin/template_spec.rb +5 -1
  264. data/spec/unit/mixin/windows_architecture_helper_spec.rb +13 -8
  265. data/spec/unit/node_spec.rb +220 -0
  266. data/spec/unit/platform/query_helpers_spec.rb +146 -3
  267. data/spec/unit/policy_builder/dynamic_spec.rb +275 -0
  268. data/spec/unit/policy_builder/expand_node_object_spec.rb +37 -38
  269. data/spec/unit/policy_builder/policyfile_spec.rb +260 -46
  270. data/spec/unit/property/state_spec.rb +506 -0
  271. data/spec/unit/property/validation_spec.rb +663 -0
  272. data/spec/unit/property_spec.rb +1094 -0
  273. data/spec/unit/provider/deploy_spec.rb +5 -5
  274. data/spec/unit/provider/directory_spec.rb +35 -0
  275. data/spec/unit/provider/dsc_resource_spec.rb +3 -10
  276. data/spec/unit/provider/ifconfig_spec.rb +22 -2
  277. data/spec/unit/provider/mount/aix_spec.rb +2 -1
  278. data/spec/unit/provider/mount/mount_spec.rb +6 -0
  279. data/spec/unit/provider/mount/windows_spec.rb +14 -0
  280. data/spec/unit/provider/mount_spec.rb +12 -1
  281. data/spec/unit/provider/package/dpkg_spec.rb +8 -1
  282. data/spec/unit/provider/package/rpm_spec.rb +18 -1
  283. data/spec/unit/provider/package/rubygems_spec.rb +18 -0
  284. data/spec/unit/provider/package/yum_spec.rb +97 -24
  285. data/spec/unit/provider/powershell_script_spec.rb +106 -0
  286. data/spec/unit/provider/registry_key_spec.rb +12 -0
  287. data/spec/unit/provider/remote_directory_spec.rb +1 -2
  288. data/spec/unit/provider/service/aix_service_spec.rb +3 -3
  289. data/spec/unit/provider/service/gentoo_service_spec.rb +4 -4
  290. data/spec/unit/provider/service/macosx_spec.rb +4 -4
  291. data/spec/unit/provider/service/openbsd_service_spec.rb +10 -8
  292. data/spec/unit/provider/service/redhat_spec.rb +88 -8
  293. data/spec/unit/provider/service/upstart_service_spec.rb +11 -7
  294. data/spec/unit/provider/service/windows_spec.rb +211 -200
  295. data/spec/unit/provider/subversion_spec.rb +50 -31
  296. data/spec/unit/provider/template/content_spec.rb +93 -2
  297. data/spec/unit/provider/user/solaris_spec.rb +66 -9
  298. data/spec/unit/provider_resolver_spec.rb +707 -650
  299. data/spec/unit/provider_spec.rb +1 -3
  300. data/spec/unit/recipe_spec.rb +0 -4
  301. data/spec/unit/resource/deploy_spec.rb +7 -1
  302. data/spec/unit/resource/dsc_script_spec.rb +4 -0
  303. data/spec/unit/resource/file/verification_spec.rb +33 -5
  304. data/spec/unit/resource/{powershell_spec.rb → powershell_script_spec.rb} +17 -13
  305. data/spec/unit/resource/service_spec.rb +4 -4
  306. data/spec/unit/resource/subversion_spec.rb +4 -0
  307. data/spec/unit/resource/yum_package_spec.rb +10 -1
  308. data/spec/unit/resource_spec.rb +2 -2
  309. data/spec/unit/run_context/child_run_context_spec.rb +133 -0
  310. data/spec/unit/run_context_spec.rb +7 -0
  311. data/spec/unit/run_list/versioned_recipe_list_spec.rb +5 -0
  312. data/spec/unit/win32/registry_spec.rb +394 -0
  313. data/tasks/external_tests.rb +47 -23
  314. data/tasks/maintainers.rb +155 -14
  315. metadata +64 -53
  316. data/lib/chef/knife/bootstrap/templates/archlinux-gems.erb +0 -76
  317. data/lib/chef/knife/bootstrap/templates/chef-aix.erb +0 -72
  318. data/spec/unit/provider/powershell_spec.rb +0 -80
  319. data/spec/unit/registry_helper_spec.rb +0 -376
  320. data/spec/unit/workstation_config_loader_spec.rb +0 -283
@@ -1,7 +1,9 @@
1
1
  #
2
2
  # Author:: Stephen Nelson-Smith (<sns@opscode.com>)
3
3
  # Author:: Jon Ramsey (<jonathon.ramsey@gmail.com>)
4
+ # Author:: Dave Eddy (<dave@daveeddy.com>)
4
5
  # Copyright:: Copyright (c) 2012 Opscode, Inc.
6
+ # Copyright:: Copyright 2015, Dave Eddy
5
7
  # License:: Apache License, Version 2.0
6
8
  #
7
9
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +25,6 @@ class Chef
23
25
  class User
24
26
  class Solaris < Chef::Provider::User::Useradd
25
27
  provides :user, platform: %w(omnios solaris2)
26
-
27
28
  UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]]
28
29
 
29
30
  attr_writer :password_file
@@ -43,6 +44,32 @@ class Chef
43
44
  super
44
45
  end
45
46
 
47
+ def check_lock
48
+ shadow_line = shell_out!('getent', 'shadow', new_resource.username).stdout.strip rescue nil
49
+
50
+ # if the command fails we return nil, this can happen if the user
51
+ # in question doesn't exist
52
+ return nil if shadow_line.nil?
53
+
54
+ # convert "dave:NP:16507::::::\n" to "NP"
55
+ fields = shadow_line.split(':')
56
+
57
+ # '*LK*...' and 'LK' are both considered locked,
58
+ # so look for LK at the beginning of the shadow entry
59
+ # optionally surrounded by '*'
60
+ @locked = !!fields[1].match(/^\*?LK\*?/)
61
+
62
+ @locked
63
+ end
64
+
65
+ def lock_user
66
+ shell_out!('passwd', '-l', new_resource.username)
67
+ end
68
+
69
+ def unlock_user
70
+ shell_out!('passwd', '-u', new_resource.username)
71
+ end
72
+
46
73
  private
47
74
 
48
75
  def manage_password
@@ -67,9 +94,10 @@ class Chef
67
94
  buffer.close
68
95
 
69
96
  # FIXME: mostly duplicates code with file provider deploying a file
70
- mode = ::File.stat(@password_file).mode & 07777
71
- uid = ::File.stat(@password_file).uid
72
- gid = ::File.stat(@password_file).gid
97
+ s = ::File.stat(@password_file)
98
+ mode = s.mode & 07777
99
+ uid = s.uid
100
+ gid = s.gid
73
101
 
74
102
  FileUtils.chown uid, gid, buffer.path
75
103
  FileUtils.chmod mode, buffer.path
@@ -23,6 +23,8 @@ class Chef
23
23
  class Provider
24
24
  class WindowsScript < Chef::Provider::Script
25
25
 
26
+ attr_reader :is_forced_32bit
27
+
26
28
  protected
27
29
 
28
30
  include Chef::Mixin::WindowsArchitectureHelper
@@ -36,11 +38,7 @@ class Chef
36
38
 
37
39
  @is_wow64 = wow64_architecture_override_required?(run_context.node, target_architecture)
38
40
 
39
- # if the user wants to run the script 32 bit && we are on a 64bit windows system && we are running a 64bit ruby ==> fail
40
- if ( target_architecture == :i386 ) && node_windows_architecture(run_context.node) == :x86_64 && !is_i386_process_on_x86_64_windows?
41
- raise Chef::Exceptions::Win32ArchitectureIncorrect,
42
- "Support for the i386 architecture from a 64-bit Ruby runtime is not yet implemented"
43
- end
41
+ @is_forced_32bit = forced_32bit_override_required?(run_context.node, target_architecture)
44
42
  end
45
43
 
46
44
  public
@@ -157,8 +157,8 @@ class Chef
157
157
  # perf concern otherwise.)
158
158
  handlers = providers.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource) }
159
159
  handlers.each do |handler|
160
- Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!")
161
- Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.")
160
+ Chef.log_deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!")
161
+ Chef.log_deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.")
162
162
  end
163
163
  end
164
164
  handlers
@@ -36,14 +36,7 @@ class Chef
36
36
  # A Recipe object is the context in which Chef recipes are evaluated.
37
37
  class Recipe
38
38
 
39
- include Chef::DSL::DataQuery
40
- include Chef::DSL::PlatformIntrospection
41
- include Chef::DSL::IncludeRecipe
42
- include Chef::DSL::Recipe
43
- include Chef::DSL::RegistryHelper
44
- include Chef::DSL::RebootPending
45
- include Chef::DSL::Audit
46
- include Chef::DSL::Powershell
39
+ include Chef::DSL::Recipe::FullDSL
47
40
 
48
41
  include Chef::Mixin::FromFile
49
42
  include Chef::Mixin::Deprecation
@@ -1,7 +1,8 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Christopher Walters (<cw@opscode.com>)
4
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # Author:: John Keiser (<jkeiser@chef.io)
5
+ # Copyright:: Copyright (c) 2008-2015 Chef, Inc.
5
6
  # License:: Apache License, Version 2.0
6
7
  #
7
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +18,7 @@
17
18
  # limitations under the License.
18
19
  #
19
20
 
21
+ require 'chef/exceptions'
20
22
  require 'chef/mixin/params_validate'
21
23
  require 'chef/dsl/platform_introspection'
22
24
  require 'chef/dsl/data_query'
@@ -27,6 +29,7 @@ require 'chef/mixin/convert_to_class_name'
27
29
  require 'chef/guard_interpreter/resource_guard_interpreter'
28
30
  require 'chef/resource/conditional'
29
31
  require 'chef/resource/conditional_action_not_nothing'
32
+ require 'chef/resource/action_class'
30
33
  require 'chef/resource_collection'
31
34
  require 'chef/node_map'
32
35
  require 'chef/node'
@@ -58,8 +61,6 @@ class Chef
58
61
  include Chef::Mixin::ShellOut
59
62
  include Chef::Mixin::PowershellOut
60
63
 
61
- NULL_ARG = Object.new
62
-
63
64
  #
64
65
  # The node the current Chef run is using.
65
66
  #
@@ -103,7 +104,7 @@ class Chef
103
104
  # @param run_context The context of the Chef run. Corresponds to #run_context.
104
105
  #
105
106
  def initialize(name, run_context=nil)
106
- name(name)
107
+ name(name) unless name.nil?
107
108
  @run_context = run_context
108
109
  @noop = nil
109
110
  @before = nil
@@ -132,37 +133,27 @@ class Chef
132
133
  end
133
134
 
134
135
  #
135
- # The name of this particular resource.
136
- #
137
- # This special resource attribute is set automatically from the declaration
138
- # of the resource, e.g.
139
- #
140
- # execute 'Vitruvius' do
141
- # command 'ls'
142
- # end
136
+ # The list of properties defined on this resource.
143
137
  #
144
- # Will set the name to "Vitruvius".
138
+ # Everything defined with `property` is in this list.
145
139
  #
146
- # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`.
140
+ # @param include_superclass [Boolean] `true` to include properties defined
141
+ # on superclasses; `false` or `nil` to return the list of properties
142
+ # directly on this class.
147
143
  #
148
- # This is also used for resource notifications and subscribes in the same manner.
144
+ # @return [Hash<Symbol,Property>] The list of property names and types.
149
145
  #
150
- # This will coerce any object into a string via #to_s. Arrays are a special case
151
- # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more
152
- # awkward `package[["foo", "bar"]]` that #to_s would produce.
153
- #
154
- # @param name [Object] The name to set, typically a String or Array
155
- # @return [String] The name of this Resource.
156
- #
157
- def name(name=nil)
158
- if !name.nil?
159
- if name.is_a?(Array)
160
- @name = name.join(', ')
146
+ def self.properties(include_superclass=true)
147
+ @properties ||= {}
148
+ if include_superclass
149
+ if superclass.respond_to?(:properties)
150
+ superclass.properties.merge(@properties)
161
151
  else
162
- @name = name.to_s
152
+ @properties.dup
163
153
  end
154
+ else
155
+ @properties
164
156
  end
165
- @name
166
157
  end
167
158
 
168
159
  #
@@ -182,8 +173,7 @@ class Chef
182
173
  end
183
174
  @action = arg
184
175
  else
185
- # Pull the action from the class if it's not set
186
- @action || self.class.default_action
176
+ @action
187
177
  end
188
178
  end
189
179
 
@@ -478,13 +468,21 @@ class Chef
478
468
  #
479
469
  # Get the value of the state attributes in this resource as a hash.
480
470
  #
471
+ # Does not include properties that are not set (unless they are identity
472
+ # properties).
473
+ #
481
474
  # @return [Hash{Symbol => Object}] A Hash of attribute => value for the
482
475
  # Resource class's `state_attrs`.
476
+ #
483
477
  def state_for_resource_reporter
484
- self.class.state_attrs.inject({}) do |state_attrs, attr_name|
485
- state_attrs[attr_name] = send(attr_name)
486
- state_attrs
478
+ state = {}
479
+ state_properties = self.class.state_properties
480
+ state_properties.each do |property|
481
+ if property.identity? || property.is_set?(self)
482
+ state[property.name] = send(property.name)
483
+ end
487
484
  end
485
+ state
488
486
  end
489
487
 
490
488
  #
@@ -497,17 +495,22 @@ class Chef
497
495
  alias_method :state, :state_for_resource_reporter
498
496
 
499
497
  #
500
- # The value of the identity attribute, if declared. Falls back to #name if
501
- # no identity attribute is declared.
498
+ # The value of the identity of this resource.
499
+ #
500
+ # - If there are no identity properties on the resource, `name` is returned.
501
+ # - If there is exactly one identity property on the resource, it is returned.
502
+ # - If there are more than one, they are returned in a hash.
502
503
  #
503
- # @return The value of the identity attribute.
504
+ # @return [Object,Hash<Symbol,Object>] The identity of this resource.
504
505
  #
505
506
  def identity
506
- if identity_attr = self.class.identity_attr
507
- send(identity_attr)
508
- else
509
- name
507
+ result = {}
508
+ identity_properties = self.class.identity_properties
509
+ identity_properties.each do |property|
510
+ result[property.name] = send(property.name)
510
511
  end
512
+ return result.values.first if identity_properties.size == 1
513
+ result
511
514
  end
512
515
 
513
516
  #
@@ -529,9 +532,7 @@ class Chef
529
532
  #
530
533
  # Equivalent to #ignore_failure.
531
534
  #
532
- def epic_fail(arg=nil)
533
- ignore_failure(arg)
534
- end
535
+ alias :epic_fail :ignore_failure
535
536
 
536
537
  #
537
538
  # Make this resource into an exact (shallow) copy of the other resource.
@@ -686,66 +687,391 @@ class Chef
686
687
  #
687
688
  # The provider class for this resource.
688
689
  #
690
+ # If `action :x do ... end` has been declared on this resource or its
691
+ # superclasses, this will return the `action_class`.
692
+ #
689
693
  # If this is not set, `provider_for_action` will dynamically determine the
690
694
  # provider.
691
695
  #
692
696
  # @param arg [String, Symbol, Class] Sets the provider class for this resource.
693
697
  # If passed a String or Symbol, e.g. `:file` or `"file"`, looks up the
694
698
  # provider based on the name.
699
+ #
695
700
  # @return The provider class for this resource.
696
701
  #
702
+ # @see Chef::Resource.action_class
703
+ #
697
704
  def provider(arg=nil)
698
705
  klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
699
706
  lookup_provider_constant(arg)
700
707
  else
701
708
  arg
702
709
  end
703
- set_or_return(:provider, klass, kind_of: [ Class ])
710
+ set_or_return(:provider, klass, kind_of: [ Class ]) ||
711
+ self.class.action_class
704
712
  end
705
713
  def provider=(arg)
706
714
  provider(arg)
707
715
  end
708
716
 
709
- # Set or return the list of "state attributes" implemented by the Resource
710
- # subclass. State attributes are attributes that describe the desired state
711
- # of the system, such as file permissions or ownership. In general, state
712
- # attributes are attributes that could be populated by examining the state
713
- # of the system (e.g., File.stat can tell you the permissions on an
714
- # existing file). Contrarily, attributes that are not "state attributes"
715
- # usually modify the way Chef itself behaves, for example by providing
716
- # additional options for a package manager to use when installing a
717
- # package.
717
+ #
718
+ # Create a property on this resource class.
719
+ #
720
+ # If a superclass has this property, or if this property has already been
721
+ # defined by this resource, this will *override* the previous value.
722
+ #
723
+ # @param name [Symbol] The name of the property.
724
+ # @param type [Object,Array<Object>] The type(s) of this property.
725
+ # If present, this is prepended to the `is` validation option.
726
+ # @param options [Hash<Symbol,Object>] Validation options.
727
+ # @option options [Object,Array] :is An object, or list of
728
+ # objects, that must match the value using Ruby's `===` operator
729
+ # (`options[:is].any? { |v| v === value }`).
730
+ # @option options [Object,Array] :equal_to An object, or list
731
+ # of objects, that must be equal to the value using Ruby's `==`
732
+ # operator (`options[:is].any? { |v| v == value }`)
733
+ # @option options [Regexp,Array<Regexp>] :regex An object, or
734
+ # list of objects, that must match the value with `regex.match(value)`.
735
+ # @option options [Class,Array<Class>] :kind_of A class, or
736
+ # list of classes, that the value must be an instance of.
737
+ # @option options [Hash<String,Proc>] :callbacks A hash of
738
+ # messages -> procs, all of which match the value. The proc must
739
+ # return a truthy or falsey value (true means it matches).
740
+ # @option options [Symbol,Array<Symbol>] :respond_to A method
741
+ # name, or list of method names, the value must respond to.
742
+ # @option options [Symbol,Array<Symbol>] :cannot_be A property,
743
+ # or a list of properties, that the value cannot have (such as `:nil` or
744
+ # `:empty`). The method with a questionmark at the end is called on the
745
+ # value (e.g. `value.empty?`). If the value does not have this method,
746
+ # it is considered valid (i.e. if you don't respond to `empty?` we
747
+ # assume you are not empty).
748
+ # @option options [Proc] :coerce A proc which will be called to
749
+ # transform the user input to canonical form. The value is passed in,
750
+ # and the transformed value returned as output. Lazy values will *not*
751
+ # be passed to this method until after they are evaluated. Called in the
752
+ # context of the resource (meaning you can access other properties).
753
+ # @option options [Boolean] :required `true` if this property
754
+ # must be present; `false` otherwise. This is checked after the resource
755
+ # is fully initialized.
756
+ # @option options [Boolean] :name_property `true` if this
757
+ # property defaults to the same value as `name`. Equivalent to
758
+ # `default: lazy { name }`, except that #property_is_set? will
759
+ # return `true` if the property is set *or* if `name` is set.
760
+ # @option options [Boolean] :name_attribute Same as `name_property`.
761
+ # @option options [Object] :default The value this property
762
+ # will return if the user does not set one. If this is `lazy`, it will
763
+ # be run in the context of the instance (and able to access other
764
+ # properties).
765
+ # @option options [Boolean] :desired_state `true` if this property is
766
+ # part of desired state. Defaults to `true`.
767
+ # @option options [Boolean] :identity `true` if this property
768
+ # is part of object identity. Defaults to `false`.
769
+ #
770
+ # @example Bare property
771
+ # property :x
772
+ #
773
+ # @example With just a type
774
+ # property :x, String
775
+ #
776
+ # @example With just options
777
+ # property :x, default: 'hi'
778
+ #
779
+ # @example With type and options
780
+ # property :x, String, default: 'hi'
781
+ #
782
+ def self.property(name, type=NOT_PASSED, **options)
783
+ name = name.to_sym
784
+
785
+ options.each { |k,v| options[k.to_sym] = v if k.is_a?(String) }
786
+
787
+ options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name)
788
+ options.merge!(name: name, declared_in: self)
789
+
790
+ if type == NOT_PASSED
791
+ # If a type is not passed, the property derives from the
792
+ # superclass property (if any)
793
+ if properties.has_key?(name)
794
+ property = properties[name].derive(**options)
795
+ else
796
+ property = property_type(**options)
797
+ end
798
+
799
+ # If a Property is specified, derive a new one from that.
800
+ elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property)
801
+ property = type.derive(**options)
802
+
803
+ # If a primitive type was passed, combine it with "is"
804
+ else
805
+ if options[:is]
806
+ options[:is] = ([ type ] + [ options[:is] ]).flatten(1)
807
+ else
808
+ options[:is] = type
809
+ end
810
+ property = property_type(**options)
811
+ end
812
+
813
+ local_properties = properties(false)
814
+ local_properties[name] = property
815
+
816
+ property.emit_dsl
817
+ end
818
+
819
+ #
820
+ # Create a reusable property type that can be used in multiple properties
821
+ # in different resources.
822
+ #
823
+ # @param options [Hash<Symbol,Object>] Validation options. see #property for
824
+ # the list of options.
825
+ #
826
+ # @example
827
+ # property_type(default: 'hi')
828
+ #
829
+ def self.property_type(**options)
830
+ Property.derive(**options)
831
+ end
832
+
833
+ #
834
+ # The name of this particular resource.
835
+ #
836
+ # This special resource attribute is set automatically from the declaration
837
+ # of the resource, e.g.
838
+ #
839
+ # execute 'Vitruvius' do
840
+ # command 'ls'
841
+ # end
842
+ #
843
+ # Will set the name to "Vitruvius".
844
+ #
845
+ # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`.
846
+ #
847
+ # This is also used for resource notifications and subscribes in the same manner.
848
+ #
849
+ # This will coerce any object into a string via #to_s. Arrays are a special case
850
+ # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more
851
+ # awkward `package[["foo", "bar"]]` that #to_s would produce.
852
+ #
853
+ # @param name [Object] The name to set, typically a String or Array
854
+ # @return [String] The name of this Resource.
855
+ #
856
+ property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(', ') : v.to_s }, desired_state: false
857
+
858
+ #
859
+ # Whether this property has been set (or whether it has a default that has
860
+ # been retrieved).
861
+ #
862
+ # @param name [Symbol] The name of the property.
863
+ # @return [Boolean] `true` if the property has been set.
864
+ #
865
+ def property_is_set?(name)
866
+ property = self.class.properties[name.to_sym]
867
+ raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
868
+ property.is_set?(self)
869
+ end
870
+
871
+ #
872
+ # Clear this property as if it had never been set. It will thereafter return
873
+ # the default.
874
+ # been retrieved).
875
+ #
876
+ # @param name [Symbol] The name of the property.
877
+ #
878
+ def reset_property(name)
879
+ property = self.class.properties[name.to_sym]
880
+ raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
881
+ property.reset(self)
882
+ end
883
+
884
+ #
885
+ # Create a lazy value for assignment to a default value.
886
+ #
887
+ # @param block The block to run when the value is retrieved.
888
+ #
889
+ # @return [Chef::DelayedEvaluator] The lazy value
890
+ #
891
+ def self.lazy(&block)
892
+ DelayedEvaluator.new(&block)
893
+ end
894
+
895
+ #
896
+ # Get or set the list of desired state properties for this resource.
897
+ #
898
+ # State properties are properties that describe the desired state
899
+ # of the system, such as file permissions or ownership.
900
+ # In general, state properties are properties that could be populated by
901
+ # examining the state of the system (e.g., File.stat can tell you the
902
+ # permissions on an existing file). Contrarily, properties that are not
903
+ # "state properties" usually modify the way Chef itself behaves, for example
904
+ # by providing additional options for a package manager to use when
905
+ # installing a package.
718
906
  #
719
907
  # This list is used by the Chef client auditing system to extract
720
908
  # information from resources to describe changes made to the system.
721
- def self.state_attrs(*attr_names)
722
- @state_attrs ||= []
723
- @state_attrs = attr_names unless attr_names.empty?
909
+ #
910
+ # This method is unnecessary when declaring properties with `property`;
911
+ # properties are added to state_properties by default, and can be turned off
912
+ # with `desired_state: false`.
913
+ #
914
+ # ```ruby
915
+ # property :x # part of desired state
916
+ # property :y, desired_state: false # not part of desired state
917
+ # ```
918
+ #
919
+ # @param names [Array<Symbol>] A list of property names to set as desired
920
+ # state.
921
+ #
922
+ # @return [Array<Property>] All properties in desired state.
923
+ #
924
+ def self.state_properties(*names)
925
+ if !names.empty?
926
+ names = names.map { |name| name.to_sym }.uniq
724
927
 
725
- # Return *all* state_attrs that this class has, including inherited ones
726
- if superclass.respond_to?(:state_attrs)
727
- superclass.state_attrs + @state_attrs
728
- else
729
- @state_attrs
928
+ local_properties = properties(false)
929
+ # Add new properties to the list.
930
+ names.each do |name|
931
+ property = properties[name]
932
+ if !property
933
+ self.property name, instance_variable_name: false, desired_state: true
934
+ elsif !property.desired_state?
935
+ self.property name, desired_state: true
936
+ end
937
+ end
938
+
939
+ # If state_attrs *excludes* something which is currently desired state,
940
+ # mark it as desired_state: false.
941
+ local_properties.each do |name,property|
942
+ if property.desired_state? && !names.include?(name)
943
+ self.property name, desired_state: false
944
+ end
945
+ end
730
946
  end
947
+
948
+ properties.values.select { |property| property.desired_state? }
731
949
  end
732
950
 
733
- # Set or return the "identity attribute" for this resource class. This is
734
- # generally going to be the "name attribute" for this resource. In other
735
- # words, the resource type plus this attribute uniquely identify a given
736
- # bit of state that chef manages. For a File resource, this would be the
737
- # path, for a package resource, it will be the package name. This will show
738
- # up in chef-client's audit records as a searchable field.
739
- def self.identity_attr(attr_name=nil)
740
- @identity_attr ||= nil
741
- @identity_attr = attr_name if attr_name
951
+ #
952
+ # Set or return the list of "state properties" implemented by the Resource
953
+ # subclass.
954
+ #
955
+ # Equivalent to calling #state_properties and getting `state_properties.keys`.
956
+ #
957
+ # @deprecated Use state_properties.keys instead. Note that when you declare
958
+ # properties with `property`: properties are added to state_properties by
959
+ # default, and can be turned off with `desired_state: false`
960
+ #
961
+ # ```ruby
962
+ # property :x # part of desired state
963
+ # property :y, desired_state: false # not part of desired state
964
+ # ```
965
+ #
966
+ # @param names [Array<Symbol>] A list of property names to set as desired
967
+ # state.
968
+ #
969
+ # @return [Array<Symbol>] All property names with desired state.
970
+ #
971
+ def self.state_attrs(*names)
972
+ state_properties(*names).map { |property| property.name }
973
+ end
742
974
 
743
- # If this class doesn't have an identity attr, we'll defer to the superclass:
744
- if @identity_attr || !superclass.respond_to?(:identity_attr)
745
- @identity_attr
746
- else
747
- superclass.identity_attr
975
+ #
976
+ # Set the identity of this resource to a particular set of properties.
977
+ #
978
+ # This drives #identity, which returns data that uniquely refers to a given
979
+ # resource on the given node (in such a way that it can be correlated
980
+ # across Chef runs).
981
+ #
982
+ # This method is unnecessary when declaring properties with `property`;
983
+ # properties can be added to identity during declaration with
984
+ # `identity: true`.
985
+ #
986
+ # ```ruby
987
+ # property :x, identity: true # part of identity
988
+ # property :y # not part of identity
989
+ # ```
990
+ #
991
+ # If no properties are marked as identity, "name" is considered the identity.
992
+ #
993
+ # @param names [Array<Symbol>] A list of property names to set as the identity.
994
+ #
995
+ # @return [Array<Property>] All identity properties.
996
+ #
997
+ def self.identity_properties(*names)
998
+ if !names.empty?
999
+ names = names.map { |name| name.to_sym }
1000
+
1001
+ # Add or change properties that are not part of the identity.
1002
+ names.each do |name|
1003
+ property = properties[name]
1004
+ if !property
1005
+ self.property name, instance_variable_name: false, identity: true
1006
+ elsif !property.identity?
1007
+ self.property name, identity: true
1008
+ end
1009
+ end
1010
+
1011
+ # If identity_properties *excludes* something which is currently part of
1012
+ # the identity, mark it as identity: false.
1013
+ properties.each do |name,property|
1014
+ if property.identity? && !names.include?(name)
1015
+ self.property name, identity: false
1016
+ end
1017
+ end
1018
+ end
1019
+
1020
+ result = properties.values.select { |property| property.identity? }
1021
+ result = [ properties[:name] ] if result.empty?
1022
+ result
1023
+ end
1024
+
1025
+ #
1026
+ # Set the identity of this resource to a particular property.
1027
+ #
1028
+ # This drives #identity, which returns data that uniquely refers to a given
1029
+ # resource on the given node (in such a way that it can be correlated
1030
+ # across Chef runs).
1031
+ #
1032
+ # This method is unnecessary when declaring properties with `property`;
1033
+ # properties can be added to identity during declaration with
1034
+ # `identity: true`.
1035
+ #
1036
+ # ```ruby
1037
+ # property :x, identity: true # part of identity
1038
+ # property :y # not part of identity
1039
+ # ```
1040
+ #
1041
+ # @param name [Symbol] A list of property names to set as the identity.
1042
+ #
1043
+ # @return [Symbol] The identity property if there is only one; or `nil` if
1044
+ # there are more than one.
1045
+ #
1046
+ # @raise [ArgumentError] If no arguments are passed and the resource has
1047
+ # more than one identity property.
1048
+ #
1049
+ def self.identity_property(name=nil)
1050
+ result = identity_properties(*Array(name))
1051
+ if result.size > 1
1052
+ raise Chef::Exceptions::MultipleIdentityError, "identity_property cannot be called on an object with more than one identity property (#{result.map { |r| r.name }.join(", ")})."
748
1053
  end
1054
+ result.first
1055
+ end
1056
+
1057
+ #
1058
+ # Set a property as the "identity attribute" for this resource.
1059
+ #
1060
+ # Identical to calling #identity_property.first.key.
1061
+ #
1062
+ # @param name [Symbol] The name of the property to set.
1063
+ #
1064
+ # @return [Symbol]
1065
+ #
1066
+ # @deprecated `identity_property` should be used instead.
1067
+ #
1068
+ # @raise [ArgumentError] If no arguments are passed and the resource has
1069
+ # more than one identity property.
1070
+ #
1071
+ def self.identity_attr(name=nil)
1072
+ property = identity_property(name)
1073
+ return nil if !property
1074
+ property.name
749
1075
  end
750
1076
 
751
1077
  #
@@ -771,8 +1097,8 @@ class Chef
771
1097
  # have.
772
1098
  #
773
1099
  attr_accessor :allowed_actions
774
- def allowed_actions(value=NULL_ARG)
775
- if value != NULL_ARG
1100
+ def allowed_actions(value=NOT_PASSED)
1101
+ if value != NOT_PASSED
776
1102
  self.allowed_actions = value
777
1103
  end
778
1104
  @allowed_actions
@@ -883,7 +1209,7 @@ class Chef
883
1209
  # @deprecated Use resource_name instead.
884
1210
  #
885
1211
  def self.dsl_name
886
- Chef::Log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead."
1212
+ Chef.log_deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead."
887
1213
  if name
888
1214
  name = self.name.split('::')[-1]
889
1215
  convert_to_snake_case(name)
@@ -906,9 +1232,9 @@ class Chef
906
1232
  #
907
1233
  # @return [Symbol] The name of this resource type (e.g. `:execute`).
908
1234
  #
909
- def self.resource_name(name=NULL_ARG)
1235
+ def self.resource_name(name=NOT_PASSED)
910
1236
  # Setter
911
- if name != NULL_ARG
1237
+ if name != NOT_PASSED
912
1238
  remove_canonical_dsl
913
1239
 
914
1240
  # Set the resource_name and call provides
@@ -923,13 +1249,25 @@ class Chef
923
1249
  @resource_name = nil
924
1250
  end
925
1251
  end
926
-
927
1252
  @resource_name
928
1253
  end
929
1254
  def self.resource_name=(name)
930
1255
  resource_name(name)
931
1256
  end
932
1257
 
1258
+ #
1259
+ # Use the class name as the resource name.
1260
+ #
1261
+ # Munges the last part of the class name from camel case to snake case,
1262
+ # and sets the resource_name to that:
1263
+ #
1264
+ # A::B::BlahDBlah -> blah_d_blah
1265
+ #
1266
+ def self.use_automatic_resource_name
1267
+ automatic_name = convert_to_snake_case(self.name.split('::')[-1])
1268
+ resource_name automatic_name
1269
+ end
1270
+
933
1271
  #
934
1272
  # The module where Chef should look for providers for this resource.
935
1273
  # The provider for `MyResource` will be looked up using
@@ -948,7 +1286,7 @@ class Chef
948
1286
  #
949
1287
  def self.provider_base(arg=nil)
950
1288
  if arg
951
- Chef::Log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.")
1289
+ Chef.log_deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.")
952
1290
  end
953
1291
  @provider_base ||= arg || Chef::Provider
954
1292
  end
@@ -986,8 +1324,8 @@ class Chef
986
1324
  #
987
1325
  # @return [Array<Symbol>] The default actions for the resource.
988
1326
  #
989
- def self.default_action(action_name=NULL_ARG)
990
- unless action_name.equal?(NULL_ARG)
1327
+ def self.default_action(action_name=NOT_PASSED)
1328
+ unless action_name.equal?(NOT_PASSED)
991
1329
  @default_action = Array(action_name).map(&:to_sym)
992
1330
  self.allowed_actions |= @default_action
993
1331
  end
@@ -1001,9 +1339,128 @@ class Chef
1001
1339
  end
1002
1340
  end
1003
1341
  def self.default_action=(action_name)
1004
- default_action(action_name)
1342
+ default_action action_name
1005
1343
  end
1006
1344
 
1345
+ #
1346
+ # Define an action on this resource.
1347
+ #
1348
+ # The action is defined as a *recipe* block that will be compiled and then
1349
+ # converged when the action is taken (when Resource is converged). The recipe
1350
+ # has access to the resource's attributes and methods, as well as the Chef
1351
+ # recipe DSL.
1352
+ #
1353
+ # Resources in the action recipe may notify and subscribe to other resources
1354
+ # within the action recipe, but cannot notify or subscribe to resources
1355
+ # in the main Chef run.
1356
+ #
1357
+ # Resource actions are *inheritable*: if resource A defines `action :create`
1358
+ # and B is a subclass of A, B gets all of A's actions. Additionally,
1359
+ # resource B can define `action :create` and call `super()` to invoke A's
1360
+ # action code.
1361
+ #
1362
+ # The first action defined (besides `:nothing`) will become the default
1363
+ # action for the resource.
1364
+ #
1365
+ # @param name [Symbol] The action name to define.
1366
+ # @param recipe_block The recipe to run when the action is taken. This block
1367
+ # takes no parameters, and will be evaluated in a new context containing:
1368
+ #
1369
+ # - The resource's public and protected methods (including attributes)
1370
+ # - The Chef Recipe DSL (file, etc.)
1371
+ # - super() referring to the parent version of the action (if any)
1372
+ #
1373
+ # @return The Action class implementing the action
1374
+ #
1375
+ def self.action(action, &recipe_block)
1376
+ action = action.to_sym
1377
+ declare_action_class
1378
+ action_class.action(action, &recipe_block)
1379
+ self.allowed_actions += [ action ]
1380
+ default_action action if Array(default_action) == [:nothing]
1381
+ end
1382
+
1383
+ #
1384
+ # Define a method to load up this resource's properties with the current
1385
+ # actual values.
1386
+ #
1387
+ # @param load_block The block to load. Will be run in the context of a newly
1388
+ # created resource with its identity values filled in.
1389
+ #
1390
+ def self.load_current_value(&load_block)
1391
+ define_method(:load_current_value!, &load_block)
1392
+ end
1393
+
1394
+ #
1395
+ # Call this in `load_current_value` to indicate that the value does not
1396
+ # exist and that `current_resource` should therefore be `nil`.
1397
+ #
1398
+ # @raise Chef::Exceptions::CurrentValueDoesNotExist
1399
+ #
1400
+ def current_value_does_not_exist!
1401
+ raise Chef::Exceptions::CurrentValueDoesNotExist
1402
+ end
1403
+
1404
+ #
1405
+ # Get the current actual value of this resource.
1406
+ #
1407
+ # This does not cache--a new value will be returned each time.
1408
+ #
1409
+ # @return A new copy of the resource, with values filled in from the actual
1410
+ # current value.
1411
+ #
1412
+ def current_value
1413
+ provider = provider_for_action(Array(action).first)
1414
+ if provider.whyrun_mode? && !provider.whyrun_supported?
1415
+ raise "Cannot retrieve #{self.class.current_resource} in why-run mode: #{provider} does not support why-run"
1416
+ end
1417
+ provider.load_current_resource
1418
+ provider.current_resource
1419
+ end
1420
+
1421
+ #
1422
+ # The action class is an automatic `Provider` created to handle
1423
+ # actions declared by `action :x do ... end`.
1424
+ #
1425
+ # This class will be returned by `resource.provider` if `resource.provider`
1426
+ # is not set. `provider_for_action` will also use this instead of calling
1427
+ # out to `Chef::ProviderResolver`.
1428
+ #
1429
+ # If the user has not declared actions on this class or its superclasses
1430
+ # using `action :x do ... end`, then there is no need for this class and
1431
+ # `action_class` will be `nil`.
1432
+ #
1433
+ # @api private
1434
+ #
1435
+ def self.action_class
1436
+ @action_class ||
1437
+ # If the superclass needed one, then we need one as well.
1438
+ if superclass.respond_to?(:action_class) && superclass.action_class
1439
+ declare_action_class
1440
+ end
1441
+ end
1442
+
1443
+ #
1444
+ # Ensure the action class actually gets created. This is called
1445
+ # when the user does `action :x do ... end`.
1446
+ #
1447
+ # If a block is passed, it is run inside the action_class.
1448
+ #
1449
+ # @api private
1450
+ def self.declare_action_class
1451
+ return @action_class if @action_class
1452
+
1453
+ if superclass.respond_to?(:action_class)
1454
+ base_provider = superclass.action_class
1455
+ end
1456
+ base_provider ||= Chef::Provider
1457
+
1458
+ resource_class = self
1459
+ @action_class = Class.new(base_provider) do
1460
+ include ActionClass
1461
+ self.resource_class = resource_class
1462
+ end
1463
+ end
1007
1464
 
1008
1465
  #
1009
1466
  # Internal Resource Interface (for Chef)
@@ -1076,7 +1533,7 @@ class Chef
1076
1533
 
1077
1534
  class << self
1078
1535
  # back-compat
1079
- # NOTE: that we do not support unregistering classes as descendents like
1536
+ # NOTE: that we do not support unregistering classes as descendants like
1080
1537
  # we used to for LWRP unloading because that was horrible and removed in
1081
1538
  # Chef-12.
1082
1539
  # @deprecated
@@ -1167,16 +1624,31 @@ class Chef
1167
1624
  run_context.delayed_notifications(self)
1168
1625
  end
1169
1626
 
1627
+ def source_line_file
1628
+ if source_line
1629
+ source_line.match(/(.*):(\d+):?.*$/).to_a[1]
1630
+ else
1631
+ nil
1632
+ end
1633
+ end
1634
+
1635
+ def source_line_number
1636
+ if source_line
1637
+ source_line.match(/(.*):(\d+):?.*$/).to_a[2]
1638
+ else
1639
+ nil
1640
+ end
1641
+ end
1642
+
1170
1643
  def defined_at
1171
1644
  # The following regexp should match these two sourceline formats:
1172
1645
  # /some/path/to/file.rb:80:in `wombat_tears'
1173
1646
  # C:/some/path/to/file.rb:80 in 1`wombat_tears'
1174
1647
  # extracting the path to the source file and the line number.
1175
- (file, line_no) = source_line.match(/(.*):(\d+):?.*$/).to_a[1,2] if source_line
1176
1648
  if cookbook_name && recipe_name && source_line
1177
- "#{cookbook_name}::#{recipe_name} line #{line_no}"
1649
+ "#{cookbook_name}::#{recipe_name} line #{source_line_number}"
1178
1650
  elsif source_line
1179
- "#{file} line #{line_no}"
1651
+ "#{source_line_file} line #{source_line_number}"
1180
1652
  else
1181
1653
  "dynamically defined"
1182
1654
  end
@@ -1202,7 +1674,8 @@ class Chef
1202
1674
  end
1203
1675
 
1204
1676
  def provider_for_action(action)
1205
- provider = Chef::ProviderResolver.new(node, self, action).resolve.new(self, run_context)
1677
+ provider_class = Chef::ProviderResolver.new(node, self, action).resolve
1678
+ provider = provider_class.new(self, run_context)
1206
1679
  provider.action = action
1207
1680
  provider
1208
1681
  end