This has been sent before, but I've rebased against master as it's a new feature, and cleaned up some doc strings etc.
On Fri, Mar 26, 2010 at 3:10 PM, Nigel Kersten <[email protected]> wrote: > > Signed-off-by: Nigel Kersten <[email protected]> > --- > lib/puppet/provider/package/dpkg.rb | 31 +++++++++++++++++++- > lib/puppet/type/package.rb | 12 +++++++- > 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 06050ce..fda9e02 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 bb3db28..99285c5 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 0c5c9b5..7e3e8df 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 > - �[email protected](:dpkgquery).returns > @fakeresult.sub("installed", "foo") > + it "should consider the package absent if it is marked > 'config-files'" do > + �[email protected](:dpkgquery).returns > @fakeresult.sub("installed", "config-files") > + �[email protected][:ensure].should == :absent > + end > + > + it "should consider the package absent if it is marked > 'half-installed'" do > + �[email protected](:dpkgquery).returns > @fakeresult.sub("installed", "half-installed") > + �[email protected][:ensure].should == :absent > + end > + > + it "should consider the package absent if it is marked 'unpacked'" do > + �[email protected](:dpkgquery).returns > @fakeresult.sub("installed", "unpacked") > + �[email protected][:ensure].should == :absent > + end > > + it "should consider the package absent if it is marked > 'half-configured'" do > + �[email protected](: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 > + �[email protected](:dpkgquery).returns > @fakeresult.sub("install", "hold") > + �[email protected][: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 > + �[email protected](:unhold).once > + �[email protected](:dpkg) > + �[email protected] > + end > + end > + > + describe "when holding or unholding" do > + before do > + �...@tempfile = stub 'tempfile', :print => nil, :close => nil, > :flush => nil, :path => "/other/file" > + �[email protected](:write) > + Tempfile.stubs(:new).returns @tempfile > + end > + > + it "should install first if holding" do > + �[email protected](:execute) > + �[email protected](:install).once > + �[email protected] > + end > + > + it "should execute dpkg --set-selections when holding" do > + �[email protected](:install) > + �[email protected](:execute).with([:dpkg, '--set-selections'], > {:stdinfile => @tempfile.path}).once > + �[email protected] > + end > + > + it "should execute dpkg --set-selections when unholding" do > + �[email protected](:install) > + �[email protected](:execute).with([:dpkg, '--set-selections'], > {:stdinfile => @tempfile.path}).once > + �[email protected] > + end > end > > it "should use :install to update" do > -- > 1.7.0.3 > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Developers" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/puppet-dev?hl=en. > > -- nigel -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
