require 'puppet/provider/package' Puppet::Type.type(:package).provide :pacman, :parent => Puppet::Provider::Package do desc "Support for the Package Manager Utility (pacman) used in Archlinux." commands :pacman => "/usr/bin/pacman" defaultfor :operatingsystem => :archlinux confine :operatingsystem => :archlinux has_feature :upgradeable # Install a package using 'pacman'. # Installs quietly, without confirmation or progressbar, updates package # list from servers defined in pacman.conf. def install pacman "--noconfirm", "--noprogressbar", "-Sy", @resource[:name] unless self.query raise Puppet::ExecutionFailure.new("Could not find package %s" % self.name) end end def self.listcmd [command(:pacman), " -Q"] end # Fetch the list of packages currently installed on the system. def self.instances packages = [] begin execpipe(listcmd()) do |process| # pacman -Q output is 'packagename version-rel' regex = %r{^(\S+)\s(\S+)} fields = [:name, :ensure] hash = {} process.each_line { |line| if match = regex.match(line) fields.zip(match.captures) { |field,value| hash[field] = value } name = hash[:name] hash[:provider] = self.name packages << new(hash) hash = {} else warning("Failed to match line %s" % line) end } end rescue Puppet::ExecutionFailure return nil end packages end # Because Archlinux is a rolling release based distro, installing a package # should always result in the newest release. def update # Install in pacman can be used for update, too self.install end def latest pacman "-Sy" output = pacman "-Sp", "--print-format", "%v", @resource[:name] output.chomp end # Querys the pacman master list for information about the package. def query begin output = pacman("-Qi", @resource[:name]) if output =~ /Version.*:\s(.+)/ return { :ensure => $1 } end rescue Puppet::ExecutionFailure return { :ensure => :purged, :status => 'missing', :name => @resource[:name], :error => 'ok', } end nil end # Removes a package from the system. def uninstall pacman "--noconfirm", "--noprogressbar", "-R", @resource[:name] end end