chef 18.3.0 → 18.4.2

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/chef.gemspec +3 -3
  4. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  5. data/lib/chef/chef_fs/path_utils.rb +7 -9
  6. data/lib/chef/cookbook/synchronizer.rb +2 -3
  7. data/lib/chef/delayed_evaluator.rb +4 -0
  8. data/lib/chef/file_access_control/windows.rb +4 -1
  9. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -0
  10. data/lib/chef/mixin/homebrew_user.rb +6 -3
  11. data/lib/chef/monkey_patches/net-http.rb +5 -5
  12. data/lib/chef/node/attribute_collections.rb +2 -1
  13. data/lib/chef/node/immutable_collections.rb +2 -1
  14. data/lib/chef/node/mixin/state_tracking_array.rb +41 -0
  15. data/lib/chef/node.rb +22 -0
  16. data/lib/chef/provider/package/apt.rb +11 -2
  17. data/lib/chef/provider/package/chocolatey.rb +228 -24
  18. data/lib/chef/provider/package/zypper.rb +5 -0
  19. data/lib/chef/provider/powershell_script.rb +96 -6
  20. data/lib/chef/provider/service/systemd.rb +23 -8
  21. data/lib/chef/provider/service/windows.rb +1 -0
  22. data/lib/chef/provider/service.rb +14 -0
  23. data/lib/chef/provider/user.rb +5 -1
  24. data/lib/chef/recipe.rb +3 -11
  25. data/lib/chef/resource/_rest_resource.rb +1 -1
  26. data/lib/chef/resource/apt_package.rb +19 -0
  27. data/lib/chef/resource/apt_repository.rb +2 -1
  28. data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
  29. data/lib/chef/resource/chocolatey_installer.rb +207 -0
  30. data/lib/chef/resource/chocolatey_package.rb +8 -0
  31. data/lib/chef/resource/homebrew_package.rb +1 -1
  32. data/lib/chef/resource/locale.rb +5 -2
  33. data/lib/chef/resource/macos_pkg.rb +111 -0
  34. data/lib/chef/resource/powershell_script.rb +5 -1
  35. data/lib/chef/resource/service.rb +3 -0
  36. data/lib/chef/resource/sudo.rb +37 -2
  37. data/lib/chef/resource/support/ulimit.erb +40 -0
  38. data/lib/chef/resource/user_ulimit.rb +38 -0
  39. data/lib/chef/resources.rb +2 -0
  40. data/lib/chef/version.rb +1 -1
  41. data/spec/data/trusted_certs/example.crt +29 -20
  42. data/spec/data/trusted_certs/example_no_cn.crt +30 -34
  43. data/spec/functional/resource/chocolatey_package_spec.rb +2 -2
  44. data/spec/functional/resource/zypper_package_spec.rb +10 -0
  45. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
  46. data/spec/unit/delayed_evaluator_spec.rb +35 -0
  47. data/spec/unit/node_spec.rb +6 -0
  48. data/spec/unit/provider/package/apt_spec.rb +18 -13
  49. data/spec/unit/provider/package/chocolatey_spec.rb +40 -12
  50. data/spec/unit/provider/powershell_script_spec.rb +100 -4
  51. data/spec/unit/provider/service/systemd_service_spec.rb +1 -0
  52. data/spec/unit/provider/user/linux_spec.rb +10 -0
  53. data/spec/unit/resource/chef_client_systemd_timer_spec.rb +1 -1
  54. data/spec/unit/resource/chocolatey_installer_spec.rb +151 -0
  55. data/spec/unit/resource/macos_pkg_spec.rb +38 -0
  56. data/spec/unit/resource/powershell_script_spec.rb +2 -2
  57. metadata +24 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3856e8d0d5224634cad3eb9d43ecf3e87cc504ee881474f7698a14eb90e15088
4
- data.tar.gz: 7830af2c8acab4e76176876a2aaac1363d9a8ff706a78422ec98d6d522772856
3
+ metadata.gz: 1b0abf8303fae83df7a99b7731d5e3eedd3dcb5f533cbc9c784527682b3daaa6
4
+ data.tar.gz: a0fa3f6ee5de4413da2bc2a8e7f41d6d50d320f7c7d2cc080cbda5c9c7bf4604
5
5
  SHA512:
6
- metadata.gz: 4503271efa5b5e0713e2753056c32f6c9fb044935802571d8ef3a4024788dd23f9b6ca7da74e1210d1eaedf03b2b44ecc6e7a0e28059078e815b78161ca4e502
7
- data.tar.gz: 150281399db54afc60e2f910b3dd4322b0d6f287f97d57b9c530fea39d705bbc4dd0b89cb43807f642674c0ae0ce20d40964bba5fe757a76d4af71fa6b7dc7d1
6
+ metadata.gz: 961231927046fcc8965d79b9138e76d7659c666d3afaafe99b4cd1816169e888cb0f87cb57bb394c1d5a81e1f7d54f69f2dad7c9f51ff573c868429449aae808
7
+ data.tar.gz: '024394b552768952422587e0c0cd68bb617c51c1baa01ee7a5421952b3d1822ad6a553e0ad549047d53f3339c2483bb54f76f556a5a180d0999bb7fd1553a7ec'
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem "ohai", git: "https://github.com/chef/ohai.git", branch: "main"
7
7
  # Nwed to file a bug with rest-client. In the meantime, we can use this until they accept the update.
8
8
  gem "rest-client", git: "https://github.com/chef/rest-client", branch: "jfm/ucrt_update1"
9
9
 
10
- gem "ffi", ">= 1.15.5"
10
+ gem "ffi", "~> 1.15.5"
11
11
  gem "chef-utils", path: File.expand_path("chef-utils", __dir__) if File.exist?(File.expand_path("chef-utils", __dir__))
12
12
  gem "chef-config", path: File.expand_path("chef-config", __dir__) if File.exist?(File.expand_path("chef-config", __dir__))
13
13
 
@@ -24,7 +24,7 @@ gem "cheffish", ">= 17"
24
24
  group(:omnibus_package) do
25
25
  gem "appbundler"
26
26
  gem "rb-readline"
27
- gem "inspec-core-bin", ">= 5" # need to provide the binaries for inspec
27
+ gem "inspec-core-bin", ">= 5", "< 6" # need to provide the binaries for inspec
28
28
  gem "chef-vault"
29
29
  end
30
30
 
data/chef.gemspec CHANGED
@@ -41,9 +41,9 @@ Gem::Specification.new do |s|
41
41
  s.add_dependency "mixlib-shellout", ">= 3.1.1", "< 4.0"
42
42
  s.add_dependency "mixlib-archive", ">= 0.4", "< 2.0"
43
43
  s.add_dependency "ohai", "~> 18.0"
44
- s.add_dependency "inspec-core", ">= 5"
44
+ s.add_dependency "inspec-core", ">= 5", "< 6"
45
45
 
46
- s.add_dependency "ffi", ">= 1.15.5"
46
+ s.add_dependency "ffi", "~> 1.15.5"
47
47
  s.add_dependency "ffi-yajl", "~> 2.2"
48
48
  s.add_dependency "net-sftp", ">= 2.1.2", "< 5.0" # remote_file resource
49
49
  s.add_dependency "net-ftp" # remote_file resource
@@ -58,7 +58,7 @@ Gem::Specification.new do |s|
58
58
  s.add_dependency "addressable"
59
59
  s.add_dependency "syslog-logger", "~> 1.6"
60
60
  s.add_dependency "uuidtools", ">= 2.1.5", "< 3.0" # osx_profile resource
61
- s.add_dependency "unf_ext", ">= 0.0.8.2" # This is ruby31 compatible ucrt gem version
61
+ s.add_dependency "unf_ext", "~> 0.0.8.2" # older platforms
62
62
  s.add_dependency "corefoundation", "~> 0.3.4" # macos_userdefaults resource
63
63
 
64
64
  s.add_dependency "proxifier2", "~> 1.1"
@@ -238,7 +238,7 @@ class Chef
238
238
  end
239
239
  end
240
240
 
241
- @regexp = Regexp.new("^#{full_regexp_parts.join(Chef::ChefFS::PathUtils.regexp_path_separator)}$")
241
+ @regexp = Regexp.new("^#{full_regexp_parts.join(Chef::ChefFS::PathUtils::REGEXP_PATH_SEPARATOR)}$")
242
242
  @normalized_pattern = Chef::ChefFS::PathUtils.join(*normalized_parts)
243
243
  @normalized_pattern = Chef::ChefFS::PathUtils.join("", @normalized_pattern) if @is_absolute
244
244
  end
@@ -40,13 +40,15 @@ class Chef
40
40
  # path to discover the Chef-FS root path) are handled in accordance to the rules
41
41
  # of the local file-system and OS.
42
42
 
43
+ REGEXP_PATH_SEPARATOR = ChefUtils.windows? ? "[\\/\\\\]" : "/"
44
+
43
45
  def self.join(*parts)
44
46
  return "" if parts.length == 0
45
47
 
46
48
  # Determine if it started with a slash
47
- absolute = parts[0].length == 0 || parts[0].length > 0 && parts[0] =~ /^#{regexp_path_separator}/
49
+ absolute = parts[0].length == 0 || parts[0].length > 0 && parts[0] =~ /^#{REGEXP_PATH_SEPARATOR}/
48
50
  # Remove leading and trailing slashes from each part so that the join will work (and the slash at the end will go away)
49
- parts = parts.map { |part| part.gsub(/^#{regexp_path_separator}+|#{regexp_path_separator}+$/, "") }
51
+ parts = parts.map { |part| part.gsub(/^#{REGEXP_PATH_SEPARATOR}+|#{REGEXP_PATH_SEPARATOR}+$/, "") }
50
52
  # Don't join empty bits
51
53
  result = parts.select { |part| part != "" }.join("/")
52
54
  # Put the / back on
@@ -54,16 +56,12 @@ class Chef
54
56
  end
55
57
 
56
58
  def self.split(path)
57
- path.split(Regexp.new(regexp_path_separator))
58
- end
59
-
60
- def self.regexp_path_separator
61
- ChefUtils.windows? ? "[\\/\\\\]" : "/"
59
+ path.split(Regexp.new(REGEXP_PATH_SEPARATOR))
62
60
  end
63
61
 
64
62
  # Given a server path, determines if it is absolute.
65
63
  def self.is_absolute?(path)
66
- !!(path =~ /^#{regexp_path_separator}/)
64
+ !!(path =~ /^#{REGEXP_PATH_SEPARATOR}/)
67
65
  end
68
66
 
69
67
  # Given a path which may only be partly real (i.e. /x/y/z when only /x exists,
@@ -118,7 +116,7 @@ class Chef
118
116
 
119
117
  if ancestor.length == path.length
120
118
  ""
121
- elsif /#{PathUtils.regexp_path_separator}/.match?(path[ancestor.length, 1])
119
+ elsif /#{PathUtils::REGEXP_PATH_SEPARATOR}/.match?(path[ancestor.length, 1])
122
120
  path[ancestor.length + 1..-1]
123
121
  else
124
122
  nil
@@ -18,7 +18,6 @@ require_relative "../util/threaded_job_queue"
18
18
  require_relative "../server_api"
19
19
  require "singleton" unless defined?(Singleton)
20
20
  require "chef-utils/dist" unless defined?(ChefUtils::Dist)
21
- require "set" unless defined?(Set)
22
21
 
23
22
  class Chef
24
23
 
@@ -240,8 +239,8 @@ class Chef
240
239
  @cookbooks_by_name.each_key do |cookbook_name|
241
240
  cache_file_hash[cookbook_name].each_key do |segment|
242
241
  manifest_segment = cookbook_segment(cookbook_name, segment)
243
- manifest_record_paths = manifest_segment.map { |manifest_record| manifest_record["path"] }.to_set
244
- to_be_removed = cache_file_hash[cookbook_name][segment].keys.to_set - manifest_record_paths
242
+ manifest_record_paths = manifest_segment.map { |manifest_record| manifest_record["path"] }
243
+ to_be_removed = cache_file_hash[cookbook_name][segment].keys - manifest_record_paths
245
244
  to_be_removed.each do |path|
246
245
  cache_file = cache_file_hash[cookbook_name][segment][path]
247
246
 
@@ -21,5 +21,9 @@ class Chef
21
21
  # super returns a "Proc" (which seems buggy) so re-wrap it
22
22
  self.class.new(&super) # rubocop:disable Layout/SpaceAroundKeyword
23
23
  end
24
+
25
+ def inspect
26
+ "lazy { (evaluates to) #{call.inspect} }"
27
+ end
24
28
  end
25
29
  end
@@ -324,7 +324,10 @@ class Chef
324
324
  acls += mode_ace(SID.Everyone, (mode & 07))
325
325
  end
326
326
 
327
- acls.nil? ? nil : Chef::ReservedNames::Win32::Security::ACL.create(acls)
327
+ # 'acls.nil?' is true if uninitialized, but false if the initial empty array value.
328
+ # 'acls.empty?' cannot be called if acls is nil but successfully guards against using the empty array value.
329
+ # either case should return nil from this method.
330
+ (acls.nil? || acls.empty?) ? nil : Chef::ReservedNames::Win32::Security::ACL.create(acls)
328
331
  end
329
332
 
330
333
  def target_group
@@ -77,6 +77,8 @@ class Chef
77
77
  @resource.updated
78
78
  rescue Mixlib::ShellOut::ShellCommandFailed
79
79
  nil
80
+ rescue ChefPowerShell::PowerShellExceptions::PowerShellCommandFailed
81
+ nil
80
82
  end
81
83
  end
82
84
 
@@ -61,8 +61,11 @@ class Chef
61
61
  if brew_bin_path && ::File.exist?(brew_bin_path)
62
62
  brew_bin_path
63
63
  else
64
- brew_bin_path = [which("brew"), "/opt/homebrew/bin/brew", "/usr/local/bin/brew", "/home/linuxbrew/.linuxbrew/bin/brew"].uniq.select { |x| ::File.exist?(x) && ::File.executable?(x) }.first
65
- brew_bin_path || nil
64
+ [which("brew"), "/opt/homebrew/bin/brew", "/usr/local/bin/brew", "/home/linuxbrew/.linuxbrew/bin/brew"].uniq.select do |x|
65
+ next if x == false
66
+
67
+ ::File.exist?(x) && ::File.executable?(x)
68
+ end.first || nil
66
69
  end
67
70
  end
68
71
 
@@ -75,7 +78,7 @@ class Chef
75
78
  owner = ::File.stat(brew_path).uid
76
79
  else
77
80
  raise Chef::Exceptions::CannotDetermineHomebrewOwner,
78
- 'Could not find the "brew" executable anywhere on the path.'
81
+ 'Couldn\'t find the "brew" executable anywhere on the path.'
79
82
  end
80
83
 
81
84
  Chef::Log.debug "Found Homebrew owner #{Etc.getpwuid(owner).name}; executing `brew` commands as them"
@@ -23,7 +23,7 @@ if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
23
23
  conn_port = port
24
24
  end
25
25
 
26
- puts "opening connection to #{conn_addr}:#{conn_port}..."
26
+ Chef::Log.debug("opening connection to #{conn_addr}:#{conn_port}...")
27
27
  s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
28
28
  begin
29
29
  TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
@@ -33,7 +33,7 @@ if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
33
33
  end
34
34
  }
35
35
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
36
- puts "opened"
36
+ Chef::Log.debug("opened")
37
37
  if use_ssl?
38
38
  if proxy?
39
39
  plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
@@ -92,7 +92,7 @@ if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
92
92
  ssl_host_address = @address
93
93
  end
94
94
 
95
- puts "starting SSL for #{conn_addr}:#{conn_port}..."
95
+ Chef::Log.debug("starting SSL for #{conn_addr}:#{conn_port}...")
96
96
  s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
97
97
  s.sync_close = true
98
98
  s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
@@ -105,7 +105,7 @@ if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
105
105
  if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
106
106
  s.post_connection_check(@address)
107
107
  end
108
- puts "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
108
+ Chef::Log.debug("SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}")
109
109
  end
110
110
  @socket = BufferedIO.new(s, read_timeout: @read_timeout,
111
111
  write_timeout: @write_timeout,
@@ -115,7 +115,7 @@ if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
115
115
  on_connect
116
116
  rescue => exception
117
117
  if s
118
- puts "Conn close because of connect error #{exception}"
118
+ Chef::Log.debug("Conn close because of connect error #{exception}")
119
119
  s.close
120
120
  end
121
121
  raise
@@ -18,6 +18,7 @@
18
18
 
19
19
  require_relative "common_api"
20
20
  require_relative "mixin/state_tracking"
21
+ require_relative "mixin/state_tracking_array"
21
22
  require_relative "mixin/immutablize_array"
22
23
  require_relative "mixin/immutablize_hash"
23
24
  require_relative "mixin/mashy_array"
@@ -97,7 +98,7 @@ class Chef
97
98
  key
98
99
  end
99
100
 
100
- prepend Chef::Node::Mixin::StateTracking
101
+ prepend Chef::Node::Mixin::StateTrackingArray
101
102
  end
102
103
 
103
104
  # == VividMash
@@ -17,6 +17,7 @@
17
17
 
18
18
  require_relative "common_api"
19
19
  require_relative "mixin/state_tracking"
20
+ require_relative "mixin/state_tracking_array"
20
21
  require_relative "mixin/immutablize_array"
21
22
  require_relative "mixin/immutablize_hash"
22
23
  require_relative "../delayed_evaluator"
@@ -119,7 +120,7 @@ class Chef
119
120
  value
120
121
  end
121
122
 
122
- prepend Chef::Node::Mixin::StateTracking
123
+ prepend Chef::Node::Mixin::StateTrackingArray
123
124
  prepend Chef::Node::Mixin::ImmutablizeArray
124
125
  end
125
126
 
@@ -0,0 +1,41 @@
1
+ #--
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
+
18
+ require_relative "immutablize_array"
19
+ require_relative "state_tracking"
20
+
21
+ class Chef
22
+ class Node
23
+ module Mixin
24
+ module StateTrackingArray
25
+ include ::Chef::Node::Mixin::StateTracking
26
+
27
+ MUTATOR_METHODS = Chef::Node::Mixin::ImmutablizeArray::DISALLOWED_MUTATOR_METHODS
28
+
29
+ # For all of the methods that may mutate an Array, we override them to
30
+ # also track the state and trigger attribute_changed event.
31
+ MUTATOR_METHODS.each do |mutator|
32
+ define_method(mutator) do |*args, &block|
33
+ ret = super(*args, &block)
34
+ send_attribute_changed_event(__path__, self)
35
+ ret
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/chef/node.rb CHANGED
@@ -401,6 +401,13 @@ class Chef
401
401
  normal[:tags]
402
402
  end
403
403
 
404
+ # Add the list of tags to the node.
405
+ #
406
+ # === Parameters
407
+ # tags<Array>:: A list of tags
408
+ #
409
+ # === Returns
410
+ # tags<Array>:: The current list of run_context.node.tags
404
411
  def tag(*args)
405
412
  args.each do |tag|
406
413
  tags.push(tag.to_s) unless tags.include? tag.to_s
@@ -409,6 +416,21 @@ class Chef
409
416
  tags
410
417
  end
411
418
 
419
+ # Removes the list of tags from the node.
420
+ #
421
+ # === Parameters
422
+ # tags<Array>:: A list of tags
423
+ #
424
+ # === Returns
425
+ # tags<Array>:: The current list of run_context.node.tags
426
+ def untag(*args)
427
+ args.each do |tag|
428
+ tags.delete(tag.to_s)
429
+ end
430
+
431
+ tags
432
+ end
433
+
412
434
  # Extracts the run list from +attrs+ and applies it. Returns the remaining attributes
413
435
  def consume_run_list(attrs)
414
436
  attrs = attrs ? attrs.dup : {}
@@ -124,6 +124,11 @@ 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
+
127
132
  # @return [String] version of apt-get which is installed
128
133
  def apt_version
129
134
  @apt_version ||= shell_out("apt-get --version").stdout.match(/^apt (\S+)/)[1]
@@ -174,10 +179,12 @@ class Chef
174
179
  end
175
180
 
176
181
  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)
177
184
  current_version = nil
178
185
  candidate_version = nil
179
186
  all_versions = []
180
- run_noninteractive("apt-cache", default_release_options, "policy", pkg).stdout.each_line do |line|
187
+ run_noninteractive("apt-cache", default_release_options, "policy", pkg_name).stdout.each_line do |line|
181
188
  case line
182
189
  when /^\s{2}Installed: (.+)$/
183
190
  current_version = ( $1 != "(none)" ) ? $1 : nil
@@ -216,7 +223,9 @@ class Chef
216
223
  end
217
224
 
218
225
  def resolve_virtual_package_name(pkg)
219
- showpkg = run_noninteractive("apt-cache", "showpkg", pkg).stdout
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
220
229
  partitions = showpkg.rpartition(/Reverse Provides: ?#{$/}/)
221
230
  return nil if partitions[0] == "" && partitions[1] == "" # not found in output
222
231