chef 17.6.18 → 17.9.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/chef.gemspec +1 -0
  4. data/lib/chef/application/base.rb +1 -1
  5. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  6. data/lib/chef/chef_fs/path_utils.rb +1 -1
  7. data/lib/chef/compliance/default_attributes.rb +12 -2
  8. data/lib/chef/compliance/runner.rb +51 -5
  9. data/lib/chef/data_collector/run_end_message.rb +1 -1
  10. data/lib/chef/dsl/reboot_pending.rb +1 -1
  11. data/lib/chef/exceptions.rb +10 -0
  12. data/lib/chef/mixin/powershell_exec.rb +6 -5
  13. data/lib/chef/mixin/why_run.rb +8 -2
  14. data/lib/chef/powershell.rb +8 -6
  15. data/lib/chef/provider/cron.rb +6 -3
  16. data/lib/chef/provider/directory.rb +2 -2
  17. data/lib/chef/provider/git.rb +1 -1
  18. data/lib/chef/provider/ifconfig/debian.rb +1 -1
  19. data/lib/chef/provider/ifconfig.rb +4 -4
  20. data/lib/chef/provider/mount/linux.rb +16 -2
  21. data/lib/chef/provider/mount/mount.rb +1 -1
  22. data/lib/chef/provider/package/dnf.rb +1 -1
  23. data/lib/chef/provider/package/habitat.rb +1 -1
  24. data/lib/chef/provider/package/powershell.rb +13 -10
  25. data/lib/chef/provider/package/yum/python_helper.rb +81 -25
  26. data/lib/chef/provider/package/yum.rb +39 -12
  27. data/lib/chef/provider/package/zypper.rb +2 -0
  28. data/lib/chef/provider/package.rb +62 -27
  29. data/lib/chef/provider/subversion.rb +5 -5
  30. data/lib/chef/provider.rb +5 -2
  31. data/lib/chef/providers.rb +0 -1
  32. data/lib/chef/pwsh.rb +3 -2
  33. data/lib/chef/resource/apt_package.rb +2 -2
  34. data/lib/chef/resource/chef_client_config.rb +21 -1
  35. data/lib/chef/resource/chef_client_launchd.rb +1 -1
  36. data/lib/chef/resource/chef_client_trusted_certificate.rb +1 -0
  37. data/lib/chef/resource/chocolatey_config.rb +1 -1
  38. data/lib/chef/resource/chocolatey_feature.rb +1 -1
  39. data/lib/chef/resource/chocolatey_package.rb +3 -3
  40. data/lib/chef/resource/chocolatey_source.rb +24 -2
  41. data/lib/chef/resource/cron/cron.rb +75 -1
  42. data/lib/chef/resource/cron/cron_d.rb +2 -1
  43. data/lib/chef/resource/directory.rb +1 -1
  44. data/lib/chef/resource/dnf_package.rb +4 -6
  45. data/lib/chef/resource/dpkg_package.rb +5 -0
  46. data/lib/chef/resource/execute.rb +1 -4
  47. data/lib/chef/resource/habitat_install.rb +5 -5
  48. data/lib/chef/resource/homebrew_tap.rb +0 -4
  49. data/lib/chef/resource/inspec_waiver.rb +1 -1
  50. data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
  51. data/lib/chef/resource/kernel_module.rb +27 -2
  52. data/lib/chef/resource/launchd.rb +0 -3
  53. data/lib/chef/resource/macos_userdefaults.rb +41 -131
  54. data/lib/chef/resource/powershell_package_source.rb +8 -8
  55. data/lib/chef/resource/rhsm_register.rb +31 -0
  56. data/lib/chef/resource/support/client.erb +7 -0
  57. data/lib/chef/resource/windows_auto_run.rb +1 -1
  58. data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
  59. data/lib/chef/resource/windows_feature_powershell.rb +8 -9
  60. data/lib/chef/resource/windows_task.rb +25 -10
  61. data/lib/chef/resource/windows_update_settings.rb +3 -3
  62. data/lib/chef/resource.rb +2 -2
  63. data/lib/chef/resource_reporter.rb +1 -1
  64. data/lib/chef/secret_fetcher/azure_key_vault.rb +64 -8
  65. data/lib/chef/secret_fetcher/hashi_vault.rb +37 -3
  66. data/lib/chef/secret_fetcher.rb +0 -1
  67. data/lib/chef/version.rb +1 -1
  68. data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
  69. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  70. data/spec/functional/resource/dnf_package_spec.rb +138 -124
  71. data/spec/functional/resource/dpkg_package_spec.rb +16 -0
  72. data/spec/functional/resource/dsc_script_spec.rb +2 -2
  73. data/spec/functional/resource/macos_userdefaults_spec.rb +139 -0
  74. data/spec/functional/resource/registry_spec.rb +81 -81
  75. data/spec/functional/resource/yum_package_spec.rb +789 -129
  76. data/spec/functional/resource/zypper_package_spec.rb +7 -0
  77. data/spec/functional/win32/registry_spec.rb +8 -8
  78. data/spec/integration/client/client_spec.rb +31 -0
  79. data/spec/unit/application/base_spec.rb +40 -0
  80. data/spec/unit/compliance/runner_spec.rb +62 -1
  81. data/spec/unit/data_collector_spec.rb +24 -1
  82. data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
  83. data/spec/unit/file_access_control_spec.rb +1 -1
  84. data/spec/unit/mixin/default_paths_spec.rb +1 -1
  85. data/spec/unit/mixin/securable_spec.rb +3 -3
  86. data/spec/unit/mixin/why_run_spec.rb +53 -0
  87. data/spec/unit/provider/cron_spec.rb +45 -0
  88. data/spec/unit/provider/group/groupadd_spec.rb +1 -0
  89. data/spec/unit/provider/group/usermod_spec.rb +2 -2
  90. data/spec/unit/provider/ifconfig_spec.rb +2 -0
  91. data/spec/unit/provider/mount/linux_spec.rb +16 -3
  92. data/spec/unit/provider/package/bff_spec.rb +1 -0
  93. data/spec/unit/provider/package/powershell_spec.rb +114 -114
  94. data/spec/unit/provider/package/rubygems_spec.rb +8 -5
  95. data/spec/unit/provider/package/solaris_spec.rb +1 -0
  96. data/spec/unit/provider/package/windows_spec.rb +1 -1
  97. data/spec/unit/provider/registry_key_spec.rb +4 -4
  98. data/spec/unit/provider/service/arch_service_spec.rb +2 -2
  99. data/spec/unit/provider/service/debian_service_spec.rb +1 -0
  100. data/spec/unit/provider/service/gentoo_service_spec.rb +1 -0
  101. data/spec/unit/provider/service/macosx_spec.rb +1 -0
  102. data/spec/unit/provider/service/redhat_spec.rb +4 -1
  103. data/spec/unit/provider/service/simple_service_spec.rb +6 -4
  104. data/spec/unit/provider/service/windows_spec.rb +5 -5
  105. data/spec/unit/provider/subversion_spec.rb +4 -4
  106. data/spec/unit/provider/user_spec.rb +2 -0
  107. data/spec/unit/provider/windows_env_spec.rb +1 -1
  108. data/spec/unit/provider/zypper_repository_spec.rb +1 -1
  109. data/spec/unit/resource/chef_client_trusted_certificate_spec.rb +14 -0
  110. data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
  111. data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
  112. data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
  113. data/spec/unit/resource/dpkg_package_spec.rb +12 -0
  114. data/spec/unit/resource/kernel_module_spec.rb +2 -1
  115. data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
  116. data/spec/unit/resource/registry_key_spec.rb +10 -10
  117. data/spec/unit/resource/rhsm_register_spec.rb +42 -0
  118. data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
  119. data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
  120. data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
  121. data/spec/unit/resource/windows_task_spec.rb +3 -3
  122. data/spec/unit/resource_reporter_spec.rb +2 -2
  123. data/spec/unit/resource_spec.rb +5 -0
  124. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
  125. data/spec/unit/secret_fetcher/hashi_vault_spec.rb +46 -0
  126. data/spec/unit/util/backup_spec.rb +1 -1
  127. data/spec/unit/win32/registry_spec.rb +3 -3
  128. metadata +24 -9
  129. data/lib/chef/provider/group/suse.rb +0 -82
  130. data/spec/unit/provider/group/suse_spec.rb +0 -90
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59f5d3f142e80c94be749ef60ee943e69079238f55209a2a10741158c8816bce
4
- data.tar.gz: 48a22e1452ab3aa51e69f64144ccccff80790f9890e81c7ea3a781a151080da6
3
+ metadata.gz: 1886ca1ea538fbe96bf89e02df660eaa7eead201d917e15525e63cb7b3c3f90c
4
+ data.tar.gz: 2f2807b137aba35aba5ab1fa719ed26d0dd5aaab8ba4989c56c33b62761c3bfc
5
5
  SHA512:
6
- metadata.gz: 28fb40af64c9a66d6e1d7ab487e88873b0eed7db8fc13f80c7e5fe5c191bbbe1b89da0d5fcf841072a12d1674ce2a5986d243dc41340ddb71508d337e804325e
7
- data.tar.gz: 24a4a408695c4c6283bcd7312b7f74c164fe2f4bb9b6eb3adce43c4182d398f86a02cbb2aa1a63df0ff0a1084961cba96f3c7a7b4fefb958b23a61c92f53a3a8
6
+ metadata.gz: e52940ab6008d9263848045de3be99288298a6b542a94e9fa6832f2e2cdb73369b0055ec1df63237338faf8f0015d65f138985201452e7b64e15ddd8a76d1619
7
+ data.tar.gz: ea68a2d6a8096d590877bef7b764b8b6283980354401b2f713177b3977ba7338bb2bd012433ae0a203cb42deacf10865a288a4b3fcedcb9d9cd0c423b749c9da
data/Gemfile CHANGED
@@ -39,6 +39,11 @@ group(:ruby_shadow) do
39
39
  gem "ruby-shadow", git: "https://github.com/chef/ruby-shadow", branch: "lcg/ruby-3.0", platforms: :ruby
40
40
  end
41
41
 
42
+ # deps that cannot be put in the knife gem because they require a compiler and fail on windows nodes
43
+ group(:knife_windows_deps) do
44
+ gem "ed25519", "~> 1.2" # ed25519 ssh key support
45
+ end
46
+
42
47
  group(:development, :test) do
43
48
  gem "rake"
44
49
  gem "rspec"
data/chef.gemspec CHANGED
@@ -52,6 +52,7 @@ Gem::Specification.new do |s|
52
52
  s.add_dependency "addressable"
53
53
  s.add_dependency "syslog-logger", "~> 1.6"
54
54
  s.add_dependency "uuidtools", ">= 2.1.5", "< 3.0" # osx_profile resource
55
+ s.add_dependency "corefoundation", "~> 0.3.4" # macos_userdefaults resource
55
56
 
56
57
  s.add_dependency "proxifier", "~> 1.0"
57
58
 
@@ -254,7 +254,7 @@ class Chef::Application::Base < Chef::Application
254
254
  short: "-K KEY_FILE",
255
255
  long: "--validation_key KEY_FILE",
256
256
  description: "Set the validation key file location, used for registering new clients.",
257
- proc: nil
257
+ proc: lambda { |argument| File.expand_path(argument) }
258
258
 
259
259
  option :client_key,
260
260
  short: "-k KEY_FILE",
@@ -276,7 +276,7 @@ class Chef
276
276
  regexp << ".*"
277
277
  when "*"
278
278
  exact = nil
279
- regexp << '[^\/]*'
279
+ regexp << "[^\\/]*"
280
280
  when "?"
281
281
  exact = nil
282
282
  regexp << "."
@@ -58,7 +58,7 @@ class Chef
58
58
  end
59
59
 
60
60
  def self.regexp_path_separator
61
- ChefUtils.windows? ? '[\/\\\\]' : "/"
61
+ ChefUtils.windows? ? "[\\/\\\\]" : "/"
62
62
  end
63
63
 
64
64
  # Given a server path, determines if it is absolute.
@@ -28,7 +28,7 @@ class Chef
28
28
  # Controls what is done with the resulting report after the Chef InSpec run.
29
29
  # Accepts a single string value or an array of multiple values.
30
30
  # Accepted values: 'chef-server-automate', 'chef-automate', 'json-file', 'audit-enforcer', 'cli'
31
- "reporter" => "cli",
31
+ "reporter" => nil,
32
32
 
33
33
  # Controls if Chef InSpec profiles should be fetched from Chef Automate or Chef Infra Server
34
34
  # in addition to the default fetch locations provided by Chef Inspec.
@@ -94,7 +94,17 @@ class Chef
94
94
 
95
95
  # Should the built-in compliance phase run. True and false force the behavior. Nil does magic based on if you have
96
96
  # profiles defined but do not have the audit cookbook enabled.
97
- "compliance_phase" => false
97
+ "compliance_phase" => false,
98
+
99
+ "interval" => {
100
+ # control how often inspec scans are run, if not on every node converge
101
+ # notes: false value will result in running inspec scan every converge
102
+ "enabled" => false,
103
+
104
+ # controls how often inspec scans are run (in minutes)
105
+ # notes: only used if interval is enabled above
106
+ "time" => 1440,
107
+ }
98
108
  )
99
109
  end
100
110
  end
@@ -71,7 +71,7 @@ class Chef
71
71
 
72
72
  logger.debug("#{self.class}##{__method__}: enabling Compliance Phase")
73
73
 
74
- report
74
+ report_with_interval
75
75
  end
76
76
 
77
77
  def run_failed(_exception, _run_status)
@@ -82,7 +82,7 @@ class Chef
82
82
 
83
83
  logger.debug("#{self.class}##{__method__}: enabling Compliance Phase")
84
84
 
85
- report
85
+ report_with_interval
86
86
  end
87
87
 
88
88
  ### Below code adapted from audit cookbook's files/default/handler/audit_report.rb
@@ -92,7 +92,6 @@ class Chef
92
92
  fail_if_not_present
93
93
  inspec_gem_source
94
94
  inspec_version
95
- interval
96
95
  owner
97
96
  raise_if_unreachable
98
97
  }.freeze
@@ -106,6 +105,15 @@ class Chef
106
105
  end
107
106
  end
108
107
 
108
+ def report_with_interval
109
+ if interval_seconds_left <= 0
110
+ create_timestamp_file if interval_enabled
111
+ report
112
+ else
113
+ logger.info "Skipping Chef Infra Compliance Phase due to interval settings (next run in #{interval_seconds_left / 60.0} mins)"
114
+ end
115
+ end
116
+
109
117
  def report(report = nil)
110
118
  logger.info "Starting Chef Infra Compliance Phase"
111
119
  report ||= generate_report
@@ -118,7 +126,7 @@ class Chef
118
126
  return
119
127
  end
120
128
 
121
- Array(node["audit"]["reporter"]).each do |reporter_type|
129
+ requested_reporters.each do |reporter_type|
122
130
  logger.info "Reporting to #{reporter_type}"
123
131
  @reporters[reporter_type].send_report(report)
124
132
  end
@@ -325,7 +333,7 @@ class Chef
325
333
  @reporters = {}
326
334
  # Note that the docs don't say you can use an array, but our implementation
327
335
  # supports it.
328
- Array(node["audit"]["reporter"]).each do |type|
336
+ requested_reporters.each do |type|
329
337
  unless SUPPORTED_REPORTERS.include? type
330
338
  raise "CMPL003: '#{type}' found in node['audit']['reporter'] is not a supported reporter for Compliance Phase. Supported reporters are: #{SUPPORTED_REPORTERS.join(", ")}. For more information, see the documentation at https://docs.chef.io/chef_compliance_phase#reporters"
331
339
  end
@@ -358,6 +366,44 @@ class Chef
358
366
  def safe_input_collection
359
367
  run_context&.input_collection
360
368
  end
369
+
370
+ def requested_reporters
371
+ (Array(node["audit"]["reporter"]) + ["cli"]).uniq
372
+ end
373
+
374
+ def create_timestamp_file
375
+ FileUtils.touch report_timing_file
376
+ end
377
+
378
+ def report_timing_file
379
+ ::File.join(Chef::FileCache.create_cache_path("compliance"), "report_timing.json")
380
+ end
381
+
382
+ def interval_time
383
+ @interval_time ||= node.read("audit", "interval", "time")
384
+ end
385
+
386
+ def interval_enabled
387
+ @interval_enabled ||= node.read("audit", "interval", "enabled")
388
+ end
389
+
390
+ def interval_seconds
391
+ @interval_seconds ||=
392
+ if interval_enabled
393
+ logger.debug "Running Chef Infra Compliance Phase every #{interval_time} minutes"
394
+ interval_time * 60
395
+ else
396
+ logger.debug "Running Chef Infra Compliance Phase on every run"
397
+ 0
398
+ end
399
+ end
400
+
401
+ def interval_seconds_left
402
+ return 0 unless ::File.exist?(report_timing_file)
403
+
404
+ seconds_since_last_run = Time.now - ::File.mtime(report_timing_file)
405
+ interval_seconds - seconds_since_last_run
406
+ end
361
407
  end
362
408
  end
363
409
  end
@@ -128,7 +128,7 @@ class Chef
128
128
 
129
129
  if new_resource.cookbook_name
130
130
  hash["cookbook_name"] = new_resource.cookbook_name
131
- hash["cookbook_version"] = new_resource.cookbook_version.version
131
+ hash["cookbook_version"] = new_resource.cookbook_version&.version
132
132
  hash["recipe_name"] = new_resource.recipe_name
133
133
  end
134
134
 
@@ -37,7 +37,7 @@ class Chef
37
37
  # due to a file being in use (usually a temporary file and a system file)
38
38
  # \??\c:\temp\test.sys!\??\c:\winnt\system32\test.sys
39
39
  # http://technet.microsoft.com/en-us/library/cc960241.aspx
40
- registry_value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { name: "PendingFileRenameOperations" }) ||
40
+ registry_value_exists?("HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager", { name: "PendingFileRenameOperations" }) ||
41
41
 
42
42
  # RebootRequired key contains Update IDs with a value of 1 if they require a reboot.
43
43
  # The existence of RebootRequired alone is sufficient on my Windows 8.1 workstation in Windows Update
@@ -308,6 +308,16 @@ class Chef
308
308
  super("No secret service provided. Supported services are: :#{fetcher_service_names.join(" :")}")
309
309
  end
310
310
  end
311
+
312
+ class Azure
313
+ class IdentityNotFound < RuntimeError
314
+ def initialize
315
+ super("The managed identity could not be found. This could mean one of the following things:\n\n" \
316
+ " 1. The VM has no system or user assigned identities.\n" \
317
+ " 2. The managed identity object_id or client_id that was specified is not assigned to the VM.\n")
318
+ end
319
+ end
320
+ end
311
321
  end
312
322
 
313
323
  # Exception class for collecting multiple failures. Used when running
@@ -104,13 +104,14 @@ class Chef
104
104
  #
105
105
  # @param script [String] script to run
106
106
  # @param interpreter [Symbol] the interpreter type, `:powershell` or `:pwsh`
107
+ # @param timeout [Integer, nil] timeout in seconds.
107
108
  # @return [Chef::PowerShell] output
108
- def powershell_exec(script, interpreter = :powershell)
109
+ def powershell_exec(script, interpreter = :powershell, timeout: -1)
109
110
  case interpreter
110
111
  when :powershell
111
- Chef::PowerShell.new(script)
112
+ Chef::PowerShell.new(script, timeout: timeout)
112
113
  when :pwsh
113
- Chef::Pwsh.new(script)
114
+ Chef::Pwsh.new(script, timeout: timeout)
114
115
  else
115
116
  raise ArgumentError, "Expected interpreter of :powershell or :pwsh"
116
117
  end
@@ -118,8 +119,8 @@ class Chef
118
119
 
119
120
  # The same as the #powershell_exec method except this will raise
120
121
  # Chef::PowerShell::CommandFailed if the command fails
121
- def powershell_exec!(script, interpreter = :powershell)
122
- cmd = powershell_exec(script, interpreter)
122
+ def powershell_exec!(script, interpreter = :powershell, **options)
123
+ cmd = powershell_exec(script, interpreter, **options)
123
124
  cmd.error!
124
125
  cmd
125
126
  end
@@ -242,8 +242,12 @@ class Chef
242
242
  end
243
243
  end
244
244
 
245
- def initialize(resource, run_context)
246
- @resource, @run_context = resource, run_context
245
+ attr_accessor :action
246
+
247
+ def initialize(resource, run_context, action)
248
+ @resource = resource
249
+ @run_context = run_context
250
+ @action = action
247
251
  @assertions = Hash.new { |h, k| h[k] = [] }
248
252
  @blocked_actions = []
249
253
  end
@@ -305,6 +309,8 @@ class Chef
305
309
  # "You don't have sufficient privileges to delete #{@new_resource.path}")
306
310
  # end
307
311
  def assert(*actions)
312
+ return unless actions.include?(action.to_sym) || actions.include?(:all_actions)
313
+
308
314
  assertion = Assertion.new
309
315
  yield assertion
310
316
  actions.each { |action| @assertions[action] << assertion }
@@ -33,15 +33,16 @@ class Chef
33
33
  # Requires: .NET Framework 4.0 or higher on the target machine.
34
34
  #
35
35
  # @param script [String] script to run
36
+ # @param timeout [Integer, nil] timeout in seconds.
36
37
  # @return [Object] output
37
- def initialize(script)
38
+ def initialize(script, timeout: -1)
38
39
  # This Powershell DLL source lives here: https://github.com/chef/chef-powershell-shim
39
40
  # Every merge into that repo triggers a Habitat build and promotion. Running
40
41
  # the rake :update_chef_exec_dll task in this (chef/chef) repo will pull down
41
42
  # the built packages and copy the binaries to distro/ruby_bin_folder. Bundle install
42
43
  # ensures that the correct architecture binaries are installed into the path.
43
44
  @dll ||= "Chef.PowerShell.Wrapper.dll"
44
- exec(script)
45
+ exec(script, timeout: timeout)
45
46
  end
46
47
 
47
48
  #
@@ -64,12 +65,13 @@ class Chef
64
65
  raise Chef::PowerShell::CommandFailed, "Unexpected exit in PowerShell command: #{@errors}" if error?
65
66
  end
66
67
 
67
- protected
68
+ private
68
69
 
69
- def exec(script)
70
+ def exec(script, timeout: -1)
70
71
  FFI.ffi_lib @dll
71
- FFI.attach_function :execute_powershell, :ExecuteScript, [:string], :pointer
72
- execution = FFI.execute_powershell(script).read_utf16string
72
+ FFI.attach_function :execute_powershell, :ExecuteScript, %i{string int}, :pointer
73
+ timeout = -1 if timeout == 0 || timeout.nil?
74
+ execution = FFI.execute_powershell(script, timeout).read_utf16string
73
75
  hashed_outcome = Chef::JSONCompat.parse(execution)
74
76
  @result = Chef::JSONCompat.parse(hashed_outcome["result"])
75
77
  @errors = hashed_outcome["errors"]
@@ -92,7 +92,7 @@ class Chef
92
92
  end
93
93
  end
94
94
 
95
- action :create do
95
+ action :create, description: "Create an entry in a cron table file (crontab). If an entry already exists (but does not match), update that entry to match." do
96
96
  crontab = ""
97
97
  newcron = ""
98
98
  cron_found = false
@@ -100,7 +100,10 @@ class Chef
100
100
  newcron = get_crontab_entry
101
101
 
102
102
  if @cron_exists
103
- unless cron_different?
103
+ # Only compare the crontab if the current resource has a set command.
104
+ # This may not be set in cases where the Chef comment exists but the
105
+ # crontab command was commented out.
106
+ if current_resource.property_is_set?(:command) && !cron_different?
104
107
  logger.debug("#{new_resource}: Skipping existing cron entry")
105
108
  return
106
109
  end
@@ -146,7 +149,7 @@ class Chef
146
149
  end
147
150
  end
148
151
 
149
- action :delete do
152
+ action :delete, description: "Delete an entry from a cron table file (crontab)." do
150
153
  if @cron_exists
151
154
  crontab = ""
152
155
  cron_found = false
@@ -121,7 +121,7 @@ class Chef
121
121
  end
122
122
  end
123
123
 
124
- action :create do
124
+ action :create, description: "Create a directory. If a directory already exists (but does not match), update that directory to match." do
125
125
  unless ::File.exist?(new_resource.path)
126
126
  converge_by("create new directory #{new_resource.path}") do
127
127
  if new_resource.recursive == true
@@ -137,7 +137,7 @@ class Chef
137
137
  load_resource_attributes_from_file(new_resource) unless Chef::Config[:why_run]
138
138
  end
139
139
 
140
- action :delete do
140
+ action :delete, description: "Delete a directory." do
141
141
  if ::File.exist?(new_resource.path)
142
142
  converge_by("delete existing directory #{new_resource.path}") do
143
143
  if new_resource.recursive == true
@@ -28,7 +28,7 @@ class Chef
28
28
  extend Forwardable
29
29
  provides :git
30
30
 
31
- GIT_VERSION_PATTERN = Regexp.compile('git version (\d+\.\d+.\d+)')
31
+ GIT_VERSION_PATTERN = Regexp.compile("git version (\\d+\\.\\d+.\\d+)")
32
32
 
33
33
  def_delegator :new_resource, :destination, :cwd
34
34
 
@@ -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))
@@ -168,7 +168,7 @@ class Chef
168
168
  end
169
169
  end
170
170
 
171
- action :add do
171
+ action :add, description: "Run ifconfig to configure a network interface and (on some platforms) write a configuration file for that network interface." do
172
172
  # check to see if load_current_resource found interface in ifconfig
173
173
  unless current_resource.inet_addr
174
174
  unless new_resource.device == loopback_device
@@ -183,7 +183,7 @@ class Chef
183
183
  generate_config
184
184
  end
185
185
 
186
- action :enable do
186
+ action :enable, description: "Run ifconfig to enable a network interface." do
187
187
  # check to see if load_current_resource found ifconfig
188
188
  # enables, but does not manage config files
189
189
  return if current_resource.inet_addr
@@ -196,7 +196,7 @@ class Chef
196
196
  end
197
197
  end
198
198
 
199
- action :delete do
199
+ action :delete, description: "Run ifconfig to disable a network interface and (on some platforms) delete that network interface’s configuration file." do
200
200
  # check to see if load_current_resource found the interface
201
201
  if current_resource.device
202
202
  command = delete_command
@@ -210,7 +210,7 @@ class Chef
210
210
  delete_config
211
211
  end
212
212
 
213
- action :disable do
213
+ action :disable, description: "Run ifconfig to disable a network interface." do
214
214
  # check to see if load_current_resource found the interface
215
215
  # disables, but leaves config files in place.
216
216
  if current_resource.device
@@ -29,10 +29,16 @@ class Chef
29
29
  # "findmnt" outputs the mount points with volume.
30
30
  # Convert the mount_point of the resource to a real path in case it
31
31
  # contains symlinks in its parents dirs.
32
+ def loop_mount_points
33
+ # get loop_mount_points only if not initialized earlier
34
+ @loop_mount_points ||= shell_out!("losetup -a").stdout
35
+
36
+ rescue Errno::ENOENT
37
+ @loop_mount_points = ""
38
+ end
32
39
 
33
40
  def mounted?
34
41
  mounted = false
35
-
36
42
  real_mount_point = if ::File.exists? @new_resource.mount_point
37
43
  ::File.realpath(@new_resource.mount_point)
38
44
  else
@@ -45,6 +51,14 @@ class Chef
45
51
  when /\A#{Regexp.escape(real_mount_point)}\s+#{device_mount_regex}\s/
46
52
  mounted = true
47
53
  logger.trace("Special device #{device_logstring} mounted as #{real_mount_point}")
54
+ # Permalink for loop type devices mount points https://rubular.com/r/a0bS4p2RvXsGxx
55
+ when %r{\A#{Regexp.escape(real_mount_point)}\s+\/dev\/loop+[0-9]+\s}
56
+ loop_mount_points.each_line do |mount_point|
57
+ if mount_point.include? device_real
58
+ mounted = true
59
+ break
60
+ end
61
+ end
48
62
  # Permalink for multiple devices mounted to the same mount point(i.e. '/proc') https://rubular.com/r/a356yzspU7N9TY
49
63
  when %r{\A#{Regexp.escape(real_mount_point)}\s+([/\w])+\s}
50
64
  mounted = false
@@ -64,4 +78,4 @@ class Chef
64
78
  end
65
79
  end
66
80
  end
67
- end
81
+ end
@@ -279,4 +279,4 @@ class Chef
279
279
  end
280
280
  end
281
281
  end
282
- end
282
+ end
@@ -98,7 +98,7 @@ class Chef
98
98
  end
99
99
  end
100
100
 
101
- def magic_version
101
+ def magic_version_array
102
102
  package_name_array.each_with_index.map do |pkg, i|
103
103
  magical_version(i).version_with_arch
104
104
  end
@@ -108,7 +108,7 @@ class Chef
108
108
  headers["Authorization"] = "Bearer #{new_resource.auth_token}" if new_resource.auth_token
109
109
 
110
110
  Chef::JSONCompat.parse(http.get(url, headers))
111
- rescue Net::HTTPServerException
111
+ rescue Net::HTTPClientException
112
112
  nil
113
113
  end
114
114
  end
@@ -17,13 +17,13 @@
17
17
 
18
18
  require_relative "../package"
19
19
  require_relative "../../resource/powershell_package"
20
- require_relative "../../mixin/powershell_out"
20
+ require_relative "../../mixin/powershell_exec"
21
21
 
22
22
  class Chef
23
23
  class Provider
24
24
  class Package
25
25
  class Powershell < Chef::Provider::Package
26
- include Chef::Mixin::PowershellOut
26
+ include Chef::Mixin::PowershellExec
27
27
 
28
28
  provides :powershell_package
29
29
 
@@ -54,9 +54,9 @@ class Chef
54
54
  # Installs the package specified with the version passed else latest version will be installed
55
55
  def install_package(names, versions)
56
56
  names.each_with_index do |name, index|
57
- cmd = powershell_out(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
57
+ cmd = powershell_exec(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
58
58
  next if cmd.nil?
59
- raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.stderr)
59
+ raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.error)
60
60
  end
61
61
  end
62
62
 
@@ -64,11 +64,12 @@ class Chef
64
64
  def remove_package(names, versions)
65
65
  names.each_with_index do |name, index|
66
66
  if versions && !versions[index].nil?
67
- powershell_out(build_powershell_package_command("Uninstall-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
67
+ powershell_exec(build_powershell_package_command("Uninstall-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
68
68
  else
69
69
  version = "0"
70
70
  until version.empty?
71
- version = powershell_out(build_powershell_package_command("Uninstall-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
71
+ version = powershell_exec(build_powershell_package_command("Uninstall-Package '#{name}'"), timeout: new_resource.timeout).result
72
+ version = version.strip if version.respond_to?(:strip)
72
73
  unless version.empty?
73
74
  logger.info("Removed package '#{name}' with version #{version}")
74
75
  end
@@ -82,13 +83,14 @@ class Chef
82
83
  versions = []
83
84
  new_resource.package_name.each_with_index do |name, index|
84
85
  version = if new_resource.version && !new_resource.version[index].nil?
85
- powershell_out(build_powershell_package_command("Find-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).stdout.strip
86
+ powershell_exec(build_powershell_package_command("Find-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).result
86
87
  else
87
- powershell_out(build_powershell_package_command("Find-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
88
+ powershell_exec(build_powershell_package_command("Find-Package '#{name}'"), timeout: new_resource.timeout).result
88
89
  end
89
90
  if version.empty?
90
91
  version = nil
91
92
  end
93
+ version = version.strip if version.respond_to?(:strip)
92
94
  versions.push(version)
93
95
  end
94
96
  versions
@@ -99,13 +101,14 @@ class Chef
99
101
  version_list = []
100
102
  new_resource.package_name.each_with_index do |name, index|
101
103
  version = if new_resource.version && !new_resource.version[index].nil?
102
- powershell_out(build_powershell_package_command("Get-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).stdout.strip
104
+ powershell_exec(build_powershell_package_command("Get-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).result
103
105
  else
104
- powershell_out(build_powershell_package_command("Get-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
106
+ powershell_exec(build_powershell_package_command("Get-Package '#{name}'"), timeout: new_resource.timeout).result
105
107
  end
106
108
  if version.empty?
107
109
  version = nil
108
110
  end
111
+ version = version.strip if version.respond_to?(:strip)
109
112
  version_list.push(version)
110
113
  end
111
114
  version_list