chef 18.9.4 → 18.11.11

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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +16 -12
  3. data/README.md +0 -1
  4. data/Rakefile +21 -5
  5. data/chef-universal-mingw-ucrt.gemspec +4 -2
  6. data/chef.gemspec +17 -14
  7. data/lib/chef/application/apply.rb +1 -1
  8. data/lib/chef/application/base.rb +4 -4
  9. data/lib/chef/application/exit_code.rb +1 -1
  10. data/lib/chef/chef_fs/command_line.rb +4 -4
  11. data/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb +1 -1
  12. data/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb +2 -3
  13. data/lib/chef/client.rb +2 -3
  14. data/lib/chef/compliance/fetcher/chef_server.rb +1 -1
  15. data/lib/chef/compliance/reporter/cli.rb +2 -2
  16. data/lib/chef/compliance/runner.rb +19 -1
  17. data/lib/chef/dsl/chef_vault.rb +1 -1
  18. data/lib/chef/dsl/rest_resource.rb +223 -16
  19. data/lib/chef/encrypted_data_bag_item/decryptor.rb +1 -5
  20. data/lib/chef/environment.rb +1 -1
  21. data/lib/chef/exceptions.rb +1 -1
  22. data/lib/chef/file_cache.rb +1 -5
  23. data/lib/chef/formatters/error_description.rb +8 -1
  24. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +1 -1
  25. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
  26. data/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb +1 -1
  27. data/lib/chef/group.rb +1 -1
  28. data/lib/chef/handler/slow_report.rb +1 -1
  29. data/lib/chef/http/authenticator.rb +25 -12
  30. data/lib/chef/mixin/api_version_request_handling.rb +1 -1
  31. data/lib/chef/mixin/powershell_type_coercions.rb +2 -2
  32. data/lib/chef/mixin/securable.rb +2 -2
  33. data/lib/chef/mixin/template.rb +25 -3
  34. data/lib/chef/mixin/versioned_api.rb +1 -1
  35. data/lib/chef/monkey_patches/net-http.rb +8 -8
  36. data/lib/chef/monkey_patches/reline-windows.rb +116 -0
  37. data/lib/chef/property.rb +1 -1
  38. data/lib/chef/provider/cron.rb +1 -1
  39. data/lib/chef/provider/directory.rb +11 -0
  40. data/lib/chef/provider/dsc_resource.rb +2 -2
  41. data/lib/chef/provider/file/content.rb +3 -2
  42. data/lib/chef/provider/file.rb +1 -1
  43. data/lib/chef/provider/git.rb +1 -1
  44. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  45. data/lib/chef/provider/ifconfig/redhat.rb +1 -1
  46. data/lib/chef/provider/mount/linux.rb +1 -1
  47. data/lib/chef/provider/mount/windows.rb +4 -4
  48. data/lib/chef/provider/package/chocolatey.rb +78 -19
  49. data/lib/chef/provider/package/dnf/dnf_helper.py +355 -65
  50. data/lib/chef/provider/package/dnf/python_helper.rb +7 -4
  51. data/lib/chef/provider/package/dnf.rb +25 -6
  52. data/lib/chef/provider/package/homebrew.rb +3 -3
  53. data/lib/chef/provider/package/rubygems.rb +25 -2
  54. data/lib/chef/provider/package/snap.rb +1 -1
  55. data/lib/chef/provider/package/windows/exe.rb +1 -1
  56. data/lib/chef/provider/package/windows/msi.rb +1 -1
  57. data/lib/chef/provider/package/yum/rpm_utils.rb +2 -2
  58. data/lib/chef/provider/package/yum.rb +1 -1
  59. data/lib/chef/provider/powershell_script.rb +84 -84
  60. data/lib/chef/provider/service/debian.rb +2 -4
  61. data/lib/chef/provider/user/dscl.rb +1 -1
  62. data/lib/chef/provider/user/mac.rb +1 -1
  63. data/lib/chef/provider/windows_script.rb +1 -1
  64. data/lib/chef/resource/_rest_resource.rb +9 -7
  65. data/lib/chef/resource/alternatives.rb +41 -41
  66. data/lib/chef/resource/apt_package.rb +31 -31
  67. data/lib/chef/resource/apt_preference.rb +22 -22
  68. data/lib/chef/resource/apt_repository.rb +2 -2
  69. data/lib/chef/resource/archive_file.rb +52 -18
  70. data/lib/chef/resource/bash.rb +129 -129
  71. data/lib/chef/resource/bff_package.rb +15 -15
  72. data/lib/chef/resource/breakpoint.rb +44 -44
  73. data/lib/chef/resource/cab_package.rb +22 -22
  74. data/lib/chef/resource/chef_client_config.rb +251 -89
  75. data/lib/chef/resource/chef_client_cron.rb +18 -18
  76. data/lib/chef/resource/chef_client_launchd.rb +1 -1
  77. data/lib/chef/resource/chef_client_scheduled_task.rb +31 -31
  78. data/lib/chef/resource/chef_client_systemd_timer.rb +16 -16
  79. data/lib/chef/resource/chef_client_trusted_certificate.rb +28 -28
  80. data/lib/chef/resource/chef_handler.rb +107 -107
  81. data/lib/chef/resource/chef_vault_secret.rb +1 -1
  82. data/lib/chef/resource/chocolatey_config.rb +14 -14
  83. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  84. data/lib/chef/resource/chocolatey_installer.rb +60 -42
  85. data/lib/chef/resource/chocolatey_package.rb +1 -1
  86. data/lib/chef/resource/chocolatey_source.rb +15 -15
  87. data/lib/chef/resource/cron/_cron_shared.rb +0 -2
  88. data/lib/chef/resource/cron/cron.rb +70 -70
  89. data/lib/chef/resource/csh.rb +5 -5
  90. data/lib/chef/resource/directory.rb +6 -6
  91. data/lib/chef/resource/dpkg_package.rb +3 -3
  92. data/lib/chef/resource/group.rb +28 -28
  93. data/lib/chef/resource/habitat/habitat_package.rb +80 -80
  94. data/lib/chef/resource/habitat/habitat_sup.rb +93 -95
  95. data/lib/chef/resource/habitat/habitat_sup_systemd.rb +10 -10
  96. data/lib/chef/resource/habitat/habitat_sup_windows.rb +3 -3
  97. data/lib/chef/resource/habitat_config.rb +13 -13
  98. data/lib/chef/resource/habitat_install.rb +17 -17
  99. data/lib/chef/resource/habitat_service.rb +1 -1
  100. data/lib/chef/resource/habitat_user_toml.rb +12 -12
  101. data/lib/chef/resource/helpers/cron_validations.rb +2 -2
  102. data/lib/chef/resource/homebrew_cask.rb +1 -1
  103. data/lib/chef/resource/homebrew_package.rb +20 -20
  104. data/lib/chef/resource/homebrew_tap.rb +1 -1
  105. data/lib/chef/resource/hostname.rb +2 -2
  106. data/lib/chef/resource/http_request.rb +2 -2
  107. data/lib/chef/resource/ifconfig.rb +34 -34
  108. data/lib/chef/resource/inspec_input.rb +37 -37
  109. data/lib/chef/resource/inspec_waiver.rb +63 -63
  110. data/lib/chef/resource/inspec_waiver_file_entry.rb +25 -25
  111. data/lib/chef/resource/ksh.rb +5 -5
  112. data/lib/chef/resource/launchd.rb +2 -2
  113. data/lib/chef/resource/link.rb +8 -8
  114. data/lib/chef/resource/locale.rb +6 -6
  115. data/lib/chef/resource/log.rb +4 -4
  116. data/lib/chef/resource/mdadm.rb +36 -36
  117. data/lib/chef/resource/mount.rb +3 -3
  118. data/lib/chef/resource/msu_package.rb +1 -1
  119. data/lib/chef/resource/ohai.rb +32 -32
  120. data/lib/chef/resource/ohai_hint.rb +24 -24
  121. data/lib/chef/resource/openssl_ec_private_key.rb +2 -2
  122. data/lib/chef/resource/openssl_ec_public_key.rb +2 -2
  123. data/lib/chef/resource/openssl_rsa_private_key.rb +1 -1
  124. data/lib/chef/resource/openssl_rsa_public_key.rb +2 -2
  125. data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
  126. data/lib/chef/resource/openssl_x509_crl.rb +15 -15
  127. data/lib/chef/resource/openssl_x509_request.rb +2 -2
  128. data/lib/chef/resource/osx_profile.rb +54 -54
  129. data/lib/chef/resource/package.rb +6 -6
  130. data/lib/chef/resource/perl.rb +5 -5
  131. data/lib/chef/resource/plist.rb +4 -4
  132. data/lib/chef/resource/powershell_package_source.rb +12 -12
  133. data/lib/chef/resource/python.rb +4 -4
  134. data/lib/chef/resource/reboot.rb +5 -5
  135. data/lib/chef/resource/registry_key.rb +81 -81
  136. data/lib/chef/resource/remote_file.rb +72 -72
  137. data/lib/chef/resource/resource_notification.rb +4 -4
  138. data/lib/chef/resource/rhsm_errata_level.rb +1 -1
  139. data/lib/chef/resource/rhsm_register.rb +2 -2
  140. data/lib/chef/resource/scm/git.rb +79 -79
  141. data/lib/chef/resource/scm/subversion.rb +9 -9
  142. data/lib/chef/resource/script.rb +3 -3
  143. data/lib/chef/resource/selinux_boolean.rb +12 -12
  144. data/lib/chef/resource/selinux_fcontext.rb +21 -21
  145. data/lib/chef/resource/selinux_install.rb +18 -18
  146. data/lib/chef/resource/selinux_login.rb +11 -11
  147. data/lib/chef/resource/selinux_module.rb +16 -16
  148. data/lib/chef/resource/selinux_permissive.rb +9 -9
  149. data/lib/chef/resource/selinux_port.rb +16 -16
  150. data/lib/chef/resource/selinux_state.rb +28 -28
  151. data/lib/chef/resource/selinux_user.rb +14 -14
  152. data/lib/chef/resource/service.rb +5 -5
  153. data/lib/chef/resource/snap_package.rb +16 -16
  154. data/lib/chef/resource/ssh_known_hosts_entry.rb +10 -10
  155. data/lib/chef/resource/sudo.rb +68 -68
  156. data/lib/chef/resource/swap_file.rb +12 -12
  157. data/lib/chef/resource/sysctl.rb +42 -42
  158. data/lib/chef/resource/systemd_unit.rb +38 -38
  159. data/lib/chef/resource/timezone.rb +16 -16
  160. data/lib/chef/resource/user/mac_user.rb +3 -3
  161. data/lib/chef/resource/user.rb +6 -6
  162. data/lib/chef/resource/user_ulimit.rb +22 -22
  163. data/lib/chef/resource/windows_ad_join.rb +25 -25
  164. data/lib/chef/resource/windows_audit_policy.rb +34 -34
  165. data/lib/chef/resource/windows_auto_run.rb +8 -8
  166. data/lib/chef/resource/windows_certificate.rb +20 -20
  167. data/lib/chef/resource/windows_defender.rb +22 -22
  168. data/lib/chef/resource/windows_defender_exclusion.rb +17 -17
  169. data/lib/chef/resource/windows_env.rb +6 -6
  170. data/lib/chef/resource/windows_feature.rb +42 -42
  171. data/lib/chef/resource/windows_feature_dism.rb +8 -8
  172. data/lib/chef/resource/windows_feature_powershell.rb +20 -20
  173. data/lib/chef/resource/windows_firewall_profile.rb +28 -28
  174. data/lib/chef/resource/windows_firewall_rule.rb +47 -47
  175. data/lib/chef/resource/windows_font.rb +7 -7
  176. data/lib/chef/resource/windows_package.rb +59 -59
  177. data/lib/chef/resource/windows_pagefile.rb +29 -29
  178. data/lib/chef/resource/windows_path.rb +12 -12
  179. data/lib/chef/resource/windows_printer.rb +28 -28
  180. data/lib/chef/resource/windows_printer_port.rb +21 -21
  181. data/lib/chef/resource/windows_security_policy.rb +23 -23
  182. data/lib/chef/resource/windows_service.rb +108 -108
  183. data/lib/chef/resource/windows_share.rb +19 -19
  184. data/lib/chef/resource/windows_shortcut.rb +7 -7
  185. data/lib/chef/resource/windows_task.rb +105 -105
  186. data/lib/chef/resource/windows_uac.rb +14 -14
  187. data/lib/chef/resource/windows_update_settings.rb +27 -27
  188. data/lib/chef/resource/windows_user_privilege.rb +59 -59
  189. data/lib/chef/resource/windows_workgroup.rb +12 -12
  190. data/lib/chef/resource/yum_package.rb +1 -1
  191. data/lib/chef/resource/yum_repository.rb +36 -36
  192. data/lib/chef/resource.rb +1 -1
  193. data/lib/chef/resource_collection/resource_set.rb +2 -3
  194. data/lib/chef/resource_inspector.rb +1 -2
  195. data/lib/chef/run_context.rb +2 -2
  196. data/lib/chef/runner.rb +1 -1
  197. data/lib/chef/secret_fetcher/akeyless_vault.rb +0 -1
  198. data/lib/chef/secret_fetcher/hashi_vault.rb +0 -1
  199. data/lib/chef/shell/ext.rb +20 -20
  200. data/lib/chef/shell/shell_session.rb +1 -1
  201. data/lib/chef/shell.rb +7 -0
  202. data/lib/chef/version.rb +1 -1
  203. data/lib/chef/version_constraint.rb +1 -1
  204. data/lib/chef/win32/file/version_info.rb +1 -1
  205. metadata +63 -38
@@ -0,0 +1,116 @@
1
+ # Author:: Chef Software Inc.
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # == Background
18
+ #
19
+ # On Windows, Reline's process_key_event emits an ESC byte (0x1B) before every
20
+ # character when the :ALT control key flag is set. This is correct for true
21
+ # Alt key combos (Meta sequences), but AltGr on European keyboards – most
22
+ # notably German layouts – is reported by Windows as Ctrl+Alt (RIGHT_CTRL +
23
+ # RIGHT_ALT pressed simultaneously). Characters that require AltGr, such as
24
+ # { } [ ] @ ~ | \, therefore receive both :CTRL and :ALT flags, causing Reline to
25
+ # emit an ESC prefix. In a terminal the result looks like ^[{ instead of {.
26
+ #
27
+ # The corrupt input leaves IRB's parser in an open-string/block state which
28
+ # re-draws continuation prompts endlessly when multi-line blocks are pasted,
29
+ # making chef-shell unusable for German (and many other European) keyboard users.
30
+ #
31
+ # == Fix
32
+ #
33
+ # Only emit the ESC Meta prefix when :ALT is set WITHOUT :CTRL. When both
34
+ # flags are present the keypress is AltGr-originated and the raw character
35
+ # bytes are sufficient and correct.
36
+ #
37
+ # == Affected versions
38
+ #
39
+ # Verified against Reline <= 0.3.x (shipped with Ruby 3.1.x in chef-foundation).
40
+ # The issue was resolved upstream in Reline 0.3.2 / irb 1.6.2 (Ruby 3.2+),
41
+ # so the patch is guarded to apply only when the installed Reline version is
42
+ # affected.
43
+ #
44
+ # == References
45
+ #
46
+ # * Upstream report: https://github.com/ruby/reline/issues/475
47
+ # * Chef PR #9267 (Ruby 2.7 IRB fixes, introduced multiline/singleline wiring)
48
+ # * Chef PR #14919 (Prompt consistency fix for left-arrow on Ruby 3.1/3.2)
49
+ # * Chef PR #15336 (IRB @ALIASES removal compat)
50
+
51
+ if Gem.win_platform? && defined?(Reline::Windows)
52
+
53
+ # Only patch versions where the bug is present. Reline 0.3.2 fixed it
54
+ # upstream. Gem::Version comparison is safe even when reline is a stdlib
55
+ # default gem without a Gemspec entry in loaded_specs.
56
+ reline_version = begin
57
+ Gem::Version.new(Reline::VERSION)
58
+ rescue StandardError
59
+ Gem::Version.new("0")
60
+ end
61
+
62
+ if reline_version < Gem::Version.new("0.3.2")
63
+ Chef::Log.debug("chef-shell: applying Reline::Windows AltGr monkey patch (reline #{Reline::VERSION})")
64
+
65
+ class Reline::Windows
66
+ class << self
67
+ # Reopen process_key_event and change only the ESC-emission guard.
68
+ # All other behavior – surrogate pair handling, KEY_MAP matching, bare
69
+ # control-key suppression – is preserved verbatim from the original.
70
+ def process_key_event(repeat_count, virtual_key_code, virtual_scan_code, char_code, control_key_state)
71
+ # ---- surrogate pair handling (unchanged) --------------------------------
72
+ if char_code.between?(0xD800, 0xDBFF)
73
+ @@hsg = char_code
74
+ return
75
+ end
76
+
77
+ if char_code.between?(0xDC00, 0xDFFF)
78
+ if @@hsg
79
+ char_code = 0x10000 + (@@hsg - 0xD800) * 0x400 + char_code - 0xDC00
80
+ @@hsg = nil
81
+ else
82
+ return # low-surrogate without preceding high-surrogate – ignore
83
+ end
84
+ else
85
+ @@hsg = nil # discard stale high-surrogate
86
+ end
87
+ # -------------------------------------------------------------------------
88
+
89
+ key = KeyEventRecord.new(virtual_key_code, char_code, control_key_state)
90
+
91
+ # KEY_MAP takes priority (arrow keys, Delete, Home, End, Tab, etc.)
92
+ match = KEY_MAP.find { |args,| key.matches?(**args) }
93
+ unless match.nil?
94
+ @@output_buf.concat(match.last)
95
+ return
96
+ end
97
+
98
+ # Suppress bare modifier-only keypresses (no printable character)
99
+ return if key.char_code == 0 && key.control_keys.any?
100
+
101
+ # ---- THE FIX -----------------------------------------------------------
102
+ # Original: @@output_buf.push("\e".ord) if key.control_keys.include?(:ALT)
103
+ #
104
+ # AltGr on European keyboards reports as Ctrl+Alt (both :CTRL and :ALT
105
+ # present). Only emit the ESC Meta prefix when Alt is pressed WITHOUT
106
+ # Ctrl – i.e. a genuine Meta/Alt sequence, not an AltGr character.
107
+ alt_without_ctrl = key.control_keys.include?(:ALT) && !key.control_keys.include?(:CTRL)
108
+ @@output_buf.push("\e".ord) if alt_without_ctrl
109
+ # -------------------------------------------------------------------------
110
+
111
+ @@output_buf.concat(key.char.bytes)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
data/lib/chef/property.rb CHANGED
@@ -698,7 +698,7 @@ class Chef
698
698
  # Weeding out class methods avoids unnecessary deprecations such Chef::Resource
699
699
  # defining a `name` property when there's an already-existing `name` method
700
700
  # for a Module.
701
- return false unless declared_in.instance_methods.include?(name)
701
+ return false unless declared_in.method_defined?(name)
702
702
 
703
703
  # Only emit deprecations for some well-known classes. This will still
704
704
  # allow more advanced users to subclass their own custom resources and
@@ -27,7 +27,7 @@ class Chef
27
27
  SPECIAL_TIME_VALUES = %i{reboot yearly annually monthly weekly daily midnight hourly}.freeze
28
28
  CRON_ATTRIBUTES = %i{minute hour day month weekday time command mailto path shell home environment}.freeze
29
29
  CRON_PATTERN = %r{\A([-0-9*,/]+)\s([-0-9*,/]+)\s([-0-9*,/]+)\s([-0-9*,/]+|[a-zA-Z]{3})\s([-0-9*,/]+|[a-zA-Z]{3})\s(.*)}.freeze
30
- SPECIAL_PATTERN = /\A(@(#{SPECIAL_TIME_VALUES.join('|')}))\s(.*)/.freeze
30
+ SPECIAL_PATTERN = /\A(@(#{SPECIAL_TIME_VALUES.join("|")}))\s(.*)/.freeze
31
31
  ENV_PATTERN = /\A(\S+)=(\S*)/.freeze
32
32
  ENVIRONMENT_PROPERTIES = %w{MAILTO PATH SHELL HOME}.freeze
33
33
 
@@ -65,6 +65,17 @@ class Chef
65
65
  a.whyrun("Assuming directory #{parent_directory} would have been created")
66
66
  end
67
67
 
68
+ requirements.assert(:create) do |a|
69
+ a.assertion do
70
+ if ::File.exist?(new_resource.path)
71
+ ::File.directory?(new_resource.path)
72
+ else
73
+ true
74
+ end
75
+ end
76
+ a.failure_message(Chef::Exceptions::FileTypeMismatch, "Cannot create #{new_resource} at #{new_resource.path} because a file already exists at that path")
77
+ end
78
+
68
79
  requirements.assert(:create) do |a|
69
80
  parent_directory = ::File.dirname(new_resource.path)
70
81
  a.assertion do
@@ -114,7 +114,7 @@ class Chef
114
114
  r = case found.length
115
115
  when 0
116
116
  raise Chef::Exceptions::ResourceNotFound,
117
- "Could not find #{dsc_resource_name}. Check to make "\
117
+ "Could not find #{dsc_resource_name}. Check to make " \
118
118
  "sure that it shows up when running Get-DscResource"
119
119
  when 1
120
120
  if found[0]["Module"].nil?
@@ -162,7 +162,7 @@ class Chef
162
162
 
163
163
  def invoke_resource(method)
164
164
  properties = translate_type(new_resource.properties)
165
- switches = "-Method #{method} -Name #{new_resource.resource}"\
165
+ switches = "-Method #{method} -Name #{new_resource.resource}" \
166
166
  " -Property #{properties} -Module #{module_info_object} -Verbose"
167
167
  Timeout.timeout(new_resource.timeout) {
168
168
  powershell_exec!("Invoke-DscResource #{switches}")
@@ -24,9 +24,10 @@ class Chef
24
24
  class File
25
25
  class Content < Chef::FileContentManagement::ContentBase
26
26
  def file_for_provider
27
- if @new_resource.content
27
+ content = @new_resource.content
28
+ if content
28
29
  tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile
29
- tempfile.write(@new_resource.content)
30
+ tempfile.write(content)
30
31
  tempfile.close
31
32
  tempfile
32
33
  else
@@ -192,7 +192,7 @@ class Chef
192
192
  # be overridden in subclasses.
193
193
  def managing_content?
194
194
  return true if new_resource.checksum
195
- return true if !new_resource.content.nil? && @action != :create_if_missing
195
+ return true if new_resource.property_is_set?(:content) && @action != :create_if_missing
196
196
 
197
197
  false
198
198
  end
@@ -61,7 +61,7 @@ class Chef
61
61
  a.assertion { ::File.directory?(dirname) }
62
62
  a.whyrun("Directory #{dirname} does not exist, this run will fail unless it has been previously created. Assuming it would have been created.")
63
63
  a.failure_message(Chef::Exceptions::MissingParentDirectory,
64
- "Cannot clone #{new_resource} to #{cwd}, the enclosing directory #{dirname} does not exist")
64
+ "Cannot clone #{new_resource} to #{cwd}, the enclosing directory #{dirname} does not exist")
65
65
  end
66
66
 
67
67
  requirements.assert(:all_actions) do |a|
@@ -87,7 +87,7 @@ iface <%= new_resource.device %> <%= new_resource.family %> static
87
87
  directory INTERFACES_DOT_D_DIR
88
88
 
89
89
  # roll our own file_edit resource, this will not get reported until we have a file_edit resource
90
- interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, "\\.") # escape dots for the regexp
90
+ interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(".", "\\.") # escape dots for the regexp
91
91
  regexp = %r{^\s*source\s+#{interfaces_dot_d_for_regexp}/\*\s*$}
92
92
 
93
93
  return if ::File.exist?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
@@ -22,7 +22,7 @@ class Chef
22
22
  class Provider
23
23
  class Ifconfig
24
24
  class Redhat < Chef::Provider::Ifconfig
25
- provides :ifconfig, platform_family: "fedora_derived"
25
+ provides :ifconfig, platform_family: %w{fedora rhel amazon}
26
26
 
27
27
  def initialize(new_resource, run_context)
28
28
  super(new_resource, run_context)
@@ -83,4 +83,4 @@ class Chef
83
83
  end
84
84
  end
85
85
  end
86
- end
86
+ end
@@ -30,7 +30,7 @@ class Chef
30
30
  provides :mount, os: "windows"
31
31
 
32
32
  def is_volume(name)
33
- /^\\\\\?\\Volume\{[\w-]+\}\\$/.match?(name) ? true : false
33
+ /^\\\\\?\\Volume\{[\w-]+\}\\$/.match?(name) || false
34
34
  end
35
35
 
36
36
  def initialize(new_resource, run_context)
@@ -62,9 +62,9 @@ class Chef
62
62
  def mount_fs
63
63
  unless @current_resource.mounted
64
64
  @mount.add(remote: @new_resource.device,
65
- username: @new_resource.username,
66
- domainname: @new_resource.domain,
67
- password: @new_resource.password)
65
+ username: @new_resource.username,
66
+ domainname: @new_resource.domain,
67
+ password: @new_resource.password)
68
68
  logger.trace("#{@new_resource} is mounted at #{@new_resource.mount_point}")
69
69
  else
70
70
  logger.debug("#{@new_resource} is already mounted at #{@new_resource.mount_point}")
@@ -257,7 +257,8 @@ class Chef
257
257
  @choco_install_path ||= begin
258
258
  result = powershell_exec!(PATHFINDING_POWERSHELL_COMMAND).result
259
259
  result = "" if result.empty?
260
- result
260
+ # Ensure consistent Windows path separators
261
+ result.empty? ? result : result.tr("/", "\\")
261
262
  end
262
263
  end
263
264
 
@@ -459,8 +460,10 @@ class Chef
459
460
  def get_local_pkg_dirs(base_dir)
460
461
  return [] unless Dir.exist?(base_dir)
461
462
 
462
- Dir.entries(base_dir).select do |dir|
463
- ::File.directory?(::File.join(base_dir, dir)) && !dir.start_with?(".")
463
+ with_file_lock_retry("reading chocolatey package directories") do
464
+ Dir.entries(base_dir).select do |dir|
465
+ ::File.directory?(::File.join(base_dir, dir)) && !dir.start_with?(".")
466
+ end
464
467
  end
465
468
  end
466
469
 
@@ -496,6 +499,60 @@ class Chef
496
499
  args
497
500
  end
498
501
 
502
+ # Wait for chocolatey to release file locks after package operations
503
+ # @param names [Array<String>] package names that were just installed/upgraded
504
+ def wait_for_chocolatey_lock_release(names)
505
+ return if names.empty?
506
+
507
+ Chef::Log.debug("Waiting for chocolatey to release file locks for packages: #{names.join(", ")}")
508
+
509
+ # Check for .chocolateyPending files and wait for them to be released
510
+ names.each do |name|
511
+ pending_file = ::File.join(choco_lib_path, name.downcase, ".chocolateyPending")
512
+ if ::File.exist?(pending_file)
513
+ with_file_lock_retry("waiting for .chocolateyPending file release: #{pending_file}") do
514
+ # Try to open the file exclusively - this will fail if it's locked
515
+ ::File.open(pending_file, "r") do |f|
516
+ f.flock(::File::LOCK_EX | ::File::LOCK_NB) or raise Errno::EAGAIN
517
+ end
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ # Retry file operations that might encounter chocolatey process file locks
524
+ # @param operation_desc [String] description of the operation for logging
525
+ # @param max_retries [Integer] maximum number of retry attempts
526
+ # @param base_delay [Float] base delay between retries in seconds
527
+ def with_file_lock_retry(operation_desc, max_retries: 5, base_delay: 0.5)
528
+ retries = 0
529
+ begin
530
+ yield
531
+ rescue Errno::EACCES, Errno::EBUSY, Errno::EAGAIN, Errno::ENOENT => e
532
+ if retries < max_retries && file_lock_error?(e)
533
+ retries += 1
534
+ delay = base_delay * (2**(retries - 1)) # exponential backoff
535
+ Chef::Log.debug("Chocolatey file lock detected during #{operation_desc}, retrying in #{delay}s (attempt #{retries}/#{max_retries}): #{e.message}")
536
+ sleep(delay)
537
+ retry
538
+ else
539
+ Chef::Log.warn("Failed #{operation_desc} after #{retries} retries: #{e.message}")
540
+ raise e
541
+ end
542
+ end
543
+ end
544
+
545
+ # Check if the error is related to file locking by chocolatey processes
546
+ # @param error [Exception] the exception to check
547
+ # @return [Boolean] true if it's a chocolatey file lock related error
548
+ def file_lock_error?(error)
549
+ error.message&.include?("being used by another process") ||
550
+ error.message&.include?("chocolateyPending") ||
551
+ error.is_a?(Errno::EACCES) ||
552
+ error.is_a?(Errno::EBUSY) ||
553
+ error.is_a?(Errno::EAGAIN)
554
+ end
555
+
499
556
  # Fetch the local package versions from chocolatey
500
557
  def fetch_package_versions(base_dir, target_dirs, targets)
501
558
  pkg_versions = {}
@@ -511,25 +568,27 @@ class Chef
511
568
  # Grab the locally installed packages from the nupkg list
512
569
  # rather than shelling out to chocolatey
513
570
  def get_pkg_data(path)
514
- t = ::File.join(path, "*.nupkg").gsub("\\", "/")
515
- targets = Dir.glob(t)
516
-
517
- # Extract package version from the first nuspec file in this nupkg
518
- targets.each do |target|
519
- Zip::File.open(target) do |zip_file|
520
- zip_file.each do |entry|
521
- next unless entry.name.end_with?(".nuspec")
522
-
523
- f = entry.get_input_stream
524
- doc = REXML::Document.new(f.read.to_s)
525
- f.close
526
- id = doc.elements["package/metadata/id"]
527
- version = doc.elements["package/metadata/version"]
528
- return { id.text.to_s.downcase => version.text } if id && version
571
+ with_file_lock_retry("get package data for #{path}") do
572
+ t = ::File.join(path, "*.nupkg")
573
+ targets = Dir.glob(t)
574
+
575
+ # Extract package version from the first nuspec file in this nupkg
576
+ targets.each do |target|
577
+ Zip::File.open(target) do |zip_file|
578
+ zip_file.each do |entry|
579
+ next unless entry.name.end_with?(".nuspec")
580
+
581
+ f = entry.get_input_stream
582
+ doc = REXML::Document.new(f.read.to_s)
583
+ f.close
584
+ id = doc.elements["package/metadata/id"]
585
+ version = doc.elements["package/metadata/version"]
586
+ return { id.text.to_s.downcase => version.text } if id && version
587
+ end
529
588
  end
530
589
  end
590
+ {}
531
591
  end
532
- {}
533
592
  rescue StandardError => e
534
593
  Chef::Log.warn("Failed to get package info for #{path}: #{e}")
535
594
  {}