diff options
author | Gregory Batye <gbatye@fb.com> | 2016-11-07 14:51:33 -0800 |
---|---|---|
committer | Gregory Batye <gbatye@fb.com> | 2016-11-07 14:51:33 -0800 |
commit | 7387b08a2ca96ed99d9828d67259ad9fb10f513a (patch) | |
tree | 07d26ccc9a21c897412053ca122c5e2ad1884ad3 /lib/chef/provider | |
parent | 3050a0594ddf3a6a65020df036226594014534b0 (diff) | |
parent | 1d61e460675a540536bd4fc893b4bc6aa7070f21 (diff) | |
download | chef-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.rb | 36 | ||||
-rw-r--r-- | lib/chef/provider/package/apt.rb | 20 | ||||
-rw-r--r-- | lib/chef/provider/package/yum.rb | 20 | ||||
-rw-r--r-- | lib/chef/provider/package/zypper.rb | 20 | ||||
-rw-r--r-- | lib/chef/provider/service/upstart.rb | 34 | ||||
-rw-r--r-- | lib/chef/provider/user/dscl.rb | 11 | ||||
-rw-r--r-- | lib/chef/provider/user/solaris.rb | 17 | ||||
-rw-r--r-- | lib/chef/provider/yum_repository.rb | 13 |
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 |