diff options
-rw-r--r-- | lib/puppet/provider/package/aix.rb | 136 | ||||
-rw-r--r-- | lib/puppet/provider/package/nim.rb | 37 | ||||
-rwxr-xr-x | spec/unit/provider/package/aix.rb | 66 | ||||
-rwxr-xr-x | spec/unit/provider/package/nim.rb | 42 |
4 files changed, 281 insertions, 0 deletions
diff --git a/lib/puppet/provider/package/aix.rb b/lib/puppet/provider/package/aix.rb new file mode 100644 index 000000000..b6f23c016 --- /dev/null +++ b/lib/puppet/provider/package/aix.rb @@ -0,0 +1,136 @@ +require 'puppet/provider/package' +require 'puppet/util/package' + +Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package do + desc "Installation from AIX Software directory" + + # The commands we are using on an AIX box are installed standard + # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset. + commands :lslpp => "/usr/bin/lslpp", + :installp => "/usr/sbin/installp" + + # AIX supports versionable packages with and without a NIM server + has_feature :versionable + + confine :operatingsystem => [ :aix ] + defaultfor :operatingsystem => :aix + + attr_accessor :latest_info + + def self.srclistcmd(source) + return [ command(:installp), "-L", "-d", source ] + end + + def self.prefetch(packages) + if Process.euid != 0 + raise Puppet::Error "The aix provider can only be used by root" + end + + return unless packages.detect { |name, package| package.should(:ensure) == :latest } + + sources = packages.collect { |name, package| package[:source] }.uniq + + updates = {} + sources.each do |source| + execute(self.srclistcmd(source)).each do |line| + if line =~ /^[^#][^:]*:([^:]*):([^:]*)/ + current = {} + current[:name] = $1 + current[:version] = $2 + current[:source] = source + + if updates.key?(current[:name]) + previous = updates[current[:name]] + + unless Puppet::Util::Package.versioncmp(previous[:version], current[:version]) == 1 + updates[ current[:name] ] = current + end + + else + updates[current[:name]] = current + end + end + end + end + + packages.each do |name, package| + if info = updates[package[:name]] + package.provider.latest_info = info[0] + end + end + end + + def uninstall + # Automatically process dependencies when installing/uninstalling + # with the -g option to installp. + installp "-gu", @resource[:name] + end + + def install(useversion = true) + unless source = @resource[:source] + self.fail "A directory is required which will be used to find packages" + end + + pkg = @resource[:name] + + if (! @resource.should(:ensure).is_a? Symbol) and useversion + pkg << " #{@resource.should(:ensure)}" + end + + installp "-acgwXY", "-d", source, pkg + end + + def self.pkglist(hash = {}) + cmd = [command(:lslpp), "-qLc"] + + if name = hash[:pkgname] + cmd << name + end + + begin + list = execute(cmd).scan(/^[^#][^:]*:([^:]*):([^:]*)/).collect { |n,e| + { :name => n, :ensure => e, :provider => self.name } + } + rescue Puppet::ExecutionFailure => detail + if hash[:pkgname] + return nil + else + raise Puppet::Error, "Could not list installed Packages: %s" % detail + end + end + + if hash[:pkgname] + return list.shift + else + return list + end + end + + def self.instances + pkglist.collect do |hash| + new(hash) + end + end + + def latest + upd = latest_info + + unless upd.nil? + return "#{upd[:version]}" + else + if properties[:ensure] == :absent + raise Puppet::DevError, "Tried to get latest on a missing package" + end + + return properties[:ensure] + end + end + + def query + return self.class.pkglist(:pkgname => @resource[:name]) + end + + def update + self.install(false) + end +end diff --git a/lib/puppet/provider/package/nim.rb b/lib/puppet/provider/package/nim.rb new file mode 100644 index 000000000..18f29215e --- /dev/null +++ b/lib/puppet/provider/package/nim.rb @@ -0,0 +1,37 @@ +require 'puppet/provider/package' +require 'puppet/util/package' + +Puppet::Type.type(:package).provide :nim, :parent => :aix, :source => :aix do + desc "Installation from NIM LPP source" + + # The commands we are using on an AIX box are installed standard + # (except nimclient) nimclient needs the bos.sysmgt.nim.client fileset. + commands :nimclient => "/usr/sbin/nimclient" + + # If NIM has not been configured, /etc/niminfo will not be present. + # However, we have no way of knowing if the NIM server is not configured + # properly. + confine :exists => "/etc/niminfo" + + has_feature :versionable + + attr_accessor :latest_info + + def self.srclistcmd(source) + return [ command(:nimclient), "-o", "showres", "-a", "installp_flags=L", "-a", "resource=#{source}" ] + end + + def install(useversion = true) + unless source = @resource[:source] + self.fail "An LPP source location is required in 'source'" + end + + pkg = @resource[:name] + + if (! @resource.should(:ensure).is_a? Symbol) and useversion + pkg << " " << @resource.should(:ensure) + end + + nimclient "-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=#{source}", "-a", "filesets=#{pkg}" + end +end diff --git a/spec/unit/provider/package/aix.rb b/spec/unit/provider/package/aix.rb new file mode 100755 index 000000000..691749df9 --- /dev/null +++ b/spec/unit/provider/package/aix.rb @@ -0,0 +1,66 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +provider_class = Puppet::Type.type(:package).provider(:aix) + +describe provider_class do + before(:each) do + # Create a mock resource + @resource = stub 'resource' + + # A catch all; no parameters set + @resource.stubs(:[]).returns(nil) + + # But set name and source + @resource.stubs(:[]).with(:name).returns "mypackage" + @resource.stubs(:[]).with(:source).returns "mysource" + @resource.stubs(:[]).with(:ensure).returns :installed + + @provider = provider_class.new + @provider.resource = @resource + end + + [:install, :uninstall, :latest, :query, :update].each do |method| + it "should have a #{method} method" do + @provider.should respond_to(method) + end + end + + it "should uninstall a package" do + @provider.expects(:installp).with('-gu', 'mypackage') + @provider.uninstall + end + + describe "when installing" do + it "should install a package" do + @resource.stubs(:should).with(:ensure).returns(:installed) + @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage') + @provider.install + end + + it "should install a specific package version" do + @resource.stubs(:should).with(:ensure).returns("1.2.3.4") + @provider.expects(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage 1.2.3.4') + @provider.install + end + end + + describe "when finding the latest version" do + it "should return the current version when no later version is present" do + @provider.stubs(:latest_info).returns(nil) + @provider.stubs(:properties).returns( { :ensure => "1.2.3.4" } ) + @provider.latest.should == "1.2.3.4" + end + + it "should return the latest version of a package" do + @provider.stubs(:latest_info).returns( { :version => "1.2.3.5" } ) + @provider.latest.should == "1.2.3.5" + end + end + + it "update should install a package" do + @provider.expects(:install).with(false) + @provider.update + end +end diff --git a/spec/unit/provider/package/nim.rb b/spec/unit/provider/package/nim.rb new file mode 100755 index 000000000..2018f6506 --- /dev/null +++ b/spec/unit/provider/package/nim.rb @@ -0,0 +1,42 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +provider_class = Puppet::Type.type(:package).provider(:nim) + +describe provider_class do + before(:each) do + # Create a mock resource + @resource = stub 'resource' + + # A catch all; no parameters set + @resource.stubs(:[]).returns(nil) + + # But set name and source + @resource.stubs(:[]).with(:name).returns "mypackage" + @resource.stubs(:[]).with(:source).returns "mysource" + @resource.stubs(:[]).with(:ensure).returns :installed + + @provider = provider_class.new + @provider.resource = @resource + end + + it "should have an install method" do + @provider = provider_class.new + @provider.should respond_to(:install) + end + + describe "when installing" do + it "should install a package" do + @resource.stubs(:should).with(:ensure).returns(:installed) + @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage'") + @provider.install + end + + it "should install a versioned package" do + @resource.stubs(:should).with(:ensure).returns("1.2.3.4") + @provider.expects(:nimclient).with("-o", "cust", "-a", "installp_flags=acgwXY", "-a", "lpp_source=mysource", "-a", "filesets='mypackage 1.2.3.4'") + @provider.install + end + end + end |