chef 18.7.6 → 18.8.9
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.
- checksums.yaml +4 -4
- data/Gemfile +4 -3
- data/Rakefile +1 -0
- data/chef.gemspec +11 -3
- data/lib/chef/cookbook_version.rb +34 -0
- data/lib/chef/http/basic_client.rb +1 -0
- data/lib/chef/http.rb +1 -0
- data/lib/chef/provider/package/apt.rb +1 -1
- data/lib/chef/provider/package/bff.rb +5 -0
- data/lib/chef/provider/package/cab.rb +9 -0
- data/lib/chef/provider/package/chocolatey.rb +6 -1
- data/lib/chef/provider/package/deb.rb +1 -1
- data/lib/chef/provider/package/dnf.rb +3 -3
- data/lib/chef/provider/package/habitat.rb +9 -0
- data/lib/chef/provider/package/homebrew.rb +9 -0
- data/lib/chef/provider/package/ips.rb +5 -0
- data/lib/chef/provider/package/macports.rb +9 -0
- data/lib/chef/provider/package/msu.rb +9 -0
- data/lib/chef/provider/package/openbsd.rb +7 -2
- data/lib/chef/provider/package/pacman.rb +9 -0
- data/lib/chef/provider/package/paludis.rb +9 -0
- data/lib/chef/provider/package/portage.rb +9 -0
- data/lib/chef/provider/package/powershell.rb +6 -1
- data/lib/chef/provider/package/rpm.rb +3 -3
- data/lib/chef/provider/package/rubygems.rb +9 -0
- data/lib/chef/provider/package/smartos.rb +9 -0
- data/lib/chef/provider/package/snap.rb +6 -1
- data/lib/chef/provider/package/solaris.rb +5 -0
- data/lib/chef/provider/package/windows.rb +5 -0
- data/lib/chef/provider/package/yum.rb +3 -3
- data/lib/chef/provider/package/zypper.rb +5 -0
- data/lib/chef/recipe.rb +20 -0
- data/lib/chef/resource/apt_package.rb +5 -0
- data/lib/chef/resource/apt_repository.rb +48 -21
- data/lib/chef/resource/archive_file.rb +49 -2
- data/lib/chef/resource/dnf_package.rb +5 -0
- data/lib/chef/resource/dpkg_package.rb +5 -0
- data/lib/chef/resource/ohai.rb +10 -0
- data/lib/chef/resource/package.rb +5 -0
- data/lib/chef/resource/rpm_package.rb +5 -0
- data/lib/chef/resource/yum_package.rb +5 -0
- data/lib/chef/shell.rb +13 -4
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/version.rb +2 -1
- data/spec/functional/resource/git_spec.rb +2 -1
- data/spec/integration/client/open_ssl_spec.rb +7 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/cookbook_version_spec.rb +39 -0
- data/spec/unit/node/attribute_spec.rb +1 -1
- data/spec/unit/provider/apt_repository_spec.rb +85 -8
- data/spec/unit/provider/package/rpm_spec.rb +10 -10
- data/spec/unit/recipe_spec.rb +51 -0
- data/spec/unit/resource/apt_package_spec.rb +5 -0
- data/spec/unit/resource/dnf_package_spec.rb +6 -0
- data/spec/unit/resource/ohai_spec.rb +73 -0
- data/spec/unit/resource/yum_package_spec.rb +9 -0
- data/spec/unit/resource_reporter_spec.rb +0 -58
- data/spec/unit/shell_spec.rb +31 -11
- data/tasks/rspec.rb +1 -1
- metadata +48 -14
@@ -237,17 +237,28 @@ class Chef
|
|
237
237
|
valid
|
238
238
|
end
|
239
239
|
|
240
|
-
# validate the key against the
|
240
|
+
# validate the key against the gpg keyring to see if that version is expired or revoked
|
241
241
|
# @param [String] key
|
242
|
+
# @param [String] keyring
|
242
243
|
#
|
243
|
-
# @return [Boolean]
|
244
|
+
# @return [Boolean] if the key valid or not
|
244
245
|
def keyring_key_is_valid?(keyring, key)
|
245
|
-
|
246
|
+
out = shell_out("gpg", "--no-default-keyring", "--keyring", keyring, "--list-public-keys", key)
|
247
|
+
valid = out.exitstatus == 0 && out.stdout.each_line.none?(/\[(expired|revoked):/)
|
246
248
|
|
247
249
|
logger.debug "key #{key} #{valid ? "is valid" : "is not valid"}"
|
248
250
|
valid
|
249
251
|
end
|
250
252
|
|
253
|
+
# validate the key against the gpg keyring to see if the key is present
|
254
|
+
# @param [String] key
|
255
|
+
# @param [String] keyring
|
256
|
+
#
|
257
|
+
# @return [Boolean] if the key present
|
258
|
+
def keyring_key_is_present?(keyring, key)
|
259
|
+
shell_out(*%W{gpg --no-default-keyring --keyring #{keyring} --list-public-keys --with-fingerprint --with-colons #{key}}).exitstatus == 0
|
260
|
+
end
|
261
|
+
|
251
262
|
# return the specified cookbook name or the cookbook containing the
|
252
263
|
# resource.
|
253
264
|
#
|
@@ -284,7 +295,7 @@ class Chef
|
|
284
295
|
# @raise [Chef::Exceptions::FileNotFound] Key isn't remote or found in the current run
|
285
296
|
#
|
286
297
|
# @return [Symbol] :remote_file or :cookbook_file
|
287
|
-
def
|
298
|
+
def key_resource_type(uri)
|
288
299
|
if uri.start_with?("http")
|
289
300
|
:remote_file
|
290
301
|
elsif has_cookbook_file?(uri)
|
@@ -307,29 +318,46 @@ class Chef
|
|
307
318
|
# @return [void]
|
308
319
|
def install_key_from_uri(key)
|
309
320
|
key_name = key.gsub(/[^0-9A-Za-z\-]/, "_")
|
310
|
-
|
321
|
+
keyfile_tmp_path = ::File.join(Chef::Config[:file_cache_path], key_name)
|
322
|
+
keyfile_path = keyring_path
|
311
323
|
tmp_dir = Dir.mktmpdir(".gpg")
|
312
324
|
at_exit { FileUtils.remove_entry(tmp_dir) }
|
313
325
|
|
314
326
|
if new_resource.signed_by
|
315
|
-
keyfile_path = keyring_path
|
316
|
-
|
317
327
|
directory "/etc/apt/keyrings" do
|
318
328
|
mode "0755"
|
319
329
|
end
|
320
|
-
end
|
321
330
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
331
|
+
declare_resource(key_resource_type(key), keyfile_tmp_path) do
|
332
|
+
source key
|
333
|
+
mode "0644"
|
334
|
+
sensitive new_resource.sensitive
|
335
|
+
action :create
|
336
|
+
verify "gpg --homedir #{tmp_dir} %{path}"
|
337
|
+
notifies :delete, "file[#{keyfile_path}]", :immediately
|
338
|
+
notifies :run, "execute[dearmor #{keyfile_path}]", :immediately
|
339
|
+
end
|
340
|
+
|
341
|
+
execute "dearmor #{keyfile_path}" do
|
342
|
+
command [ "gpg", "--batch", "--yes", "--dearmor", "-o", keyfile_path, keyfile_tmp_path ]
|
343
|
+
default_env true
|
344
|
+
sensitive new_resource.sensitive
|
345
|
+
action :nothing
|
346
|
+
only_if { !::File.exist?(keyfile_path) || ::File.read(keyfile_path).include?("-----BEGIN PGP PUBLIC KEY BLOCK-----") }
|
347
|
+
end
|
348
|
+
|
349
|
+
file keyfile_path do
|
350
|
+
mode "0644"
|
351
|
+
end
|
352
|
+
else
|
353
|
+
declare_resource(key_resource_type(key), keyfile_path) do
|
354
|
+
source key
|
355
|
+
mode "0644"
|
356
|
+
sensitive new_resource.sensitive
|
357
|
+
action :create
|
358
|
+
verify "gpg --homedir #{tmp_dir} %{path}"
|
359
|
+
end
|
329
360
|
|
330
|
-
# If signed by is true, then we don't need to
|
331
|
-
# add to the default keyring
|
332
|
-
unless new_resource.signed_by
|
333
361
|
execute "apt-key add #{keyfile_path}" do
|
334
362
|
command [ "apt-key", "add", keyfile_path ]
|
335
363
|
default_env true
|
@@ -403,8 +431,7 @@ class Chef
|
|
403
431
|
default_env true
|
404
432
|
sensitive new_resource.sensitive
|
405
433
|
not_if do
|
406
|
-
|
407
|
-
present && keyring_key_is_valid?(keyring, key.upcase)
|
434
|
+
keyring_key_is_present?(keyring, key.upcase) && keyring_key_is_valid?(keyring, key.upcase)
|
408
435
|
end
|
409
436
|
notifies :run, "execute[apt-cache gencaches]", :immediately
|
410
437
|
end
|
@@ -420,7 +447,7 @@ class Chef
|
|
420
447
|
# @return [void]
|
421
448
|
def install_ppa_key(owner, repo)
|
422
449
|
url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}"
|
423
|
-
key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"')
|
450
|
+
key_id = Chef::HTTP::Simple.new(url, {}).get("signing_key_fingerprint").delete('"')
|
424
451
|
install_key_from_keyserver(key_id, "keyserver.ubuntu.com")
|
425
452
|
rescue Net::HTTPClientException => e
|
426
453
|
raise "Could not access Launchpad ppa API: #{e.message}"
|
@@ -21,10 +21,57 @@
|
|
21
21
|
require_relative "../resource"
|
22
22
|
require "fileutils" unless defined?(FileUtils)
|
23
23
|
begin
|
24
|
+
# The explicit call to FFI::DynamicLibrary.open was added to address an issue specific to the Habitat packaging of Chef Infra Client on windows.
|
25
|
+
# In the Habitat environment, the libarchive library (archive.dll) is installed in a non-standard location that is not included
|
26
|
+
# in the default search paths used by the FFI gem to locate dynamic libraries. The default search paths for FFI are:
|
27
|
+
# - <system library path>
|
28
|
+
# - /usr/lib
|
29
|
+
# - /usr/local/lib
|
30
|
+
# - /opt/local/lib
|
31
|
+
# These paths do not account for the Habitat package structure, where libraries are installed in isolated directories under
|
32
|
+
# the Habitat package path (e.g., C:/hab/pkgs/core/libarchive/<version>/bin on Windows).
|
33
|
+
#
|
34
|
+
# Without explicitly loading archive.dll using FFI::DynamicLibrary.open, the ffi-libarchive gem fails to locate and load the library,
|
35
|
+
# resulting in runtime errors when attempting to use the archive_file resource.
|
36
|
+
#
|
37
|
+
# This code dynamically determines the path to archive.dll using the Habitat CLI (`hab pkg path core/libarchive`) and explicitly
|
38
|
+
# loads the library using FFI::DynamicLibrary.open. This ensures that the library is correctly loaded in the Habitat environment.
|
39
|
+
#
|
40
|
+
# Note: This logic is gated by a check for Habitat-specific environment variables (HAB_CACHE_SRC_PATH or HAB_PKG_PATH) to ensure
|
41
|
+
# that it is only applied in Habitat runs. For other environments (e.g., Omnibus, plain gem installations, or git checkouts),
|
42
|
+
# the default behavior of FFI is sufficient, as the libraries are installed in standard locations or embedded paths that are
|
43
|
+
# included in the default search paths.
|
44
|
+
if RUBY_PLATFORM.match?(/mswin|mingw|windows/) && (ENV["HAB_CACHE_SRC_PATH"] || ENV["HAB_PKG_PATH"])
|
45
|
+
require "ffi" unless defined?(FFI)
|
46
|
+
require "open3" unless defined?(Open3)
|
47
|
+
# Dynamically determine the path to the core/libarchive package
|
48
|
+
stdout, stderr, status = Open3.capture3("hab pkg path core/libarchive")
|
49
|
+
unless status.success?
|
50
|
+
Chef::Log.debug("Failed to determine Habitat libarchive path: #{stderr}")
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
habitat_libarchive_path = File.join(stdout.strip.tr("\\", "/"), "bin")
|
55
|
+
unless Dir.exist?(habitat_libarchive_path)
|
56
|
+
Chef::Log.debug("Habitat libarchive path not found: #{habitat_libarchive_path}")
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
archive_dll_path = File.join(habitat_libarchive_path, "archive.dll")
|
61
|
+
unless File.exist?(archive_dll_path)
|
62
|
+
Chef::Log.debug("archive.dll not found in Habitat path: #{habitat_libarchive_path}")
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
FFI::DynamicLibrary.open(archive_dll_path, FFI::DynamicLibrary::RTLD_LAZY) # Explicitly load the DLL
|
67
|
+
Chef::Log.debug("Explicitly loaded archive.dll from Habitat path: #{archive_dll_path}")
|
68
|
+
end
|
69
|
+
|
24
70
|
# ffi-libarchive must be eager loaded see: https://github.com/chef/chef/issues/12228
|
25
71
|
require "ffi-libarchive" unless defined?(Archive::Reader)
|
26
|
-
rescue LoadError
|
27
|
-
STDERR.puts "ffi-libarchive could not be loaded
|
72
|
+
rescue LoadError => e
|
73
|
+
STDERR.puts "ffi-libarchive could not be loaded: #{e.message}"
|
74
|
+
STDERR.puts "libarchive is probably not installed on system, archive_file will not be available"
|
28
75
|
end
|
29
76
|
|
30
77
|
class Chef
|
@@ -71,6 +71,11 @@ class Chef
|
|
71
71
|
description: "Allow downgrading a package to satisfy requested version requirements.",
|
72
72
|
default: true,
|
73
73
|
desired_state: false
|
74
|
+
|
75
|
+
property :environment, Hash,
|
76
|
+
introduced: "18.8",
|
77
|
+
description: "A Hash of environment variables in the form of {'ENV_VARIABLE' => 'VALUE'} to be set before running the command.",
|
78
|
+
default: {}, desired_state: false
|
74
79
|
end
|
75
80
|
end
|
76
81
|
end
|
@@ -41,6 +41,11 @@ class Chef
|
|
41
41
|
description: "Allow downgrading a package to satisfy requested version requirements.",
|
42
42
|
default: true,
|
43
43
|
desired_state: false
|
44
|
+
|
45
|
+
property :environment, Hash,
|
46
|
+
introduced: "18.8",
|
47
|
+
description: "A Hash of environment variables in the form of {'ENV_VARIABLE' => 'VALUE'} to be set before running the command.",
|
48
|
+
default: {}, desired_state: false
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
data/lib/chef/resource/ohai.rb
CHANGED
@@ -84,6 +84,16 @@ class Chef
|
|
84
84
|
converge_by("re-run ohai and merge results into node attributes") do
|
85
85
|
ohai = ::Ohai::System.new
|
86
86
|
|
87
|
+
# Load any custom plugins from cookbooks if they exist
|
88
|
+
# This ensures that cookbook-provided Ohai plugins are available
|
89
|
+
# when the resource reloads Ohai data
|
90
|
+
ohai_plugin_path = Chef::Config[:ohai_segment_plugin_path]
|
91
|
+
if ohai_plugin_path && Dir.exist?(ohai_plugin_path) && !Dir.empty?(ohai_plugin_path)
|
92
|
+
# Configure Ohai to load plugins from the cookbook segment path
|
93
|
+
ohai.config[:plugin_path] << ohai_plugin_path
|
94
|
+
logger.trace("Added cookbook plugin path to ohai: #{ohai_plugin_path}")
|
95
|
+
end
|
96
|
+
|
87
97
|
# If new_resource.plugin is nil, ohai will reload all the plugins
|
88
98
|
# Otherwise it will only reload the specified plugin
|
89
99
|
# Note that any changes to plugins, or new plugins placed on
|
@@ -60,6 +60,11 @@ class Chef
|
|
60
60
|
description: "The amount of time (in seconds) to wait before timing out.",
|
61
61
|
desired_state: false
|
62
62
|
|
63
|
+
property :environment, Hash,
|
64
|
+
introduced: "18.8",
|
65
|
+
description: "A Hash of environment variables in the form of {'ENV_VARIABLE' => 'VALUE'} to be set before running the command.",
|
66
|
+
desired_state: false
|
67
|
+
|
63
68
|
end
|
64
69
|
end
|
65
70
|
end
|
@@ -39,6 +39,11 @@ class Chef
|
|
39
39
|
|
40
40
|
property :version, String,
|
41
41
|
description: "The version of a package to be installed or upgraded."
|
42
|
+
|
43
|
+
property :environment, Hash,
|
44
|
+
introduced: "18.8",
|
45
|
+
description: "A Hash of environment variables in the form of {'ENV_VARIABLE' => 'VALUE'} to be set before running the command.",
|
46
|
+
default: {}, desired_state: false
|
42
47
|
end
|
43
48
|
end
|
44
49
|
end
|
@@ -155,6 +155,11 @@ class Chef
|
|
155
155
|
|
156
156
|
property :yum_binary, String,
|
157
157
|
description: "The path to the yum binary."
|
158
|
+
|
159
|
+
property :environment, Hash,
|
160
|
+
introduced: "18.8",
|
161
|
+
description: "A Hash of environment variables in the form of {'ENV_VARIABLE' => 'VALUE'} to be set before running the command.",
|
162
|
+
default: {}, desired_state: false
|
158
163
|
end
|
159
164
|
end
|
160
165
|
end
|
data/lib/chef/shell.rb
CHANGED
@@ -132,11 +132,20 @@ module Shell
|
|
132
132
|
irb_conf[:IRB_RC] = lambda do |conf|
|
133
133
|
m = conf.main
|
134
134
|
|
135
|
-
|
136
|
-
|
135
|
+
# remove this clause for any Chef version that has upgraded to ruby >= 3.3.0
|
136
|
+
if RUBY_VERSION >= "3.3.0"
|
137
|
+
conf.prompt_c = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)} > "
|
138
|
+
conf.prompt_n = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)} ?> "
|
139
|
+
conf.prompt_s = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)}%l> "
|
140
|
+
else
|
141
|
+
# there's a bug if you use a left arrow and the alternative prompts
|
142
|
+
# ... looks like 3.1.0 < version < 3.3.0 have it, from my manual testing
|
143
|
+
conf.prompt_c = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)} (#{Chef::VERSION})> "
|
144
|
+
conf.prompt_n = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)}(#{Chef::VERSION})?> "
|
145
|
+
conf.prompt_s = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)}(#{Chef::VERSION})%l> "
|
146
|
+
end
|
137
147
|
conf.prompt_i = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)} (#{Chef::VERSION})> "
|
138
|
-
conf.
|
139
|
-
conf.prompt_s = "#{ChefUtils::Dist::Infra::EXEC}#{leader(m)}%l> "
|
148
|
+
conf.return_format = " => %s \n"
|
140
149
|
conf.use_tracer = false
|
141
150
|
conf.instance_variable_set(:@use_multiline, false)
|
142
151
|
conf.instance_variable_set(:@use_singleline, false)
|
data/lib/chef/version.rb
CHANGED
data/lib/chef/win32/version.rb
CHANGED
@@ -49,7 +49,8 @@ class Chef
|
|
49
49
|
private_class_method :method_name_from_marketing_name
|
50
50
|
|
51
51
|
WIN_VERSIONS = {
|
52
|
-
"Windows Server
|
52
|
+
"Windows Server 2025" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 25398 } },
|
53
|
+
"Windows Server 2022" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 20348 && build_number < 25398 } },
|
53
54
|
"Windows Server 2019" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 17763 && build_number < 20348 } },
|
54
55
|
"Windows 11" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 22000 } },
|
55
56
|
"Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 19044 && build_number < 22000 } },
|
@@ -263,7 +263,8 @@ describe Chef::Resource::Git do
|
|
263
263
|
|
264
264
|
context "when dealing with a repo with a degenerate tag named 'HEAD'" do
|
265
265
|
before do
|
266
|
-
shell_out!("git", "tag", "-m\"degenerate tag\"", "
|
266
|
+
shell_out!("git", "tag", "-m\"degenerate tag\"", "HEAD_TAG", "ed181b3419b6f489bedab282348162a110d6d3a1", cwd: origin_repo)
|
267
|
+
# The original tag name of 'HEAD' caused errors in new git clients since it's a reserved name.
|
267
268
|
end
|
268
269
|
|
269
270
|
it "checks out the (master) HEAD revision and ignores the tag" do
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "openssl"
|
2
3
|
|
3
4
|
describe "openssl checks" do
|
4
5
|
let(:openssl_version_default) do
|
5
6
|
if windows?
|
6
|
-
"3.
|
7
|
+
"3.2.4"
|
7
8
|
elsif macos?
|
8
9
|
"1.1.1m"
|
9
10
|
else
|
10
|
-
"3.
|
11
|
+
"3.2.4"
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
@@ -17,4 +18,8 @@ describe "openssl checks" do
|
|
17
18
|
expect(OpenSSL.const_get("OPENSSL_#{method.upcase}")).to match(openssl_version_default), "OpenSSL doesn't match omnibus_overrides.rb"
|
18
19
|
end
|
19
20
|
end
|
21
|
+
|
22
|
+
example "check SSL_ENV_HACK", windows_only: true, validate_only: true do
|
23
|
+
expect(defined?(::SSL_ENV_CACERT_PATCH)).to be_truthy, "SSL_ENV_CACERT_PATCH is not defined, did you forget to include the openssl-customization.rb file in your project?"
|
24
|
+
end
|
20
25
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -180,6 +180,7 @@ RSpec.configure do |config|
|
|
180
180
|
config.filter_run_excluding openssl_gte_101: true unless openssl_gte_101?
|
181
181
|
config.filter_run_excluding openssl_lt_101: true unless openssl_lt_101?
|
182
182
|
config.filter_run_excluding aes_256_gcm_only: true unless aes_256_gcm?
|
183
|
+
config.filter_run_excluding validate_only: true unless ENV["BUILDKITE_BUILD_URL"] =~ /validate/ && ENV.fetch("BUILDKITE_LABEL", "") !~ /(Integration |Functional |Unit )/
|
183
184
|
config.filter_run_excluding broken: true
|
184
185
|
config.filter_run_excluding not_wpar: true unless wpar?
|
185
186
|
config.filter_run_excluding not_supported_on_s390x: true unless s390x?
|
@@ -96,6 +96,45 @@ describe Chef::CookbookVersion do
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
+
describe "#recipe_json_filenames_by_name" do
|
100
|
+
let(:cookbook_version) { Chef::CookbookVersion.new("mycb", "/tmp/mycb") }
|
101
|
+
|
102
|
+
def files_for_recipe(extension)
|
103
|
+
[
|
104
|
+
{ name: "recipes/default.#{extension}", full_path: "/home/user/repo/cookbooks/test/recipes/default.#{extension}" },
|
105
|
+
{ name: "recipes/other.#{extension}", full_path: "/home/user/repo/cookbooks/test/recipes/other.#{extension}" },
|
106
|
+
]
|
107
|
+
end
|
108
|
+
|
109
|
+
%w{json}.each do |extension|
|
110
|
+
|
111
|
+
context "and JSON files are present including a recipes/default.#{extension}" do
|
112
|
+
before(:each) do
|
113
|
+
allow(cookbook_version).to receive(:files_for).with("recipes").and_return(files_for_recipe(extension))
|
114
|
+
end
|
115
|
+
|
116
|
+
context "and manifest does not include a root_files/recipe.#{extension}" do
|
117
|
+
it "returns all JSON recipes with a correct default of default.#{extension}" do
|
118
|
+
expect(cookbook_version.recipe_json_filenames_by_name).to eq({ "default" => "/home/user/repo/cookbooks/test/recipes/default.#{extension}",
|
119
|
+
"other" => "/home/user/repo/cookbooks/test/recipes/other.#{extension}" })
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "and manifest also includes a root_files/recipe.#{extension}" do
|
124
|
+
let(:root_files) { [{ name: "root_files/recipe.#{extension}", full_path: "/home/user/repo/cookbooks/test/recipe.#{extension}" } ] }
|
125
|
+
before(:each) do
|
126
|
+
allow(cookbook_version.cookbook_manifest).to receive(:root_files).and_return(root_files)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns all JSON recipes with a correct default of recipe.#{extension}" do
|
130
|
+
expect(cookbook_version.recipe_json_filenames_by_name).to eq({ "default" => "/home/user/repo/cookbooks/test/recipe.#{extension}",
|
131
|
+
"other" => "/home/user/repo/cookbooks/test/recipes/other.#{extension}" })
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
99
138
|
describe "with a cookbook directory named tatft" do
|
100
139
|
MD5 = /[0-9a-f]{32}/.freeze
|
101
140
|
|
@@ -1100,7 +1100,7 @@ describe Chef::Node::Attribute do
|
|
1100
1100
|
"c" => 4,
|
1101
1101
|
}
|
1102
1102
|
attributes = Chef::Node::Attribute.new(nil, default_hash, override_hash, nil)
|
1103
|
-
expect(attributes
|
1103
|
+
expect(attributes).to match({ "a" => 1, "b" => 3, "c" => 4 })
|
1104
1104
|
end
|
1105
1105
|
end
|
1106
1106
|
|
@@ -45,12 +45,33 @@ describe "Chef::Provider::AptRepository" do
|
|
45
45
|
sub:-:2048:16:84080586D1CA74A1:2009-04-22::::
|
46
46
|
EOF
|
47
47
|
|
48
|
+
# Output of the command:
|
49
|
+
# gpg --no-default-keyring --keyring ${keyring} --list-public-keys ${key}
|
50
|
+
APG_GPG_KEYS_EXPIRED = <<~EOF.freeze
|
51
|
+
pub dsa1024 2009-04-22 [SC] [expired: 2018-02-22]
|
52
|
+
F36A89E33CC1BD0F71079007327574EE02A818DD
|
53
|
+
uid Cloudera Apt Repository
|
54
|
+
sub elg2048 2009-04-22 [E] [expired: 2018-02-22]
|
55
|
+
EOF
|
56
|
+
|
57
|
+
# Output of the command:
|
58
|
+
# gpg --no-default-keyring --keyring ${keyring} --list-public-keys ${key}
|
59
|
+
APG_GPG_KEYS_REVOKED = <<~EOF.freeze
|
60
|
+
pub dsa1024 2009-04-22 [SC] [revoked: 2018-02-22]
|
61
|
+
F36A89E33CC1BD0F71079007327574EE02A818DD
|
62
|
+
uid Cloudera Apt Repository
|
63
|
+
sub elg2048 2009-04-22 [E] [revoked: 2018-02-22]
|
64
|
+
EOF
|
65
|
+
|
48
66
|
let(:node) { Chef::Node.new }
|
49
67
|
let(:events) { Chef::EventDispatch::Dispatcher.new }
|
50
68
|
let(:run_context) { Chef::RunContext.new(node, {}, events) }
|
51
69
|
let(:collection) { double("resource collection") }
|
52
70
|
let(:new_resource) { Chef::Resource::AptRepository.new("multiverse", run_context) }
|
53
71
|
let(:provider) { new_resource.provider_for_action(:add) }
|
72
|
+
let(:keyring) { "/etc/apt/keyrings/ring.gpg" }
|
73
|
+
let(:key) { "ASDF1234" }
|
74
|
+
let(:keyserver) { "keyserver.ubuntu.com" }
|
54
75
|
|
55
76
|
let(:apt_key_finger_cmd) do
|
56
77
|
%w{apt-key adv --list-public-keys --with-fingerprint --with-colons}
|
@@ -70,9 +91,17 @@ describe "Chef::Provider::AptRepository" do
|
|
70
91
|
end
|
71
92
|
|
72
93
|
let(:gpg_shell_out_failure) do
|
73
|
-
double("shell_out", stderr: "gpg:
|
74
|
-
|
75
|
-
exitstatus:
|
94
|
+
double("shell_out", stderr: "gpg: keybox '/etc/apt/keyrings/ring.gpg' created\ngpg: error reading key: No public key\n",
|
95
|
+
stdout: "",
|
96
|
+
exitstatus: 2, error?: true)
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:gpg_shell_out_expired) do
|
100
|
+
double("shell_out", stdout: APG_GPG_KEYS_EXPIRED, exitstatus: 0, error?: false)
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:gpg_shell_out_revoked) do
|
104
|
+
double("shell_out", stdout: APG_GPG_KEYS_REVOKED, exitstatus: 0, error?: false)
|
76
105
|
end
|
77
106
|
|
78
107
|
let(:apt_fingerprints) do
|
@@ -141,6 +170,40 @@ C5986B4F1257FFA86632CBA746181433FBB75451
|
|
141
170
|
end
|
142
171
|
end
|
143
172
|
|
173
|
+
describe "#keyring_key_is_valid?" do
|
174
|
+
it "returns true for a valid key" do
|
175
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_success)
|
176
|
+
expect(provider.keyring_key_is_valid?(keyring, key)).to eql(true)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns false when the key does not exist" do
|
180
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_failure)
|
181
|
+
expect(provider.keyring_key_is_valid?(keyring, key)).to eql(false)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "returns false when the key is expired" do
|
185
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_expired)
|
186
|
+
expect(provider.keyring_key_is_valid?(keyring, key)).to eql(false)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "returns false when the key has been revoked" do
|
190
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_revoked)
|
191
|
+
expect(provider.keyring_key_is_valid?(keyring, key)).to eql(false)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#keyring_key_is_present?" do
|
196
|
+
it "returns true for a key that exists" do
|
197
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_success)
|
198
|
+
expect(provider.keyring_key_is_present?(keyring, key)).to eql(true)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "returns false when the key is not present in the keyring" do
|
202
|
+
expect(provider).to receive(:shell_out).and_return(gpg_shell_out_failure)
|
203
|
+
expect(provider.keyring_key_is_present?(keyring, key)).to eql(false)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
144
207
|
describe "#no_new_keys?" do
|
145
208
|
before do
|
146
209
|
allow(provider).to receive(:extract_public_keys_from_cmd).with(*apt_key_finger_cmd).and_return(apt_public_keys)
|
@@ -165,17 +228,17 @@ C5986B4F1257FFA86632CBA746181433FBB75451
|
|
165
228
|
|
166
229
|
describe "#key_type" do
|
167
230
|
it "returns :remote_file with an http URL" do
|
168
|
-
expect(provider.
|
231
|
+
expect(provider.key_resource_type("https://www.chef.io/key")).to eq(:remote_file)
|
169
232
|
end
|
170
233
|
|
171
234
|
it "returns :cookbook_file with a chef managed file" do
|
172
235
|
expect(provider).to receive(:has_cookbook_file?).and_return(true)
|
173
|
-
expect(provider.
|
236
|
+
expect(provider.key_resource_type("/foo/bar.key")).to eq(:cookbook_file)
|
174
237
|
end
|
175
238
|
|
176
239
|
it "throws exception if an unknown file specified" do
|
177
240
|
expect(provider).to receive(:has_cookbook_file?).and_return(false)
|
178
|
-
expect { provider.
|
241
|
+
expect { provider.key_resource_type("/foo/bar.key") }.to raise_error(Chef::Exceptions::FileNotFound)
|
179
242
|
end
|
180
243
|
end
|
181
244
|
|
@@ -223,6 +286,20 @@ C5986B4F1257FFA86632CBA746181433FBB75451
|
|
223
286
|
end
|
224
287
|
end
|
225
288
|
|
289
|
+
describe "#install_key_from_keyserver_to_keyring" do
|
290
|
+
it "does not raise an error when the key is valid" do
|
291
|
+
expect(provider).to receive(:execute).and_return(nil)
|
292
|
+
expect(provider).to receive(:keyring_key_is_valid?).and_return(true)
|
293
|
+
expect { provider.install_key_from_keyserver_to_keyring(key, keyserver, keyring) }.not_to raise_error
|
294
|
+
end
|
295
|
+
|
296
|
+
it "raises an error with the key is invalid" do
|
297
|
+
expect(provider).to receive(:execute).and_return(nil)
|
298
|
+
expect(provider).to receive(:keyring_key_is_valid?).and_return(false)
|
299
|
+
expect { provider.install_key_from_keyserver_to_keyring(key, keyserver, keyring) }.to raise_error(RuntimeError)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
226
303
|
describe "#install_ppa_key" do
|
227
304
|
let(:url) { "https://launchpad.net/api/1.0/~chef/+archive/main" }
|
228
305
|
let(:key) { "C5986B4F1257FFA86632CBA746181433FBB75451" }
|
@@ -230,8 +307,8 @@ C5986B4F1257FFA86632CBA746181433FBB75451
|
|
230
307
|
it "gets a key" do
|
231
308
|
simples = double("HTTP")
|
232
309
|
allow(simples).to receive(:get).and_return("\"#{key}\"")
|
233
|
-
expect(Chef::HTTP::Simple).to receive(:new).with(url).and_return(simples)
|
234
|
-
expect(provider).to receive(:install_key_from_keyserver).with(key,
|
310
|
+
expect(Chef::HTTP::Simple).to receive(:new).with(url, {}).and_return(simples)
|
311
|
+
expect(provider).to receive(:install_key_from_keyserver).with(key, keyserver)
|
235
312
|
provider.install_ppa_key("chef", "main")
|
236
313
|
end
|
237
314
|
end
|
@@ -151,7 +151,7 @@ describe Chef::Provider::Package::Rpm do
|
|
151
151
|
|
152
152
|
context "when at the desired version already" do
|
153
153
|
it "does nothing when the correct version is installed" do
|
154
|
-
expect(provider).to_not receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
154
|
+
expect(provider).to_not receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
155
155
|
|
156
156
|
provider.action_install
|
157
157
|
end
|
@@ -162,7 +162,7 @@ describe Chef::Provider::Package::Rpm do
|
|
162
162
|
let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" }
|
163
163
|
|
164
164
|
it "runs rpm -u with the package source to upgrade" do
|
165
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
165
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
166
166
|
provider.action_install
|
167
167
|
end
|
168
168
|
end
|
@@ -177,7 +177,7 @@ describe Chef::Provider::Package::Rpm do
|
|
177
177
|
let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" }
|
178
178
|
|
179
179
|
it "should run rpm -u --oldpackage with the package source to downgrade" do
|
180
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
180
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
181
181
|
provider.action_install
|
182
182
|
end
|
183
183
|
|
@@ -208,7 +208,7 @@ describe Chef::Provider::Package::Rpm do
|
|
208
208
|
let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" }
|
209
209
|
|
210
210
|
it "runs rpm -u with the package source to upgrade" do
|
211
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
211
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
212
212
|
provider.action_upgrade
|
213
213
|
end
|
214
214
|
end
|
@@ -224,7 +224,7 @@ describe Chef::Provider::Package::Rpm do
|
|
224
224
|
let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" }
|
225
225
|
|
226
226
|
it "should run rpm -u --oldpackage with the package source to downgrade" do
|
227
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
227
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
228
228
|
provider.action_upgrade
|
229
229
|
end
|
230
230
|
|
@@ -368,7 +368,7 @@ describe Chef::Provider::Package::Rpm do
|
|
368
368
|
describe "action install" do
|
369
369
|
|
370
370
|
it "installs the package" do
|
371
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, timeout: 900)
|
371
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, env: {}, timeout: 900)
|
372
372
|
|
373
373
|
provider.action_install
|
374
374
|
end
|
@@ -376,7 +376,7 @@ describe Chef::Provider::Package::Rpm do
|
|
376
376
|
context "when custom resource options are given" do
|
377
377
|
it "installs with custom options specified in the resource" do
|
378
378
|
new_resource.options("--dbpath /var/lib/rpm")
|
379
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "--dbpath", "/var/lib/rpm", "-i", package_source, timeout: 900)
|
379
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "--dbpath", "/var/lib/rpm", "-i", package_source, env: {}, timeout: 900)
|
380
380
|
provider.action_install
|
381
381
|
end
|
382
382
|
end
|
@@ -387,7 +387,7 @@ describe Chef::Provider::Package::Rpm do
|
|
387
387
|
let(:action) { :upgrade }
|
388
388
|
|
389
389
|
it "installs the package" do
|
390
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, timeout: 900)
|
390
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, env: {}, timeout: 900)
|
391
391
|
|
392
392
|
provider.action_upgrade
|
393
393
|
end
|
@@ -424,7 +424,7 @@ describe Chef::Provider::Package::Rpm do
|
|
424
424
|
it "should install from a path when the package is a path and the source is nil" do
|
425
425
|
expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
|
426
426
|
provider.current_resource = current_resource
|
427
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
427
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
428
428
|
provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
|
429
429
|
end
|
430
430
|
|
@@ -432,7 +432,7 @@ describe Chef::Provider::Package::Rpm do
|
|
432
432
|
expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
|
433
433
|
current_resource.version("21.4-19.el5")
|
434
434
|
provider.current_resource = current_resource
|
435
|
-
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
|
435
|
+
expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", env: {}, timeout: 900)
|
436
436
|
provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
|
437
437
|
end
|
438
438
|
end
|