+0.75 ! I finally got a change to test this on an OpenSolaris box. It works fine - there's just a few tweaks I'd like to see in the code:
1) Uninstall should probably be recursive ( -r ), on other providers "ensure => absent" will remove dependent packages, because that's the default behavior for most other package managers 2) the "Executing" debug message is redundant, commands are already output to the debug log. I saw: debug: Executing '/usr/bin/pkg list -H' debug: Puppet::Type::Package::ProviderPkg: Executing '/usr/bin/pkg list -H' 3) it would be nice to have spec tests for #query() and self.parse_line() 4) unfortunately, Puppet still uses 4-space indentation. This patch is in 2-space indentation. ~Jesse Wolfe On Sun, Jan 17, 2010 at 2:23 AM, James Turnbull <[email protected]>wrote: > From: Martin Englund <[email protected]> > > Plus very basic spec tests > > Signed-off-by: James Turnbull <[email protected]> > --- > lib/puppet/provider/package/pkg.rb | 114 > ++++++++++++++++++++++++++++++++++++ > spec/unit/provider/package/pkg.rb | 41 +++++++++++++ > 2 files changed, 155 insertions(+), 0 deletions(-) > create mode 100644 lib/puppet/provider/package/pkg.rb > create mode 100644 spec/unit/provider/package/pkg.rb > > diff --git a/lib/puppet/provider/package/pkg.rb > b/lib/puppet/provider/package/pkg.rb > new file mode 100644 > index 0000000..3b95642 > --- /dev/null > +++ b/lib/puppet/provider/package/pkg.rb > @@ -0,0 +1,114 @@ > +require 'puppet/provider/package' > + > +Puppet::Type.type(:package).provide :pkg, :parent => > Puppet::Provider::Package do > + desc "OpenSolaris image packaging system. See pkg(5) for more > information" > + > + commands :pkg => "/usr/bin/pkg" > + > + confine :operatingsystem => :solaris > + > + #defaultfor [:operatingsystem => :solaris, :kernelrelease => "5.11"] > + > + def self.instances > + packages = [] > + > + cmd = "#{command(:pkg)} list -H" > + Puppet.debug "Executing '%s'" % cmd > + execpipe(cmd) do |process| > + hash = {} > + > + # now turn each returned line into a package object > + process.each { |line| > + if hash = parse_line(line) > + packages << new(hash) > + end > + } > + end > + > + packages > + end > + > + REGEX = %r{^(\S+)\s+(\S+)\s+(\S+)\s+} > + FIELDS = [:name, :version, :status] > + > + def self.parse_line(line) > + hash = {} > + if match = REGEX.match(line) > + > + FIELDS.zip(match.captures) { |field,value| > + hash[field] = value > + } > + > + hash[:provider] = self.name > + > + if hash[:status] == "installed" > + hash[:ensure] = :present > + else > + hash[:ensure] = :absent > + end > + else > + Puppet.warning "Failed to match 'pkg list' line %s" % line.inspect > + return nil > + end > + > + return hash > + end > + > + # return the version of the package > + # TODO deal with multiple publishers > + def latest > + version = nil > + pkg(:list, "-Ha", @resource[:name]).split("\n").each do |line| > + v = line.split[2] > + case v > + when "known" > + return v > + when "installed" > + version = v > + else > + Puppet.warn "unknown package state for %s: %s" % > [...@resource[:name], v] > + end > + end > + version > + end > + > + # install the package > + def install > + pkg :install, @resource[:name] > + end > + > + # uninstall the package > + def uninstall > + pkg :uninstall, @resource[:name] > + end > + > + # update the package to the latest version available > + def update > + self.install > + end > + > + # list a specific package > + def query > + begin > + output = pkg(:list, "-H", @resource[:name]) > + rescue Puppet::ExecutionFailure > + # pkg returns 1 if the package is not found. > + return {:ensure => :absent, :status => 'missing', > + :name => @resource[:name], :error => 'ok'} > + end > + > + hash = self.class.parse_line(output) || > + {:ensure => :absent, :status => 'missing', > + :name => @resource[:name], :error => 'ok'} > + > + if hash[:error] != "ok" > + raise Puppet::Error.new( > + "Package %s, version %s is in error state: %s" % > + [hash[:name], hash[:ensure], hash[:error]] > + ) > + end > + > + return hash > + end > + > +end > \ No newline at end of file > diff --git a/spec/unit/provider/package/pkg.rb > b/spec/unit/provider/package/pkg.rb > new file mode 100644 > index 0000000..c153678 > --- /dev/null > +++ b/spec/unit/provider/package/pkg.rb > @@ -0,0 +1,41 @@ > +#!/usr/bin/env ruby > + > +require File.dirname(__FILE__) + '/../../../spec_helper' > + > +provider_class = Puppet::Type.type(:package).provider(:pkg) > + > +describe provider_class do > + before(:each) do > + @provider = provider_class.new > + end > + > + it "should have documentation" do > + provider_class.doc.should be_instance_of(String) > + end > + > + it "should have an install method" do > + @provider.should respond_to(:install) > + end > + > + it "should have an uninstall method" do > + @provider.should respond_to(:uninstall) > + end > + > + it "should have a latest method" do > + @provider.should respond_to(:latest) > + end > + > + it "should have an update method" do > + @provider.should respond_to(:update) > + end > + > + it "should have a query method" do > + @provider.should respond_to(:query) > + end > + > + it "should use :install to update" do > + @provider.expects(:install) > + @provider.update > + end > + > + end > -- > 1.6.5.2 > > > -- > 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]<puppet-dev%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/puppet-dev?hl=en. > > > > -- 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.
