+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.

Reply via email to