diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/provider/apt_repository.rb | 154 | ||||
-rw-r--r-- | lib/chef/provider/package.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/package/macports.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/package/portage.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource/apt_package.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource/git.rb | 15 | ||||
-rw-r--r-- | lib/chef/resource/osx_profile.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource/portage_package.rb | 10 | ||||
-rw-r--r-- | lib/chef/resource/registry_key.rb | 28 | ||||
-rw-r--r-- | lib/chef/resource/windows_service.rb | 4 | ||||
-rw-r--r-- | lib/chef/version.rb | 2 |
11 files changed, 143 insertions, 82 deletions
diff --git a/lib/chef/provider/apt_repository.rb b/lib/chef/provider/apt_repository.rb index c16f1e5767..1909ed8034 100644 --- a/lib/chef/provider/apt_repository.rb +++ b/lib/chef/provider/apt_repository.rb @@ -29,14 +29,15 @@ class Chef provides :apt_repository, platform_family: "debian" - LIST_APT_KEYS = "apt-key list".freeze LIST_APT_KEY_FINGERPRINTS = "apt-key adv --list-public-keys --with-fingerprint --with-colons".freeze def load_current_resource end action :add do - unless new_resource.key.nil? + if new_resource.key.nil? + Chef::Log.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) @@ -56,16 +57,10 @@ class Chef action :nothing end - components = if is_ppa_url?(new_resource.uri) && new_resource.components.empty? - "main" - else - new_resource.components - end - repo = build_repo( new_resource.uri, new_resource.distribution, - components, + repo_components, new_resource.trusted, new_resource.arch, new_resource.deb_src @@ -96,19 +91,27 @@ class Chef ignore_failure true action :nothing end - end + else + Chef::Log.debug("/etc/apt/sources.list.d/#{new_resource.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 [String] cmd the command to run + # + # @return [Array] an array of fingerprints def extract_fingerprints_from_cmd(cmd) so = shell_out(cmd) - so.run_command so.stdout.split(/\n/).map do |t| if z = t.match(/^fpr:+([0-9A-F]+):/) z[1].split.join @@ -116,11 +119,23 @@ class Chef end.compact end - def key_is_valid?(cmd, key) + # see if the keyfile is invalid such as a text file that is not actually a gpg key + # @param [String] keyfile the path to the keyfile + # + # @return [Boolean] is the key file invalid + def keyfile_is_invalid?(keyfile) + so = shell_out("gpg #{keyfile}") + so.error? + 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(cmd) - so.run_command + so = shell_out("apt-key list") so.stdout.split(/\n/).map do |t| if t =~ %r{^\/#{key}.*\[expired: .*\]$} Chef::Log.debug "Found expired key: #{t}" @@ -133,14 +148,27 @@ class Chef 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] path 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 @@ -149,37 +177,57 @@ class Chef (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) - type = if key.start_with?("http") - :remote_file - elsif has_cookbook_file?(key) - :cookbook_file - else - raise Chef::Exceptions::FileNotFound, "Cannot locate key file" - end - declare_resource(type, cached_keyfile) do + declare_resource(key_type(key), cached_keyfile) do source key mode "0644" sensitive new_resource.sensitive action :create end - raise "The key #{cached_keyfile} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("gpg #{cached_keyfile}", "") + raise "The key #{cached_keyfile} is invalid and cannot be used to verify an apt repository." if keyfile_is_invalid?(cached_keyfile) declare_resource(:execute, "apt-key add #{cached_keyfile}") do sensitive new_resource.sensitive action :run - not_if do - no_new_keys?(cached_keyfile) - end + not_if { no_new_keys?(cached_keyfile) } notifies :run, "execute[apt-cache gencaches]", :immediately end end - def install_key_from_keyserver(key, keyserver = new_resource.keyserver) + # 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 --recv" cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy cmd << " --keyserver " @@ -190,22 +238,37 @@ class Chef 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 cmd + command keyserver_install_cmd(key, keyserver) 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?(LIST_APT_KEYS, key.upcase) + 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?(LIST_APT_KEYS, key.upcase) + 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('"') @@ -214,12 +277,33 @@ class Chef 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) - return unless is_ppa_url?(ppa) owner, repo = ppa[4..-1].split("/") repo ||= "ppa" @@ -227,6 +311,14 @@ class Chef "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) diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index df3f2a46b1..9bfe94d5d0 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -480,7 +480,7 @@ class Chef elsif current_version.nil? Chef::Log.debug("#{new_resource} has no existing installed version. Installing install #{candidate_version}") target_version_array.push(candidate_version) - elsif version_compare(current_version, candidate_version) == 1 && !new_resource.allow_downgrade + elsif version_compare(current_version, candidate_version) == 1 && !allow_downgrade Chef::Log.debug("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{candidate_version}. Skipping...)") target_version_array.push(nil) else diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb index ad4be00477..514f3580d4 100644 --- a/lib/chef/provider/package/macports.rb +++ b/lib/chef/provider/package/macports.rb @@ -91,7 +91,7 @@ class Chef raise Chef::Exceptions::Package, "Could not read from STDOUT on command: #{command}" end unless status.exitstatus == 0 || status.exitstatus == 1 - raise Chef::Exceptions::Package, "#{command} failed - #{status.insect}!" + raise Chef::Exceptions::Package, "#{command} failed - #{status.inspect}!" end output end diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb index 05a5df370e..e43e71f210 100644 --- a/lib/chef/provider/package/portage.rb +++ b/lib/chef/provider/package/portage.rb @@ -17,7 +17,7 @@ # require "chef/provider/package" -require "chef/resource/package" +require "chef/resource/portage_package" require "chef/util/path_helper" class Chef diff --git a/lib/chef/resource/apt_package.rb b/lib/chef/resource/apt_package.rb index ea0c9c6183..22680d5b44 100644 --- a/lib/chef/resource/apt_package.rb +++ b/lib/chef/resource/apt_package.rb @@ -23,7 +23,7 @@ class Chef class Resource class AptPackage < Chef::Resource::Package resource_name :apt_package - provides :package, os: "linux", platform_family: "debian" + provides :package, platform_family: "debian" description "Use the apt_package resource to manage packages on Debian and Ubuntu platforms." diff --git a/lib/chef/resource/git.rb b/lib/chef/resource/git.rb index 9f1702f715..58200815d4 100644 --- a/lib/chef/resource/git.rb +++ b/lib/chef/resource/git.rb @@ -21,27 +21,14 @@ require "chef/resource/scm" class Chef class Resource class Git < Chef::Resource::Scm - description "Use the git resource to manage source control resources that exist"\ " in a git repository. git version 1.6.5 (or higher) is required to"\ " use all of the functionality in the git resource." - def initialize(name, run_context = nil) - super - @additional_remotes = Hash[] - end - - def additional_remotes(arg = nil) - set_or_return( - :additional_remotes, - arg, - :kind_of => Hash - ) - end + property :additional_remotes, Hash, default: {} alias :branch :revision alias :reference :revision - alias :repo :repository end end diff --git a/lib/chef/resource/osx_profile.rb b/lib/chef/resource/osx_profile.rb index a2f880d38d..cf857cec6f 100644 --- a/lib/chef/resource/osx_profile.rb +++ b/lib/chef/resource/osx_profile.rb @@ -24,8 +24,6 @@ class Chef provides :osx_profile, os: "darwin" provides :osx_config_profile, os: "darwin" - identity_attr :profile_name - description "Use the osx_profile resource to manage configuration profiles (.mobileconfig files)"\ " on the macOS platform. The osx_profile resource installs profiles by using"\ " the uuidgen library to generate a unique ProfileUUID, and then using the"\ @@ -35,7 +33,7 @@ class Chef default_action :install allowed_actions :install, :remove - property :profile_name, String, name_property: true + property :profile_name, String, name_property: true, identity: true property :profile, [ String, Hash ] property :identifier, String property :path, String diff --git a/lib/chef/resource/portage_package.rb b/lib/chef/resource/portage_package.rb index a12039b555..6936f5129f 100644 --- a/lib/chef/resource/portage_package.rb +++ b/lib/chef/resource/portage_package.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,13 +22,9 @@ class Chef class Resource class PortagePackage < Chef::Resource::Package resource_name :portage_package - description "Use the portage_package resource to manage packages for the Gentoo platform." - - def initialize(name, run_context = nil) - super - @provider = Chef::Provider::Package::Portage - end + provides :portage_package + description "Use the portage_package resource to manage packages for the Gentoo platform." end end end diff --git a/lib/chef/resource/registry_key.rb b/lib/chef/resource/registry_key.rb index 565ff278ea..8ca111bf33 100644 --- a/lib/chef/resource/registry_key.rb +++ b/lib/chef/resource/registry_key.rb @@ -15,14 +15,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # -require "chef/provider/registry_key" + require "chef/resource" require "chef/digester" class Chef class Resource - # Use the registry_key resource to create and delete registry keys in Microsoft Windows. class RegistryKey < Chef::Resource + resource_name :registry_key + provides :registry_key + + description "Use the registry_key resource to create and delete registry keys in Microsoft Windows." + introduced "11.0" + identity_attr :key state_attrs :values @@ -62,8 +67,6 @@ class Chef def initialize(name, run_context = nil) super - @architecture = :machine - @recursive = false @key = name @values, @unscrubbed_values = [], [] end @@ -102,21 +105,8 @@ class Chef end end - def recursive(arg = nil) - set_or_return( - :recursive, - arg, - :kind_of => [TrueClass, FalseClass] - ) - end - - def architecture(arg = nil) - set_or_return( - :architecture, - arg, - :kind_of => Symbol - ) - end + property :recursive, [TrueClass, FalseClass], default: false + property :architecture, Symbol, default: :machine, equal_to: [:machine, :x86_64, :i386] private diff --git a/lib/chef/resource/windows_service.rb b/lib/chef/resource/windows_service.rb index 8a76a716aa..aaa21aa6a7 100644 --- a/lib/chef/resource/windows_service.rb +++ b/lib/chef/resource/windows_service.rb @@ -41,11 +41,9 @@ class Chef allowed_actions :configure_startup, :create, :delete, :configure - identity_attr :service_name - state_attrs :enabled, :running - property :service_name, name_property: true + property :service_name, name_property: true, identity: true # The display name to be used by user interface programs to identify the # service. This string has a maximum length of 256 characters. diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 7bb86374ca..69b6ab16be 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require "chef/version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("14.0.105") + VERSION = Chef::VersionString.new("14.0.110") end # |