chef 18.4.2 → 18.5.0

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 (223) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -1
  3. data/chef.gemspec +7 -7
  4. data/lib/chef/application/client.rb +12 -0
  5. data/lib/chef/client.rb +10 -16
  6. data/lib/chef/compliance/runner.rb +10 -0
  7. data/lib/chef/cookbook/chefignore.rb +4 -1
  8. data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
  9. data/lib/chef/cookbook/synchronizer.rb +7 -1
  10. data/lib/chef/cookbook_manifest.rb +2 -2
  11. data/lib/chef/file_access_control/unix.rb +9 -9
  12. data/lib/chef/file_cache.rb +17 -2
  13. data/lib/chef/file_content_management/deploy/target_io.rb +29 -0
  14. data/lib/chef/file_content_management/deploy.rb +4 -1
  15. data/lib/chef/formatters/doc.rb +1 -1
  16. data/lib/chef/mixin/file_class.rb +3 -1
  17. data/lib/chef/mixin/get_source_from_package.rb +1 -1
  18. data/lib/chef/mixin/openssl_helper.rb +1 -1
  19. data/lib/chef/node/attribute.rb +3 -11
  20. data/lib/chef/node/immutable_collections.rb +15 -8
  21. data/lib/chef/node/mixin/state_tracking.rb +6 -3
  22. data/lib/chef/node.rb +1 -1
  23. data/lib/chef/policy_builder/policyfile.rb +8 -0
  24. data/lib/chef/provider/.gitkeep +0 -0
  25. data/lib/chef/provider/cookbook_file.rb +1 -1
  26. data/lib/chef/provider/cron.rb +1 -1
  27. data/lib/chef/provider/directory.rb +15 -15
  28. data/lib/chef/provider/file.rb +42 -29
  29. data/lib/chef/provider/git.rb +8 -8
  30. data/lib/chef/provider/group/aix.rb +1 -1
  31. data/lib/chef/provider/group/dscl.rb +1 -1
  32. data/lib/chef/provider/group/gpasswd.rb +2 -2
  33. data/lib/chef/provider/group/groupadd.rb +1 -1
  34. data/lib/chef/provider/group/groupmod.rb +2 -2
  35. data/lib/chef/provider/group/pw.rb +2 -2
  36. data/lib/chef/provider/group/solaris.rb +2 -2
  37. data/lib/chef/provider/group/usermod.rb +2 -2
  38. data/lib/chef/provider/group.rb +1 -1
  39. data/lib/chef/provider/http_request.rb +2 -3
  40. data/lib/chef/provider/ifconfig/aix.rb +1 -1
  41. data/lib/chef/provider/ifconfig/debian.rb +3 -3
  42. data/lib/chef/provider/ifconfig/redhat.rb +1 -1
  43. data/lib/chef/provider/ifconfig.rb +1 -1
  44. data/lib/chef/provider/link.rb +10 -10
  45. data/lib/chef/provider/mount/aix.rb +4 -4
  46. data/lib/chef/provider/mount/linux.rb +4 -4
  47. data/lib/chef/provider/mount/mount.rb +11 -11
  48. data/lib/chef/provider/package/apt.rb +2 -11
  49. data/lib/chef/provider/package/bff.rb +3 -3
  50. data/lib/chef/provider/package/chocolatey.rb +54 -24
  51. data/lib/chef/provider/package/dpkg.rb +3 -3
  52. data/lib/chef/provider/package/freebsd/base.rb +1 -1
  53. data/lib/chef/provider/package/habitat.rb +5 -3
  54. data/lib/chef/provider/package/ips.rb +2 -2
  55. data/lib/chef/provider/package/openbsd.rb +3 -2
  56. data/lib/chef/provider/package/pacman.rb +4 -4
  57. data/lib/chef/provider/package/paludis.rb +2 -2
  58. data/lib/chef/provider/package/portage.rb +1 -1
  59. data/lib/chef/provider/package/powershell.rb +1 -0
  60. data/lib/chef/provider/package/rpm.rb +2 -2
  61. data/lib/chef/provider/package/smartos.rb +2 -2
  62. data/lib/chef/provider/package/snap.rb +2 -1
  63. data/lib/chef/provider/package/snap_tm.rb +79 -0
  64. data/lib/chef/provider/package/solaris.rb +4 -4
  65. data/lib/chef/provider/package/zypper.rb +4 -5
  66. data/lib/chef/provider/package.rb +1 -1
  67. data/lib/chef/provider/remote_directory.rb +5 -5
  68. data/lib/chef/provider/remote_file/http.rb +2 -3
  69. data/lib/chef/provider/remote_file.rb +1 -1
  70. data/lib/chef/provider/route.rb +9 -9
  71. data/lib/chef/provider/service/aix.rb +1 -1
  72. data/lib/chef/provider/service/aixinit.rb +4 -4
  73. data/lib/chef/provider/service/arch.rb +6 -6
  74. data/lib/chef/provider/service/debian.rb +5 -5
  75. data/lib/chef/provider/service/freebsd.rb +7 -7
  76. data/lib/chef/provider/service/gentoo.rb +5 -5
  77. data/lib/chef/provider/service/init.rb +2 -2
  78. data/lib/chef/provider/service/insserv.rb +2 -2
  79. data/lib/chef/provider/service/invokercd.rb +1 -1
  80. data/lib/chef/provider/service/openbsd.rb +7 -7
  81. data/lib/chef/provider/service/redhat.rb +3 -3
  82. data/lib/chef/provider/service/solaris.rb +2 -2
  83. data/lib/chef/provider/service/systemd.rb +2 -2
  84. data/lib/chef/provider/service/upstart.rb +2 -2
  85. data/lib/chef/provider/service/windows.rb +0 -1
  86. data/lib/chef/provider/subversion.rb +8 -8
  87. data/lib/chef/provider/systemd_unit.rb +3 -3
  88. data/lib/chef/provider/template.rb +1 -1
  89. data/lib/chef/provider/user/aix.rb +3 -3
  90. data/lib/chef/provider/user/linux.rb +7 -2
  91. data/lib/chef/provider/user/pw.rb +3 -3
  92. data/lib/chef/provider/user/solaris.rb +7 -7
  93. data/lib/chef/provider/user.rb +7 -8
  94. data/lib/chef/provider/yum_repository.rb +1 -3
  95. data/lib/chef/provider/zypper_repository.rb +1 -1
  96. data/lib/chef/providers.rb +1 -0
  97. data/lib/chef/resource/.gitkeep +0 -0
  98. data/lib/chef/resource/alternatives.rb +2 -2
  99. data/lib/chef/resource/apt_preference.rb +1 -1
  100. data/lib/chef/resource/apt_repository.rb +7 -9
  101. data/lib/chef/resource/apt_update.rb +3 -3
  102. data/lib/chef/resource/bff_package.rb +1 -1
  103. data/lib/chef/resource/chef_client_config.rb +3 -2
  104. data/lib/chef/resource/chef_client_systemd_timer.rb +5 -0
  105. data/lib/chef/resource/chef_gem.rb +1 -1
  106. data/lib/chef/resource/chef_sleep.rb +1 -1
  107. data/lib/chef/resource/cookbook_file.rb +1 -1
  108. data/lib/chef/resource/cron/cron.rb +1 -1
  109. data/lib/chef/resource/cron/cron_d.rb +1 -1
  110. data/lib/chef/resource/cron_access.rb +1 -1
  111. data/lib/chef/resource/directory.rb +1 -1
  112. data/lib/chef/resource/dpkg_package.rb +1 -1
  113. data/lib/chef/resource/execute.rb +8 -6
  114. data/lib/chef/resource/file/verification/json.rb +1 -1
  115. data/lib/chef/resource/file/verification/systemd_unit.rb +1 -1
  116. data/lib/chef/resource/file/verification/yaml.rb +1 -1
  117. data/lib/chef/resource/file.rb +1 -1
  118. data/lib/chef/resource/freebsd_package.rb +2 -2
  119. data/lib/chef/resource/group.rb +1 -1
  120. data/lib/chef/resource/habitat/habitat_package.rb +1 -1
  121. data/lib/chef/resource/habitat/habitat_sup.rb +9 -9
  122. data/lib/chef/resource/habitat/habitat_sup_systemd.rb +2 -2
  123. data/lib/chef/resource/habitat_install.rb +5 -4
  124. data/lib/chef/resource/hostname.rb +11 -10
  125. data/lib/chef/resource/http_request.rb +1 -1
  126. data/lib/chef/resource/ifconfig.rb +1 -1
  127. data/lib/chef/resource/inspec_input.rb +3 -1
  128. data/lib/chef/resource/inspec_waiver.rb +1 -1
  129. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  130. data/lib/chef/resource/ips_package.rb +2 -2
  131. data/lib/chef/resource/kernel_module.rb +2 -2
  132. data/lib/chef/resource/link.rb +1 -1
  133. data/lib/chef/resource/locale.rb +2 -2
  134. data/lib/chef/resource/mount.rb +1 -1
  135. data/lib/chef/resource/notify_group.rb +1 -1
  136. data/lib/chef/resource/ohai.rb +1 -1
  137. data/lib/chef/resource/ohai_hint.rb +1 -1
  138. data/lib/chef/resource/openbsd_package.rb +2 -2
  139. data/lib/chef/resource/package.rb +1 -1
  140. data/lib/chef/resource/pacman_package.rb +1 -1
  141. data/lib/chef/resource/paludis_package.rb +1 -1
  142. data/lib/chef/resource/portage_package.rb +1 -1
  143. data/lib/chef/resource/powershell_package.rb +4 -0
  144. data/lib/chef/resource/reboot.rb +1 -1
  145. data/lib/chef/resource/remote_directory.rb +1 -1
  146. data/lib/chef/resource/remote_file.rb +1 -1
  147. data/lib/chef/resource/rhsm_errata.rb +1 -1
  148. data/lib/chef/resource/rhsm_errata_level.rb +1 -1
  149. data/lib/chef/resource/rhsm_register.rb +1 -1
  150. data/lib/chef/resource/rhsm_repo.rb +3 -4
  151. data/lib/chef/resource/rhsm_subscription.rb +8 -9
  152. data/lib/chef/resource/route.rb +1 -1
  153. data/lib/chef/resource/rpm_package.rb +1 -1
  154. data/lib/chef/resource/scm/git.rb +1 -1
  155. data/lib/chef/resource/scm/subversion.rb +1 -1
  156. data/lib/chef/resource/selinux/common_helpers.rb +1 -1
  157. data/lib/chef/resource/selinux_boolean.rb +1 -1
  158. data/lib/chef/resource/selinux_fcontext.rb +3 -3
  159. data/lib/chef/resource/selinux_install.rb +1 -1
  160. data/lib/chef/resource/selinux_login.rb +1 -1
  161. data/lib/chef/resource/selinux_module.rb +5 -5
  162. data/lib/chef/resource/selinux_permissive.rb +2 -2
  163. data/lib/chef/resource/selinux_port.rb +2 -2
  164. data/lib/chef/resource/selinux_state.rb +2 -2
  165. data/lib/chef/resource/selinux_user.rb +1 -1
  166. data/lib/chef/resource/smartos_package.rb +2 -2
  167. data/lib/chef/resource/snap_package.rb +24 -1
  168. data/lib/chef/resource/solaris_package.rb +1 -1
  169. data/lib/chef/resource/ssh_known_hosts_entry.rb +1 -1
  170. data/lib/chef/resource/sudo.rb +5 -5
  171. data/lib/chef/resource/support/client.erb +1 -1
  172. data/lib/chef/resource/swap_file.rb +6 -6
  173. data/lib/chef/resource/sysctl.rb +6 -5
  174. data/lib/chef/resource/systemd_unit.rb +1 -1
  175. data/lib/chef/resource/template.rb +1 -1
  176. data/lib/chef/resource/timezone.rb +5 -5
  177. data/lib/chef/resource/user/aix_user.rb +2 -2
  178. data/lib/chef/resource/user/linux_user.rb +2 -2
  179. data/lib/chef/resource/user/pw_user.rb +2 -2
  180. data/lib/chef/resource/user/solaris_user.rb +2 -2
  181. data/lib/chef/resource/user_ulimit.rb +1 -1
  182. data/lib/chef/resource/yum_repository.rb +1 -1
  183. data/lib/chef/resource/zypper_package.rb +2 -2
  184. data/lib/chef/resource/zypper_repository.rb +2 -2
  185. data/lib/chef/run_lock.rb +3 -0
  186. data/lib/chef/scan_access_control.rb +6 -6
  187. data/lib/chef/target_io/dir.rb +12 -0
  188. data/lib/chef/target_io/etc.rb +16 -0
  189. data/lib/chef/target_io/file.rb +12 -0
  190. data/lib/chef/target_io/fileutils.rb +12 -0
  191. data/lib/chef/target_io/http.rb +22 -0
  192. data/lib/chef/target_io/io.rb +12 -0
  193. data/lib/chef/target_io/shadow.rb +44 -0
  194. data/lib/chef/target_io/train/dir.rb +69 -0
  195. data/lib/chef/target_io/train/etc.rb +112 -0
  196. data/lib/chef/target_io/train/file.rb +219 -0
  197. data/lib/chef/target_io/train/fileutils.rb +220 -0
  198. data/lib/chef/target_io/train/http.rb +117 -0
  199. data/lib/chef/target_io/train/io.rb +13 -0
  200. data/lib/chef/target_io/train/shadow.rb +52 -0
  201. data/lib/chef/target_io/train_compat.rb +7 -0
  202. data/lib/chef/target_io.rb +9 -0
  203. data/lib/chef/util/backup.rb +1 -1
  204. data/lib/chef/util/diff.rb +14 -1
  205. data/lib/chef/util/file_edit.rb +4 -4
  206. data/lib/chef/version.rb +1 -1
  207. data/lib/chef.rb +2 -0
  208. data/spec/functional/resource/remote_file_spec.rb +1 -1
  209. data/spec/integration/client/fips_spec.rb +11 -2
  210. data/spec/integration/client/open_ssl_spec.rb +20 -0
  211. data/spec/spec_helper.rb +3 -1
  212. data/spec/support/platform_helpers.rb +20 -7
  213. data/spec/unit/client_spec.rb +0 -16
  214. data/spec/unit/file_cache_spec.rb +64 -0
  215. data/spec/unit/mixin/openssl_helper_spec.rb +6 -1
  216. data/spec/unit/provider/apt_repository_spec.rb +1 -1
  217. data/spec/unit/provider/package/chocolatey_spec.rb +17 -12
  218. data/spec/unit/provider/package/windows_spec.rb +5 -5
  219. data/spec/unit/provider/package/zypper_spec.rb +0 -10
  220. data/spec/unit/provider/route_spec.rb +6 -4
  221. data/spec/unit/resource/rhsm_repo_spec.rb +1 -0
  222. data/spec/unit/resource/rhsm_subscription_spec.rb +2 -0
  223. metadata +31 -10
@@ -21,7 +21,7 @@ class Chef
21
21
  class Provider
22
22
  class Mount
23
23
  class Aix < Chef::Provider::Mount::Mount
24
- provides :mount, platform: "aix"
24
+ provides :mount, platform: "aix", target_mode: true
25
25
 
26
26
  # Override for aix specific handling
27
27
  def initialize(new_resource, run_context)
@@ -163,7 +163,7 @@ class Chef
163
163
  # disable, then enable.
164
164
  disable_fs
165
165
  end
166
- ::File.open("/etc/filesystems", "a") do |fstab|
166
+ ::TargetIO::File.open("/etc/filesystems", "a") do |fstab|
167
167
  fstab.puts("\n\n#{@new_resource.mount_point}:")
168
168
  if network_device?
169
169
  device_details = device_fstab.split(":")
@@ -194,7 +194,7 @@ class Chef
194
194
  contents = []
195
195
  if @current_resource.enabled
196
196
  found_device = false
197
- ::File.open("/etc/filesystems", "r").each_line do |line|
197
+ ::TargetIO::File.open("/etc/filesystems", "r").each_line do |line|
198
198
  case line
199
199
  when %r{^/.+:\s*$}
200
200
  if /#{Regexp.escape(@new_resource.mount_point)}+:/.match?(line)
@@ -207,7 +207,7 @@ class Chef
207
207
  contents << line
208
208
  end
209
209
  end
210
- ::File.open("/etc/filesystems", "w") do |fstab|
210
+ ::TargetIO::File.open("/etc/filesystems", "w") do |fstab|
211
211
  contents.each { |line| fstab.puts line }
212
212
  end
213
213
  else
@@ -23,7 +23,7 @@ class Chef
23
23
  class Mount
24
24
  class Linux < Chef::Provider::Mount::Mount
25
25
 
26
- provides :mount, os: "linux"
26
+ provides :mount, os: "linux", target_mode: true
27
27
 
28
28
  # Check to see if the volume is mounted.
29
29
  # "findmnt" outputs the mount points with volume.
@@ -39,8 +39,8 @@ class Chef
39
39
 
40
40
  def mounted?
41
41
  mounted = false
42
- real_mount_point = if ::File.exist? @new_resource.mount_point
43
- ::File.realpath(@new_resource.mount_point)
42
+ real_mount_point = if ::TargetIO::File.exist? @new_resource.mount_point
43
+ ::TargetIO::File.realpath(@new_resource.mount_point)
44
44
  else
45
45
  @new_resource.mount_point
46
46
  end
@@ -83,4 +83,4 @@ class Chef
83
83
  end
84
84
  end
85
85
  end
86
- end
86
+ end
@@ -42,9 +42,9 @@ class Chef
42
42
 
43
43
  def mountable?
44
44
  # only check for existence of non-remote devices
45
- if device_should_exist? && !::File.exist?(device_real)
45
+ if device_should_exist? && !::TargetIO::File.exist?(device_real)
46
46
  raise Chef::Exceptions::Mount, "Device #{@new_resource.device} does not exist"
47
- elsif @new_resource.mount_point != "none" && !::File.exist?(@new_resource.mount_point)
47
+ elsif @new_resource.mount_point != "none" && !::TargetIO::File.exist?(@new_resource.mount_point)
48
48
  raise Chef::Exceptions::Mount, "Mount point #{@new_resource.mount_point} does not exist"
49
49
  end
50
50
 
@@ -54,11 +54,11 @@ class Chef
54
54
  def enabled?
55
55
  # Check to see if there is a entry in /etc/fstab. Last entry for a volume wins.
56
56
  enabled = false
57
- unless ::File.exist?("/etc/fstab")
57
+ unless ::TargetIO::File.exist?("/etc/fstab")
58
58
  logger.debug "/etc/fstab not found, treating mount as not-enabled"
59
59
  return
60
60
  end
61
- ::File.foreach("/etc/fstab") do |line|
61
+ ::TargetIO::File.foreach("/etc/fstab") do |line|
62
62
  case line
63
63
  when /^[#\s]/
64
64
  next
@@ -81,8 +81,8 @@ class Chef
81
81
  # "mount" outputs the mount points as real paths. Convert
82
82
  # the mount_point of the resource to a real path in case it
83
83
  # contains symlinks in its parents dirs.
84
- real_mount_point = if ::File.exist? @new_resource.mount_point
85
- ::File.realpath(@new_resource.mount_point)
84
+ real_mount_point = if ::TargetIO::File.exist? @new_resource.mount_point
85
+ ::TargetIO::File.realpath(@new_resource.mount_point)
86
86
  else
87
87
  @new_resource.mount_point
88
88
  end
@@ -168,7 +168,7 @@ class Chef
168
168
  # and order will remain the same.
169
169
  edit_fstab
170
170
  else
171
- ::File.open("/etc/fstab", "a") do |fstab|
171
+ ::TargetIO::File.open("/etc/fstab", "a") do |fstab|
172
172
  fstab.puts("#{device_fstab} #{@new_resource.mount_point} #{@new_resource.fstype} #{@new_resource.options.nil? ? default_mount_options : @new_resource.options.join(",")} #{@new_resource.dump} #{@new_resource.pass}")
173
173
  logger.trace("#{@new_resource} is enabled at #{@new_resource.mount_point}")
174
174
  end
@@ -229,12 +229,12 @@ class Chef
229
229
  if network_device?
230
230
  # ignore trailing slash
231
231
  Regexp.escape(device_real) + "/?"
232
- elsif ::File.symlink?(device_real)
232
+ elsif ::TargetIO::File.symlink?(device_real)
233
233
  # This regular expression tries to match device_real. If that does not match it will try to match the target of device_real.
234
234
  # So given a symlink like this:
235
235
  # /dev/mapper/vgroot-tmp.vol -> /dev/dm-9
236
236
  # First it will try to match "/dev/mapper/vgroot-tmp.vol". If there is no match it will try matching for "/dev/dm-9".
237
- "(?:#{Regexp.escape(device_real)}|#{Regexp.escape(::File.expand_path(::File.readlink(device_real), ::File.dirname(device_real)))})"
237
+ "(?:#{Regexp.escape(device_real)}|#{Regexp.escape(::File.expand_path(::TargetIO::File.readlink(device_real), ::File.dirname(device_real)))})"
238
238
  else
239
239
  Regexp.escape(device_real)
240
240
  end
@@ -261,7 +261,7 @@ class Chef
261
261
  contents = []
262
262
 
263
263
  found = false
264
- ::File.readlines("/etc/fstab").reverse_each do |line|
264
+ ::TargetIO::File.readlines("/etc/fstab").reverse_each do |line|
265
265
  if !found && line =~ /^#{device_fstab_regex}\s+#{Regexp.escape(@new_resource.mount_point)}\s/
266
266
  found = true
267
267
  if remove
@@ -276,7 +276,7 @@ class Chef
276
276
  end
277
277
  end
278
278
 
279
- ::File.open("/etc/fstab", "w") do |fstab|
279
+ ::TargetIO::File.open("/etc/fstab", "w") do |fstab|
280
280
  contents.reverse_each { |line| fstab.puts line }
281
281
  end
282
282
  else
@@ -124,11 +124,6 @@ class Chef
124
124
 
125
125
  private
126
126
 
127
- # @return [String] package name with or without anchors attached to it.
128
- def resolve_package(pkg)
129
- new_resource.anchor_package_regex ? "^#{pkg}$" : pkg
130
- end
131
-
132
127
  # @return [String] version of apt-get which is installed
133
128
  def apt_version
134
129
  @apt_version ||= shell_out("apt-get --version").stdout.match(/^apt (\S+)/)[1]
@@ -179,12 +174,10 @@ class Chef
179
174
  end
180
175
 
181
176
  def resolve_package_versions(pkg)
182
- # apt-cache considers package names as regex by default. The anchor_package_regex flag will decide whether to match name exact string or not
183
- pkg_name = resolve_package(pkg)
184
177
  current_version = nil
185
178
  candidate_version = nil
186
179
  all_versions = []
187
- run_noninteractive("apt-cache", default_release_options, "policy", pkg_name).stdout.each_line do |line|
180
+ run_noninteractive("apt-cache", default_release_options, "policy", pkg).stdout.each_line do |line|
188
181
  case line
189
182
  when /^\s{2}Installed: (.+)$/
190
183
  current_version = ( $1 != "(none)" ) ? $1 : nil
@@ -223,9 +216,7 @@ class Chef
223
216
  end
224
217
 
225
218
  def resolve_virtual_package_name(pkg)
226
- # apt-cache considers package names as regex by default. The anchor_package_regex flag will decide whether to match name exact string or not
227
- pkg_name = resolve_package(pkg)
228
- showpkg = run_noninteractive("apt-cache", "showpkg", pkg_name).stdout
219
+ showpkg = run_noninteractive("apt-cache", "showpkg", pkg).stdout
229
220
  partitions = showpkg.rpartition(/Reverse Provides: ?#{$/}/)
230
221
  return nil if partitions[0] == "" && partitions[1] == "" # not found in output
231
222
 
@@ -25,8 +25,8 @@ class Chef
25
25
  class Package
26
26
  class Bff < Chef::Provider::Package
27
27
 
28
- provides :package, os: "aix"
29
- provides :bff_package
28
+ provides :package, os: "aix", target_mode: true
29
+ provides :bff_package, target_mode: true
30
30
 
31
31
  include Chef::Mixin::GetSourceFromPackage
32
32
 
@@ -134,7 +134,7 @@ class Chef
134
134
  end
135
135
 
136
136
  def package_source_found?
137
- @package_source_found ||= new_resource.source && ::File.exist?(new_resource.source)
137
+ @package_source_found ||= new_resource.source && ::TargetIO::File.exist?(new_resource.source)
138
138
  end
139
139
 
140
140
  end
@@ -144,7 +144,11 @@ class Chef
144
144
  def check_resource_semantics!; end
145
145
 
146
146
  def get_choco_version
147
- @get_choco_version ||= powershell_exec!("#{choco_exe} --version").result
147
+ # We need a different way to get the version than by simply calling "choco --version".
148
+ # If the license file is installed (for business customers) but not the Chocolatey.Extension (because you're using the choco resource to install it)
149
+ # then you get a license error. This method bypasses that by getting the version from the exe directly instead of invoking it.
150
+ # deprecated: @get_choco_version ||= powershell_exec!("#{choco_exe} --version").result
151
+ @get_choco_version ||= powershell_exec!("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").result
148
152
  end
149
153
 
150
154
  # Choco V2 uses 'Search' for remote repositories and 'List' for local packages
@@ -167,22 +171,34 @@ class Chef
167
171
  true
168
172
  end
169
173
 
170
- # walk the collection to find peer resources to ensure that
171
- # we get as much of the cache this run as possible. Unified mode
172
- # sub-resources will, of course, be incremental with this, since we can't
173
- # grab them in advance, but even in that case we're still way, way
174
- # more efficient with our queries...
174
+ # Find the set of packages to ask the chocolatey server about
175
+ #
176
+ # if walk_resource_tree is true, this finds _all_ of the packages that
177
+ # we have referenced anywhere in our recipes - this is so we can
178
+ # attempt to query them all in a single transaction. However,
179
+ # currently we don't do that - see the comment on available_packages
180
+ # for details of the why, but the TL;DR is that the public chocolatey
181
+ # servers do not support `or` type queries properly.
182
+ #
183
+ # If walk_resource_tree is false, we don't do any of that - we just filter
184
+ # the package list based on cache data. This is the default due to reasons
185
+ # explained in the comment on available_packages - the goal is to eventually
186
+ # turn this back on, hence the default false parameter here.
175
187
  #
176
188
  # @return [Array] List of chocolatey packages referenced in the run list
177
- def collect_package_requests(ignore_list: [])
189
+ def collect_package_requests(ignore_list: [], walk_resource_tree: false)
178
190
  return ["*"] if new_resource.bulk_query || Chef::Config[:always_use_bulk_chocolatey_package_list]
179
191
 
180
- # Get to the root of the resource collection
181
- rc = run_context.parent_run_context || run_context
182
- rc = rc.parent_run_context while rc.parent_run_context
192
+ if walk_resource_tree
193
+ # Get to the root of the resource collection
194
+ rc = run_context.parent_run_context || run_context
195
+ rc = rc.parent_run_context while rc.parent_run_context
183
196
 
184
- package_collection = package_name_array
185
- package_collection += nested_package_resources(rc.resource_collection)
197
+ package_collection = package_name_array
198
+ package_collection += nested_package_resources(rc.resource_collection)
199
+ else
200
+ package_collection = package_name_array
201
+ end
186
202
  # downcase the array and uniq. sorted for easier testing...
187
203
  package_collection.uniq.sort.filter { |pkg| !ignore_list.include?(pkg) }
188
204
  end
@@ -339,22 +355,33 @@ class Chef
339
355
  @@choco_available_packages[new_resource.list_options] = {}
340
356
  end
341
357
 
342
- # Attempt to get everything we need in a single query.
343
- # Grab 25 packages at a time at most, to avoid hurting servers too badly
358
+ # This would previously grab 25 packages at a time, which previously worked - however,
359
+ # upstream changed and it turns out this was only working by accident - see
360
+ # https://github.com/chocolatey/choco/issues/2116 for this. So the TL;DR ends up
361
+ # being that this can be re-enabled when the chocolatey server actually supports an
362
+ # or operator. So it makes sense to leave the logic here for this split, while we
363
+ # work with upstream to get this to be a working feature there
364
+ #
365
+ # Foot guns: there is a --id-starts-with for chocolatey, which you'd think would work,
366
+ # but that actually fails on public chocolatey as well, because it seems to do the filtering
367
+ # locally. Which means it too will omit a lot of results (this is also corroborated by
368
+ # the 2116 issue above).
344
369
  #
345
- # For v1 we actually used to grab the entire list of packages, but we found
346
- # that it could cause undue load on really large package lists
370
+ # collect_package_requests, however, continues to be useful here because it filters
371
+ # the already cached things from the list. However, for now it will no longer walk the
372
+ # resource tree until 2116 can be sorted out. When we regain that ability, we should
373
+ # re-evaluate this, since it does save a LOT of API requests!
347
374
  collect_package_requests(
348
375
  ignore_list: @@choco_available_packages[new_resource.list_options].keys
349
- ).each_slice(25) do |pkg_set|
376
+ ).each do |pkg_set|
350
377
  available_versions =
351
378
  begin
352
379
  cmd = [ query_command, "-r" ]
353
380
 
354
381
  # Chocolatey doesn't actually take a wildcard for this query, however
355
382
  # it will return all packages when using '*' as a query
356
- unless pkg_set == ["*"]
357
- cmd += pkg_set
383
+ unless pkg_set == "*"
384
+ cmd << pkg_set
358
385
  end
359
386
  cmd += common_options
360
387
  cmd.push( new_resource.list_options ) if new_resource.list_options
@@ -383,10 +410,12 @@ class Chef
383
410
  #
384
411
  # @return [Hash] name-to-version mapping of installed packages
385
412
  def installed_packages
386
- if new_resource.use_choco_list == false || !Chef::Config[:always_use_choco_list]
387
- installed_packages_via_choco
388
- else
413
+ # Logic here must be either use_choco_list is false _and_ always_use_choco_list is
414
+ # falsy, since the global overrides the local
415
+ if new_resource.use_choco_list == false && !Chef::Config[:always_use_choco_list]
389
416
  installed_packages_via_disk
417
+ else
418
+ installed_packages_via_choco
390
419
  end
391
420
  end
392
421
 
@@ -413,8 +442,8 @@ class Chef
413
442
  # that contains all possible package folders, and so we push our
414
443
  # guess to the front as an optimization.
415
444
  target_dirs << targets.first.downcase if targets.length == 1
416
- if targets.downcase is_a?(String)
417
- target_dirs << targets
445
+ if targets.is_a?(String)
446
+ target_dirs << targets.downcase
418
447
  end
419
448
  target_dirs += get_local_pkg_dirs(choco_lib_path)
420
449
  fetch_package_versions(choco_lib_path, target_dirs, targets)
@@ -465,6 +494,7 @@ class Chef
465
494
  # Fetch the local package versions from chocolatey
466
495
  def fetch_package_versions(base_dir, target_dirs, targets)
467
496
  pkg_versions = {}
497
+ targets = [targets] if targets.is_a?(String)
468
498
  target_dirs.each do |dir|
469
499
  pkg_versions.merge!(get_pkg_data(::File.join(base_dir, dir)))
470
500
  # return early if we found the single package version we were looking for
@@ -29,7 +29,7 @@ class Chef
29
29
  DPKG_INSTALLED = /^Status: install ok installed/.freeze
30
30
  DPKG_VERSION = /^Version: (.+)$/.freeze
31
31
 
32
- provides :dpkg_package
32
+ provides :dpkg_package, target_mode: true
33
33
 
34
34
  use_multipackage_api
35
35
  use_package_name_for_source
@@ -146,14 +146,14 @@ class Chef
146
146
  #
147
147
  # @return [Boolean] True if all sources exist
148
148
  def source_files_exist?
149
- resolved_source_array.all? { |s| s && ::File.exist?(s) }
149
+ resolved_source_array.all? { |s| s && ::TargetIO::File.exist?(s) }
150
150
  end
151
151
 
152
152
  # Helper to return all the names of the missing sources for error messages.
153
153
  #
154
154
  # @return [Array<String>] Array of missing sources
155
155
  def missing_sources
156
- resolved_source_array.select { |s| s.nil? || !::File.exist?(s) }
156
+ resolved_source_array.select { |s| s.nil? || !::TargetIO::File.exist?(s) }
157
157
  end
158
158
 
159
159
  def current_package_name_array
@@ -30,7 +30,7 @@ class Chef
30
30
 
31
31
  module PortsHelper
32
32
  def supports_ports?
33
- ::File.exist?("/usr/ports/Makefile")
33
+ ::TargetIO::File.exist?("/usr/ports/Makefile")
34
34
  end
35
35
 
36
36
  def port_dir(port)
@@ -15,7 +15,6 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
- require_relative "../../http/simple"
19
18
  require_relative "../../json_compat"
20
19
  require_relative "../../exceptions"
21
20
  require_relative "../package"
@@ -27,7 +26,7 @@ class Chef
27
26
  class Habitat < Chef::Provider::Package
28
27
  use_multipackage_api
29
28
  use "../../resource/habitat/habitat_shared"
30
- provides :habitat_package
29
+ provides :habitat_package, target_mode: true
31
30
 
32
31
  def load_current_resource
33
32
  @current_resource = Chef::Resource::HabitatPackage.new(new_resource.name)
@@ -40,6 +39,9 @@ class Chef
40
39
  end
41
40
 
42
41
  def install_package(names, versions)
42
+ # License acceptance needed outside of local Chef Client
43
+ shell_out!("hab license accept") if Chef::Config.target_mode?
44
+
43
45
  names.zip(versions).map do |n, v|
44
46
  opts = ["pkg", "install", "--channel", new_resource.channel, "--url", new_resource.bldr_url]
45
47
  opts += ["--auth", new_resource.auth_token] if new_resource.auth_token
@@ -120,7 +122,7 @@ class Chef
120
122
 
121
123
  def http
122
124
  # FIXME: use SimpleJSON when the depot mime-type is fixed
123
- @http ||= Chef::HTTP::Simple.new(new_resource.bldr_url.to_s)
125
+ @http ||= TargetIO::HTTP.new(new_resource.bldr_url.to_s)
124
126
  end
125
127
 
126
128
  def candidate_versions
@@ -26,8 +26,8 @@ class Chef
26
26
  class Package
27
27
  class Ips < Chef::Provider::Package
28
28
 
29
- provides :package, platform: %w{openindiana omnios solaris2}
30
- provides :ips_package
29
+ provides :package, platform: %w{openindiana omnios solaris2}, target_mode: true
30
+ provides :ips_package, target_mode: true
31
31
 
32
32
  attr_accessor :virtual
33
33
 
@@ -30,8 +30,8 @@ class Chef
30
30
  class Package
31
31
  class Openbsd < Chef::Provider::Package
32
32
 
33
- provides :package, os: "openbsd"
34
- provides :openbsd_package
33
+ provides :package, os: "openbsd", target_mode: true
34
+ provides :openbsd_package, target_mode: true
35
35
 
36
36
  include Chef::Mixin::ShellOut
37
37
  include Chef::Mixin::GetSourceFromPackage
@@ -129,6 +129,7 @@ class Chef
129
129
  end
130
130
  end
131
131
 
132
+ # Target Mode limitation: ENV["PKG_PATH"] cannot be evaluated, as remote commands are not run in a standard shell
132
133
  def pkg_path
133
134
  ENV["PKG_PATH"] || "http://ftp.OpenBSD.org/pub/#{node["kernel"]["name"]}/#{node["kernel"]["release"]}/packages/#{node["kernel"]["machine"]}/"
134
135
  end
@@ -24,8 +24,8 @@ class Chef
24
24
  class Package
25
25
  class Pacman < Chef::Provider::Package
26
26
 
27
- provides :package, platform: "arch"
28
- provides :pacman_package
27
+ provides :package, platform: "arch", target_mode: true
28
+ provides :pacman_package, target_mode: true
29
29
 
30
30
  use_multipackage_api
31
31
  allow_nils
@@ -37,8 +37,8 @@ class Chef
37
37
 
38
38
  repos = %w{extra core community}
39
39
 
40
- if ::File.exist?("/etc/pacman.conf")
41
- pacman = ::File.read("/etc/pacman.conf")
40
+ if ::TargetIO::File.exist?("/etc/pacman.conf")
41
+ pacman = ::TargetIO::File.read("/etc/pacman.conf")
42
42
  repos = pacman.scan(/\[(.+)\]/).flatten
43
43
  end
44
44
 
@@ -24,8 +24,8 @@ class Chef
24
24
  class Package
25
25
  class Paludis < Chef::Provider::Package
26
26
 
27
- provides :package, platform: "exherbo"
28
- provides :paludis_package
27
+ provides :package, platform: "exherbo", target_mode: true
28
+ provides :paludis_package, target_mode: true
29
29
 
30
30
  def load_current_resource
31
31
  @current_resource = Chef::Resource::Package.new(new_resource.package_name)
@@ -38,7 +38,7 @@ class Chef
38
38
 
39
39
  globsafe_category = category ? Chef::Util::PathHelper.escape_glob_dir(category) : nil
40
40
  globsafe_pkg = Chef::Util::PathHelper.escape_glob_dir(pkg)
41
- possibilities = Dir["/var/db/pkg/#{globsafe_category || "*"}/#{globsafe_pkg}-*"].map { |d| d.sub(%r{/var/db/pkg/}, "") }
41
+ possibilities = TargetIO::Dir["/var/db/pkg/#{globsafe_category || "*"}/#{globsafe_pkg}-*"].map { |d| d.sub(%r{/var/db/pkg/}, "") }
42
42
  versions = possibilities.map do |entry|
43
43
  if entry =~ %r{[^/]+/#{Regexp.escape(pkg)}\-(\d[\.\d]*[a-z]?((_(alpha|beta|pre|rc|p)\d*)*)?(-r\d+)?)}
44
44
  [$&, $1]
@@ -127,6 +127,7 @@ class Chef
127
127
  command.push("-RequiredVersion #{version}") if version
128
128
  command.push("-Source #{new_resource.source}") if new_resource.source && cmdlet_name =~ Regexp.union(/Install-Package/, /Find-Package/)
129
129
  command.push("-SkipPublisherCheck") if new_resource.skip_publisher_check && cmdlet_name !~ /Find-Package/
130
+ command.push("-AllowClobber") if new_resource.allow_clobber
130
131
  if new_resource.options && cmdlet_name !~ Regexp.union(/Get-Package/, /Find-Package/)
131
132
  new_resource.options.each do |arg|
132
133
  command.push(arg) unless command.include?(arg)
@@ -24,7 +24,7 @@ class Chef
24
24
  class Provider
25
25
  class Package
26
26
  class Rpm < Chef::Provider::Package
27
- provides :rpm_package
27
+ provides :rpm_package, target_mode: true
28
28
 
29
29
  include Chef::Mixin::GetSourceFromPackage
30
30
 
@@ -51,7 +51,7 @@ class Chef
51
51
  current_resource.package_name(new_resource.package_name)
52
52
 
53
53
  if new_resource.source
54
- unless uri_scheme?(new_resource.source) || ::File.exist?(new_resource.source)
54
+ unless uri_scheme?(new_resource.source) || ::TargetIO::File.exist?(new_resource.source)
55
55
  @package_source_exists = false
56
56
  return
57
57
  end
@@ -29,8 +29,8 @@ class Chef
29
29
  class SmartOS < Chef::Provider::Package
30
30
  attr_accessor :is_virtual_package
31
31
 
32
- provides :package, platform: "smartos"
33
- provides :smartos_package
32
+ provides :package, platform: "smartos", target_mode: true
33
+ provides :smartos_package, target_mode: true
34
34
 
35
35
  def load_current_resource
36
36
  logger.trace("#{new_resource} loading current resource")
@@ -218,6 +218,7 @@ class Chef
218
218
  waiting = true
219
219
  while waiting
220
220
  result = get_change_id(id)
221
+
221
222
  case result["result"]["status"]
222
223
  when "Do", "Doing", "Undoing", "Undo"
223
224
  # Continue
@@ -329,7 +330,7 @@ class Chef
329
330
  def generate_snap_json(snap_names, action, channel, options, revision = nil)
330
331
  request = {
331
332
  "action" => action,
332
- "snaps" => snap_names,
333
+ "snaps" => Array(snap_names),
333
334
  }
334
335
  if %w{install refresh switch}.include?(action) && channel
335
336
  request["channel"] = channel
@@ -0,0 +1,79 @@
1
+ #
2
+ # Author:: T.Heinen (<thomas.heinen@gmail.com>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "snap"
20
+
21
+ class Chef
22
+ class Provider
23
+ class Package
24
+ class SnapTM < Chef::Provider::Package::Snap
25
+ provides :snap_package, target_mode: true
26
+
27
+ def install_package(names, versions)
28
+ if new_resource.source
29
+ install_snap_from_source(names, new_resource.source)
30
+ else
31
+ Array(names).each do |snap|
32
+ snap_options = new_resource.options
33
+
34
+ snapctl([
35
+ "install",
36
+ "--channel=#{new_resource.channel}",
37
+ snap_options&.map { |opt| "--#{opt}" },
38
+ snap,
39
+ ].flatten.compact)
40
+ end
41
+ end
42
+ end
43
+
44
+ def remove_package(names, versions)
45
+ Array(names).each do |snap|
46
+ snapctl([
47
+ "remove",
48
+ snap,
49
+ ])
50
+ end
51
+ end
52
+
53
+ def snapctl(*args)
54
+ # Deferred execution can result in exit code 10
55
+ shell_out!("snap", *args, returns: [0, 10])
56
+ end
57
+
58
+ def get_latest_package_version(name, channel)
59
+ cmd = shell_out("snap info #{name}")
60
+ latest = cmd.stdout.lines.detect { |l| l.start_with? " latest/#{new_resource.channel}:" }
61
+ return unless latest
62
+
63
+ latest.split.at(1)
64
+ end
65
+
66
+ def get_installed_package_by_name(name)
67
+ cmd = shell_out("snap info #{name}")
68
+ installed = cmd.stdout.lines.detect { |l| l.start_with? "installed:" }
69
+ return {} unless installed
70
+
71
+ {
72
+ "name" => name,
73
+ "version" => installed.split.at(1),
74
+ }
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -26,7 +26,7 @@ class Chef
26
26
 
27
27
  include Chef::Mixin::GetSourceFromPackage
28
28
 
29
- provides :solaris_package
29
+ provides :solaris_package, target_mode: true
30
30
 
31
31
  # def initialize(*args)
32
32
  # super
@@ -50,7 +50,7 @@ class Chef
50
50
  current_resource.package_name(new_resource.package_name)
51
51
 
52
52
  if new_resource.source
53
- @package_source_found = ::File.exist?(new_resource.source)
53
+ @package_source_found = ::TargetIO::File.exist?(new_resource.source)
54
54
  if @package_source_found
55
55
  logger.trace("#{new_resource} checking pkg status")
56
56
  shell_out("pkginfo", "-l", "-d", new_resource.source, new_resource.package_name).stdout.each_line do |line|
@@ -101,7 +101,7 @@ class Chef
101
101
  def install_package(name, version)
102
102
  logger.trace("#{new_resource} package install options: #{options}")
103
103
  if options.nil?
104
- command = if ::File.directory?(new_resource.source) # CHEF-4469
104
+ command = if ::TargetIO::File.directory?(new_resource.source) # CHEF-4469
105
105
  [ "pkgadd", "-n", "-d", new_resource.source, new_resource.package_name ]
106
106
  else
107
107
  [ "pkgadd", "-n", "-d", new_resource.source, "all" ]
@@ -109,7 +109,7 @@ class Chef
109
109
  shell_out!(command)
110
110
  logger.trace("#{new_resource} installed version #{new_resource.version} from: #{new_resource.source}")
111
111
  else
112
- command = if ::File.directory?(new_resource.source) # CHEF-4469
112
+ command = if ::TargetIO::File.directory?(new_resource.source) # CHEF-4469
113
113
  [ "pkgadd", "-n", options, "-d", new_resource.source, new_resource.package_name ]
114
114
  else
115
115
  [ "pkgadd", "-n", options, "-d", new_resource.source, "all" ]