chef 18.2.7 → 18.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/chef-universal-mingw-ucrt.gemspec +1 -1
- data/chef.gemspec +3 -3
- data/lib/chef/application/base.rb +2 -0
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +7 -9
- data/lib/chef/client.rb +2 -2
- data/lib/chef/cookbook/synchronizer.rb +19 -2
- data/lib/chef/cookbook_version.rb +1 -1
- data/lib/chef/delayed_evaluator.rb +4 -0
- data/lib/chef/file_access_control/windows.rb +4 -1
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -0
- data/lib/chef/http/ssl_policies.rb +2 -2
- data/lib/chef/mixin/homebrew_user.rb +15 -5
- data/lib/chef/monkey_patches/net-http.rb +127 -0
- data/lib/chef/node/attribute_collections.rb +10 -1
- data/lib/chef/node/immutable_collections.rb +7 -3
- data/lib/chef/node/mixin/state_tracking.rb +1 -1
- data/lib/chef/node/mixin/state_tracking_array.rb +41 -0
- data/lib/chef/node.rb +22 -0
- data/lib/chef/provider/launchd.rb +1 -1
- data/lib/chef/provider/mount/linux.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +5 -5
- data/lib/chef/provider/package/apt.rb +11 -2
- data/lib/chef/provider/package/chocolatey.rb +239 -18
- data/lib/chef/provider/package/zypper.rb +6 -0
- data/lib/chef/provider/powershell_script.rb +96 -6
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/service/systemd.rb +23 -8
- data/lib/chef/provider/service/windows.rb +1 -0
- data/lib/chef/provider/service.rb +14 -0
- data/lib/chef/provider/user.rb +5 -1
- data/lib/chef/provider/yum_repository.rb +1 -1
- data/lib/chef/recipe.rb +3 -11
- data/lib/chef/resource/_rest_resource.rb +1 -1
- data/lib/chef/resource/apt_package.rb +19 -0
- data/lib/chef/resource/apt_repository.rb +26 -6
- data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
- data/lib/chef/resource/chocolatey_installer.rb +207 -0
- data/lib/chef/resource/chocolatey_package.rb +8 -0
- data/lib/chef/resource/homebrew_cask.rb +6 -7
- data/lib/chef/resource/homebrew_package.rb +1 -1
- data/lib/chef/resource/homebrew_tap.rb +5 -5
- data/lib/chef/resource/launchd.rb +5 -1
- data/lib/chef/resource/locale.rb +5 -2
- data/lib/chef/resource/macos_pkg.rb +111 -0
- data/lib/chef/resource/powershell_script.rb +5 -1
- data/lib/chef/resource/service.rb +3 -0
- data/lib/chef/resource/sudo.rb +37 -2
- data/lib/chef/resource/support/ulimit.erb +40 -0
- data/lib/chef/resource/user_ulimit.rb +38 -0
- data/lib/chef/resource/windows_certificate.rb +1 -1
- data/lib/chef/resource/windows_security_policy.rb +2 -2
- data/lib/chef/resource.rb +11 -1
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/security.rb +7 -1
- data/spec/data/trusted_certs/example.crt +29 -20
- data/spec/data/trusted_certs/example_no_cn.crt +30 -34
- data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/functional/resource/windows_certificate_spec.rb +25 -0
- data/spec/functional/resource/zypper_package_spec.rb +10 -0
- data/spec/unit/client_spec.rb +2 -2
- data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
- data/spec/unit/delayed_evaluator_spec.rb +35 -0
- data/spec/unit/mixin/homebrew_user_spec.rb +30 -7
- data/spec/unit/node/vivid_mash_spec.rb +42 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/provider/apt_repository_spec.rb +17 -7
- data/spec/unit/provider/launchd_spec.rb +2 -2
- data/spec/unit/provider/mount/aix_spec.rb +2 -2
- data/spec/unit/provider/mount/linux_spec.rb +6 -5
- data/spec/unit/provider/mount/mount_spec.rb +8 -8
- data/spec/unit/provider/package/apt_spec.rb +18 -13
- data/spec/unit/provider/package/chocolatey_spec.rb +53 -9
- data/spec/unit/provider/package/rpm_spec.rb +2 -2
- data/spec/unit/provider/package/zypper_spec.rb +10 -0
- data/spec/unit/provider/powershell_script_spec.rb +100 -4
- data/spec/unit/provider/remote_file/http_spec.rb +4 -4
- data/spec/unit/provider/service/systemd_service_spec.rb +1 -0
- data/spec/unit/provider/user/linux_spec.rb +10 -0
- data/spec/unit/resource/apt_repository_spec.rb +5 -0
- data/spec/unit/resource/chef_client_systemd_timer_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_installer_spec.rb +151 -0
- data/spec/unit/resource/macos_pkg_spec.rb +38 -0
- data/spec/unit/resource/powershell_script_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +86 -0
- metadata +29 -16
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b0abf8303fae83df7a99b7731d5e3eedd3dcb5f533cbc9c784527682b3daaa6
|
4
|
+
data.tar.gz: a0fa3f6ee5de4413da2bc2a8e7f41d6d50d320f7c7d2cc080cbda5c9c7bf4604
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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", "
|
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
|
|
@@ -15,7 +15,7 @@ gemspec.add_dependency "wmi-lite", "~> 1.0"
|
|
15
15
|
gemspec.add_dependency "win32-taskscheduler", "~> 2.0"
|
16
16
|
gemspec.add_dependency "iso8601", ">= 0.12.1", "< 0.14" # validate 0.14 when it comes out
|
17
17
|
gemspec.add_dependency "win32-certstore", "~> 0.6.15" # 0.5+ required for specifying user vs. system store
|
18
|
-
gemspec.add_dependency "chef-powershell", "~> 18.
|
18
|
+
gemspec.add_dependency "chef-powershell", "~> 18.1.0" # The guts of the powershell_exec code have been moved to its own gem, chef-powershell. It's part of the chef-powershell-shim repo.
|
19
19
|
|
20
20
|
gemspec.extensions << "ext/win32-eventlog/Rakefile"
|
21
21
|
gemspec.files += Dir.glob("{distro,ext}/**/*")
|
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", "
|
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", "
|
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"
|
@@ -24,6 +24,8 @@ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
|
24
24
|
require_relative "../daemon"
|
25
25
|
require "chef-config/mixin/dot_d"
|
26
26
|
require "license_acceptance/cli_flags/mixlib_cli"
|
27
|
+
require "chef/monkey_patches/net-http"
|
28
|
+
|
27
29
|
module Mixlib
|
28
30
|
autoload :Archive, "mixlib/archive"
|
29
31
|
end
|
@@ -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
|
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] =~ /^#{
|
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(/^#{
|
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(
|
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 =~ /^#{
|
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
|
119
|
+
elsif /#{PathUtils::REGEXP_PATH_SEPARATOR}/.match?(path[ancestor.length, 1])
|
122
120
|
path[ancestor.length + 1..-1]
|
123
121
|
else
|
124
122
|
nil
|
data/lib/chef/client.rb
CHANGED
@@ -663,7 +663,7 @@ class Chef
|
|
663
663
|
logger.trace("New client keys created in the Certificate Store - skipping registration")
|
664
664
|
end
|
665
665
|
events.skipping_registration(client_name, config)
|
666
|
-
elsif File.
|
666
|
+
elsif File.exist?(config[:client_key])
|
667
667
|
events.skipping_registration(client_name, config)
|
668
668
|
logger.trace("Client key #{config[:client_key]} is present - skipping registration")
|
669
669
|
else
|
@@ -1069,7 +1069,7 @@ class Chef
|
|
1069
1069
|
end
|
1070
1070
|
|
1071
1071
|
def empty_directory?(path)
|
1072
|
-
!File.
|
1072
|
+
!File.exist?(path) || (Dir.entries(path).size <= 2)
|
1073
1073
|
end
|
1074
1074
|
|
1075
1075
|
def is_last_element?(index, object)
|
@@ -219,14 +219,31 @@ class Chef
|
|
219
219
|
|
220
220
|
# remove deleted files in cookbooks that are being used on the node
|
221
221
|
def remove_deleted_files
|
222
|
+
cache_file_hash = {}
|
223
|
+
@cookbooks_by_name.each_key do |k|
|
224
|
+
cache_file_hash[k] = {}
|
225
|
+
end
|
226
|
+
|
227
|
+
# First populate files from cache
|
222
228
|
cache.find(File.join(%w{cookbooks ** {*,.*}})).each do |cache_file|
|
223
229
|
md = cache_file.match(%r{^cookbooks/([^/]+)/([^/]+)/(.*)})
|
224
230
|
next unless md
|
225
231
|
|
226
|
-
(
|
232
|
+
(cookbook_name, segment, file) = md[1..3]
|
227
233
|
if have_cookbook?(cookbook_name)
|
234
|
+
cache_file_hash[cookbook_name][segment] ||= {}
|
235
|
+
cache_file_hash[cookbook_name][segment]["#{segment}/#{file}"] = cache_file
|
236
|
+
end
|
237
|
+
end
|
238
|
+
# Determine which files don't match manifest
|
239
|
+
@cookbooks_by_name.each_key do |cookbook_name|
|
240
|
+
cache_file_hash[cookbook_name].each_key do |segment|
|
228
241
|
manifest_segment = cookbook_segment(cookbook_name, segment)
|
229
|
-
|
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
|
244
|
+
to_be_removed.each do |path|
|
245
|
+
cache_file = cache_file_hash[cookbook_name][segment][path]
|
246
|
+
|
230
247
|
Chef::Log.info("Removing #{cache_file} from the cache; its is no longer in the cookbook manifest.")
|
231
248
|
cache.delete(cache_file)
|
232
249
|
@events.removed_cookbook_file(cache_file)
|
@@ -324,7 +324,10 @@ class Chef
|
|
324
324
|
acls += mode_ace(SID.Everyone, (mode & 07))
|
325
325
|
end
|
326
326
|
|
327
|
-
acls.nil?
|
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
|
@@ -103,10 +103,10 @@ class Chef
|
|
103
103
|
unless config[:ssl_client_cert] && config[:ssl_client_key]
|
104
104
|
raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
|
105
105
|
end
|
106
|
-
unless ::File.
|
106
|
+
unless ::File.exist?(config[:ssl_client_cert])
|
107
107
|
raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
|
108
108
|
end
|
109
|
-
unless ::File.
|
109
|
+
unless ::File.exist?(config[:ssl_client_key])
|
110
110
|
raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
|
111
111
|
end
|
112
112
|
|
@@ -57,18 +57,28 @@ class Chef
|
|
57
57
|
@homebrew_owner_username
|
58
58
|
end
|
59
59
|
|
60
|
+
def homebrew_bin_path(brew_bin_path = nil)
|
61
|
+
if brew_bin_path && ::File.exist?(brew_bin_path)
|
62
|
+
brew_bin_path
|
63
|
+
else
|
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
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
60
72
|
private
|
61
73
|
|
62
74
|
def calculate_owner
|
63
|
-
|
64
|
-
if
|
75
|
+
brew_path = homebrew_bin_path
|
76
|
+
if brew_path
|
65
77
|
# By default, this follows symlinks which is what we want
|
66
|
-
owner = ::File.stat(default_brew_path).uid
|
67
|
-
elsif (brew_path = shell_out("which brew").stdout.strip) && !brew_path.empty?
|
68
78
|
owner = ::File.stat(brew_path).uid
|
69
79
|
else
|
70
80
|
raise Chef::Exceptions::CannotDetermineHomebrewOwner,
|
71
|
-
'
|
81
|
+
'Couldn\'t find the "brew" executable anywhere on the path.'
|
72
82
|
end
|
73
83
|
|
74
84
|
Chef::Log.debug "Found Homebrew owner #{Etc.getpwuid(owner).name}; executing `brew` commands as them"
|
@@ -0,0 +1,127 @@
|
|
1
|
+
if RUBY_VERSION.split(".")[0..1].join(".") == "3.1"
|
2
|
+
require "net/http" unless defined?(Net::HTTP)
|
3
|
+
# This is monkey-patch for ruby 3.1.x
|
4
|
+
# Due to change https://github.com/ruby/net-http/pull/10, when making net/http requests to a url which supports only IPv6 and not IPv4,
|
5
|
+
# ruby waits for IPv4 request to timeout first, then makes IPv6 request. This increased response time.
|
6
|
+
# NOTE 1: This is already reverted https://github.com/ruby/ruby/commit/f88bff770578583a708093f4a0d8b1483a1d2039 but under ruby 3.2.2
|
7
|
+
# NOTE 2: We are patching action `connect` from here https://github.com/ruby/ruby/blob/f88bff770578583a708093f4a0d8b1483a1d2039/lib/net/http.rb#L1000
|
8
|
+
|
9
|
+
module Net
|
10
|
+
class HTTP
|
11
|
+
def connect
|
12
|
+
if use_ssl?
|
13
|
+
# reference early to load OpenSSL before connecting,
|
14
|
+
# as OpenSSL may take time to load.
|
15
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
16
|
+
end
|
17
|
+
|
18
|
+
if proxy?
|
19
|
+
conn_addr = proxy_address
|
20
|
+
conn_port = proxy_port
|
21
|
+
else
|
22
|
+
conn_addr = conn_address
|
23
|
+
conn_port = port
|
24
|
+
end
|
25
|
+
|
26
|
+
Chef::Log.debug("opening connection to #{conn_addr}:#{conn_port}...")
|
27
|
+
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
|
28
|
+
begin
|
29
|
+
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
|
30
|
+
rescue => e
|
31
|
+
raise e, "Failed to open TCP connection to " +
|
32
|
+
"#{conn_addr}:#{conn_port} (#{e.message})"
|
33
|
+
end
|
34
|
+
}
|
35
|
+
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
36
|
+
Chef::Log.debug("opened")
|
37
|
+
if use_ssl?
|
38
|
+
if proxy?
|
39
|
+
plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
|
40
|
+
write_timeout: @write_timeout,
|
41
|
+
continue_timeout: @continue_timeout,
|
42
|
+
debug_output: @debug_output)
|
43
|
+
buf = "CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n"
|
44
|
+
buf << "Host: #{@address}:#{@port}\r\n"
|
45
|
+
if proxy_user
|
46
|
+
credential = ["#{proxy_user}:#{proxy_pass}"].pack("m0")
|
47
|
+
buf << "Proxy-Authorization: Basic #{credential}\r\n"
|
48
|
+
end
|
49
|
+
buf << "\r\n"
|
50
|
+
plain_sock.write(buf)
|
51
|
+
HTTPResponse.read_new(plain_sock).value
|
52
|
+
# assuming nothing left in buffers after successful CONNECT response
|
53
|
+
end
|
54
|
+
|
55
|
+
ssl_parameters = {}
|
56
|
+
iv_list = instance_variables
|
57
|
+
SSL_IVNAMES.each_with_index do |ivname, i|
|
58
|
+
if iv_list.include?(ivname)
|
59
|
+
value = instance_variable_get(ivname)
|
60
|
+
unless value.nil?
|
61
|
+
ssl_parameters[SSL_ATTRIBUTES[i]] = value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
@ssl_context.set_params(ssl_parameters)
|
66
|
+
unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
|
67
|
+
@ssl_context.session_cache_mode =
|
68
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
|
69
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
|
70
|
+
end
|
71
|
+
if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
|
72
|
+
@ssl_context.session_new_cb = proc { |sock, sess| @ssl_session = sess }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Still do the post_connection_check below even if connecting
|
76
|
+
# to IP address
|
77
|
+
verify_hostname = @ssl_context.verify_hostname
|
78
|
+
|
79
|
+
# requiring 'resolv' near the top of the file causes registry.rb monkey patch to fail
|
80
|
+
# Windows 2012 R2 somehow fails to have Resolv defined unless we require it manually
|
81
|
+
require "resolv" unless defined?(Resolv)
|
82
|
+
|
83
|
+
# Server Name Indication (SNI) RFC 3546/6066
|
84
|
+
case @address
|
85
|
+
when ::Resolv::IPv4::Regex, ::Resolv::IPv6::Regex
|
86
|
+
# don't set SNI, as IP addresses in SNI is not valid
|
87
|
+
# per RFC 6066, section 3.
|
88
|
+
|
89
|
+
# Avoid openssl warning
|
90
|
+
@ssl_context.verify_hostname = false
|
91
|
+
else
|
92
|
+
ssl_host_address = @address
|
93
|
+
end
|
94
|
+
|
95
|
+
Chef::Log.debug("starting SSL for #{conn_addr}:#{conn_port}...")
|
96
|
+
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
|
97
|
+
s.sync_close = true
|
98
|
+
s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
|
99
|
+
|
100
|
+
if @ssl_session &&
|
101
|
+
(Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout)
|
102
|
+
s.session = @ssl_session
|
103
|
+
end
|
104
|
+
ssl_socket_connect(s, @open_timeout)
|
105
|
+
if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
|
106
|
+
s.post_connection_check(@address)
|
107
|
+
end
|
108
|
+
Chef::Log.debug("SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}")
|
109
|
+
end
|
110
|
+
@socket = BufferedIO.new(s, read_timeout: @read_timeout,
|
111
|
+
write_timeout: @write_timeout,
|
112
|
+
continue_timeout: @continue_timeout,
|
113
|
+
debug_output: @debug_output)
|
114
|
+
@last_communicated = nil
|
115
|
+
on_connect
|
116
|
+
rescue => exception
|
117
|
+
if s
|
118
|
+
Chef::Log.debug("Conn close because of connect error #{exception}")
|
119
|
+
s.close
|
120
|
+
end
|
121
|
+
raise
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
else
|
126
|
+
warn "Not applying net/http monkey patch needed for ruby 3.1"
|
127
|
+
end
|
@@ -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"
|
@@ -39,11 +40,19 @@ class Chef
|
|
39
40
|
MUTATOR_METHODS.each do |mutator|
|
40
41
|
define_method(mutator) do |*args, &block|
|
41
42
|
ret = super(*args, &block)
|
43
|
+
# TODO: use `send_reset_cache(__path__)` for all mutator methods?
|
42
44
|
send_reset_cache
|
43
45
|
ret
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
49
|
+
def <<(obj)
|
50
|
+
ret = super(obj)
|
51
|
+
# NOTE: Expecting __path__ to be top-level attribute only
|
52
|
+
send_reset_cache(__path__)
|
53
|
+
ret
|
54
|
+
end
|
55
|
+
|
47
56
|
def delete(key, &block)
|
48
57
|
send_reset_cache(__path__, key)
|
49
58
|
super
|
@@ -89,7 +98,7 @@ class Chef
|
|
89
98
|
key
|
90
99
|
end
|
91
100
|
|
92
|
-
prepend Chef::Node::Mixin::
|
101
|
+
prepend Chef::Node::Mixin::StateTrackingArray
|
93
102
|
end
|
94
103
|
|
95
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"
|
@@ -32,13 +33,16 @@ class Chef
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def convert_value(value)
|
36
|
+
# The order in this case statement is *important*.
|
37
|
+
# ImmutableMash and ImmutableArray should be tested first,
|
38
|
+
# as this saves unnecessary creation of intermediate objects
|
35
39
|
case value
|
40
|
+
when ImmutableMash, ImmutableArray
|
41
|
+
value
|
36
42
|
when Hash
|
37
43
|
ImmutableMash.new(value, __root__, __node__, __precedence__)
|
38
44
|
when Array
|
39
45
|
ImmutableArray.new(value, __root__, __node__, __precedence__)
|
40
|
-
when ImmutableMash, ImmutableArray
|
41
|
-
value
|
42
46
|
else
|
43
47
|
safe_dup(value).freeze
|
44
48
|
end
|
@@ -116,7 +120,7 @@ class Chef
|
|
116
120
|
value
|
117
121
|
end
|
118
122
|
|
119
|
-
prepend Chef::Node::Mixin::
|
123
|
+
prepend Chef::Node::Mixin::StateTrackingArray
|
120
124
|
prepend Chef::Node::Mixin::ImmutablizeArray
|
121
125
|
end
|
122
126
|
|
@@ -78,7 +78,7 @@ class Chef
|
|
78
78
|
|
79
79
|
def send_reset_cache(path = nil, key = nil)
|
80
80
|
next_path = [ path, key ].flatten.compact
|
81
|
-
__root__.reset_cache(next_path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache)
|
81
|
+
__root__.reset_cache(next_path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache)
|
82
82
|
end
|
83
83
|
|
84
84
|
def copy_state_to(ret, next_path)
|
@@ -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 : {}
|
@@ -39,7 +39,7 @@ class Chef
|
|
39
39
|
|
40
40
|
def mounted?
|
41
41
|
mounted = false
|
42
|
-
real_mount_point = if ::File.
|
42
|
+
real_mount_point = if ::File.exist? @new_resource.mount_point
|
43
43
|
::File.realpath(@new_resource.mount_point)
|
44
44
|
else
|
45
45
|
@new_resource.mount_point
|
@@ -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.
|
45
|
+
if device_should_exist? && !::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.
|
47
|
+
elsif @new_resource.mount_point != "none" && !::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
|
|
@@ -81,7 +81,7 @@ 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.
|
84
|
+
real_mount_point = if ::File.exist? @new_resource.mount_point
|
85
85
|
::File.realpath(@new_resource.mount_point)
|
86
86
|
else
|
87
87
|
@new_resource.mount_point
|
@@ -186,7 +186,7 @@ class Chef
|
|
186
186
|
def device_should_exist?
|
187
187
|
( @new_resource.device != "none" ) &&
|
188
188
|
( not network_device? ) &&
|
189
|
-
( not %w{ cgroup tmpfs fuse vboxsf zfs }.include? @new_resource.fstype )
|
189
|
+
( not %w{ cgroup tmpfs fuse vboxsf zfs efivarfs }.include? @new_resource.fstype )
|
190
190
|
end
|
191
191
|
|
192
192
|
private
|
@@ -287,4 +287,4 @@ class Chef
|
|
287
287
|
end
|
288
288
|
end
|
289
289
|
end
|
290
|
-
end
|
290
|
+
end
|
@@ -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",
|
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
|
-
|
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
|
|