Please review pull request #719: Solaris 11 Support in pkg provider opened by (stschulte)
Description:
As Robert van Veelen mentioned in https://projects.puppetlabs.com/issues/11004:
/Oracle has changed the output format of pkg again for the final release of s11. The “status” field is no longer present in the output of “pkg list -H”. There is now an IFO field that has the following status flags .../
The patch now modifies the regex and marks the status field as an optional field so the regex will match on solaris 10 and also on solaris 11 lines. If the status field (installed or known) is not present, it will be generated by looking at the flag field which does indicate installed on solaris 11.
Please not that I do not own a solaris machine so I'm fixing the bug that is described in the ticket but I cannot tell if that is enough to fully support solaris 11 with the pkg provider.
- Opened: Thu Apr 26 14:59:48 UTC 2012
- Based on: puppetlabs:2.7.x (727dce84dfe41c3cbabb36b818368d7d9f28c553)
- Requested merge: stschulte:feature/2.7.x/11004 (6aa8441b7f1eaa54918a7bc49faf9b5ae01b60ea)
Diff follows:
diff --git a/lib/puppet/provider/package/pkg.rb b/lib/puppet/provider/package/pkg.rb
index 399a9df..3c4414f 100644
--- a/lib/puppet/provider/package/pkg.rb
+++ b/lib/puppet/provider/package/pkg.rb
@@ -22,8 +22,8 @@ def self.instances
packages
end
- self::REGEX = /^(\S+)(?:\s+\(.*?\))?\s+(\S+)\s+(\S+)\s+\S+$/
- self::FIELDS = [:name, :version, :status]
+ self::REGEX = /^(\S+)(?:\s+\(.*?\))?\s+(\S+)\s+(\S+)?\s+(\S+)$/
+ self::FIELDS = [:name, :version, :status, :flags]
def self.parse_line(line)
hash = {}
@@ -35,6 +35,22 @@ def self.parse_line(line)
hash[:provider] = self.name
+ # on solaris 11 we do not have a status field because the status
+ # seems to be merged in the flags field. Simulate old behaviour on
+ # solaris 11
+ flags = hash.delete(:flags)
+ unless hash[:status]
+ hash[:status] = case flags
+ when /^i/
+ 'installed'
+ when /^-/
+ 'known'
+ else
+ warning "unknown package state for #{hash[:name]}: #{flags}"
+ 'unknown'
+ end
+ end
+
if hash[:status] == "installed"
hash[:ensure] = :present
else
diff --git a/spec/fixtures/unit/provider/package/pkg/dummy b/spec/fixtures/unit/provider/package/pkg/dummy
deleted file mode 100644
index 2d56c39..0000000
--- a/spec/fixtures/unit/provider/package/pkg/dummy
+++ /dev/null
@@ -1 +0,0 @@
-dummy 2.5.5-0.111 installed ----
diff --git a/spec/fixtures/unit/provider/package/pkg/dummy_solaris10 b/spec/fixtures/unit/provider/package/pkg/dummy_solaris10
new file mode 100644
index 0000000..2d56c39
--- /dev/null
+++ b/spec/fixtures/unit/provider/package/pkg/dummy_solaris10
@@ -0,0 +1 @@
+dummy 2.5.5-0.111 installed ----
diff --git a/spec/fixtures/unit/provider/package/pkg/dummy_solaris11 b/spec/fixtures/unit/provider/package/pkg/dummy_solaris11
new file mode 100644
index 0000000..6c88019
--- /dev/null
+++ b/spec/fixtures/unit/provider/package/pkg/dummy_solaris11
@@ -0,0 +1 @@
+dummy 1.0.6-0.175.0.0.0.2.537 i--
diff --git a/spec/fixtures/unit/provider/package/pkg/solaris11 b/spec/fixtures/unit/provider/package/pkg/solaris11
new file mode 100644
index 0000000..e5bab71
--- /dev/null
+++ b/spec/fixtures/unit/provider/package/pkg/solaris11
@@ -0,0 +1,12 @@
+compress/zip 3.0-0.175.0.0.0.2.537 i--
+archiver/gnu-tar 1.26-0.175.0.0.0.2.537 i--
+compress/bzip2 1.0.6-0.175.0.0.0.2.537 i--
+compress/gzip 1.3.5-0.175.0.0.0.2.537 i--
+compress/p7zip 9.20.1-0.175.0.0.0.2.537 i--
+compress/unzip 6.0-0.175.0.0.0.2.537 i--
+compress/zip 3.0-0.175.0.0.0.2.537 i--
+x11/library/toolkit/libxaw7 1.0.9-0.175.0.0.0.0.1215 i--
+x11/library/toolkit/libxt 1.0.9-0.175.0.0.0.0.1215 i--
+shell/bash 4.1.9-0.175.0.0.0.2.537 i--
+shell/zsh 4.3.12-0.175.0.0.0.2.537 i--
+security/sudo 1.8.1.2-0.175.0.0.0.2.537 i--
diff --git a/spec/fixtures/unit/provider/package/pkg/unknown_status b/spec/fixtures/unit/provider/package/pkg/unknown_status
new file mode 100644
index 0000000..70a645b
--- /dev/null
+++ b/spec/fixtures/unit/provider/package/pkg/unknown_status
@@ -0,0 +1,12 @@
+compress/zip 3.0-0.175.0.0.0.2.537 i--
+archiver/gnu-tar 1.26-0.175.0.0.0.2.537 i--
+compress/bzip2 1.0.6-0.175.0.0.0.2.537 i--
+compress/gzip 1.3.5-0.175.0.0.0.2.537 i--
+compress/p7zip 9.20.1-0.175.0.0.0.2.537 i--
+compress/unzip 6.0-0.175.0.0.0.2.537 x--
+compress/zip 3.0-0.175.0.0.0.2.537 i--
+x11/library/toolkit/libxaw7 1.0.9-0.175.0.0.0.0.1215 i--
+x11/library/toolkit/libxt 1.0.9-0.175.0.0.0.0.1215 i--
+shell/bash 4.1.9-0.175.0.0.0.2.537 i--
+shell/zsh 4.3.12-0.175.0.0.0.2.537 i--
+security/sudo 1.8.1.2-0.175.0.0.0.2.537 i--
diff --git a/spec/unit/provider/package/pkg_spec.rb b/spec/unit/provider/package/pkg_spec.rb
index 50a87ce..71682df 100755
--- a/spec/unit/provider/package/pkg_spec.rb
+++ b/spec/unit/provider/package/pkg_spec.rb
@@ -29,20 +29,39 @@ def self.it_should_respond_to(*actions)
describe "when calling instances" do
it "should correctly parse lines with preferred publisher" do
described_class.expects(:pkg).with(:list,'-H').returns File.read(my_fixture('simple'))
- @instances = described_class.instances.map { |p| Hash.new(:name => p.get(:name), :ensure => p.get(:ensure)) }
+ @instances = described_class.instances.map { |p| {:name => p.get(:name), :ensure => p.get(:ensure)} }
@instances.size.should == 4
- @instances[0].should == Hash.new(:name => 'SUNPython', :ensure => :present)
- @instances[1].should == Hash.new(:name => 'SUNWbind', :ensure => :present)
- @instances[2].should == Hash.new(:name => 'SUNWdistro-license-copyright', :ensure => :present)
- @instances[3].should == Hash.new(:name => 'SUNWfppd', :ensure => :present)
+ @instances[0].should == {:name => 'SUNPython', :ensure => :present}
+ @instances[1].should == {:name => 'SUNWbind', :ensure => :present}
+ @instances[2].should == {:name => 'SUNWdistro-license-copyright', :ensure => :present}
+ @instances[3].should == {:name => 'SUNWfppd', :ensure => :present}
end
it "should correctly parse lines with non preferred publisher" do
described_class.expects(:pkg).with(:list,'-H').returns File.read(my_fixture('publisher'))
- @instances = described_class.instances.map { |p| Hash.new(:name => p.get(:name), :ensure => p.get(:ensure)) }
+ @instances = described_class.instances.map { |p| {:name => p.get(:name), :ensure => p.get(:ensure)} }
@instances.size.should == 2
- @instances[0].should == Hash.new(:name => 'SUNWpcre', :ensure => :present)
- @instances[1].should == Hash.new(:name => 'service/network/ssh', :ensure => :present)
+ @instances[0].should == {:name => 'SUNWpcre', :ensure => :present}
+ @instances[1].should == {:name => 'service/network/ssh', :ensure => :present}
+ end
+
+ it "should correctly parse lines on solaris 11" do
+ described_class.expects(:pkg).with(:list, '-H').returns File.read(my_fixture('solaris11'))
+ described_class.expects(:warning).never
+ @instances = described_class.instances.map { |p| {:name => p.get(:name), :ensure => p.get(:ensure) }}
+ @instances.size.should == 12
+ @instances[0].should == {:name => 'compress/zip', :ensure => :present}
+ @instances[1].should == {:name => 'archiver/gnu-tar', :ensure => :present}
+ @instances[2].should == {:name => 'compress/bzip2', :ensure => :present}
+ @instances[3].should == {:name => 'compress/gzip', :ensure => :present}
+ @instances[4].should == {:name => 'compress/p7zip', :ensure => :present}
+ @instances[5].should == {:name => 'compress/unzip', :ensure => :present}
+ @instances[6].should == {:name => 'compress/zip', :ensure => :present}
+ @instances[7].should == {:name => 'x11/library/toolkit/libxaw7', :ensure => :present}
+ @instances[8].should == {:name => 'x11/library/toolkit/libxt', :ensure => :present}
+ @instances[9].should == {:name => 'shell/bash', :ensure => :present}
+ @instances[10].should == {:name => 'shell/zsh', :ensure => :present}
+ @instances[11].should == {:name => 'security/sudo', :ensure => :present}
end
it "should warn about incorrect lines" do
@@ -52,25 +71,54 @@ def self.it_should_respond_to(*actions)
described_class.expects(:warning).with "Failed to match 'pkg list' line #{error_line.inspect}"
described_class.instances
end
+
+ it "should warn about unknown package status" do
+ described_class.expects(:pkg).with(:list,'-H').returns File.read(my_fixture('unknown_status'))
+ described_class.expects(:warning).with "unknown package state for compress/unzip: x--"
+ described_class.instances
+ end
end
describe "when query a package" do
- it "should find the package" do
- @provider.stubs(:pkg).with(:list,'-H','dummy').returns File.read(my_fixture('dummy'))
- @provider.query.should == {
- :name => 'dummy',
- :ensure => :present,
- :version => '2.5.5-0.111',
- :status => "installed",
- :provider => :pkg,
- }
+
+ context "on solaris 10" do
+ it "should find the package" do
+ @provider.stubs(:pkg).with(:list,'-H','dummy').returns File.read(my_fixture('dummy_solaris10'))
+ @provider.query.should == {
+ :name => 'dummy',
+ :ensure => :present,
+ :version => '2.5.5-0.111',
+ :status => "installed",
+ :provider => :pkg,
+ }
+ end
+
+ it "should return :absent when the package is not found" do
+ # I dont know what the acutal error looks like, but according to type/pkg.rb we're just
+ # reacting on the Exception anyways
+ @provider.expects(:pkg).with(:list, "-H", "dummy").raises Puppet::ExecutionFailure, 'Not found'
+ @provider.query.should == {:ensure => :absent, :name => "dummy"}
+ end
end
- it "should return :absent when the package is not found" do
- # I dont know what the acutal error looks like, but according to type/pkg.rb we're just
- # reacting on the Exception anyways
- @provider.expects(:pkg).with(:list, "-H", "dummy").raises Puppet::ExecutionFailure, 'Not found'
- @provider.query.should == {:ensure => :absent, :name => "dummy"}
+ context "on solaris 11" do
+ it "should find the package" do
+ @provider.stubs(:pkg).with(:list,'-H','dummy').returns File.read(my_fixture('dummy_solaris11'))
+ @provider.query.should == {
+ :name => 'dummy',
+ :ensure => :present,
+ :version => '1.0.6-0.175.0.0.0.2.537',
+ :status => "installed",
+ :provider => :pkg,
+ }
+ end
+
+ it "should return :absent when the package is not found" do
+ # I dont know what the acutal error looks like, but according to type/pkg.rb we're just
+ # reacting on the Exception anyways
+ @provider.expects(:pkg).with(:list, "-H", "dummy").raises Puppet::ExecutionFailure, 'Not found'
+ @provider.query.should == {:ensure => :absent, :name => "dummy"}
+ end
end
it "should return :absent when the packageline cannot be parsed" do
-- 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.
