From d8cc0b16b732be66d98a7bb893f3a889b086d6c2 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 21 Jan 2020 12:14:50 -0800 Subject: WIP: Chef-16 resource cleanup + unified_mode (#9174) * Chef-16 resource cleanup + unified_mode Signed-off-by: Lamont Granquist --- lib/chef/provider/apt_preference.rb | 93 -------- lib/chef/provider/apt_repository.rb | 358 ----------------------------- lib/chef/provider/apt_update.rb | 79 ------- lib/chef/provider/cookbook_file.rb | 2 +- lib/chef/provider/cookbook_file/content.rb | 2 +- lib/chef/provider/package/cab.rb | 6 +- lib/chef/providers.rb | 5 +- lib/chef/resource/action_class.rb | 2 +- lib/chef/resource/apt_package.rb | 4 +- lib/chef/resource/apt_preference.rb | 70 +++++- lib/chef/resource/apt_repository.rb | 334 ++++++++++++++++++++++++++- lib/chef/resource/apt_update.rb | 52 +++++ lib/chef/resource/archive_file.rb | 1 + lib/chef/resource/bash.rb | 2 +- lib/chef/resource/batch.rb | 2 +- lib/chef/resource/bff_package.rb | 4 +- lib/chef/resource/breakpoint.rb | 2 +- lib/chef/resource/build_essential.rb | 20 +- lib/chef/resource/cab_package.rb | 1 + lib/chef/resource/chef_gem.rb | 3 +- lib/chef/resource/chef_handler.rb | 4 +- lib/chef/resource/chef_sleep.rb | 2 +- lib/chef/resource/chocolatey_config.rb | 3 +- lib/chef/resource/chocolatey_feature.rb | 3 +- lib/chef/resource/chocolatey_package.rb | 2 + lib/chef/resource/chocolatey_source.rb | 3 +- lib/chef/resource/cookbook_file.rb | 2 +- lib/chef/resource/cron.rb | 1 + lib/chef/resource/cron_access.rb | 3 +- lib/chef/resource/cron_d.rb | 3 +- lib/chef/resource/csh.rb | 2 +- lib/chef/resource/directory.rb | 2 +- lib/chef/resource/dmg_package.rb | 6 +- lib/chef/resource/dnf_package.rb | 1 + lib/chef/resource/dpkg_package.rb | 4 +- lib/chef/resource/dsc_resource.rb | 2 +- lib/chef/resource/dsc_script.rb | 3 +- lib/chef/resource/freebsd_package.rb | 3 +- lib/chef/resource/gem_package.rb | 3 +- 39 files changed, 517 insertions(+), 577 deletions(-) delete mode 100644 lib/chef/provider/apt_preference.rb delete mode 100644 lib/chef/provider/apt_repository.rb delete mode 100644 lib/chef/provider/apt_update.rb (limited to 'lib') diff --git a/lib/chef/provider/apt_preference.rb b/lib/chef/provider/apt_preference.rb deleted file mode 100644 index 0e655cf0c0..0000000000 --- a/lib/chef/provider/apt_preference.rb +++ /dev/null @@ -1,93 +0,0 @@ -# -# Author:: Tim Smith () -# Copyright:: 2016-2017, Chef Software, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require_relative "../provider" -require_relative "../dsl/declare_resource" -require_relative "noop" -require_relative "../log" - -class Chef - class Provider - class AptPreference < Chef::Provider - provides :apt_preference, platform_family: "debian" - - APT_PREFERENCE_DIR = "/etc/apt/preferences.d".freeze - - def load_current_resource; end - - action :add do - preference = build_pref( - new_resource.glob || new_resource.package_name, - new_resource.pin, - new_resource.pin_priority - ) - - declare_resource(:directory, APT_PREFERENCE_DIR) do - mode "0755" - action :create - end - - sanitized_prefname = safe_name(new_resource.package_name) - - # cleanup any existing pref files w/o the sanitized name (created by old apt cookbook) - if (sanitized_prefname != new_resource.package_name) && ::File.exist?("#{APT_PREFERENCE_DIR}/#{new_resource.package_name}.pref") - logger.warn "Replacing legacy #{new_resource.package_name}.pref with #{sanitized_prefname}.pref in #{APT_PREFERENCE_DIR}" - declare_resource(:file, "#{APT_PREFERENCE_DIR}/#{new_resource.package_name}.pref") do - action :delete - end - end - - # cleanup any existing pref files without the .pref extension (created by old apt cookbook) - if ::File.exist?("#{APT_PREFERENCE_DIR}/#{new_resource.package_name}") - logger.warn "Replacing legacy #{new_resource.package_name} with #{sanitized_prefname}.pref in #{APT_PREFERENCE_DIR}" - declare_resource(:file, "#{APT_PREFERENCE_DIR}/#{new_resource.package_name}") do - action :delete - end - end - - declare_resource(:file, "#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref") do - mode "0644" - content preference - action :create - end - end - - action :remove do - sanitized_prefname = safe_name(new_resource.package_name) - - if ::File.exist?("#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref") - logger.info "Un-pinning #{sanitized_prefname} from #{APT_PREFERENCE_DIR}" - declare_resource(:file, "#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref") do - action :delete - end - end - end - - # Build preferences.d file contents - def build_pref(package_name, pin, pin_priority) - "Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n" - end - - def safe_name(name) - name.tr(".", "_").gsub("*", "wildcard") - end - end - end -end - -Chef::Provider::Noop.provides :apt_preference diff --git a/lib/chef/provider/apt_repository.rb b/lib/chef/provider/apt_repository.rb deleted file mode 100644 index 9443c58ef8..0000000000 --- a/lib/chef/provider/apt_repository.rb +++ /dev/null @@ -1,358 +0,0 @@ -# -# Author:: Thom May () -# Copyright:: Copyright (c) 2016-2018, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require_relative "../resource" -require_relative "../dsl/declare_resource" -require_relative "../mixin/shell_out" -require_relative "../http/simple" -require_relative "noop" -require "tmpdir" unless defined?(Dir.mktmpdir) - -class Chef - class Provider - class AptRepository < Chef::Provider - include Chef::Mixin::ShellOut - - provides :apt_repository, platform_family: "debian" - - LIST_APT_KEY_FINGERPRINTS = %w{apt-key adv --list-public-keys --with-fingerprint --with-colons}.freeze - - def load_current_resource; end - - action :add do - if new_resource.key.nil? - logger.debug "No 'key' property specified skipping key import" - else - new_resource.key.each do |k| - if is_key_id?(k) && !has_cookbook_file?(k) - install_key_from_keyserver(k) - else - install_key_from_uri(k) - end - end - end - - declare_resource(:execute, "apt-cache gencaches") do - command %w{apt-cache gencaches} - default_env true - ignore_failure true - action :nothing - end - - declare_resource(:apt_update, new_resource.name) do - ignore_failure true - action :nothing - end - - cleanup_legacy_file! - - repo = build_repo( - new_resource.uri, - new_resource.distribution, - repo_components, - new_resource.trusted, - new_resource.arch, - new_resource.deb_src - ) - - declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.repo_name}.list") do - owner "root" - group "root" - mode "0644" - content repo - sensitive new_resource.sensitive - action :create - notifies :run, "execute[apt-cache gencaches]", :immediately - notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild - end - end - - action :remove do - cleanup_legacy_file! - if ::File.exist?("/etc/apt/sources.list.d/#{new_resource.repo_name}.list") - converge_by "Removing #{new_resource.repo_name} repository from /etc/apt/sources.list.d/" do - declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.repo_name}.list") do - sensitive new_resource.sensitive - action :delete - notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild - end - - declare_resource(:apt_update, new_resource.name) do - ignore_failure true - action :nothing - end - end - else - logger.trace("/etc/apt/sources.list.d/#{new_resource.repo_name}.list does not exist. Nothing to do") - end - end - - # is the provided ID a key ID from a keyserver. Looks at length and HEX only values - # @param [String] id the key value passed by the user that *may* be an ID - def is_key_id?(id) - id = id[2..-1] if id.start_with?("0x") - id =~ /^\h+$/ && [8, 16, 40].include?(id.length) - end - - # run the specified command and extract the fingerprints from the output - # accepts a command so it can be used to extract both the current key's fingerprints - # and the fingerprint of the new key - # @param [Array] cmd the command to run - # - # @return [Array] an array of fingerprints - def extract_fingerprints_from_cmd(*cmd) - so = shell_out(*cmd) - so.stdout.split(/\n/).map do |t| - if z = t.match(/^fpr:+([0-9A-F]+):/) - z[1].split.join - end - end.compact - end - - # validate the key against the apt keystore to see if that version is expired - # @param [String] key - # - # @return [Boolean] is the key valid or not - def key_is_valid?(key) - valid = true - - so = shell_out("apt-key", "list") - so.stdout.split(/\n/).map do |t| - if t =~ %r{^\/#{key}.*\[expired: .*\]$} - logger.debug "Found expired key: #{t}" - valid = false - break - end - end - - logger.debug "key #{key} #{valid ? "is valid" : "is not valid"}" - valid - end - - # return the specified cookbook name or the cookbook containing the - # resource. - # - # @return [String] name of the cookbook - def cookbook_name - new_resource.cookbook || new_resource.cookbook_name - end - - # determine if a cookbook file is available in the run - # @param [String] fn the path to the cookbook file - # - # @return [Boolean] cookbook file exists or doesn't - def has_cookbook_file?(fn) - run_context.has_cookbook_file_in_cookbook?(cookbook_name, fn) - end - - # determine if there are any new keys by comparing the fingerprints of installed - # keys to those of the passed file - # @param [String] file the keyfile of the new repository - # - # @return [Boolean] true: no new keys in the file. false: there are new keys - def no_new_keys?(file) - # Now we are using the option --with-colons that works across old os versions - # as well as the latest (16.10). This for both `apt-key` and `gpg` commands - installed_keys = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS) - proposed_keys = extract_fingerprints_from_cmd("gpg", "--with-fingerprint", "--with-colons", file) - (installed_keys & proposed_keys).sort == proposed_keys.sort - end - - # Given the provided key URI determine what kind of chef resource we need - # to fetch the key - # @param [String] uri the uri of the gpg key (local path or http URL) - # - # @raise [Chef::Exceptions::FileNotFound] Key isn't remote or found in the current run - # - # @return [Symbol] :remote_file or :cookbook_file - def key_type(uri) - if uri.start_with?("http") - :remote_file - elsif has_cookbook_file?(uri) - :cookbook_file - else - raise Chef::Exceptions::FileNotFound, "Cannot locate key file: #{uri}" - end - end - - # Fetch the key using either cookbook_file or remote_file, validate it, - # and install it with apt-key add - # @param [String] key the key to install - # - # @raise [RuntimeError] Invalid key which can't verify the apt repository - # - # @return [void] - def install_key_from_uri(key) - key_name = key.gsub(/[^0-9A-Za-z\-]/, "_") - cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name) - tmp_dir = Dir.mktmpdir(".gpg") - at_exit { FileUtils.remove_entry(tmp_dir) } - - declare_resource(key_type(key), cached_keyfile) do - source key - mode "0644" - sensitive new_resource.sensitive - action :create - verify "gpg --homedir #{tmp_dir} %{path}" - end - - declare_resource(:execute, "apt-key add #{cached_keyfile}") do - command [ "apt-key", "add", cached_keyfile ] - default_env true - sensitive new_resource.sensitive - action :run - not_if { no_new_keys?(cached_keyfile) } - notifies :run, "execute[apt-cache gencaches]", :immediately - end - end - - # build the apt-key command to install the keyserver - # @param [String] key the key to install - # @param [String] keyserver the key server to use - # - # @return [String] the full apt-key command to run - def keyserver_install_cmd(key, keyserver) - cmd = "apt-key adv --no-tty --recv" - cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy - cmd << " --keyserver " - cmd << if keyserver.start_with?("hkp://") - keyserver - else - "hkp://#{keyserver}:80" - end - - cmd << " #{key}" - cmd - end - - # @param [String] key - # @param [String] keyserver - # - # @raise [RuntimeError] Invalid key which can't verify the apt repository - # - # @return [void] - def install_key_from_keyserver(key, keyserver = new_resource.keyserver) - declare_resource(:execute, "install-key #{key}") do - command keyserver_install_cmd(key, keyserver) - default_env true - sensitive new_resource.sensitive - not_if do - present = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS).any? do |fp| - fp.end_with? key.upcase - end - present && key_is_valid?(key.upcase) - end - notifies :run, "execute[apt-cache gencaches]", :immediately - end - - raise "The key #{key} is invalid and cannot be used to verify an apt repository." unless key_is_valid?(key.upcase) - end - - # @param [String] owner - # @param [String] repo - # - # @raise [RuntimeError] Could not access the Launchpad PPA API - # - # @return [void] - def install_ppa_key(owner, repo) - url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}" - key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"') - install_key_from_keyserver(key_id, "keyserver.ubuntu.com") - rescue Net::HTTPClientException => e - raise "Could not access Launchpad ppa API: #{e.message}" - end - - # determine if the repository URL is a PPA - # @param [String] url the url of the repository - # - # @return [Boolean] is the repo URL a PPA - def is_ppa_url?(url) - url.start_with?("ppa:") - end - - # determine the repository's components: - # - "components" property if defined - # - "main" if "components" not defined and the repo is a PPA URL - # - otherwise nothing - # - # @return [String] the repository component - def repo_components - if is_ppa_url?(new_resource.uri) && new_resource.components.empty? - "main" - else - new_resource.components - end - end - - # given a PPA return a PPA URL in http://ppa.launchpad.net format - # @param [String] ppa the ppa URL - # - # @return [String] full PPA URL - def make_ppa_url(ppa) - owner, repo = ppa[4..-1].split("/") - repo ||= "ppa" - - install_ppa_key(owner, repo) - "http://ppa.launchpad.net/#{owner}/#{repo}/ubuntu" - end - - # build complete repo text that will be written to the config - # @param [String] uri - # @param [Array] components - # @param [Boolean] trusted - # @param [String] arch - # @param [Boolean] add_src - # - # @return [String] complete repo config text - def build_repo(uri, distribution, components, trusted, arch, add_src = false) - uri = make_ppa_url(uri) if is_ppa_url?(uri) - uri = URI.escape(uri) - components = Array(components).join(" ") - options = [] - options << "arch=#{arch}" if arch - options << "trusted=yes" if trusted - optstr = unless options.empty? - "[" + options.join(" ") + "]" - end - info = [ optstr, uri, distribution, components ].compact.join(" ") - repo = "deb #{info}\n" - repo << "deb-src #{info}\n" if add_src - repo - end - - # clean up a potentially legacy file from before we fixed the usage of - # new_resource.name vs. new_resource.repo_name. We might have the - # name.list file hanging around and need to clean it up. - # - # @return [void] - def cleanup_legacy_file! - legacy_path = "/etc/apt/sources.list.d/#{new_resource.name}.list" - if new_resource.name != new_resource.repo_name && ::File.exist?(legacy_path) - converge_by "Cleaning up legacy #{legacy_path} repo file" do - declare_resource(:file, legacy_path) do - action :delete - # Not triggering an update since it isn't super likely to be needed. - end - end - end - end - end - end -end - -Chef::Provider::Noop.provides :apt_repository diff --git a/lib/chef/provider/apt_update.rb b/lib/chef/provider/apt_update.rb deleted file mode 100644 index 8914d5412b..0000000000 --- a/lib/chef/provider/apt_update.rb +++ /dev/null @@ -1,79 +0,0 @@ -# -# Author:: Thom May () -# Copyright:: Copyright (c) 2016-2018, Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require_relative "../provider" -require_relative "noop" -require_relative "../dsl/declare_resource" - -class Chef - class Provider - class AptUpdate < Chef::Provider - provides :apt_update, platform_family: "debian" - - APT_CONF_DIR = "/etc/apt/apt.conf.d".freeze - STAMP_DIR = "/var/lib/apt/periodic".freeze - - def load_current_resource; end - - action :periodic do - unless apt_up_to_date? - converge_by "update new lists of packages" do - do_update - end - end - end - - action :update do - converge_by "force update new lists of packages" do - do_update - end - end - - private - - # Determines whether we need to run `apt-get update` - # - # @return [Boolean] - def apt_up_to_date? - ::File.exist?("#{STAMP_DIR}/update-success-stamp") && - ::File.mtime("#{STAMP_DIR}/update-success-stamp") > Time.now - new_resource.frequency - end - - def do_update - [STAMP_DIR, APT_CONF_DIR].each do |d| - declare_resource(:directory, d) do - recursive true - end - end - - declare_resource(:file, "#{APT_CONF_DIR}/15update-stamp") do - content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};\n" - action :create_if_missing - end - - declare_resource(:execute, "apt-get -q update") do - command [ "apt-get", "-q", "update" ] - default_env true - end - end - - end - end -end - -Chef::Provider::Noop.provides :apt_update diff --git a/lib/chef/provider/cookbook_file.rb b/lib/chef/provider/cookbook_file.rb index 3d09d291a3..e964b6279f 100644 --- a/lib/chef/provider/cookbook_file.rb +++ b/lib/chef/provider/cookbook_file.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo () -# Copyright:: Copyright 2010-2016, Chef Software Inc. +# Copyright:: Copyright 2010-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/provider/cookbook_file/content.rb b/lib/chef/provider/cookbook_file/content.rb index 873f3bb394..8307fc1934 100644 --- a/lib/chef/provider/cookbook_file/content.rb +++ b/lib/chef/provider/cookbook_file/content.rb @@ -1,6 +1,6 @@ # # Author:: Lamont Granquist () -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/provider/package/cab.rb b/lib/chef/provider/package/cab.rb index fd099811e0..9ccc373dd1 100644 --- a/lib/chef/provider/package/cab.rb +++ b/lib/chef/provider/package/cab.rb @@ -1,6 +1,6 @@ # # Author:: Vasundhara Jagdale () -# Copyright:: Copyright 2015-2016, Chef Software, Inc. +# Copyright:: Copyright 2015-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,13 +45,11 @@ class Chef end def download_source_file - source_resource.run_action(:create) - logger.trace("#{new_resource} fetched source file to #{source_resource.path}") source_resource.path end def source_resource - @source_resource ||= declare_resource(:remote_file, new_resource.name) do + declare_resource(:remote_file, new_resource.name) do path default_download_cache_path source new_resource.source backup false diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb index 629b64d2d5..5022ef7327 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo () -# Copyright:: Copyright 2010-2018, Chef Software Inc. +# Copyright:: Copyright 2010-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,6 @@ # limitations under the License. # -require_relative "provider/apt_update" -require_relative "provider/apt_preference" -require_relative "provider/apt_repository" require_relative "provider/batch" require_relative "provider/cookbook_file" require_relative "provider/cron" diff --git a/lib/chef/resource/action_class.rb b/lib/chef/resource/action_class.rb index 03756062ef..5e9e26b02d 100644 --- a/lib/chef/resource/action_class.rb +++ b/lib/chef/resource/action_class.rb @@ -1,6 +1,6 @@ # # Author:: John Keiser () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,8 @@ require_relative "package" class Chef class Resource class AptPackage < Chef::Resource::Package + unified_mode true + resource_name :apt_package provides :apt_package, target_mode: true provides :package, platform_family: "debian", target_mode: true diff --git a/lib/chef/resource/apt_preference.rb b/lib/chef/resource/apt_preference.rb index 810a8dcad8..2c8debcb10 100644 --- a/lib/chef/resource/apt_preference.rb +++ b/lib/chef/resource/apt_preference.rb @@ -1,6 +1,6 @@ # # Author:: Tim Smith () -# Copyright:: 2016-2017, Chef Software, Inc. +# Copyright:: 2016-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,8 @@ class Chef class Resource # @since 13.3 class AptPreference < Chef::Resource + unified_mode true + resource_name :apt_preference provides(:apt_preference) { true } @@ -47,6 +49,72 @@ class Chef default_action :add allowed_actions :add, :remove + + APT_PREFERENCE_DIR = "/etc/apt/preferences.d".freeze + + action_class do + # Build preferences.d file contents + def build_pref(package_name, pin, pin_priority) + "Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n" + end + + def safe_name(name) + name.tr(".", "_").gsub("*", "wildcard") + end + end + + action :add do + return unless debian? + + preference = build_pref( + new_resource.glob || new_resource.package_name, + new_resource.pin, + new_resource.pin_priority + ) + + directory APT_PREFERENCE_DIR do + mode "0755" + action :create + end + + sanitized_prefname = safe_name(new_resource.package_name) + + # cleanup any existing pref files w/o the sanitized name (created by old apt cookbook) + if (sanitized_prefname != new_resource.package_name) && ::File.exist?("#{APT_PREFERENCE_DIR}/#{new_resource.package_name}.pref") + logger.warn "Replacing legacy #{new_resource.package_name}.pref with #{sanitized_prefname}.pref in #{APT_PREFERENCE_DIR}" + file "#{APT_PREFERENCE_DIR}/#{new_resource.package_name}.pref" do + action :delete + end + end + + # cleanup any existing pref files without the .pref extension (created by old apt cookbook) + if ::File.exist?("#{APT_PREFERENCE_DIR}/#{new_resource.package_name}") + logger.warn "Replacing legacy #{new_resource.package_name} with #{sanitized_prefname}.pref in #{APT_PREFERENCE_DIR}" + file "#{APT_PREFERENCE_DIR}/#{new_resource.package_name}" do + action :delete + end + end + + file "#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref" do + mode "0644" + content preference + action :create + end + end + + action :remove do + return unless debian? + + sanitized_prefname = safe_name(new_resource.package_name) + + if ::File.exist?("#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref") + logger.info "Un-pinning #{sanitized_prefname} from #{APT_PREFERENCE_DIR}" + file "#{APT_PREFERENCE_DIR}/#{sanitized_prefname}.pref" do + action :delete + end + end + end + end end end diff --git a/lib/chef/resource/apt_repository.rb b/lib/chef/resource/apt_repository.rb index 213acc166b..2fefded6fd 100644 --- a/lib/chef/resource/apt_repository.rb +++ b/lib/chef/resource/apt_repository.rb @@ -1,6 +1,6 @@ # # Author:: Thom May () -# Copyright:: 2016-2019, Chef Software, Inc. +# Copyright:: 2016-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,10 +17,14 @@ # require_relative "../resource" +require_relative "../http/simple" +require "tmpdir" unless defined?(Dir.mktmpdir) class Chef class Resource class AptRepository < Chef::Resource + unified_mode true + resource_name :apt_repository provides(:apt_repository) { true } @@ -150,6 +154,334 @@ class Chef default_action :add allowed_actions :add, :remove + + action_class do + LIST_APT_KEY_FINGERPRINTS = %w{apt-key adv --list-public-keys --with-fingerprint --with-colons}.freeze + + # is the provided ID a key ID from a keyserver. Looks at length and HEX only values + # @param [String] id the key value passed by the user that *may* be an ID + def is_key_id?(id) + id = id[2..-1] if id.start_with?("0x") + id =~ /^\h+$/ && [8, 16, 40].include?(id.length) + end + + # run the specified command and extract the fingerprints from the output + # accepts a command so it can be used to extract both the current key's fingerprints + # and the fingerprint of the new key + # @param [Array] cmd the command to run + # + # @return [Array] an array of fingerprints + def extract_fingerprints_from_cmd(*cmd) + so = shell_out(*cmd) + so.stdout.split(/\n/).map do |t| + if z = t.match(/^fpr:+([0-9A-F]+):/) + z[1].split.join + end + end.compact + end + + # validate the key against the apt keystore to see if that version is expired + # @param [String] key + # + # @return [Boolean] is the key valid or not + def key_is_valid?(key) + valid = true + + so = shell_out("apt-key", "list") + so.stdout.split(/\n/).map do |t| + if t =~ %r{^\/#{key}.*\[expired: .*\]$} + logger.debug "Found expired key: #{t}" + valid = false + break + end + end + + logger.debug "key #{key} #{valid ? "is valid" : "is not valid"}" + valid + end + + # return the specified cookbook name or the cookbook containing the + # resource. + # + # @return [String] name of the cookbook + def cookbook_name + new_resource.cookbook || new_resource.cookbook_name + end + + # determine if a cookbook file is available in the run + # @param [String] fn the path to the cookbook file + # + # @return [Boolean] cookbook file exists or doesn't + def has_cookbook_file?(fn) + run_context.has_cookbook_file_in_cookbook?(cookbook_name, fn) + end + + # determine if there are any new keys by comparing the fingerprints of installed + # keys to those of the passed file + # @param [String] file the keyfile of the new repository + # + # @return [Boolean] true: no new keys in the file. false: there are new keys + def no_new_keys?(file) + # Now we are using the option --with-colons that works across old os versions + # as well as the latest (16.10). This for both `apt-key` and `gpg` commands + installed_keys = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS) + proposed_keys = extract_fingerprints_from_cmd("gpg", "--with-fingerprint", "--with-colons", file) + (installed_keys & proposed_keys).sort == proposed_keys.sort + end + + # Given the provided key URI determine what kind of chef resource we need + # to fetch the key + # @param [String] uri the uri of the gpg key (local path or http URL) + # + # @raise [Chef::Exceptions::FileNotFound] Key isn't remote or found in the current run + # + # @return [Symbol] :remote_file or :cookbook_file + def key_type(uri) + if uri.start_with?("http") + :remote_file + elsif has_cookbook_file?(uri) + :cookbook_file + else + raise Chef::Exceptions::FileNotFound, "Cannot locate key file: #{uri}" + end + end + + # Fetch the key using either cookbook_file or remote_file, validate it, + # and install it with apt-key add + # @param [String] key the key to install + # + # @raise [RuntimeError] Invalid key which can't verify the apt repository + # + # @return [void] + def install_key_from_uri(key) + key_name = key.gsub(/[^0-9A-Za-z\-]/, "_") + cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name) + tmp_dir = Dir.mktmpdir(".gpg") + at_exit { FileUtils.remove_entry(tmp_dir) } + + declare_resource(key_type(key), cached_keyfile) do + source key + mode "0644" + sensitive new_resource.sensitive + action :create + verify "gpg --homedir #{tmp_dir} %{path}" + end + + execute "apt-key add #{cached_keyfile}" do + command [ "apt-key", "add", cached_keyfile ] + default_env true + sensitive new_resource.sensitive + action :run + not_if { no_new_keys?(cached_keyfile) } + notifies :run, "execute[apt-cache gencaches]", :immediately + end + end + + # build the apt-key command to install the keyserver + # @param [String] key the key to install + # @param [String] keyserver the key server to use + # + # @return [String] the full apt-key command to run + def keyserver_install_cmd(key, keyserver) + cmd = "apt-key adv --no-tty --recv" + cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy + cmd << " --keyserver " + cmd << if keyserver.start_with?("hkp://") + keyserver + else + "hkp://#{keyserver}:80" + end + + cmd << " #{key}" + cmd + end + + # @param [String] key + # @param [String] keyserver + # + # @raise [RuntimeError] Invalid key which can't verify the apt repository + # + # @return [void] + def install_key_from_keyserver(key, keyserver = new_resource.keyserver) + execute "install-key #{key}" do + command keyserver_install_cmd(key, keyserver) + default_env true + sensitive new_resource.sensitive + not_if do + present = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS).any? do |fp| + fp.end_with? key.upcase + end + present && key_is_valid?(key.upcase) + end + notifies :run, "execute[apt-cache gencaches]", :immediately + end + + raise "The key #{key} is invalid and cannot be used to verify an apt repository." unless key_is_valid?(key.upcase) + end + + # @param [String] owner + # @param [String] repo + # + # @raise [RuntimeError] Could not access the Launchpad PPA API + # + # @return [void] + def install_ppa_key(owner, repo) + url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}" + key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"') + install_key_from_keyserver(key_id, "keyserver.ubuntu.com") + rescue Net::HTTPClientException => e + raise "Could not access Launchpad ppa API: #{e.message}" + end + + # determine if the repository URL is a PPA + # @param [String] url the url of the repository + # + # @return [Boolean] is the repo URL a PPA + def is_ppa_url?(url) + url.start_with?("ppa:") + end + + # determine the repository's components: + # - "components" property if defined + # - "main" if "components" not defined and the repo is a PPA URL + # - otherwise nothing + # + # @return [String] the repository component + def repo_components + if is_ppa_url?(new_resource.uri) && new_resource.components.empty? + "main" + else + new_resource.components + end + end + + # given a PPA return a PPA URL in http://ppa.launchpad.net format + # @param [String] ppa the ppa URL + # + # @return [String] full PPA URL + def make_ppa_url(ppa) + owner, repo = ppa[4..-1].split("/") + repo ||= "ppa" + + install_ppa_key(owner, repo) + "http://ppa.launchpad.net/#{owner}/#{repo}/ubuntu" + end + + # build complete repo text that will be written to the config + # @param [String] uri + # @param [Array] components + # @param [Boolean] trusted + # @param [String] arch + # @param [Boolean] add_src + # + # @return [String] complete repo config text + def build_repo(uri, distribution, components, trusted, arch, add_src = false) + uri = make_ppa_url(uri) if is_ppa_url?(uri) + + uri = URI.escape(uri) + components = Array(components).join(" ") + options = [] + options << "arch=#{arch}" if arch + options << "trusted=yes" if trusted + optstr = unless options.empty? + "[" + options.join(" ") + "]" + end + info = [ optstr, uri, distribution, components ].compact.join(" ") + repo = "deb #{info}\n" + repo << "deb-src #{info}\n" if add_src + repo + end + + # clean up a potentially legacy file from before we fixed the usage of + # new_resource.name vs. new_resource.repo_name. We might have the + # name.list file hanging around and need to clean it up. + # + # @return [void] + def cleanup_legacy_file! + legacy_path = "/etc/apt/sources.list.d/#{new_resource.name}.list" + if new_resource.name != new_resource.repo_name && ::File.exist?(legacy_path) + converge_by "Cleaning up legacy #{legacy_path} repo file" do + file legacy_path do + action :delete + # Not triggering an update since it isn't super likely to be needed. + end + end + end + end + end + + action :add do + return unless debian? + + execute "apt-cache gencaches" do + command %w{apt-cache gencaches} + default_env true + ignore_failure true + action :nothing + end + + apt_update new_resource.name do + ignore_failure true + action :nothing + end + + if new_resource.key.nil? + logger.debug "No 'key' property specified skipping key import" + else + new_resource.key.each do |k| + if is_key_id?(k) && !has_cookbook_file?(k) + install_key_from_keyserver(k) + else + install_key_from_uri(k) + end + end + end + + cleanup_legacy_file! + + repo = build_repo( + new_resource.uri, + new_resource.distribution, + repo_components, + new_resource.trusted, + new_resource.arch, + new_resource.deb_src + ) + + file "/etc/apt/sources.list.d/#{new_resource.repo_name}.list" do + owner "root" + group "root" + mode "0644" + content repo + sensitive new_resource.sensitive + action :create + notifies :run, "execute[apt-cache gencaches]", :immediately + notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild + end + end + + action :remove do + return unless debian? + + cleanup_legacy_file! + if ::File.exist?("/etc/apt/sources.list.d/#{new_resource.repo_name}.list") + converge_by "Removing #{new_resource.repo_name} repository from /etc/apt/sources.list.d/" do + apt_update new_resource.name do + ignore_failure true + action :nothing + end + + file "/etc/apt/sources.list.d/#{new_resource.repo_name}.list" do + sensitive new_resource.sensitive + action :delete + notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild + end + end + else + logger.trace("/etc/apt/sources.list.d/#{new_resource.repo_name}.list does not exist. Nothing to do") + end + end + end end end diff --git a/lib/chef/resource/apt_update.rb b/lib/chef/resource/apt_update.rb index 330f5b6071..b0d0df2e15 100644 --- a/lib/chef/resource/apt_update.rb +++ b/lib/chef/resource/apt_update.rb @@ -21,6 +21,8 @@ require_relative "../resource" class Chef class Resource class AptUpdate < Chef::Resource + unified_mode true + resource_name :apt_update provides(:apt_update) { true } @@ -50,6 +52,56 @@ class Chef default_action :periodic allowed_actions :update, :periodic + + action_class do + APT_CONF_DIR = "/etc/apt/apt.conf.d".freeze + STAMP_DIR = "/var/lib/apt/periodic".freeze + + # Determines whether we need to run `apt-get update` + # + # @return [Boolean] + def apt_up_to_date? + ::File.exist?("#{STAMP_DIR}/update-success-stamp") && + ::File.mtime("#{STAMP_DIR}/update-success-stamp") > Time.now - new_resource.frequency + end + + def do_update + [STAMP_DIR, APT_CONF_DIR].each do |d| + directory d do + recursive true + end + end + + file "#{APT_CONF_DIR}/15update-stamp" do + content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};\n" + action :create_if_missing + end + + execute "apt-get -q update" do + command [ "apt-get", "-q", "update" ] + default_env true + end + end + end + + action :periodic do + return unless debian? + + unless apt_up_to_date? + converge_by "update new lists of packages" do + do_update + end + end + end + + action :update do + return unless debian? + + converge_by "force update new lists of packages" do + do_update + end + end + end end end diff --git a/lib/chef/resource/archive_file.rb b/lib/chef/resource/archive_file.rb index 58681ecb47..da59ccf0ba 100644 --- a/lib/chef/resource/archive_file.rb +++ b/lib/chef/resource/archive_file.rb @@ -23,6 +23,7 @@ require_relative "../resource" class Chef class Resource class ArchiveFile < Chef::Resource + unified_mode true resource_name :archive_file provides :archive_file diff --git a/lib/chef/resource/bash.rb b/lib/chef/resource/bash.rb index 0399ff715b..a3502310e7 100644 --- a/lib/chef/resource/bash.rb +++ b/lib/chef/resource/bash.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/batch.rb b/lib/chef/resource/batch.rb index f36a70cd0c..6d7f87c3d6 100644 --- a/lib/chef/resource/batch.rb +++ b/lib/chef/resource/batch.rb @@ -1,6 +1,6 @@ # # Author:: Adam Edwards () -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/bff_package.rb b/lib/chef/resource/bff_package.rb index 819d0a8eb8..d6a59c0bd0 100644 --- a/lib/chef/resource/bff_package.rb +++ b/lib/chef/resource/bff_package.rb @@ -1,6 +1,6 @@ # # Author:: Deepali Jagtap () -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,8 @@ require_relative "package" class Chef class Resource class BffPackage < Chef::Resource::Package + unified_mode true + resource_name :bff_package provides :bff_package diff --git a/lib/chef/resource/breakpoint.rb b/lib/chef/resource/breakpoint.rb index 0beb7152a0..409e14f04f 100644 --- a/lib/chef/resource/breakpoint.rb +++ b/lib/chef/resource/breakpoint.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/build_essential.rb b/lib/chef/resource/build_essential.rb index 963481b5ee..2a702aadf9 100644 --- a/lib/chef/resource/build_essential.rb +++ b/lib/chef/resource/build_essential.rb @@ -19,6 +19,8 @@ require_relative "../resource" class Chef class Resource class BuildEssential < Chef::Resource + unified_mode true + resource_name :build_essential provides(:build_essential) { true } @@ -56,11 +58,11 @@ class Chef case when debian? package %w{ autoconf binutils-doc bison build-essential flex gettext ncurses-dev } - when fedora_derived? - package %w{ autoconf bison flex gcc gcc-c++ gettext kernel-devel make m4 ncurses-devel patch } + when fedora_derived? + package %w{ autoconf bison flex gcc gcc-c++ gettext kernel-devel make m4 ncurses-devel patch } # Ensure GCC 4 is available on older pre-6 EL - package %w{ gcc44 gcc44-c++ } if platform_family?("rhel") && node["platform_version"].to_i < 6 + package %w{ gcc44 gcc44-c++ } if platform_family?("rhel") && node["platform_version"].to_i < 6 when freebsd? package "devel/gmake" package "devel/autoconf" @@ -126,16 +128,14 @@ class Chef package %w{ autoconf bison flex gcc gcc-c++ kernel-default-devel make m4 } package %w{ gcc48 gcc48-c++ } if node["platform_version"].to_i < 12 else - if new_resource.raise_if_unsupported - raise <<-EOH + msg = <<-EOH The build_essential resource does not currently support the '#{node["platform_family"]}' platform family. Skipping... - EOH + EOH + if new_resource.raise_if_unsupported + raise msg else - Chef::Log.warn <<-EOH - The build_essential resource does not currently support the '#{node["platform_family"]}' - platform family. Skipping... - EOH + Chef::Log.warn msg end end end diff --git a/lib/chef/resource/cab_package.rb b/lib/chef/resource/cab_package.rb index 376a384bd7..b5c2c5cbc9 100644 --- a/lib/chef/resource/cab_package.rb +++ b/lib/chef/resource/cab_package.rb @@ -23,6 +23,7 @@ class Chef class Resource class CabPackage < Chef::Resource::Package include Chef::Mixin::Uris + unified_mode true resource_name :cab_package provides :cab_package diff --git a/lib/chef/resource/chef_gem.rb b/lib/chef/resource/chef_gem.rb index 04492e2a26..f37809b7c5 100644 --- a/lib/chef/resource/chef_gem.rb +++ b/lib/chef/resource/chef_gem.rb @@ -1,6 +1,6 @@ # # Author:: Bryan McLellan -# Copyright:: Copyright 2012-2017, Chef Software Inc. +# Copyright:: Copyright 2012-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ class Chef # - Runs Gem.clear_paths after the action, ensuring that gem is aware of changes so that it can be required # immediately after it is installed class ChefGem < Chef::Resource::Package::GemPackage + unified_mode true resource_name :chef_gem property :gem_binary, default: "#{RbConfig::CONFIG["bindir"]}/gem", default_description: "Chef's built-in gem binary.", diff --git a/lib/chef/resource/chef_handler.rb b/lib/chef/resource/chef_handler.rb index 2fa5173401..b8272cddea 100644 --- a/lib/chef/resource/chef_handler.rb +++ b/lib/chef/resource/chef_handler.rb @@ -1,6 +1,6 @@ # # Author:: Seth Chisamore -# Copyright:: 2011-2018, Chef Software, Inc +# Copyright:: 2011-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ require_relative "../dist" class Chef class Resource class ChefHandler < Chef::Resource + unified_mode true + resource_name :chef_handler provides(:chef_handler) { true } diff --git a/lib/chef/resource/chef_sleep.rb b/lib/chef/resource/chef_sleep.rb index 8bd7d2421d..51778f5fa5 100644 --- a/lib/chef/resource/chef_sleep.rb +++ b/lib/chef/resource/chef_sleep.rb @@ -1,5 +1,5 @@ # -# Copyright:: 2019, Chef Software Inc. +# Copyright:: 2019-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/resource/chocolatey_config.rb b/lib/chef/resource/chocolatey_config.rb index 216dc85fc9..3c49061f25 100644 --- a/lib/chef/resource/chocolatey_config.rb +++ b/lib/chef/resource/chocolatey_config.rb @@ -1,5 +1,5 @@ # -# Copyright:: 2018-2019, Chef Software, Inc. +# Copyright:: 2018-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ class Chef class Resource class ChocolateyConfig < Chef::Resource resource_name :chocolatey_config + unified_mode true description "Use the chocolatey_config resource to add or remove Chocolatey configuration keys." introduced "14.3" diff --git a/lib/chef/resource/chocolatey_feature.rb b/lib/chef/resource/chocolatey_feature.rb index 37ca9c0228..3789247f57 100644 --- a/lib/chef/resource/chocolatey_feature.rb +++ b/lib/chef/resource/chocolatey_feature.rb @@ -1,5 +1,5 @@ # -# Copyright:: 2019, Chef Software, Inc. +# Copyright:: 2019-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ class Chef class Resource class ChocolateyFeature < Chef::Resource + unified_mode true resource_name :chocolatey_feature description "Use the chocolatey_feature resource to enable and disable Chocolatey features." diff --git a/lib/chef/resource/chocolatey_package.rb b/lib/chef/resource/chocolatey_package.rb index d42a247c95..d80a79d65b 100644 --- a/lib/chef/resource/chocolatey_package.rb +++ b/lib/chef/resource/chocolatey_package.rb @@ -21,6 +21,8 @@ require_relative "package" class Chef class Resource class ChocolateyPackage < Chef::Resource::Package + unified_mode true + resource_name :chocolatey_package provides :chocolatey_package diff --git a/lib/chef/resource/chocolatey_source.rb b/lib/chef/resource/chocolatey_source.rb index f002d7d28b..b79443ae67 100644 --- a/lib/chef/resource/chocolatey_source.rb +++ b/lib/chef/resource/chocolatey_source.rb @@ -1,5 +1,5 @@ # -# Copyright:: 2018-2019, Chef Software, Inc. +# Copyright:: 2018-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ class Chef class Resource class ChocolateySource < Chef::Resource + unified_mode true resource_name :chocolatey_source description "Use the chocolatey_source resource to add, remove, enable, or disable Chocolatey sources." diff --git a/lib/chef/resource/cookbook_file.rb b/lib/chef/resource/cookbook_file.rb index d2c38d92dc..338c387008 100644 --- a/lib/chef/resource/cookbook_file.rb +++ b/lib/chef/resource/cookbook_file.rb @@ -2,7 +2,7 @@ # Author:: Adam Jacob () # Author:: Seth Chisamore () # Author:: Tyler Cloke () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/cron.rb b/lib/chef/resource/cron.rb index 6f85d68e5d..0f39347e0f 100644 --- a/lib/chef/resource/cron.rb +++ b/lib/chef/resource/cron.rb @@ -23,6 +23,7 @@ require_relative "../provider/cron" # do not remove. we actually need this below class Chef class Resource class Cron < Chef::Resource + unified_mode true resource_name :cron provides :cron diff --git a/lib/chef/resource/cron_access.rb b/lib/chef/resource/cron_access.rb index 3ee371e9fa..1d5b2dc358 100644 --- a/lib/chef/resource/cron_access.rb +++ b/lib/chef/resource/cron_access.rb @@ -3,7 +3,7 @@ # Author:: Tim Smith # # Copyright:: 2014-2018, Sander Botman -# Copyright:: 2018-2019, Chef Software, Inc. +# Copyright:: 2018-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ require_relative "../resource" class Chef class Resource class CronAccess < Chef::Resource + unified_mode true resource_name :cron_access provides(:cron_manage) # legacy name @todo in Chef 15 we should { true } this so it wins over the cookbook diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb index 281fad9dae..420e19d707 100644 --- a/lib/chef/resource/cron_d.rb +++ b/lib/chef/resource/cron_d.rb @@ -1,5 +1,5 @@ # -# Copyright:: 2008-2019, Chef Software, Inc. +# Copyright:: 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,7 @@ require_relative "../dist" class Chef class Resource class CronD < Chef::Resource + unified_mode true resource_name :cron_d introduced "14.4" diff --git a/lib/chef/resource/csh.rb b/lib/chef/resource/csh.rb index ea8e44c175..b04f7f9cee 100644 --- a/lib/chef/resource/csh.rb +++ b/lib/chef/resource/csh.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/directory.rb b/lib/chef/resource/directory.rb index b817a3ff08..f072584121 100644 --- a/lib/chef/resource/directory.rb +++ b/lib/chef/resource/directory.rb @@ -2,7 +2,7 @@ # Author:: Adam Jacob () # Author:: Seth Chisamore () # Author:: Tyler Cloke () -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/dmg_package.rb b/lib/chef/resource/dmg_package.rb index cb115a235f..07ab920411 100644 --- a/lib/chef/resource/dmg_package.rb +++ b/lib/chef/resource/dmg_package.rb @@ -20,6 +20,7 @@ require_relative "../resource" class Chef class Resource class DmgPackage < Chef::Resource + unified_mode true resource_name :dmg_package provides(:dmg_package) { true } @@ -129,8 +130,8 @@ class Chef end end - ruby_block "attach #{dmg_file}" do - block do + unless dmg_attached? + converge_by "attach #{dmg_file}" do raise "This DMG package requires EULA acceptance. Add 'accept_eula true' to dmg_package resource to accept the EULA during installation." if software_license_agreement? && !new_resource.accept_eula attach_cmd = new_resource.accept_eula ? "yes | " : "" @@ -138,7 +139,6 @@ class Chef shell_out!(attach_cmd, env: { "PAGER" => "true" }) end - not_if { dmg_attached? } end case new_resource.type diff --git a/lib/chef/resource/dnf_package.rb b/lib/chef/resource/dnf_package.rb index b4eabbc3c7..6d0810ab2a 100644 --- a/lib/chef/resource/dnf_package.rb +++ b/lib/chef/resource/dnf_package.rb @@ -26,6 +26,7 @@ class Chef extend Chef::Mixin::Which extend Chef::Mixin::ShellOut + unified_mode true resource_name :dnf_package # all rhel variants >= 8 will use DNF diff --git a/lib/chef/resource/dpkg_package.rb b/lib/chef/resource/dpkg_package.rb index 116e17d6a6..7ce4da6b85 100644 --- a/lib/chef/resource/dpkg_package.rb +++ b/lib/chef/resource/dpkg_package.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob () -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,8 @@ require_relative "package" class Chef class Resource class DpkgPackage < Chef::Resource::Package + unified_mode true + resource_name :dpkg_package provides :dpkg_package diff --git a/lib/chef/resource/dsc_resource.rb b/lib/chef/resource/dsc_resource.rb index fe47d7fd1a..9c17139544 100644 --- a/lib/chef/resource/dsc_resource.rb +++ b/lib/chef/resource/dsc_resource.rb @@ -1,7 +1,7 @@ # # Author:: Adam Edwards () # -# Copyright:: Copyright 2014-2016, Chef Software Inc. +# Copyright:: Copyright 2014-2019, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/resource/dsc_script.rb b/lib/chef/resource/dsc_script.rb index 2ebb224b5b..34662ff3b9 100644 --- a/lib/chef/resource/dsc_script.rb +++ b/lib/chef/resource/dsc_script.rb @@ -1,6 +1,6 @@ # # Author:: Adam Edwards () -# Copyright:: Copyright 2014-2016, Chef Software, Inc. +# Copyright:: Copyright 2014-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +26,7 @@ class Chef class DscScript < Chef::Resource include Chef::DSL::Powershell + unified_mode true resource_name :dsc_script provides :dsc_script diff --git a/lib/chef/resource/freebsd_package.rb b/lib/chef/resource/freebsd_package.rb index dccb1e1a4f..bc94190c5b 100644 --- a/lib/chef/resource/freebsd_package.rb +++ b/lib/chef/resource/freebsd_package.rb @@ -1,7 +1,7 @@ # # Authors:: AJ Christensen () # Richard Manyanza () -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # Copyright:: Copyright 2014-2016, Richard Manyanza. # License:: Apache License, Version 2.0 # @@ -28,6 +28,7 @@ class Chef class FreebsdPackage < Chef::Resource::Package include Chef::Mixin::ShellOut + unified_mode true resource_name :freebsd_package provides :package, platform: "freebsd" diff --git a/lib/chef/resource/gem_package.rb b/lib/chef/resource/gem_package.rb index 30e9edf0b4..8497923a50 100644 --- a/lib/chef/resource/gem_package.rb +++ b/lib/chef/resource/gem_package.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob () -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,7 @@ require_relative "../dist" class Chef class Resource class GemPackage < Chef::Resource::Package + unified_mode true resource_name :gem_package description "Use the gem_package resource to manage gem packages that are only included in recipes. When a package is installed from a local file, it must be added to the node using the remote_file or cookbook_file resources." -- cgit v1.2.1