diff options
author | c5227532 <eike.waldt@sap.com> | 2016-09-28 19:49:49 +0200 |
---|---|---|
committer | c5227532 <eike.waldt@sap.com> | 2016-09-28 19:49:49 +0200 |
commit | 5320cb1b139defb1a37df0a12e26fe8dad1cc8bf (patch) | |
tree | 4f70ebd4403f3613a4d8e7e856eaf529a7e097bb | |
parent | 7ed29654c4adf43efbdddd2dccc5afb014c88cca (diff) | |
download | chef-5320cb1b139defb1a37df0a12e26fe8dad1cc8bf.tar.gz |
implement locking
-rw-r--r-- | lib/chef/provider/package.rb | 43 | ||||
-rw-r--r-- | lib/chef/provider/package/zypper.rb | 30 | ||||
-rw-r--r-- | lib/chef/resource/package.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/package/zypper_spec.rb | 18 | ||||
-rw-r--r-- | spec/unit/provider/package_spec.rb | 37 |
5 files changed, 129 insertions, 1 deletions
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index 3f641145e6..5d2c85bcfe 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -218,6 +218,41 @@ class Chef end end + def package_locked? + if !current_version_array.any? + # ! any? means it's all nil's, which means nothing is installed + false + elsif !new_version_array.any? + true # remove any version of all packages + elsif have_any_matching_version? + true # remove the version we have + else + false # we don't have the version we want to remove + end + end + + def action_lock + multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version| + if package_locked(name) == true + Chef::Log.debug("#{new_resource} is already locked") + else + lock_package(name) + Chef::Log.info("#{@new_resource} locked") + end + end + end + + def action_unlock + multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version| + if package_locked(name) == false + Chef::Log.debug("#{new_resource} is already unlocked") + else + unlock_package(name) + Chef::Log.info("#{@new_resource} unlocked") + end + end + end + # @todo use composition rather than inheritance def multipackage_api_adapter(name, version) @@ -252,6 +287,14 @@ class Chef raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :reconfig" ) end + def lock_package(name) + raise( Chef::Exceptions::UnsupportedAction, "#{self} does not support :lock" ) + end + + def unlock_package(name) + 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/zypper.rb b/lib/chef/provider/package/zypper.rb index e20a7332f7..efe07f52af 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -75,6 +75,28 @@ class Chef end end +### def package_locked? +### package_name_array.map do |package_name| +#### lock = `zypper locks | grep "| #{package_name} "`.split("|").shift(2).last.strip +### package_name.lock = `zypper locks | grep "| #{package_name} "` +### if package_name.lock.empty? +### false +### else +### true +### end +### end +### end + def package_locked(name) + islocked = false + locked = shell_out_with_timeout!("zypper locks") + locked.stdout.each_line do |line| + if line.split('|').shift(2).last.strip == name.first + 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 +129,14 @@ class Chef zypper_package("remove --clean-deps", name, version) end + def lock_package(name) + shell_out_with_timeout!(a_to_s("zypper", "addlock", name)) + end + + def unlock_package(name) + shell_out_with_timeout!(a_to_s("zypper", "removelock", name)) + end + private def zip(names, versions) diff --git a/lib/chef/resource/package.rb b/lib/chef/resource/package.rb index 32339e1a24..0738107339 100644 --- a/lib/chef/resource/package.rb +++ b/lib/chef/resource/package.rb @@ -25,7 +25,7 @@ class Chef resource_name :package default_action :install - allowed_actions :install, :upgrade, :remove, :purge, :reconfig + allowed_actions :install, :upgrade, :remove, :purge, :reconfig, :lock, :unlock def initialize(name, *args) # We capture name here, before it gets coerced to name diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index 8838c26b71..c64b113649 100644 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -231,6 +231,24 @@ describe Chef::Provider::Package::Zypper do end end + describe "lock_package" do + it "should run zypper addlock with the package name" do + shell_out_expectation!( + "zypper addlock emacs" + ) + provider.lock_package(["emacs"]) + end + end + + describe "unlock_package" do + it "should run zypper removelock with the package name" do + shell_out_expectation!( + "zypper removelock emacs" + ) + provider.unlock_package(["emacs"]) + end + end + describe "on an older zypper" do before(:each) do allow(provider).to receive(:`).and_return("0.11.6") diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb index 40b7516b5c..082fc00ba5 100644 --- a/spec/unit/provider/package_spec.rb +++ b/spec/unit/provider/package_spec.rb @@ -321,6 +321,35 @@ describe Chef::Provider::Package do end end + describe "When locking the package" do + before(:each) do + allow(provider).to receive(:lock_package).and_return(true) + end + + it "should lock the package if it is unlocked" do + expect(provider).to be_locking_package + expect(provider).to receive(:lock_package).with("emacs") + provider.run_action(:lock) + expect(new_resource).to be_updated + expect(new_resource).to be_updated_by_last_action + end + + it "should not purge the package if it is not installed" do + current_resource.instance_variable_set(:@version, nil) + expect(provider).not_to be_locking_package + + expect(provider).not_to receive(:lock_package) + provider.run_action(:lock) + expect(new_resource).not_to be_updated_by_last_action + end + + it "should set the resource to updated if it purges the package" do + provider.run_action(:lock) + expect(new_resource).to be_updated + end + + end + describe "when running commands to be implemented by subclasses" do it "should raises UnsupportedAction for install" do expect { provider.install_package("emacs", "1.4.2") }.to raise_error(Chef::Exceptions::UnsupportedAction) @@ -346,6 +375,14 @@ describe Chef::Provider::Package do it "should raise UnsupportedAction for reconfig" do expect { provider.reconfig_package("emacs", "1.4.2") }.to raise_error(Chef::Exceptions::UnsupportedAction) end + + it "should raise UnsupportedAction for lock" do + expect { provider.lock_package("emacs") }.to raise_error(Chef::Exceptions::UnsupportedAction) + end + + it "should raise UnsupportedAction for unlock" do + expect { provider.unlock_package("emacs") }.to raise_error(Chef::Exceptions::UnsupportedAction) + end end describe "when given a response file" do |