summaryrefslogtreecommitdiff
path: root/lib/chef/provider
diff options
context:
space:
mode:
authorGregory Batye <gbatye@fb.com>2016-11-07 14:51:33 -0800
committerGregory Batye <gbatye@fb.com>2016-11-07 14:51:33 -0800
commit7387b08a2ca96ed99d9828d67259ad9fb10f513a (patch)
tree07d26ccc9a21c897412053ca122c5e2ad1884ad3 /lib/chef/provider
parent3050a0594ddf3a6a65020df036226594014534b0 (diff)
parent1d61e460675a540536bd4fc893b4bc6aa7070f21 (diff)
downloadchef-7387b08a2ca96ed99d9828d67259ad9fb10f513a.tar.gz
Merge remote-tracking branch 'chef/master' into fix_osx_profile
Diffstat (limited to 'lib/chef/provider')
-rw-r--r--lib/chef/provider/package.rb36
-rw-r--r--lib/chef/provider/package/apt.rb20
-rw-r--r--lib/chef/provider/package/yum.rb20
-rw-r--r--lib/chef/provider/package/zypper.rb20
-rw-r--r--lib/chef/provider/service/upstart.rb34
-rw-r--r--lib/chef/provider/user/dscl.rb11
-rw-r--r--lib/chef/provider/user/solaris.rb17
-rw-r--r--lib/chef/provider/yum_repository.rb13
8 files changed, 140 insertions, 31 deletions
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 3fed63c914..048807dd05 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -220,6 +220,34 @@ class Chef
end
end
+ def action_lock
+ if package_locked(@new_resource.name, @new_resource.version) == false
+ description = @new_resource.version ? "version #{@new_resource.version} of " : ""
+ converge_by("lock #{description}package #{@current_resource.package_name}") do
+ multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version|
+ lock_package(name, version)
+ Chef::Log.info("#{@new_resource} locked")
+ end
+ end
+ else
+ Chef::Log.debug("#{new_resource} is already locked")
+ end
+ end
+
+ def action_unlock
+ if package_locked(@new_resource.name, @new_resource.version) == true
+ description = @new_resource.version ? "version #{@new_resource.version} of " : ""
+ converge_by("unlock #{description}package #{@current_resource.package_name}") do
+ multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version|
+ unlock_package(name, version)
+ Chef::Log.info("#{@new_resource} unlocked")
+ end
+ end
+ else
+ Chef::Log.debug("#{new_resource} is already unlocked")
+ end
+ end
+
# @todo use composition rather than inheritance
def multipackage_api_adapter(name, version)
@@ -254,6 +282,14 @@ class Chef
raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :reconfig" )
end
+ def lock_package(name, version)
+ raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :lock" )
+ end
+
+ def unlock_package(name, version)
+ raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :unlock" )
+ end
+
# used by subclasses. deprecated. use #a_to_s instead.
def expand_options(options)
options ? " #{options}" : ""
diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb
index 8af089e14a..1c8ed8bc94 100644
--- a/lib/chef/provider/package/apt.rb
+++ b/lib/chef/provider/package/apt.rb
@@ -70,6 +70,18 @@ class Chef
@candidate_version ||= get_candidate_versions
end
+ def package_locked(name, version)
+ islocked = false
+ locked = shell_out_with_timeout!("apt-mark showhold")
+ locked.stdout.each_line do |line|
+ line_package = line.strip
+ if line_package == name
+ islocked = true
+ end
+ end
+ return islocked
+ end
+
def install_package(name, version)
package_name = name.zip(version).map do |n, v|
package_data[n][:virtual] ? n : "#{n}=#{v}"
@@ -105,6 +117,14 @@ class Chef
run_noninteractive("dpkg-reconfigure", name)
end
+ def lock_package(name, version)
+ run_noninteractive("apt-mark", new_resource.options, "hold", name)
+ end
+
+ def unlock_package(name, version)
+ run_noninteractive("apt-mark", new_resource.options, "unhold", name)
+ end
+
private
# Runs command via shell_out with magic environment to disable
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb
index 74d52946f7..022fdcae09 100644
--- a/lib/chef/provider/package/yum.rb
+++ b/lib/chef/provider/package/yum.rb
@@ -123,6 +123,18 @@ class Chef
end
end
+ def package_locked(name, version)
+ islocked = false
+ locked = shell_out_with_timeout!("yum versionlock")
+ locked.stdout.each_line do |line|
+ line_package = line.sub(/-[^-]*-[^-]*$/, "").split(":").last.strip
+ if line_package == name
+ islocked = true
+ end
+ end
+ return islocked
+ end
+
# Standard Provider methods for Parent
#
@@ -369,6 +381,14 @@ class Chef
remove_package(name, version)
end
+ def lock_package(name, version)
+ yum_command("-d0 -e0 -y#{expand_options(@new_resource.options)} versionlock add #{name}")
+ end
+
+ def unlock_package(name, version)
+ yum_command("-d0 -e0 -y#{expand_options(@new_resource.options)} versionlock delete #{name}")
+ end
+
private
def parse_arch(package_name)
diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb
index e20a7332f7..edad45c3e4 100644
--- a/lib/chef/provider/package/zypper.rb
+++ b/lib/chef/provider/package/zypper.rb
@@ -75,6 +75,18 @@ class Chef
end
end
+ def package_locked(name, version)
+ islocked = false
+ locked = shell_out_with_timeout!("zypper locks")
+ locked.stdout.each_line do |line|
+ line_package = line.split("|").shift(2).last.strip
+ if line_package == name
+ islocked = true
+ end
+ end
+ return islocked
+ end
+
def load_current_resource
@current_resource = Chef::Resource::ZypperPackage.new(new_resource.name)
current_resource.package_name(new_resource.package_name)
@@ -107,6 +119,14 @@ class Chef
zypper_package("remove --clean-deps", name, version)
end
+ def lock_package(name, version)
+ zypper_package("addlock", name, version)
+ end
+
+ def unlock_package(name, version)
+ zypper_package("removelock", name, version)
+ end
+
private
def zip(names, versions)
diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb
index 6e2a3b6473..9c0d97d376 100644
--- a/lib/chef/provider/service/upstart.rb
+++ b/lib/chef/provider/service/upstart.rb
@@ -26,6 +26,9 @@ class Chef
class Service
class Upstart < Chef::Provider::Service::Simple
+ # to maintain a local state of service across restart's internal calls
+ attr_accessor :upstart_service_running
+
provides :service, platform_family: "debian", override: true do |node|
Chef::Platform::ServiceHelpers.service_resource_providers.include?(:upstart)
end
@@ -110,23 +113,23 @@ class Chef
begin
if shell_out!(@new_resource.status_command).exitstatus == 0
- @current_resource.running true
+ @upstart_service_running = true
end
rescue
@command_success = false
- @current_resource.running false
+ @upstart_service_running = false
nil
end
else
begin
if upstart_goal_state == "start"
- @current_resource.running true
+ @upstart_service_running = true
else
- @current_resource.running false
+ @upstart_service_running = false
end
rescue Chef::Exceptions::Exec
@command_success = false
- @current_resource.running false
+ @upstart_service_running = false
nil
end
end
@@ -153,13 +156,14 @@ class Chef
@current_resource.enabled false
end
+ @current_resource.running @upstart_service_running
@current_resource
end
def start_service
# Calling start on a service that is already started will return 1
# Our 'goal' when we call start is to ensure the service is started
- if @current_resource.running
+ if @upstart_service_running
Chef::Log.debug("#{@new_resource} already running, not starting")
else
if @new_resource.start_command
@@ -168,12 +172,14 @@ class Chef
shell_out_with_systems_locale!("/sbin/start #{@job}")
end
end
+
+ @upstart_service_running = true
end
def stop_service
# Calling stop on a service that is already stopped will return 1
# Our 'goal' when we call stop is to ensure the service is stopped
- unless @current_resource.running
+ unless @upstart_service_running
Chef::Log.debug("#{@new_resource} not running, not stopping")
else
if @new_resource.stop_command
@@ -182,6 +188,8 @@ class Chef
shell_out_with_systems_locale!("/sbin/stop #{@job}")
end
end
+
+ @upstart_service_running = false
end
def restart_service
@@ -189,13 +197,19 @@ class Chef
super
# Upstart always provides restart functionality so we don't need to mimic it with stop/sleep/start.
# Older versions of upstart would fail on restart if the service was currently stopped, check for that. LP:430883
+ # But for safe working of latest upstart job config being loaded, 'restart' can't be used as per link
+ # http://upstart.ubuntu.com/cookbook/#restart (it doesn't uses latest jon config from disk but retains old)
else
- if @current_resource.running
- shell_out_with_systems_locale!("/sbin/restart #{@job}")
+ if @upstart_service_running
+ stop_service
+ sleep 1
+ start_service
else
start_service
end
end
+
+ @upstart_service_running = true
end
def reload_service
@@ -205,6 +219,8 @@ class Chef
# upstart >= 0.6.3-4 supports reload (HUP)
shell_out_with_systems_locale!("/sbin/reload #{@job}")
end
+
+ @upstart_service_running = true
end
# https://bugs.launchpad.net/upstart/+bug/94065
diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb
index 01203c0d9f..16d60ba116 100644
--- a/lib/chef/provider/user/dscl.rb
+++ b/lib/chef/provider/user/dscl.rb
@@ -51,6 +51,11 @@ class Chef
provides :dscl_user
provides :user, os: "darwin"
+ # Just-in-case a recipe calls the user dscl provider without specifying
+ # a gid property. Avoids chown issues in move_home when the manage_home
+ # property is in use. #5393
+ STAFF_GROUP_ID = 20
+
def define_resource_requirements
super
@@ -264,12 +269,12 @@ user password using shadow hash.")
#
# Sets the group id for the user using dscl. Fails if a group doesn't
# exist on the system with given group id. If `gid` is not specified, it
- # sets a default Mac user group "staff", with id 20.
+ # sets a default Mac user group "staff", with id 20 using the CONSTANT
#
def dscl_set_gid
if new_resource.gid.nil?
# XXX: mutates the new resource
- new_resource.gid(20)
+ new_resource.gid(STAFF_GROUP_ID)
elsif !new_resource.gid.to_s.match(/^\d+$/)
begin
possible_gid = run_dscl("read /Groups/#{new_resource.gid} PrimaryGroupID").split(" ").last
@@ -329,7 +334,7 @@ user password using shadow hash.")
def move_home
Chef::Log.debug("#{new_resource} moving #{self} home from #{current_resource.home} to #{new_resource.home}")
-
+ new_resource.gid(STAFF_GROUP_ID) if new_resource.gid.nil?
src = current_resource.home
FileUtils.mkdir_p(new_resource.home)
files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob_dir(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.", "#{src}/.."]
diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb
index 04567e6bca..7aa0ceb93a 100644
--- a/lib/chef/provider/user/solaris.rb
+++ b/lib/chef/provider/user/solaris.rb
@@ -46,21 +46,14 @@ class Chef
end
def check_lock
- shadow_line = shell_out!("getent", "shadow", new_resource.username).stdout.strip rescue nil
+ user = IO.read(@password_file).match(/^#{Regexp.escape(@new_resource.username)}:([^:]*):/)
- # if the command fails we return nil, this can happen if the user
- # in question doesn't exist
- return nil if shadow_line.nil?
+ # If we're in whyrun mode, and the user is not created, we assume it will be
+ return false if whyrun_mode? && user.nil?
- # convert "dave:NP:16507::::::\n" to "NP"
- fields = shadow_line.split(":")
+ raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if user.nil?
- # '*LK*...' and 'LK' are both considered locked,
- # so look for LK at the beginning of the shadow entry
- # optionally surrounded by '*'
- @locked = !!fields[1].match(/^\*?LK\*?/)
-
- @locked
+ @locked = user[1].start_with?("*LK*")
end
def lock_user
diff --git a/lib/chef/provider/yum_repository.rb b/lib/chef/provider/yum_repository.rb
index 09ff2c5512..be4d43f7ad 100644
--- a/lib/chef/provider/yum_repository.rb
+++ b/lib/chef/provider/yum_repository.rb
@@ -76,18 +76,17 @@ class Chef
end
action :delete do
+ # clean the repo cache first
+ declare_resource(:execute, "yum clean all #{new_resource.repositoryid}") do
+ command "yum clean all --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
+ only_if "yum repolist all | grep -P '^#{new_resource.repositoryid}([ \t]|$)'"
+ end
+
declare_resource(:file, "/etc/yum.repos.d/#{new_resource.repositoryid}.repo") do
action :delete
- notifies :run, "execute[yum clean all #{new_resource.repositoryid}]", :immediately
notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately
end
- declare_resource(:execute, "yum clean all #{new_resource.repositoryid}") do
- command "yum clean all --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
- only_if "yum repolist | grep -P '^#{new_resource.repositoryid}([ \t]|$)'"
- action :nothing
- end
-
declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do
block { Chef::Provider::Package::Yum::YumCache.instance.reload }
action :nothing