chef 12.4.3-universal-mingw32 → 12.5.1-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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