summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorAndrew Forgue <andrew.forgue@gmail.com>2009-12-07 17:43:09 -0500
committertest branch <puppet-dev@googlegroups.com>2010-02-17 06:50:53 -0800
commitbca7e2c2cca97c33466609e299122c448e669b22 (patch)
tree68428b9a6a57788ef85afce00cbbea0582c3486e /lib/puppet
parentb2c9455293796ab1d726314f6e5d2bd021fd648c (diff)
downloadpuppet-bca7e2c2cca97c33466609e299122c448e669b22.tar.gz
puppet-bca7e2c2cca97c33466609e299122c448e669b22.tar.xz
puppet-bca7e2c2cca97c33466609e299122c448e669b22.zip
Add AIX package management support (installp&nim)
This patch adds support for the native AIX package manager. It allows installation from either the name of an lpp_source (if you have a NIM environment configured, or from a directory containing .bff files. Signed-off-by: Andrew Forgue <andrew.forgue@gmail.com>
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/provider/package/aix.rb136
-rw-r--r--lib/puppet/provider/package/nim.rb37
2 files changed, 173 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