summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider
diff options
context:
space:
mode:
authorJosh Cooper <josh@puppetlabs.com>2011-04-21 14:37:50 -0700
committerJosh Cooper <josh@puppetlabs.com>2011-04-21 14:37:50 -0700
commit01f610bb223b435dc52f491260af3ea002930102 (patch)
tree93565136d5ef2b4156fdd64476792e441bcfbb4e /lib/puppet/provider
parentac428b9557e2da251e4b51e48de844833ca0aa2a (diff)
parentfc66e98b84b9a16728af054485883334a5887cca (diff)
Merge branch 'next'
Diffstat (limited to 'lib/puppet/provider')
-rw-r--r--lib/puppet/provider/cisco.rb9
-rw-r--r--lib/puppet/provider/interface/cisco.rb18
-rw-r--r--lib/puppet/provider/network_device.rb23
-rwxr-xr-xlib/puppet/provider/package/aptitude.rb1
-rwxr-xr-xlib/puppet/provider/package/pkgutil.rb175
-rw-r--r--lib/puppet/provider/vlan/cisco.rb14
6 files changed, 211 insertions, 29 deletions
diff --git a/lib/puppet/provider/cisco.rb b/lib/puppet/provider/cisco.rb
new file mode 100644
index 000000000..918982f59
--- /dev/null
+++ b/lib/puppet/provider/cisco.rb
@@ -0,0 +1,9 @@
+require 'puppet/util/network_device/cisco/device'
+require 'puppet/provider/network_device'
+
+# This is the base class of all prefetched cisco device providers
+class Puppet::Provider::Cisco < Puppet::Provider::NetworkDevice
+ def self.device(url)
+ Puppet::Util::NetworkDevice::Cisco::Device.new(url)
+ end
+end
diff --git a/lib/puppet/provider/interface/cisco.rb b/lib/puppet/provider/interface/cisco.rb
index f3bd202e9..795a7f1ac 100644
--- a/lib/puppet/provider/interface/cisco.rb
+++ b/lib/puppet/provider/interface/cisco.rb
@@ -1,22 +1,20 @@
-require 'puppet/util/network_device/cisco/device'
-require 'puppet/provider/network_device'
+require 'puppet/provider/cisco'
-Puppet::Type.type(:interface).provide :cisco, :parent => Puppet::Provider::NetworkDevice do
+Puppet::Type.type(:interface).provide :cisco, :parent => Puppet::Provider::Cisco do
desc "Cisco switch/router provider for interface."
mk_resource_methods
- def self.lookup(url, name)
+ def self.lookup(device, name)
interface = nil
- network_gear = Puppet::Util::NetworkDevice::Cisco::Device.new(url)
- network_gear.command do |ng|
- interface = network_gear.interface(name)
+ device.command do |ng|
+ interface = device.interface(name)
end
interface
end
- def initialize(*args)
+ def initialize(device, *args)
super
end
@@ -26,8 +24,4 @@ Puppet::Type.type(:interface).provide :cisco, :parent => Puppet::Provider::Netwo
end
super
end
-
- def device
- @device ||= Puppet::Util::NetworkDevice::Cisco::Device.new(resource[:device_url])
- end
end
diff --git a/lib/puppet/provider/network_device.rb b/lib/puppet/provider/network_device.rb
index 58865fddc..46be27968 100644
--- a/lib/puppet/provider/network_device.rb
+++ b/lib/puppet/provider/network_device.rb
@@ -2,17 +2,22 @@
# This is the base class of all prefetched network device provider
class Puppet::Provider::NetworkDevice < Puppet::Provider
- def self.lookup(url, name)
+ def self.device(url)
+ raise "This provider doesn't implement the necessary device method"
+ end
+
+ def self.lookup(device, name)
raise "This provider doesn't implement the necessary lookup method"
end
def self.prefetch(resources)
resources.each do |name, resource|
- if result = lookup(resource[:device_url], name)
+ device = Puppet::Util::NetworkDevice.current || device(resource[:device_url])
+ if result = lookup(device, name)
result[:ensure] = :present
- resource.provider = new(result)
+ resource.provider = new(device, result)
else
- resource.provider = new(:ensure => :absent)
+ resource.provider = new(device, :ensure => :absent)
end
end
end
@@ -21,8 +26,12 @@ class Puppet::Provider::NetworkDevice < Puppet::Provider
@property_hash[:ensure] != :absent
end
- def initialize(*args)
- super
+ attr_accessor :device
+
+ def initialize(device, *args)
+ super(*args)
+
+ @device = device
# Make a duplicate, so that we have a copy for comparison
# at the end.
@@ -56,4 +65,4 @@ class Puppet::Provider::NetworkDevice < Puppet::Provider
def properties
@property_hash.dup
end
-end \ No newline at end of file
+end
diff --git a/lib/puppet/provider/package/aptitude.rb b/lib/puppet/provider/package/aptitude.rb
index 8bdf984e6..2eafd3ef8 100755
--- a/lib/puppet/provider/package/aptitude.rb
+++ b/lib/puppet/provider/package/aptitude.rb
@@ -12,6 +12,7 @@ Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg
args.flatten!
# Apparently aptitude hasn't always supported a -q flag.
args.delete("-q") if args.include?("-q")
+ args.delete("--force-yes") if args.include?("--force-yes")
output = aptitude(*args)
# Yay, stupid aptitude doesn't throw an error when the package is missing.
diff --git a/lib/puppet/provider/package/pkgutil.rb b/lib/puppet/provider/package/pkgutil.rb
new file mode 100755
index 000000000..a1d844f73
--- /dev/null
+++ b/lib/puppet/provider/package/pkgutil.rb
@@ -0,0 +1,175 @@
+# 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 :operatingsystem => :solaris
+
+ commands :pkguti => pkgutil_bin
+
+ def self.healthcheck()
+ unless FileTest.exists?("/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| 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 = []
+ pkglist(hash).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"]
+
+ list = 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 %s" % line
+ end
+ end.reject { |h| h.nil? }
+ end
+
+ # Turn our pkgutil -c listing into a bunch of hashes.
+ # Supports :justme => packagename, which uses the optimised --single arg
+ def self.pkglist(hash)
+ command = ["-c"]
+
+ if hash[:justme]
+ # The --single option speeds up the execution, because it queries
+ # the package managament system for one package only.
+ command << "--single"
+ command << hash[:justme]
+ end
+
+ output = pkguti(command).split("\n")
+
+ if output[-1] == "Not in catalog"
+ Puppet.warning "Package not in pkgutil catalog: %s" % 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 %s" % line
+ return nil
+ end
+ end
+
+ def install
+ pkguti "-y", "-i", @resource[:name]
+ end
+
+ # Retrieve the version from the current package file.
+ def latest
+ hash = self.class.pkglist(:justme => @resource[:name])
+ hash[:avail] if hash
+ end
+
+ def query
+ if hash = self.class.pkglist(:justme => @resource[:name])
+ hash
+ else
+ {:ensure => :absent}
+ end
+ end
+
+ def update
+ pkguti "-y", "-u", @resource[:name]
+ end
+
+ def uninstall
+ pkguti "-y", "-r", @resource[:name]
+ end
+end
+
diff --git a/lib/puppet/provider/vlan/cisco.rb b/lib/puppet/provider/vlan/cisco.rb
index 46e172c73..3421d35b0 100644
--- a/lib/puppet/provider/vlan/cisco.rb
+++ b/lib/puppet/provider/vlan/cisco.rb
@@ -1,22 +1,20 @@
-require 'puppet/util/network_device/cisco/device'
-require 'puppet/provider/network_device'
+require 'puppet/provider/cisco'
-Puppet::Type.type(:vlan).provide :cisco, :parent => Puppet::Provider::NetworkDevice do
+Puppet::Type.type(:vlan).provide :cisco, :parent => Puppet::Provider::Cisco do
desc "Cisco switch/router provider for vlans."
mk_resource_methods
- def self.lookup(url, id)
+ def self.lookup(device, id)
vlans = {}
- device = Puppet::Util::NetworkDevice::Cisco::Device.new(url)
device.command do |d|
vlans = d.parse_vlans || {}
end
vlans[id]
end
- def initialize(*args)
+ def initialize(device, *args)
super
end
@@ -27,8 +25,4 @@ Puppet::Type.type(:vlan).provide :cisco, :parent => Puppet::Provider::NetworkDev
end
super
end
-
- def device
- @device ||= Puppet::Util::NetworkDevice::Cisco::Device.new(resource[:device_url])
- end
end