chef 16.6.14 → 16.7.61

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -11
  3. data/Rakefile +21 -14
  4. data/chef-universal-mingw32.gemspec +1 -1
  5. data/lib/chef/application/knife.rb +1 -1
  6. data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +1 -1
  7. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  8. data/lib/chef/client.rb +1 -1
  9. data/lib/chef/cookbook_manifest.rb +1 -1
  10. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  11. data/lib/chef/cookbook_version.rb +2 -5
  12. data/lib/chef/environment.rb +1 -1
  13. data/lib/chef/exceptions.rb +1 -1
  14. data/lib/chef/file_access_control/windows.rb +1 -4
  15. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
  16. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +4 -4
  17. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +28 -39
  18. data/lib/chef/http.rb +2 -12
  19. data/lib/chef/http/basic_client.rb +1 -1
  20. data/lib/chef/http/http_request.rb +1 -1
  21. data/lib/chef/http/socketless_chef_zero_client.rb +1 -1
  22. data/lib/chef/json_compat.rb +2 -7
  23. data/lib/chef/key.rb +1 -1
  24. data/lib/chef/knife/bootstrap.rb +2 -1
  25. data/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb +2 -2
  26. data/lib/chef/knife/config_show.rb +1 -1
  27. data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
  28. data/lib/chef/knife/core/gem_glob_loader.rb +1 -1
  29. data/lib/chef/knife/core/windows_bootstrap_context.rb +7 -4
  30. data/lib/chef/mixin/convert_to_class_name.rb +0 -56
  31. data/lib/chef/mixin/openssl_helper.rb +1 -1
  32. data/lib/chef/mixin/properties.rb +2 -0
  33. data/lib/chef/mixin/unformatter.rb +1 -1
  34. data/lib/chef/node/attribute_collections.rb +2 -6
  35. data/lib/chef/powershell.rb +5 -2
  36. data/lib/chef/property.rb +1 -1
  37. data/lib/chef/provider/cron.rb +2 -13
  38. data/lib/chef/provider/group.rb +14 -6
  39. data/lib/chef/provider/group/windows.rb +12 -1
  40. data/lib/chef/provider/ifconfig.rb +7 -7
  41. data/lib/chef/provider/ifconfig/debian.rb +5 -7
  42. data/lib/chef/provider/ifconfig/redhat.rb +3 -1
  43. data/lib/chef/provider/launchd.rb +1 -11
  44. data/lib/chef/provider/mount.rb +18 -1
  45. data/lib/chef/provider/mount/linux.rb +4 -0
  46. data/lib/chef/provider/mount/mount.rb +41 -43
  47. data/lib/chef/provider/package.rb +3 -0
  48. data/lib/chef/provider/package/apt.rb +1 -1
  49. data/lib/chef/provider/package/chocolatey.rb +6 -6
  50. data/lib/chef/provider/package/freebsd/base.rb +3 -2
  51. data/lib/chef/provider/package/freebsd/pkgng.rb +1 -1
  52. data/lib/chef/provider/package/ips.rb +1 -1
  53. data/lib/chef/provider/package/powershell.rb +2 -3
  54. data/lib/chef/provider/package/rubygems.rb +1 -1
  55. data/lib/chef/provider/package/snap.rb +1 -3
  56. data/lib/chef/provider/package/solaris.rb +0 -2
  57. data/lib/chef/provider/package/yum/rpm_utils.rb +1 -1
  58. data/lib/chef/provider/package/zypper.rb +98 -71
  59. data/lib/chef/provider/registry_key.rb +4 -3
  60. data/lib/chef/provider/route.rb +2 -2
  61. data/lib/chef/provider/service/debian.rb +2 -1
  62. data/lib/chef/provider/user.rb +17 -9
  63. data/lib/chef/provider/user/aix.rb +1 -1
  64. data/lib/chef/provider/user/mac.rb +12 -4
  65. data/lib/chef/provider/user/solaris.rb +1 -1
  66. data/lib/chef/provider/user/windows.rb +10 -3
  67. data/lib/chef/providers.rb +0 -3
  68. data/lib/chef/pwsh.rb +7 -0
  69. data/lib/chef/resource/bash.rb +119 -1
  70. data/lib/chef/resource/batch.rb +1 -1
  71. data/lib/chef/resource/breakpoint.rb +3 -1
  72. data/lib/chef/resource/build_essential.rb +5 -8
  73. data/lib/chef/resource/csh.rb +2 -2
  74. data/lib/chef/resource/execute.rb +6 -4
  75. data/lib/chef/resource/file.rb +1 -1
  76. data/lib/chef/resource/homebrew_update.rb +4 -1
  77. data/lib/chef/resource/hostname.rb +2 -2
  78. data/lib/chef/resource/ifconfig.rb +52 -5
  79. data/lib/chef/resource/ksh.rb +3 -3
  80. data/lib/chef/resource/lwrp_base.rb +3 -5
  81. data/lib/chef/resource/mount.rb +7 -1
  82. data/lib/chef/resource/perl.rb +2 -2
  83. data/lib/chef/resource/plist.rb +2 -6
  84. data/lib/chef/resource/powershell_package_source.rb +19 -18
  85. data/lib/chef/resource/powershell_script.rb +7 -10
  86. data/lib/chef/resource/python.rb +2 -2
  87. data/lib/chef/resource/registry_key.rb +93 -2
  88. data/lib/chef/resource/route.rb +1 -1
  89. data/lib/chef/resource/ruby.rb +2 -2
  90. data/lib/chef/resource/scm/_scm.rb +2 -1
  91. data/lib/chef/resource/scm/git.rb +82 -1
  92. data/lib/chef/resource/scm/subversion.rb +12 -0
  93. data/lib/chef/resource/script.rb +2 -2
  94. data/lib/chef/resource/solaris_package.rb +0 -2
  95. data/lib/chef/resource/sudo.rb +1 -1
  96. data/lib/chef/resource/support/client.erb +4 -5
  97. data/lib/chef/resource/systemd_unit.rb +42 -1
  98. data/lib/chef/resource/windows_ad_join.rb +9 -9
  99. data/lib/chef/resource/windows_certificate.rb +6 -6
  100. data/lib/chef/resource/windows_dfs_server.rb +7 -4
  101. data/lib/chef/resource/windows_env.rb +173 -0
  102. data/lib/chef/resource/windows_feature.rb +2 -0
  103. data/lib/chef/resource/windows_firewall_profile.rb +7 -12
  104. data/lib/chef/resource/windows_firewall_rule.rb +9 -11
  105. data/lib/chef/resource/windows_font.rb +1 -1
  106. data/lib/chef/resource/windows_package.rb +1 -0
  107. data/lib/chef/resource/windows_path.rb +38 -0
  108. data/lib/chef/resource/windows_security_policy.rb +5 -5
  109. data/lib/chef/resource/windows_service.rb +108 -0
  110. data/lib/chef/resource/windows_share.rb +18 -18
  111. data/lib/chef/resource/windows_task.rb +629 -28
  112. data/lib/chef/resource/windows_workgroup.rb +6 -4
  113. data/lib/chef/resource/yum_repository.rb +1 -1
  114. data/lib/chef/resource_collection/resource_set.rb +1 -5
  115. data/lib/chef/resource_inspector.rb +77 -75
  116. data/lib/chef/run_lock.rb +1 -1
  117. data/lib/chef/server_api.rb +0 -4
  118. data/lib/chef/shell/ext.rb +1 -1
  119. data/lib/chef/util/dsc/lcm_output_parser.rb +1 -3
  120. data/lib/chef/util/dsc/local_configuration_manager.rb +1 -1
  121. data/lib/chef/util/powershell/cmdlet.rb +3 -9
  122. data/lib/chef/version.rb +1 -1
  123. data/lib/chef/win32/security/sid.rb +1 -1
  124. data/spec/functional/mixin/powershell_out_spec.rb +4 -4
  125. data/spec/functional/resource/apt_package_spec.rb +4 -6
  126. data/spec/functional/resource/chocolatey_package_spec.rb +3 -3
  127. data/spec/functional/resource/cron_spec.rb +3 -3
  128. data/spec/functional/resource/dsc_script_spec.rb +3 -3
  129. data/spec/functional/resource/mount_spec.rb +10 -2
  130. data/spec/functional/resource/powershell_package_source_spec.rb +107 -0
  131. data/spec/functional/resource/windows_certificate_spec.rb +10 -6
  132. data/spec/functional/resource/windows_firewall_rule_spec.rb +93 -0
  133. data/spec/functional/resource/windows_package_spec.rb +36 -10
  134. data/spec/functional/resource/windows_share_spec.rb +103 -0
  135. data/spec/functional/resource/windows_task_spec.rb +2 -3
  136. data/spec/functional/resource/zypper_package_spec.rb +11 -0
  137. data/spec/integration/knife/client_key_create_spec.rb +1 -1
  138. data/spec/integration/knife/node_create_spec.rb +1 -1
  139. data/spec/integration/knife/node_environment_set_spec.rb +1 -1
  140. data/spec/integration/knife/node_run_list_add_spec.rb +4 -4
  141. data/spec/integration/knife/node_run_list_remove_spec.rb +1 -1
  142. data/spec/integration/knife/node_run_list_set_spec.rb +1 -1
  143. data/spec/integration/knife/node_show_spec.rb +1 -1
  144. data/spec/integration/recipes/notifies_spec.rb +1 -1
  145. data/spec/integration/recipes/provider_choice.rb +2 -2
  146. data/spec/support/lib/chef/resource/cat.rb +1 -1
  147. data/spec/support/lib/chef/resource/one_two_three_four.rb +1 -1
  148. data/spec/support/mock/platform.rb +24 -16
  149. data/spec/support/platform_helpers.rb +6 -4
  150. data/spec/support/shared/unit/knife_shared.rb +1 -1
  151. data/spec/support/shared/unit/script_resource.rb +4 -4
  152. data/spec/support/shared/unit/windows_script_resource.rb +1 -1
  153. data/spec/unit/client_spec.rb +16 -0
  154. data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +11 -11
  155. data/spec/unit/knife/client_create_spec.rb +2 -2
  156. data/spec/unit/knife/configure_client_spec.rb +5 -5
  157. data/spec/unit/knife/configure_spec.rb +3 -3
  158. data/spec/unit/knife/cookbook_delete_spec.rb +2 -2
  159. data/spec/unit/knife/cookbook_download_spec.rb +2 -2
  160. data/spec/unit/knife/cookbook_list_spec.rb +2 -2
  161. data/spec/unit/knife/cookbook_metadata_spec.rb +3 -3
  162. data/spec/unit/knife/environment_compare_spec.rb +3 -3
  163. data/spec/unit/knife/supermarket_download_spec.rb +8 -8
  164. data/spec/unit/knife/supermarket_list_spec.rb +3 -3
  165. data/spec/unit/knife/supermarket_search_spec.rb +1 -1
  166. data/spec/unit/knife/tag_create_spec.rb +1 -1
  167. data/spec/unit/knife/tag_delete_spec.rb +1 -1
  168. data/spec/unit/knife/user_create_spec.rb +1 -1
  169. data/spec/unit/mixin/which.rb +1 -1
  170. data/spec/unit/provider/group/windows_spec.rb +6 -0
  171. data/spec/unit/provider/group_spec.rb +1 -1
  172. data/spec/unit/provider/mount/linux_spec.rb +10 -0
  173. data/spec/unit/provider/mount/mount_spec.rb +21 -10
  174. data/spec/unit/provider/mount/solaris_spec.rb +1 -1
  175. data/spec/unit/provider/mount_spec.rb +31 -0
  176. data/spec/unit/provider/package/chocolatey_spec.rb +1 -2
  177. data/spec/unit/provider/package/powershell_spec.rb +87 -95
  178. data/spec/unit/provider/package/zypper_spec.rb +0 -25
  179. data/spec/unit/provider/package_spec.rb +2 -2
  180. data/spec/unit/provider/subversion_spec.rb +0 -3
  181. data/spec/unit/provider/user_spec.rb +7 -1
  182. data/spec/unit/provider/windows_env_spec.rb +18 -34
  183. data/spec/unit/provider/windows_path_spec.rb +6 -11
  184. data/spec/unit/provider/windows_task_spec.rb +7 -6
  185. data/spec/unit/resource/breakpoint_spec.rb +1 -1
  186. data/spec/unit/resource/build_essential_spec.rb +0 -12
  187. data/spec/unit/resource/ifconfig_spec.rb +2 -10
  188. data/spec/unit/resource/mount_spec.rb +18 -5
  189. data/spec/unit/resource/powershell_package_source_spec.rb +20 -20
  190. data/spec/unit/resource/powershell_script_spec.rb +4 -74
  191. data/spec/unit/resource/service_spec.rb +2 -2
  192. data/spec/unit/resource/solaris_package_spec.rb +8 -10
  193. data/spec/unit/resource_inspector_spec.rb +3 -3
  194. data/spec/unit/shell_spec.rb +2 -2
  195. data/tasks/rspec.rb +1 -1
  196. metadata +9 -15
  197. data/lib/chef/monkey_patches/net_http.rb +0 -22
  198. data/lib/chef/provider/windows_env.rb +0 -210
  199. data/lib/chef/provider/windows_path.rb +0 -61
  200. data/lib/chef/provider/windows_task.rb +0 -631
  201. data/spec/support/mock/constant.rb +0 -52
  202. data/spec/unit/monkey_patches/uri_spec.rb +0 -34
  203. data/spec/unit/provider_resolver_spec.rb +0 -885
  204. data/spec/unit/resource/data/InstallHistory_with_CLT.plist +0 -92
  205. data/spec/unit/resource/data/InstallHistory_without_CLT.plist +0 -38
@@ -35,6 +35,8 @@ class Chef
35
35
 
36
36
  include Chef::Mixin::Checksum
37
37
 
38
+ WORD_TYPES = %i{dword dword_big_endian qword}.freeze
39
+
38
40
  def running_on_windows!
39
41
  unless ChefUtils.windows?
40
42
  raise Chef::Exceptions::Win32NotWindows, "Attempt to manipulate the windows registry on a non-windows node"
@@ -122,9 +124,8 @@ class Chef
122
124
  new_resource.unscrubbed_values.each do |value|
123
125
  if @name_hash.key?(value[:name].downcase)
124
126
  current_value = @name_hash[value[:name].downcase]
125
- if %i{dword dword_big_endian qword}.include? value[:type]
126
- value[:data] = value[:data].to_i
127
- end
127
+ value[:data] = value[:data].to_i if WORD_TYPES.include?(value[:type])
128
+
128
129
  unless current_value[:type] == value[:type] && current_value[:data] == value[:data]
129
130
  converge_by_value = if new_resource.sensitive
130
131
  value.merge(data: "*sensitive value suppressed*")
@@ -188,8 +188,8 @@ class Chef
188
188
  logger.trace("#{new_resource} writing default route #{new_resource.gateway} to #{network_file_name}")
189
189
  if ::File.exist?(network_file_name)
190
190
  network_file = ::Chef::Util::FileEdit.new(network_file_name)
191
- network_file.search_file_replace_line /^GATEWAY=/, "GATEWAY=#{new_resource.gateway}"
192
- network_file.insert_line_if_no_match /^GATEWAY=/, "GATEWAY=#{new_resource.gateway}"
191
+ network_file.search_file_replace_line(/^GATEWAY=/, "GATEWAY=#{new_resource.gateway}")
192
+ network_file.insert_line_if_no_match(/^GATEWAY=/, "GATEWAY=#{new_resource.gateway}")
193
193
  network_file.write_file
194
194
  else
195
195
  network_file = ::File.new(network_file_name, "w")
@@ -28,6 +28,7 @@ class Chef
28
28
 
29
29
  UPDATE_RC_D_ENABLED_MATCHES = %r{/rc[\dS].d/S|not installed}i.freeze
30
30
  UPDATE_RC_D_PRIORITIES = %r{/rc([\dS]).d/([SK])(\d\d)}i.freeze
31
+ RUNLEVELS = %w{ 1 2 3 4 5 S }.freeze
31
32
 
32
33
  def self.supports?(resource, action)
33
34
  service_script_exist?(:initd, resource.service_name)
@@ -121,7 +122,7 @@ class Chef
121
122
  priority.each do |runlevel, arguments|
122
123
  logger.trace("#{new_resource} runlevel #{runlevel}, action #{arguments[0]}, priority #{arguments[1]}")
123
124
  # if we are in a update-rc.d default startup runlevel && we start in this runlevel
124
- if %w{ 1 2 3 4 5 S }.include?(runlevel) && arguments[0] == :start
125
+ if RUNLEVELS.include?(runlevel) && arguments[0] == :start
125
126
  enabled = true
126
127
  end
127
128
  end
@@ -24,6 +24,7 @@ class Chef
24
24
  class User < Chef::Provider
25
25
 
26
26
  attr_accessor :user_exists, :locked
27
+ attr_accessor :change_desc
27
28
 
28
29
  def initialize(new_resource, run_context)
29
30
  super
@@ -107,13 +108,20 @@ class Chef
107
108
  # <true>:: If a change is required
108
109
  # <false>:: If the users are identical
109
110
  def compare_user
110
- return true if !new_resource.home.nil? && Pathname.new(new_resource.home).cleanpath != Pathname.new(current_resource.home).cleanpath
111
+ @change_desc = []
112
+ if !new_resource.home.nil? && Pathname.new(new_resource.home).cleanpath != Pathname.new(current_resource.home).cleanpath
113
+ @change_desc << "change homedir from #{current_resource.home} to #{new_resource.home}"
114
+ end
111
115
 
112
116
  %i{comment shell password uid gid}.each do |user_attrib|
113
- return true if !new_resource.send(user_attrib).nil? && new_resource.send(user_attrib).to_s != current_resource.send(user_attrib).to_s
117
+ new_val = new_resource.send(user_attrib)
118
+ cur_val = current_resource.send(user_attrib)
119
+ if !new_val.nil? && new_val.to_s != cur_val.to_s
120
+ @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}"
121
+ end
114
122
  end
115
123
 
116
- false
124
+ !@change_desc.empty?
117
125
  end
118
126
 
119
127
  action :create do
@@ -123,9 +131,9 @@ class Chef
123
131
  logger.info("#{new_resource} created")
124
132
  end
125
133
  elsif compare_user
126
- converge_by("alter user #{new_resource.username}") do
134
+ converge_by(["alter user #{new_resource.username}"] + change_desc) do
127
135
  manage_user
128
- logger.info("#{new_resource} altered")
136
+ logger.info("#{new_resource} altered, #{change_desc.join(", ")}")
129
137
  end
130
138
  end
131
139
  end
@@ -142,18 +150,18 @@ class Chef
142
150
  action :manage do
143
151
  return unless @user_exists && compare_user
144
152
 
145
- converge_by("manage user #{new_resource.username}") do
153
+ converge_by(["manage user #{new_resource.username}"] + change_desc) do
146
154
  manage_user
147
- logger.info("#{new_resource} managed")
155
+ logger.info("#{new_resource} managed: #{change_desc.join(", ")}")
148
156
  end
149
157
  end
150
158
 
151
159
  action :modify do
152
160
  return unless compare_user
153
161
 
154
- converge_by("modify user #{new_resource.username}") do
162
+ converge_by(["modify user #{new_resource.username}"] + change_desc) do
155
163
  manage_user
156
- logger.info("#{new_resource} modified")
164
+ logger.info("#{new_resource} modified: #{change_desc.join(", ")}")
157
165
  end
158
166
  end
159
167
 
@@ -68,7 +68,7 @@ class Chef
68
68
 
69
69
  def check_lock
70
70
  lock_info = shell_out!("lsuser", "-a", "account_locked", new_resource.username)
71
- if whyrun_mode? && passwd_s.stdout.empty? && lock_info.stderr.match(/does not exist/)
71
+ if whyrun_mode? && passwd_s.stdout.empty? && lock_info.stderr.include?("does not exist")
72
72
  # if we're in whyrun mode and the user is not yet created we assume it would be
73
73
  return false
74
74
  end
@@ -221,7 +221,17 @@ class Chef
221
221
  end
222
222
 
223
223
  def compare_user
224
- %i{comment shell uid gid salt password admin secure_token hidden}.any? { |m| diverged?(m) }
224
+ @change_desc = []
225
+ %i{comment shell uid gid salt password admin secure_token hidden}.each do |attr|
226
+ if diverged?(attr)
227
+ desc = "Update #{attr}"
228
+ unless %i{password gid secure_token hidden}.include?(attr)
229
+ desc << " from #{current_resource.send(attr)} to #{new_resource.send(attr)}"
230
+ end
231
+ @change_desc << desc
232
+ end
233
+ end
234
+ !@change_desc.empty?
225
235
  end
226
236
 
227
237
  def manage_user
@@ -290,9 +300,7 @@ class Chef
290
300
  end
291
301
 
292
302
  if diverged?(:hidden)
293
- converge_by("alter hidden") do
294
- set_hidden
295
- end
303
+ converge_by("alter hidden") { set_hidden }
296
304
  end
297
305
 
298
306
  reload_user_plist
@@ -25,7 +25,7 @@ class Chef
25
25
  class User
26
26
  class Solaris < Chef::Provider::User
27
27
  provides :solaris_user
28
- provides :user, os: %w{openindiana opensolaris illumos omnios solaris2 smartos}
28
+ provides :user, os: %w{openindiana illumos omnios solaris2 smartos}
29
29
 
30
30
  PASSWORD_FILE = "/etc/shadow".freeze
31
31
 
@@ -61,13 +61,20 @@ class Chef
61
61
  # <true>:: If a change is required
62
62
  # <false>:: If the users are identical
63
63
  def compare_user
64
+ @change_desc = []
64
65
  unless @net_user.validate_credentials(new_resource.password)
65
- logger.trace("#{new_resource} password has changed")
66
- return true
66
+ @change_desc << "update password"
67
67
  end
68
+
68
69
  %i{uid comment home shell full_name}.any? do |user_attrib|
69
- !new_resource.send(user_attrib).nil? && new_resource.send(user_attrib) != current_resource.send(user_attrib)
70
+ new_val = new_resource.send(user_attrib)
71
+ cur_val = current_resource.send(user_attrib)
72
+ if !new_val.nil? && new_val != cur_val
73
+ @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}"
74
+ end
70
75
  end
76
+
77
+ !@change_desc.empty?
71
78
  end
72
79
 
73
80
  def create_user
@@ -47,11 +47,8 @@ require_relative "provider/systemd_unit"
47
47
  require_relative "provider/template"
48
48
  require_relative "provider/user"
49
49
  require_relative "provider/whyrun_safe_ruby_block"
50
- require_relative "provider/windows_env"
51
50
  require_relative "provider/yum_repository"
52
- require_relative "provider/windows_task"
53
51
  require_relative "provider/zypper_repository"
54
- require_relative "provider/windows_path"
55
52
 
56
53
  require_relative "provider/package/apt"
57
54
  require_relative "provider/package/chocolatey"
@@ -58,6 +58,13 @@ class Chef
58
58
  end
59
59
 
60
60
  def self.dll
61
+ # This Powershell DLL source lives here: https://github.com/chef/chef-powershell-shim
62
+ # Every merge into that repo triggers a Habitat build and promotion. Running
63
+ # the rake :update_chef_exec_dll task in this (chef/chef) repo will pull down
64
+ # the built packages and copy the binaries to distro/ruby_bin_folder. Bundle install
65
+ # ensures that the correct architecture binaries are installed into the path.
66
+ # Also note that the version of pwsh is determined by which assemblies the dll was
67
+ # built with. To update powershell, those dependencies must be bumped.
61
68
  @dll ||= Dir.glob("#{RbConfig::CONFIG["bindir"]}/**/Chef.PowerShell.Wrapper.Core.dll").last
62
69
  end
63
70
  end
@@ -25,7 +25,125 @@ class Chef
25
25
 
26
26
  provides :bash
27
27
 
28
- description "Use the **bash** resource to execute scripts using the Bash interpreter. This resource may also use any of the actions and properties that are available to the execute resource. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use not_if and only_if to guard this resource for idempotence."
28
+ description "Use the **bash** resource to execute scripts using the Bash interpreter. This resource may also use any of the actions and properties that are available to the **execute** resource. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use `not_if` and `only_if` to guard this resource for idempotence."
29
+ examples <<~'DOC'
30
+ **Compile an application**
31
+
32
+ ```ruby
33
+ bash 'install_something' do
34
+ user 'root'
35
+ cwd '/tmp'
36
+ code <<-EOH
37
+ wget http://www.example.com/tarball.tar.gz
38
+ tar -zxf tarball.tar.gz
39
+ cd tarball
40
+ ./configure
41
+ make
42
+ make install
43
+ EOH
44
+ end
45
+ ```
46
+
47
+ **Install a file from a remote location**
48
+
49
+ The following is an example of how to install the foo123 module for Nginx. This module adds shell-style functionality to an Nginx configuration file and does the following:
50
+
51
+ - Declares three variables
52
+ - Gets the Nginx file from a remote location
53
+ - Installs the file using Bash to the path specified by the `src_filepath` variable
54
+
55
+ ```ruby
56
+ src_filename = "foo123-nginx-module-v#{node['nginx']['foo123']['version']}.tar.gz"
57
+ src_filepath = "#{Chef::Config['file_cache_path']}/#{src_filename}"
58
+ extract_path = "#{Chef::Config['file_cache_path']}/nginx_foo123_module/#{node['nginx']['foo123']['checksum']}"
59
+
60
+ remote_file 'src_filepath' do
61
+ source node['nginx']['foo123']['url']
62
+ checksum node['nginx']['foo123']['checksum']
63
+ owner 'root'
64
+ group 'root'
65
+ mode '0755'
66
+ end
67
+
68
+ bash 'extract_module' do
69
+ cwd ::File.dirname(src_filepath)
70
+ code <<-EOH
71
+ mkdir -p #{extract_path}
72
+ tar xzf #{src_filename} -C #{extract_path}
73
+ mv #{extract_path}/*/* #{extract_path}/
74
+ EOH
75
+ not_if { ::File.exist?(extract_path) }
76
+ end
77
+ ```
78
+
79
+ **Install an application from git**
80
+
81
+ ```ruby
82
+ git "#{Chef::Config[:file_cache_path]}/ruby-build" do
83
+ repository 'git://github.com/rbenv/ruby-build.git'
84
+ revision 'master'
85
+ action :sync
86
+ end
87
+
88
+ bash 'install_ruby_build' do
89
+ cwd "#{Chef::Config[:file_cache_path]}/ruby-build"
90
+ user 'rbenv'
91
+ group 'rbenv'
92
+ code <<-EOH
93
+ ./install.sh
94
+ EOH
95
+ environment 'PREFIX' => '/usr/local'
96
+ end
97
+ ```
98
+
99
+ **Using Attributes in Bash Code**
100
+
101
+ The following recipe shows how an attributes file can be used to store certain settings. An attributes file is located in the `attributes/`` directory in the same cookbook as the recipe which calls the attributes file. In this example, the attributes file specifies certain settings for Python that are then used across all nodes against which this recipe will run.
102
+
103
+ Python packages have versions, installation directories, URLs, and checksum files. An attributes file that exists to support this type of recipe would include settings like the following:
104
+
105
+ ```ruby
106
+ default['python']['version'] = '2.7.1'
107
+
108
+ if python['install_method'] == 'package'
109
+ default['python']['prefix_dir'] = '/usr'
110
+ else
111
+ default['python']['prefix_dir'] = '/usr/local'
112
+ end
113
+
114
+ default['python']['url'] = 'http://www.python.org/ftp/python'
115
+ default['python']['checksum'] = '80e387...85fd61'
116
+ ```
117
+
118
+ and then the methods in the recipe may refer to these values. A recipe that is used to install Python will need to do the following:
119
+
120
+ - Identify each package to be installed (implied in this example, not shown)
121
+ - Define variables for the package `version` and the `install_path`
122
+ - Get the package from a remote location, but only if the package does not already exist on the target system
123
+ - Use the **bash** resource to install the package on the node, but only when the package is not already installed
124
+
125
+ ```ruby
126
+ version = node['python']['version']
127
+ install_path = "#{node['python']['prefix_dir']}/lib/python#{version.split(/(^\d+\.\d+)/)[1]}"
128
+
129
+ remote_file "#{Chef::Config[:file_cache_path]}/Python-#{version}.tar.bz2" do
130
+ source "#{node['python']['url']}/#{version}/Python-#{version}.tar.bz2"
131
+ checksum node['python']['checksum']
132
+ mode '0755'
133
+ not_if { ::File.exist?(install_path) }
134
+ end
135
+
136
+ bash 'build-and-install-python' do
137
+ cwd Chef::Config[:file_cache_path]
138
+ code <<-EOF
139
+ tar -jxvf Python-#{version}.tar.bz2
140
+ (cd Python-#{version} && ./configure #{configure_options})
141
+ (cd Python-#{version} && make && make install)
142
+ EOF
143
+ not_if { ::File.exist?(install_path) }
144
+ end
145
+ ```
146
+ DOC
29
147
 
30
148
  def initialize(name, run_context = nil)
31
149
  super
@@ -25,7 +25,7 @@ class Chef
25
25
 
26
26
  provides :batch
27
27
 
28
- description "Use the **batch** resource to execute a batch script using the cmd.exe interpreter on Windows. The batch resource creates and executes a temporary file (similar to how the script resource behaves), rather than running the command inline. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use not_if and only_if to guard this resource for idempotence."
28
+ description "Use the **batch** resource to execute a batch script using the cmd.exe interpreter on Windows. The batch resource creates and executes a temporary file (similar to how the script resource behaves), rather than running the command inline. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use `not_if` and `only_if` to guard this resource for idempotence."
29
29
 
30
30
  def initialize(*args)
31
31
  super
@@ -49,6 +49,8 @@ class Chef
49
49
 
50
50
  **The same recipe with breakpoints**
51
51
 
52
+ In the following example, the name of each breakpoint is an arbitrary string.
53
+
52
54
  ```ruby
53
55
  breakpoint "before yum_key node['yum']['repo_name']['key']" do
54
56
  action :break
@@ -81,7 +83,7 @@ class Chef
81
83
  end
82
84
  ```
83
85
 
84
- where the name of each breakpoint is an arbitrary string. In the previous examples, the names are used to indicate if the breakpoint is before or after a resource, and then also to specify which resource.
86
+ In the previous examples, the names are used to indicate if the breakpoint is before or after a resource and also to specify which resource it is before or after.
85
87
  DOC
86
88
 
87
89
  default_action :break
@@ -15,7 +15,6 @@
15
15
  #
16
16
 
17
17
  require_relative "../resource"
18
- autoload :Plist, "plist"
19
18
 
20
19
  class Chef
21
20
  class Resource
@@ -130,8 +129,8 @@ class Chef
130
129
  pkg_label = xcode_cli_package_label
131
130
 
132
131
  # With upgrade action we should install if it's not installed or if there's an available update.
133
- # `xcode_cli_package_label` will be nil if there's no update.
134
- install_xcode_cli_tools(pkg_label) if !xcode_cli_installed? || xcode_cli_package_label
132
+ # `pkg_label` will be nil if there's no update.
133
+ install_xcode_cli_tools(pkg_label) if !xcode_cli_installed? || pkg_label
135
134
  else
136
135
  Chef::Log.info "The build_essential resource :upgrade action is only supported on macOS systems. Skipping..."
137
136
  end
@@ -160,14 +159,12 @@ class Chef
160
159
  end
161
160
 
162
161
  #
163
- # Determine if the XCode Command Line Tools are installed by parsing the install history plist.
164
- # We parse the plist data install of running pkgutil because we found that pkgutils doesn't always contain all the packages
162
+ # Determine if the XCode Command Line Tools are installed by checking
163
+ # for success from `xcode-select -p`
165
164
  #
166
165
  # @return [true, false]
167
166
  def xcode_cli_installed?
168
- packages = ::Plist.parse_xml(::File.open("/Library/Receipts/InstallHistory.plist", "r"))
169
- packages.select! { |package| package["displayName"].match? "Command Line Tools" }
170
- !packages.empty?
167
+ !shell_out("xcode-select", "-p").error?
171
168
  end
172
169
 
173
170
  #
@@ -27,9 +27,9 @@ class Chef
27
27
 
28
28
  description "Use the **csh** resource to execute scripts using the csh interpreter."\
29
29
  " This resource may also use any of the actions and properties that are"\
30
- " available to the execute resource. Commands that are executed with this"\
30
+ " available to the **execute** resource. Commands that are executed with this"\
31
31
  " resource are (by their nature) not idempotent, as they are typically"\
32
- " unique to the environment in which they are run. Use not_if and only_if"\
32
+ " unique to the environment in which they are run. Use `not_if` and `only_if`"\
33
33
  " to guard this resource for idempotence."
34
34
 
35
35
  def initialize(name, run_context = nil)
@@ -27,7 +27,7 @@ class Chef
27
27
 
28
28
  provides :execute, target_mode: true
29
29
 
30
- description "Use the **execute** resource to execute a single command. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use not_if and only_if to guard this resource for idempotence. Note: Use the **script** resource to execute a script using a specific interpreter (Ruby, Python, Perl, csh, or Bash)."
30
+ description "Use the **execute** resource to execute a single command. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use `not_if` and `only_if` to guard this resource for idempotence. Note: Use the **script** resource to execute a script using a specific interpreter (Ruby, Python, Perl, csh, or Bash)."
31
31
 
32
32
  examples <<~EXAMPLES
33
33
  **Run a command upon notification**:
@@ -549,11 +549,11 @@ class Chef
549
549
  desired_state: false
550
550
 
551
551
  property :user, [ String, Integer ],
552
- description: "The user name of the user identity with which to launch the new process. The user name may optionally be specified with a domain, i.e. domainuser or user@my.dns.domain.com via Universal Principal Name (UPN)format. It can also be specified without a domain simply as user if the domain is instead specified using the domain property. On Windows only, if this property is specified, the password property must be specified."
552
+ description: "The user name of the user identity with which to launch the new process. The user name may optionally be specified with a domain, i.e. `domainuser` or `user@my.dns.domain.com` via Universal Principal Name (UPN)format. It can also be specified without a domain simply as user if the domain is instead specified using the domain property. On Windows only, if this property is specified, the password property must be specified."
553
553
 
554
554
  property :domain, String,
555
555
  introduced: "12.21",
556
- description: "Windows only: The domain of the user user specified by the user property. If not specified, the user name and password specified by the user and password properties will be used to resolve that user against the domain in which the system running #{ChefUtils::Dist::Infra::PRODUCT} is joined, or if that system is not joined to a domain it will resolve the user as a local account on that system. An alternative way to specify the domain is to leave this property unspecified and specify the domain as part of the user property."
556
+ description: "Windows only: The domain of the user user specified by the user property. If not specified, the username and password specified by the `user` and `password` properties will be used to resolve that user against the domain in which the system running #{ChefUtils::Dist::Infra::PRODUCT} is joined, or if that system is not joined to a domain it will resolve the user as a local account on that system. An alternative way to specify the domain is to leave this property unspecified and specify the domain as part of the user property."
557
557
 
558
558
  property :password, String, sensitive: true,
559
559
  introduced: "12.21",
@@ -565,7 +565,7 @@ class Chef
565
565
  default: lazy { password ? true : false }, default_description: "True if the password property is set. False otherwise."
566
566
 
567
567
  property :elevated, [ TrueClass, FalseClass ], default: false,
568
- description: "Determines whether the script will run with elevated permissions to circumvent User Access Control (UAC) interactively blocking the process.\nThis will cause the process to be run under a batch login instead of an interactive login. The user running #{ChefUtils::Dist::Infra::CLIENT} needs the 'Replace a process level token' and 'Adjust Memory Quotas for a process' permissions. The user that is running the command needs the 'Log on as a batch job' permission.\nBecause this requires a login, the user and password properties are required.",
568
+ description: "Determines whether the script will run with elevated permissions to circumvent User Access Control (UAC) from interactively blocking the process.\nThis will cause the process to be run under a batch login instead of an interactive login. The user running #{ChefUtils::Dist::Infra::CLIENT} needs the 'Replace a process level token' and 'Adjust Memory Quotas for a process' permissions. The user that is running the command needs the 'Log on as a batch job' permission.\nBecause this requires a login, the user and password properties are required.",
569
569
  introduced: "13.3"
570
570
 
571
571
  property :input, [String],
@@ -661,8 +661,10 @@ class Chef
661
661
 
662
662
  set_guard_inherited_attributes(
663
663
  :cwd,
664
+ :domain,
664
665
  :environment,
665
666
  :group,
667
+ :password,
666
668
  :user,
667
669
  :umask
668
670
  )