diff options
| author | Nigel Kersten <nigelk@google.com> | 2010-03-26 14:58:02 -0700 |
|---|---|---|
| committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
| commit | 02ed8db54372c8b824a10f6fb1df9773f0eb93d5 (patch) | |
| tree | 3fb184d164637f22fb82de0d281baeea3a6afccc | |
| parent | 0f2d3ce686f7e706537e03ebb2166478fa55f649 (diff) | |
| download | puppet-02ed8db54372c8b824a10f6fb1df9773f0eb93d5.tar.gz puppet-02ed8db54372c8b824a10f6fb1df9773f0eb93d5.tar.xz puppet-02ed8db54372c8b824a10f6fb1df9773f0eb93d5.zip | |
Fixes #2836. Add hold support to dpkg provider
| -rwxr-xr-x | lib/puppet/provider/package/dpkg.rb | 31 | ||||
| -rw-r--r-- | lib/puppet/type/package.rb | 12 | ||||
| -rwxr-xr-x | spec/unit/provider/package/dpkg.rb | 55 |
3 files changed, 94 insertions, 4 deletions
diff --git a/lib/puppet/provider/package/dpkg.rb b/lib/puppet/provider/package/dpkg.rb index 06050cefd..fda9e02fb 100755 --- a/lib/puppet/provider/package/dpkg.rb +++ b/lib/puppet/provider/package/dpkg.rb @@ -5,6 +5,8 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package and not ``apt``, you must specify the source of any packages you want to manage." + has_feature :holdable + commands :dpkg => "/usr/bin/dpkg" commands :dpkg_deb => "/usr/bin/dpkg-deb" commands :dpkgquery => "/usr/bin/dpkg-query" @@ -47,9 +49,12 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package if hash[:status] == 'not-installed' hash[:ensure] = :purged - elsif hash[:status] != "installed" + elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status]) hash[:ensure] = :absent end + if hash[:desired] == 'hold' + hash[:ensure] = :held + end else Puppet.warning "Failed to match dpkg-query line %s" % line.inspect return nil @@ -65,6 +70,9 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package args = [] + # We always unhold when installing to remove any prior hold. + self.unhold + if @resource[:configfiles] == :keep args << '--force-confold' else @@ -127,4 +135,25 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package def purge dpkg "--purge", @resource[:name] end + + def hold + self.install + begin + Tempfile.open('puppet_dpkg_set_selection') { |tmpfile| + tmpfile.write("#{@resource[:name]} hold\n") + tmpfile.flush + execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s) + } + end + end + + def unhold + begin + Tempfile.open('puppet_dpkg_set_selection') { |tmpfile| + tmpfile.write("#{@resource[:name]} install\n") + tmpfile.flush + execute([:dpkg, "--set-selections"], :stdinfile => tmpfile.path.to_s) + } + end + end end diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb index 5c2ffa6a8..827fee12b 100644 --- a/lib/puppet/type/package.rb +++ b/lib/puppet/type/package.rb @@ -35,6 +35,12 @@ module Puppet package database for installed version(s), and can select which out of a set of available versions of a package to install if asked." + feature :holdable, "The provider is capable of placing packages on hold + such that they are not automatically upgraded as a result of + other package dependencies unless explicit action is taken by + a user or another package. Held is considered a superset of + installed.", + :methods => [:hold] ensurable do desc "What state the package should be in. @@ -60,6 +66,10 @@ module Puppet provider.purge end + newvalue(:held, :event => :package_held, :required_features => :holdable) do + provider.hold + end + # Alias the 'present' value. aliasvalue(:installed, :present) @@ -111,7 +121,7 @@ module Puppet @should.each { |should| case should when :present - return true unless [:absent, :purged].include?(is) + return true unless [:absent, :purged, :held].include?(is) when :latest # Short-circuit packages that are not present return false if is == :absent or is == :purged diff --git a/spec/unit/provider/package/dpkg.rb b/spec/unit/provider/package/dpkg.rb index 0c5c9b527..7e3e8df43 100755 --- a/spec/unit/provider/package/dpkg.rb +++ b/spec/unit/provider/package/dpkg.rb @@ -88,11 +88,30 @@ describe provider do @provider.query[:ensure].should == :purged end - it "should consider the package absent if its status is neither 'installed' nor 'not-installed'" do - @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "foo") + it "should consider the package absent if it is marked 'config-files'" do + @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "config-files") + @provider.query[:ensure].should == :absent + end + + it "should consider the package absent if it is marked 'half-installed'" do + @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-installed") + @provider.query[:ensure].should == :absent + end + + it "should consider the package absent if it is marked 'unpacked'" do + @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "unpacked") + @provider.query[:ensure].should == :absent + end + it "should consider the package absent if it is marked 'half-configured'" do + @provider.expects(:dpkgquery).returns @fakeresult.sub("installed", "half-configured") @provider.query[:ensure].should == :absent end + + it "should consider the package held if its state is 'hold'" do + @provider.expects(:dpkgquery).returns @fakeresult.sub("install", "hold") + @provider.query[:ensure].should == :held + end end it "should be able to install" do @@ -130,6 +149,38 @@ describe provider do @provider.install end + + it "should ensure any hold is removed" do + @provider.expects(:unhold).once + @provider.expects(:dpkg) + @provider.install + end + end + + describe "when holding or unholding" do + before do + @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file" + @tempfile.stubs(:write) + Tempfile.stubs(:new).returns @tempfile + end + + it "should install first if holding" do + @provider.stubs(:execute) + @provider.expects(:install).once + @provider.hold + end + + it "should execute dpkg --set-selections when holding" do + @provider.stubs(:install) + @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once + @provider.hold + end + + it "should execute dpkg --set-selections when unholding" do + @provider.stubs(:install) + @provider.expects(:execute).with([:dpkg, '--set-selections'], {:stdinfile => @tempfile.path}).once + @provider.hold + end end it "should use :install to update" do |
