[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, experimental, updated. debian/2.6.8-1-844-g7ec39d5

Dominic Cleal dcleal at redhat.com
Tue May 10 08:06:18 UTC 2011


The following commit has been merged in the experimental branch:
commit 7c99dd966845fde026178a50b62c52735b2e5a1b
Author: Dominic Cleal <dcleal at redhat.com>
Date:   Sat Mar 19 00:07:30 2011 +0000

    (#4258) Use pkgutil -a to reliably determine package common names/aliases
    
    Populate instances with both the real package name ("CSWsvn") and the alias
    name ("subversion") from separate "pkgutil -a" call.
    
    Fixed cases where pkgutil noise was parsed as aliased package names and also
    breaking "not in catalog" detection.
    
    Updated pkgutil_spec test to show various edge cases.

diff --git a/lib/puppet/provider/package/pkgutil.rb b/lib/puppet/provider/package/pkgutil.rb
index 3a23796..350cacc 100755
--- a/lib/puppet/provider/package/pkgutil.rb
+++ b/lib/puppet/provider/package/pkgutil.rb
@@ -23,10 +23,45 @@ Puppet::Type.type(:package).provide :pkgutil, :parent => :sun, :source => :sun d
   end
 
   def self.instances(hash = {})
-    pkglist(hash).collect do |bhash|
-      bhash.delete(:avail)
-      new(bhash)
+    # Use the available pkg list (-a) to work out aliases
+    aliases = {}
+    availlist.each do |pkg|
+      aliases[pkg[:name]] = pkg[:alias]
     end
+
+    # The -c pkglist lists installed packages
+    pkginsts = []
+    pkglist(hash).each do |pkg|
+      pkg.delete(:avail)
+      pkginsts << new(pkg)
+
+      # Create a second instance with the alias if it's different
+      pkgalias = aliases[pkg[:name]]
+      if pkgalias and pkg[:name] != pkgalias
+        apkg = Hash.new(pkg)
+        apkg[:name] = pkgalias
+        pkginsts << new(apkg)
+      end
+    end
+
+    pkginsts
+  end
+
+  # Turns a pkgutil -a listing into hashes with the common alias, full
+  # package name and available version
+  def self.availlist
+    output = pkguti ["-a"]
+
+    list = output.split("\n").collect do |line|
+      next if line =~ /^common\s+package/  # header of package list
+      next if noise?(line)
+
+      if line =~ /\s*(\S+)\s+(\S+)\s+(.*)/
+        { :alias => $1, :name => $2, :avail => $3 }
+      else
+        Puppet.warning "Cannot match %s" % line
+      end
+    end.reject { |h| h.nil? }
   end
 
   # Turn our pkgutil -c listing into a bunch of hashes.
@@ -41,36 +76,45 @@ Puppet::Type.type(:package).provide :pkgutil, :parent => :sun, :source => :sun d
       command << hash[:justme]
     end
 
-    output = pkguti command
+    output = pkguti(command).split("\n")
 
-    list = output.split("\n").collect do |line|
-      next if line =~ /^#/
+    if output[-1] == "Not in catalog"
+      Puppet.warning "Package not in pkgutil catalog: %s" % hash[:justme]
+      return nil
+    end
+
+    list = output.collect do |line|
       next if line =~ /installed\s+catalog/  # header of package list
-      next if line =~ /^Checking integrity / # use_gpg
-      next if line =~ /^gpg: /               # gpg verification
-      next if line =~ /^=+> /                # catalog fetch
-      next if line =~ /\d+:\d+:\d+ URL:/     # wget without -q
+      next if noise?(line)
 
-      pkgsplit(line, hash[:justme])
+      pkgsplit(line)
     end.reject { |h| h.nil? }
 
     if hash[:justme]
-      # Ensure we picked up the package line, not any pkgutil noise.
-      list.reject! { |h| h[:name] != hash[:justme] }
-      return list[-1]
+      # Single queries may have been for an alias so return the name requested
+      if list.any?
+        list[-1][:name] = hash[:justme]
+        return list[-1]
+      end
     else
       list.reject! { |h| h[:ensure] == :absent }
       return list
     end
+  end
 
+  # Identify common types of pkgutil noise as it downloads catalogs etc
+  def self.noise?(line)
+    true if line =~ /^#/
+    true if line =~ /^Checking integrity / # use_gpg
+    true if line =~ /^gpg: /               # gpg verification
+    true if line =~ /^=+> /                # catalog fetch
+    true if line =~ /\d+:\d+:\d+ URL:/     # wget without -q
+    false
   end
 
   # Split the different lines into hashes.
-  def self.pkgsplit(line, justme)
-    if line == "Not in catalog"
-      Puppet.warning "Package not in pkgutil catalog: %s" % justme
-      return nil
-    elsif line =~ /\s*(\S+)\s+(\S+)\s+(.*)/
+  def self.pkgsplit(line)
+    if line =~ /\s*(\S+)\s+(\S+)\s+(.*)/
       hash = {}
       hash[:name] = $1
       hash[:ensure] = if $2 == "notinst"
@@ -80,10 +124,6 @@ Puppet::Type.type(:package).provide :pkgutil, :parent => :sun, :source => :sun d
       end
       hash[:avail] = $3
 
-      if justme
-        hash[:name] = justme
-      end
-
       if hash[:avail] =~ /^SAME\s*$/
         hash[:avail] = hash[:ensure]
       end
diff --git a/spec/unit/provider/package/pkgutil_spec.rb b/spec/unit/provider/package/pkgutil_spec.rb
index 01142b4..4f0e0cc 100755
--- a/spec/unit/provider/package/pkgutil_spec.rb
+++ b/spec/unit/provider/package/pkgutil_spec.rb
@@ -67,16 +67,15 @@ TESTpkg                   1.4.5,REV=2007.11.18      SAME"
     end
 
     it "should handle a non-existent package" do
-      fake_data = "noisy output here"
+      fake_data = "noisy output here
+Not in catalog"
       provider.expects(:pkguti).with(['-c', '--single', 'TESTpkg']).returns fake_data
       @provider.latest.should == nil
     end
 
     it "should warn on unknown pkgutil noise" do
-      provider.expects(:pkguti).returns("testingnoise")
-      Puppet.expects(:warning)
-      provider.expects(:new).never
-      provider.instances.should == []
+      provider.expects(:pkguti).with(['-c', '--single', 'TESTpkg']).returns("testingnoise")
+      @provider.latest.should == nil
     end
 
     it "should ignore pkgutil noise/headers to find TESTpkg" do
@@ -92,6 +91,14 @@ TESTpkg                   1.4.5,REV=2007.11.18      1.4.5,REV=2007.11.20"
       provider.expects(:pkguti).with(['-c', '--single', 'TESTpkg']).returns fake_data
       @provider.latest.should == "1.4.5,REV=2007.11.20"
     end
+
+    it "should find REALpkg via an alias (TESTpkg)" do
+      fake_data = "
+noisy output here
+REALpkg                   1.4.5,REV=2007.11.18      1.4.5,REV=2007.11.20"
+      provider.expects(:pkguti).with(['-c', '--single', 'TESTpkg']).returns fake_data
+      @provider.query[:name].should == "TESTpkg"
+    end
   end
 
   describe "when querying current version" do
@@ -108,14 +115,26 @@ TESTpkg                   1.4.5,REV=2007.11.18      1.4.5,REV=2007.11.20"
     end
 
     it "should handle a non-existent package" do
-      fake_data = "noisy output here"
+      fake_data = "noisy output here
+Not in catalog"
       provider.expects(:pkguti).with(['-c', '--single', 'TESTpkg']).returns fake_data
       @provider.query[:ensure].should == :absent
     end
   end
 
   describe "when querying current instances" do
+    it "should warn on unknown pkgutil noise" do
+      provider.expects(:pkguti).with(['-a']).returns("testingnoise")
+      provider.expects(:pkguti).with(['-c']).returns("testingnoise")
+      Puppet.expects(:warning).times(2)
+      provider.expects(:new).never
+      provider.instances.should == []
+    end
+
     it "should return TESTpkg's version string" do
+      fake_data = "TESTpkg  TESTpkg  1.4.5,REV=2007.11.20"
+      provider.expects(:pkguti).with(['-a']).returns fake_data
+
       fake_data = "TESTpkg  1.4.5,REV=2007.11.18  1.4.5,REV=2007.11.20"
       provider.expects(:pkguti).with(['-c']).returns fake_data
 
@@ -123,6 +142,35 @@ TESTpkg                   1.4.5,REV=2007.11.18      1.4.5,REV=2007.11.20"
       provider.expects(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).returns testpkg
       provider.instances.should == [testpkg]
     end
+
+    it "should also return both TESTpkg and mypkg alias instances" do
+      fake_data = "mypkg  TESTpkg  1.4.5,REV=2007.11.20"
+      provider.expects(:pkguti).with(['-a']).returns fake_data
+
+      fake_data = "TESTpkg  1.4.5,REV=2007.11.18  1.4.5,REV=2007.11.20"
+      provider.expects(:pkguti).with(['-c']).returns fake_data
+
+      testpkg = mock 'pkg1'
+      provider.expects(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).returns testpkg
+
+      aliaspkg = mock 'pkg2'
+      provider.expects(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "mypkg", :provider => :pkgutil).returns aliaspkg
+
+      provider.instances.should == [testpkg,aliaspkg]
+    end
+
+    it "shouldn't mind noise in the -a output" do
+      fake_data = "noisy output here"
+      provider.expects(:pkguti).with(['-a']).returns fake_data
+
+      fake_data = "TESTpkg  1.4.5,REV=2007.11.18  1.4.5,REV=2007.11.20"
+      provider.expects(:pkguti).with(['-c']).returns fake_data
+
+      testpkg = mock 'pkg1'
+      provider.expects(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).returns testpkg
+
+      provider.instances.should == [testpkg]
+    end
   end
 
 end

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list