summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/mixin/why_run.rb10
-rw-r--r--lib/chef/provider.rb2
-rw-r--r--lib/chef/provider/mount/linux.rb18
-rw-r--r--lib/chef/provider/mount/mount.rb2
-rw-r--r--lib/chef/provider/package.rb81
-rw-r--r--lib/chef/provider/package/dnf.rb2
-rw-r--r--lib/chef/provider/package/powershell.rb23
-rw-r--r--lib/chef/resource/chef_client_config.rb23
-rw-r--r--lib/chef/resource/dnf_package.rb10
-rw-r--r--lib/chef/resource/support/client.erb7
-rw-r--r--lib/chef/version.rb2
11 files changed, 132 insertions, 48 deletions
diff --git a/lib/chef/mixin/why_run.rb b/lib/chef/mixin/why_run.rb
index efe327168e..357c4a655d 100644
--- a/lib/chef/mixin/why_run.rb
+++ b/lib/chef/mixin/why_run.rb
@@ -242,8 +242,12 @@ class Chef
end
end
- def initialize(resource, run_context)
- @resource, @run_context = resource, run_context
+ attr_accessor :action
+
+ def initialize(resource, run_context, action)
+ @resource = resource
+ @run_context = run_context
+ @action = action
@assertions = Hash.new { |h, k| h[k] = [] }
@blocked_actions = []
end
@@ -305,6 +309,8 @@ class Chef
# "You don't have sufficient privileges to delete #{@new_resource.path}")
# end
def assert(*actions)
+ return unless actions.include?(action.to_sym) || actions.include?(:all_actions)
+
assertion = Assertion.new
yield assertion
actions.each { |action| @assertions[action] << assertion }
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb
index e7d7ca84ff..80c58c09ee 100644
--- a/lib/chef/provider.rb
+++ b/lib/chef/provider.rb
@@ -269,7 +269,7 @@ class Chef
end
def requirements
- @requirements ||= ResourceRequirements.new(@new_resource, run_context)
+ @requirements ||= ResourceRequirements.new(@new_resource, run_context, action || new_resource.action)
end
def description(description = "NOT_PASSED")
diff --git a/lib/chef/provider/mount/linux.rb b/lib/chef/provider/mount/linux.rb
index 382e37d41a..83fbfab957 100644
--- a/lib/chef/provider/mount/linux.rb
+++ b/lib/chef/provider/mount/linux.rb
@@ -29,10 +29,16 @@ class Chef
# "findmnt" outputs the mount points with volume.
# Convert the mount_point of the resource to a real path in case it
# contains symlinks in its parents dirs.
+ def loop_mount_points
+ # get loop_mount_points only if not initialized earlier
+ @loop_mount_points ||= shell_out!("losetup -a").stdout
+
+ rescue Errno::ENOENT
+ @loop_mount_points = ""
+ end
def mounted?
mounted = false
-
real_mount_point = if ::File.exists? @new_resource.mount_point
::File.realpath(@new_resource.mount_point)
else
@@ -45,6 +51,14 @@ class Chef
when /\A#{Regexp.escape(real_mount_point)}\s+#{device_mount_regex}\s/
mounted = true
logger.trace("Special device #{device_logstring} mounted as #{real_mount_point}")
+ # Permalink for loop type devices mount points https://rubular.com/r/a0bS4p2RvXsGxx
+ when %r{\A#{Regexp.escape(real_mount_point)}\s+\/dev\/loop+[0-9]+\s}
+ loop_mount_points.each_line do |mount_point|
+ if mount_point.include? device_real
+ mounted = true
+ break
+ end
+ end
# Permalink for multiple devices mounted to the same mount point(i.e. '/proc') https://rubular.com/r/a356yzspU7N9TY
when %r{\A#{Regexp.escape(real_mount_point)}\s+([/\w])+\s}
mounted = false
@@ -64,4 +78,4 @@ class Chef
end
end
end
-end
+end \ No newline at end of file
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index 802ee11c23..2bc9d2c78f 100644
--- a/lib/chef/provider/mount/mount.rb
+++ b/lib/chef/provider/mount/mount.rb
@@ -279,4 +279,4 @@ class Chef
end
end
end
-end
+end \ No newline at end of file
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 65d2254258..82d7ed00cf 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -438,47 +438,81 @@ class Chef
@target_version_array ||=
begin
target_version_array = []
- each_package do |package_name, new_version, current_version, candidate_version|
+ each_package do |package_name, new_version, current_version, candidate_version, magic_version|
case action
when :upgrade
- if current_version.nil?
- # with use_magic_version there may be a package installed, but it fails the user's
- # requested new_resource.version constraints
+ if version_equals?(current_version, new_version)
+ # This is a short-circuit (mostly for the rubygems provider) to avoid needing to
+ # expensively query the candidate_version which must come later. This only checks
+ # exact matching, the check for fuzzy matching is later.
+ logger.trace("#{new_resource} #{package_name} #{new_version} is already installed")
+ target_version_array.push(nil)
+ elsif current_version.nil?
+ # This is a simple check to see if we have any currently installed version at all, this is
+ # safe to do before the allow_downgrade check so we check this before.
logger.trace("#{new_resource} has no existing installed version. Installing install #{candidate_version}")
target_version_array.push(candidate_version)
- elsif !use_magic_version? && version_equals?(current_version, new_version)
- # this is a short-circuit (mostly for the rubygems provider) to avoid needing to expensively query the candidate_version which must come later
- logger.trace("#{new_resource} #{package_name} #{new_version} is already installed")
+ elsif !allow_downgrade && version_compare(current_version, candidate_version) == 1
+ # This check for downgrading when allow_downgrade is false uses the current_version rather
+ # than the magic_version since we never want to downgrade even if the constraints are not met
+ # if the version is higher. This check does use the candidate_version and unlazies this so
+ # there will a perf hit on idempotent use when allow_downgrade is false which is unavoidable.
+ logger.trace("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{candidate_version}. Skipping...)")
target_version_array.push(nil)
+ elsif magic_version.nil?
+ # This is the check for fuzzy matching of the installed_version, where if the installed version
+ # does not match the desired version constraints (but is not an exact match) then we need to
+ # install the candidate_version (this must come after the allow_downgrade check)
+ logger.trace("#{new_resource} has an installed version that does not match the version constraint. Installing install #{candidate_version}")
+ target_version_array.push(candidate_version)
elsif candidate_version.nil?
+ # This check necessarily unlazies the candidate_version and may be expensive (connecting to
+ # rubygems.org or whatever). It comes as late as possible.
logger.trace("#{new_resource} #{package_name} has no candidate_version to upgrade to")
target_version_array.push(nil)
elsif version_equals?(current_version, candidate_version)
+ # This check sees if the candidate_version is already installed or if we should upgrade/update the
+ # package. This is the normal idempotent behavior of :upgrade and is inherently expensive due to
+ # unlazying the candidate_version. To prevent the perf hit the version may be specified with a full
+ # version constraint. Then the cookbook can roll the version forward and use :upgrade to force version
+ # pinning.
logger.trace("#{new_resource} #{package_name} #{candidate_version} is already installed")
target_version_array.push(nil)
- elsif !allow_downgrade && version_compare(current_version, candidate_version) == 1
- logger.trace("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{candidate_version}. Skipping...)")
- target_version_array.push(nil)
else
- logger.trace("#{new_resource} #{package_name} is out of date, will upgrade to #{candidate_version}")
+ logger.trace("#{new_resource} #{package_name} is out of date, will update to #{candidate_version}")
target_version_array.push(candidate_version)
end
when :install
- if new_version && !use_magic_version?
+ if current_version && new_version && !allow_downgrade && version_compare(current_version, new_version) == 1
+ # This is the idempotency guard for downgrades when downgrades are not allowed. This should perhaps raise
+ # an exception since we were told to install an exact package version but we are silently refusing to do so
+ # because a higher version is already installed. Maybe we need a flag for users to apply their preferred
+ # declarative philosophy? This has to come early and outside of the two code paths below.
+ logger.warn("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{new_version}. Skipping...)")
+ target_version_array.push(nil)
+ elsif new_version && !use_magic_version?
+ # This is for "non magic version using" subclasses to do comparisons between the current_version and the
+ # desired new_version. XXX: If we converted this to current_version_requirement_satisfied? and made it specific
+ # to the current version check and then eliminated the magic_version, we might be able to eliminate separate codepaths
+ # here, and eliminate the semantic confusion around the magic_version?
if version_requirement_satisfied?(current_version, new_version)
logger.trace("#{new_resource} #{package_name} #{current_version} satisfies #{new_version} requirement")
target_version_array.push(nil)
- elsif current_version && !allow_downgrade && version_compare(current_version, new_version) == 1
- logger.warn("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{new_version}. Skipping...)")
- target_version_array.push(nil)
else
+ # XXX: some subclasses seem to depend on this behavior where the new_version can be different from the
+ # candidate_version and we install the new_version, it seems like the candidate_version should be fixed to
+ # be resolved correctly to the new_version for those providers. although it may just be unit test bugs.
+ # it would be more correct to use the candidate_version here, but then it needs to be the correctly resolved
+ # candidate_version against the new_version constraint.
logger.trace("#{new_resource} #{package_name} #{current_version} needs updating to #{new_version}")
target_version_array.push(new_version)
end
- elsif current_version.nil?
- # with use_magic_version there may be a package installed, but it fails the user's
- # requested new_resource.version constraints
+ elsif magic_version.nil?
+ # This is for when we have a "magic version using" subclass and where the installed version does not match the
+ # constraint specified in the new_version, so we need to upgrade to the candidate_version. This is the only
+ # codepath in the :install branch which references the candidate_version so it is slow, but it is the path where
+ # we need to do work anyway. XXX: should we check for candidate_version.nil? somewhere around here?
logger.trace("#{new_resource} #{package_name} not installed, installing #{candidate_version}")
target_version_array.push(candidate_version)
else
@@ -512,8 +546,8 @@ class Chef
@packages_missing_candidates ||=
begin
missing = []
- each_package do |package_name, new_version, current_version, candidate_version|
- missing.push(package_name) if current_version.nil? && candidate_version.nil?
+ each_package do |package_name, new_version, current_version, candidate_version, magic_version|
+ missing.push(package_name) if magic_version.nil? && candidate_version.nil?
end
missing
end
@@ -536,7 +570,7 @@ class Chef
@forced_packages_missing_candidates ||=
begin
missing = []
- each_package do |package_name, new_version, current_version, candidate_version|
+ each_package do |package_name, new_version, current_version, candidate_version, magic_version|
next if new_version.nil? || current_version.nil?
if use_magic_version?
@@ -559,9 +593,10 @@ class Chef
def each_package
package_name_array.each_with_index do |package_name, i|
candidate_version = candidate_version_array[i]
- current_version = use_magic_version? ? magic_version[i] : current_version_array[i]
+ current_version = current_version_array[i]
+ magic_version = use_magic_version? ? magic_version_array[i] : current_version_array[i]
new_version = new_version_array[i]
- yield package_name, new_version, current_version, candidate_version
+ yield package_name, new_version, current_version, candidate_version, magic_version
end
end
diff --git a/lib/chef/provider/package/dnf.rb b/lib/chef/provider/package/dnf.rb
index 5c74ad0414..67bf24a411 100644
--- a/lib/chef/provider/package/dnf.rb
+++ b/lib/chef/provider/package/dnf.rb
@@ -98,7 +98,7 @@ class Chef
end
end
- def magic_version
+ def magic_version_array
package_name_array.each_with_index.map do |pkg, i|
magical_version(i).version_with_arch
end
diff --git a/lib/chef/provider/package/powershell.rb b/lib/chef/provider/package/powershell.rb
index 1c123d7952..2fe6cc2abc 100644
--- a/lib/chef/provider/package/powershell.rb
+++ b/lib/chef/provider/package/powershell.rb
@@ -17,13 +17,13 @@
require_relative "../package"
require_relative "../../resource/powershell_package"
-require_relative "../../mixin/powershell_out"
+require_relative "../../mixin/powershell_exec"
class Chef
class Provider
class Package
class Powershell < Chef::Provider::Package
- include Chef::Mixin::PowershellOut
+ include Chef::Mixin::PowershellExec
provides :powershell_package
@@ -54,9 +54,9 @@ class Chef
# Installs the package specified with the version passed else latest version will be installed
def install_package(names, versions)
names.each_with_index do |name, index|
- cmd = powershell_out(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
+ cmd = powershell_exec(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
next if cmd.nil?
- raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.stderr)
+ raise Chef::Exceptions::PowershellCmdletException, "Failed to install package due to catalog signing error, use skip_publisher_check to force install" if /SkipPublisherCheck/.match?(cmd.error)
end
end
@@ -64,11 +64,12 @@ class Chef
def remove_package(names, versions)
names.each_with_index do |name, index|
if versions && !versions[index].nil?
- powershell_out(build_powershell_package_command("Uninstall-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
+ powershell_exec(build_powershell_package_command("Uninstall-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
else
version = "0"
until version.empty?
- version = powershell_out(build_powershell_package_command("Uninstall-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
+ version = powershell_exec(build_powershell_package_command("Uninstall-Package '#{name}'"), timeout: new_resource.timeout).result
+ version = version.strip if version.respond_to?(:strip)
unless version.empty?
logger.info("Removed package '#{name}' with version #{version}")
end
@@ -82,13 +83,14 @@ class Chef
versions = []
new_resource.package_name.each_with_index do |name, index|
version = if new_resource.version && !new_resource.version[index].nil?
- powershell_out(build_powershell_package_command("Find-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).stdout.strip
+ powershell_exec(build_powershell_package_command("Find-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).result
else
- powershell_out(build_powershell_package_command("Find-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
+ powershell_exec(build_powershell_package_command("Find-Package '#{name}'"), timeout: new_resource.timeout).result
end
if version.empty?
version = nil
end
+ version = version.strip if version.respond_to?(:strip)
versions.push(version)
end
versions
@@ -99,13 +101,14 @@ class Chef
version_list = []
new_resource.package_name.each_with_index do |name, index|
version = if new_resource.version && !new_resource.version[index].nil?
- powershell_out(build_powershell_package_command("Get-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).stdout.strip
+ powershell_exec(build_powershell_package_command("Get-Package '#{name}'", new_resource.version[index]), timeout: new_resource.timeout).result
else
- powershell_out(build_powershell_package_command("Get-Package '#{name}'"), timeout: new_resource.timeout).stdout.strip
+ powershell_exec(build_powershell_package_command("Get-Package '#{name}'"), timeout: new_resource.timeout).result
end
if version.empty?
version = nil
end
+ version = version.strip if version.respond_to?(:strip)
version_list.push(version)
end
version_list
diff --git a/lib/chef/resource/chef_client_config.rb b/lib/chef/resource/chef_client_config.rb
index bd4ccbc478..ed5f3b26a8 100644
--- a/lib/chef/resource/chef_client_config.rb
+++ b/lib/chef/resource/chef_client_config.rb
@@ -87,6 +87,17 @@ class Chef
]
end
```
+
+ **Report directly to the [Chef Automate data collector endpoint](/automate/data_collection/#configure-chef-infra-client-to-use-the-data-collector-endpoint-in-chef-automate).**
+
+ ```ruby
+ chef_client_config 'Create client.rb' do
+ chef_server_url 'https://chef.example.dmz'
+ data_collector_server_url 'https://automate.example.dmz'
+ data_collector_token 'TEST_TOKEN_TEST'
+ end
+ ```
+
DOC
# @todo policy_file or policy_group being set requires the other to be set so enforce that.
@@ -231,6 +242,14 @@ class Chef
property :additional_config, String,
description: "Additional text to add at the bottom of the client.rb config. This can be used to run custom Ruby or to add less common config options"
+ property :data_collector_server_url, String,
+ description: "The data collector url (typically automate) to send node, converge and compliance data. Note: Data collection reporting to Automate should be performed directly by Chef Infra Server if possible, as this removes the need to distribute tokens to individual nodes.",
+ introduced: "17.8"
+
+ property :data_collector_token, String,
+ description: "The data collector token to interact with the data collector server url (Automate). Note: Data collection reporting to Automate should be performed directly by Chef Infra Server if possible, as this removes the need to distribute tokens to individual nodes.",
+ introduced: "17.8"
+
action :create, description: "Create a client.rb config file for configuring #{ChefUtils::Dist::Infra::PRODUCT}." do
unless ::Dir.exist?(new_resource.config_directory)
directory new_resource.config_directory do
@@ -282,7 +301,9 @@ class Chef
ssl_verify_mode: new_resource.ssl_verify_mode,
start_handlers: format_handler(new_resource.start_handlers),
additional_config: new_resource.additional_config,
- policy_persist_run_list: new_resource.policy_persist_run_list
+ policy_persist_run_list: new_resource.policy_persist_run_list,
+ data_collector_server_url: new_resource.data_collector_server_url,
+ data_collector_token: new_resource.data_collector_token
)
mode "0640"
action :create
diff --git a/lib/chef/resource/dnf_package.rb b/lib/chef/resource/dnf_package.rb
index 80727de7d0..aad0192490 100644
--- a/lib/chef/resource/dnf_package.rb
+++ b/lib/chef/resource/dnf_package.rb
@@ -68,12 +68,10 @@ class Chef
end
}
- def allow_downgrade(arg = nil)
- unless arg.nil?
- Chef.deprecated(:dnf_package_allow_downgrade, "the allow_downgrade property on the dnf_package provider is not used, DNF supports downgrades by default.")
- end
- true
- end
+ property :allow_downgrade, [ TrueClass, FalseClass ],
+ description: "Allow downgrading a package to satisfy requested version requirements.",
+ default: true,
+ desired_state: false
end
end
end
diff --git a/lib/chef/resource/support/client.erb b/lib/chef/resource/support/client.erb
index 0a0db02249..8e96ca49e2 100644
--- a/lib/chef/resource/support/client.erb
+++ b/lib/chef/resource/support/client.erb
@@ -37,6 +37,13 @@ log_location <%= @log_location %>
log_location <%= @log_location.inspect %>
<% end -%>
<% end -%>
+<%# These data_collector options are special as they have a '.' -%>
+<% unless @data_collector_server_url.nil? || @data_collector_server_url.empty? %>
+data_collector.server_url <%= @data_collector_server_url %>
+<% end %>
+<% unless @data_collector_token.nil? || @data_collector_token.empty? %>
+data_collector.token <%= @data_collector_token %>
+<% end %>
<%# The code below is not DRY on purpose to improve readability -%>
<% unless @start_handlers.empty? -%>
# Do not crash if a start handler is missing / not installed yet
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index ab1d551e75..ef237e0df9 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -23,7 +23,7 @@ require_relative "version_string"
class Chef
CHEF_ROOT = File.expand_path("..", __dir__)
- VERSION = Chef::VersionString.new("17.8.7")
+ VERSION = Chef::VersionString.new("17.8.20")
end
#