# Packaging using Peter Bonivart's pkgutil program.
Puppet::Type.type(:package).provide :pkgutil, :parent => :sun, :source => :sun do
desc "Package management using Peter Bonivart's ``pkgutil`` command on Solaris."
pkgutil_bin = "pkgutil"
if FileTest.executable?("/opt/csw/bin/pkgutil")
pkgutil_bin = "/opt/csw/bin/pkgutil"
end
confine :osfamily => :solaris
has_command(:pkguti, pkgutil_bin) do
environment :HOME => ENV['HOME']
end
def self.healthcheck()
unless Puppet::FileSystem.exist?("/var/opt/csw/pkgutil/admin")
Puppet.notice _("It is highly recommended you create '/var/opt/csw/pkgutil/admin'.")
Puppet.notice _("See /var/opt/csw/pkgutil")
end
correct_wgetopts = false
[ "/opt/csw/etc/pkgutil.conf", "/etc/opt/csw/pkgutil.conf" ].each do |confpath|
File.open(confpath) do |conf|
conf.each_line {|line| correct_wgetopts = true if line =~ /^\s*wgetopts\s*=.*(-nv|-q|--no-verbose|--quiet)/ }
end
end
if ! correct_wgetopts
Puppet.notice _("It is highly recommended that you set 'wgetopts=-nv' in your pkgutil.conf.")
end
end
def self.instances(hash = {})
healthcheck
# Use the available pkg list (-a) to work out aliases
aliases = {}
availlist.each do |pkg|
aliases[pkg[:name]] = pkg[:alias]
end
# The -c pkglist lists installed packages
pkginsts = []
output = pkguti(["-c"])
parse_pkglist(output).each do |pkg|
pkg.delete(:avail)
pkginsts << new(pkg)
# Create a second instance with the alias if it's different
pkgalias = aliases[pkg[:name]]
if pkgalias and pkg[:name] != pkgalias
apkg = pkg.dup
apkg[:name] = pkgalias
pkginsts << new(apkg)
end
end
pkginsts
end
# Turns a pkgutil -a listing into hashes with the common alias, full
# package name and available version
def self.availlist
output = pkguti ["-a"]
output.split("\n").collect do |line|
next if line =~ /^common\s+package/ # header of package list
next if noise?(line)
if line =~ /\s*(\S+)\s+(\S+)\s+(.*)/
{ :alias => $1, :name => $2, :avail => $3 }
else
Puppet.warning _("Cannot match %{line}") % { line: line }
end
end.reject { |h| h.nil? }
end
# Turn our pkgutil -c listing into a hash for a single package.
def pkgsingle(resource)
# The --single option speeds up the execution, because it queries
# the package management system for one package only.
command = ["-c", "--single", resource[:name]]
self.class.parse_pkglist(run_pkgutil(resource, command), { :justme => resource[:name] })
end
# Turn our pkgutil -c listing into a bunch of hashes.
def self.parse_pkglist(output, hash = {})
output = output.split("\n")
if output[-1] == "Not in catalog"
Puppet.warning _("Package not in pkgutil catalog: %{package}") % { package: hash[:justme] }
return nil
end
list = output.collect do |line|
next if line =~ /installed\s+catalog/ # header of package list
next if noise?(line)
pkgsplit(line)
end.reject { |h| h.nil? }
if hash[:justme]
# Single queries may have been for an alias so return the name requested
if list.any?
list[-1][:name] = hash[:justme]
return list[-1]
end
else
list.reject! { |h| h[:ensure] == :absent }
return list
end
end
# Identify common types of pkgutil noise as it downloads catalogs etc
def self.noise?(line)
true if line =~ /^#/
true if line =~ /^Checking integrity / # use_gpg
true if line =~ /^gpg: / # gpg verification
true if line =~ /^=+> / # catalog fetch
true if line =~ /\d+:\d+:\d+ URL:/ # wget without -q
false
end
# Split the different lines into hashes.
def self.pkgsplit(line)
if line =~ /\s*(\S+)\s+(\S+)\s+(.*)/
hash = {}
hash[:name] = $1
hash[:ensure] = if $2 == "notinst"
:absent
else
$2
end
hash[:avail] = $3
if hash[:avail] =~ /^SAME\s*$/
hash[:avail] = hash[:ensure]
end
# Use the name method, so it works with subclasses.
hash[:provider] = self.name
return hash
else
Puppet.warning _("Cannot match %{line}") % { line: line }
return nil
end
end
def run_pkgutil(resource, *args)
# Allow source to be one or more URLs pointing to a repository that all
# get passed to pkgutil via one or more -t options
if resource[:source]
sources = [resource[:source]].flatten
pkguti(*[sources.map{|src| [ "-t", src ]}, *args].flatten)
else
pkguti(*args.flatten)
end
end
def install
run_pkgutil @resource, "-y", "-i", @resource[:name]
end
# Retrieve the version from the current package file.
def latest
hash = pkgsingle(@resource)
hash[:avail] if hash
end
def query
hash = pkgsingle(@resource)
if hash
hash
else
{:ensure => :absent}
end
end
def update
run_pkgutil @resource, "-y", "-u", @resource[:name]
end
def uninstall
run_pkgutil @resource, "-y", "-r", @resource[:name]
end
end
Copyright 2K16 - 2K18 Indonesian Hacker Rulez