diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-11-13 04:20:57 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-11-13 04:20:57 +0000 |
| commit | 4e96031745a215b84f1ae45916050f35741f9201 (patch) | |
| tree | 929ae6e35efe6ffcd417dad1a43bb1d22061b841 | |
| parent | 064ddbc218c56de91318c9dfedc481e67ed60750 (diff) | |
| download | puppet-4e96031745a215b84f1ae45916050f35741f9201.tar.gz puppet-4e96031745a215b84f1ae45916050f35741f9201.tar.xz puppet-4e96031745a215b84f1ae45916050f35741f9201.zip | |
Adding a NetInfo provider for hosts. Yay!
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1865 980ebf18-57e1-0310-9a29-db15c13687c0
| -rw-r--r-- | lib/puppet/metatype/providers.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/provider/host/netinfo.rb | 18 | ||||
| -rw-r--r-- | lib/puppet/provider/mount/netinfo.rb | 3 | ||||
| -rw-r--r-- | lib/puppet/provider/nameservice/netinfo.rb | 142 | ||||
| -rwxr-xr-x | lib/puppet/provider/parsedfile.rb | 1 | ||||
| -rwxr-xr-x | test/providers/netinfo_host.rb | 58 |
6 files changed, 154 insertions, 69 deletions
diff --git a/lib/puppet/metatype/providers.rb b/lib/puppet/metatype/providers.rb index 04de20732..62f36b807 100644 --- a/lib/puppet/metatype/providers.rb +++ b/lib/puppet/metatype/providers.rb @@ -58,7 +58,6 @@ class Puppet::Type # Mark found objects as present obj.is = [:ensure, :present] - obj.state(:ensure).found = :present hash.each { |param, value| if state = obj.state(param) state.is = value diff --git a/lib/puppet/provider/host/netinfo.rb b/lib/puppet/provider/host/netinfo.rb new file mode 100644 index 000000000..dfdc4b447 --- /dev/null +++ b/lib/puppet/provider/host/netinfo.rb @@ -0,0 +1,18 @@ +# Manage NetInfo POSIX objects. Probably only used on OS X, but I suppose +# it could be used elsewhere. +require 'puppet/provider/nameservice/netinfo' +require 'puppet/provider/host/netinfo' + +Puppet::Type.type(:host).provide :netinfo, :parent => Puppet::Provider::NameService::NetInfo, + :netinfodir => "machines" do + desc "Host management in NetInfo. This provider is highly experimental and is known + not to work currently." + commands :nireport => "nireport", :niutil => "niutil" + commands :mountcmd => "mount", :umount => "umount", :df => "df" + + options :ip, :key => "ip_address" + + defaultfor :operatingsystem => :darwin +end + +# $Id$ diff --git a/lib/puppet/provider/mount/netinfo.rb b/lib/puppet/provider/mount/netinfo.rb index 4f39dfbdf..9cd57fe06 100644 --- a/lib/puppet/provider/mount/netinfo.rb +++ b/lib/puppet/provider/mount/netinfo.rb @@ -3,7 +3,7 @@ require 'puppet/provider/nameservice/netinfo' require 'puppet/provider/mount' -Puppet::Type.type(:mount).provide :netinfo, :parent => Puppet::Provider::NameService::NetInfo do +Puppet::Type.type(:mount).provide :netinfo, :parent => Puppet::Provider::NetInfo do include Puppet::Provider::Mount desc "Mount management in NetInfo. This provider is highly experimental and is known not to work currently." @@ -21,6 +21,7 @@ Puppet::Type.type(:mount).provide :netinfo, :parent => Puppet::Provider::NameSer def initialize(model) warning "The NetInfo mount provider is highly experimental. Use at your own risk." + super end def mount diff --git a/lib/puppet/provider/nameservice/netinfo.rb b/lib/puppet/provider/nameservice/netinfo.rb index 00d1e4478..879bb7757 100644 --- a/lib/puppet/provider/nameservice/netinfo.rb +++ b/lib/puppet/provider/nameservice/netinfo.rb @@ -6,6 +6,9 @@ require 'puppet/provider/nameservice' class Puppet::Provider::NameService class NetInfo < Puppet::Provider::NameService + class << self + attr_writer :netinfodir + end # Attempt to flush the database, but this doesn't seem to work at all. def self.flush begin @@ -34,6 +37,68 @@ class NetInfo < Puppet::Provider::NameService noautogen end end + + # Convert a NetInfo line into a hash of data. + def self.line2hash(line, params) + values = line.split(/\t/) + + hash = {} + params.zip(values).each do |param, value| + next if value == '#NoValue#' + hash[param] = if value =~ /^[-0-9]+$/ + Integer(value) + else + value + end + end + hash + end + + def self.list + report(@model.validstates).collect do |hash| + @model.hash2obj(hash) + end + end + + # What field the value is stored under. + def self.netinfokey(name) + name = symbolize(name) + self.option(name, :key) || name + end + + # Retrieve the data, yo. + # FIXME This should retrieve as much information as possible, + # rather than retrieving it one at a time. + def self.report(*params) + dir = self.netinfodir() + cmd = [command(:nireport), "/", "/%s" % dir] + + # We require the name in order to know if we match. There's no + # way to just report on our individual object, we have to get the + # whole list. + params.unshift :name unless params.include? :name + + params.each do |param| + if key = netinfokey(param) + cmd << key.to_s + else + raise Puppet::DevError, + "Could not find netinfokey for state %s" % + self.class.name + end + end + + begin + output = execute(cmd.join(" ")) + rescue Puppet::ExecutionFailure => detail + Puppet.err "Failed to call nireport: %s" % detail + return nil + end + + return output.split("\n").collect { |line| + line2hash(line, params) + } + end # How to add an object. def addcmd @@ -52,6 +117,10 @@ class NetInfo < Puppet::Provider::NameService def deletecmd creatorcmd("-destroy") end + + def destroy + delete() + end def ensure=(arg) super @@ -91,7 +160,7 @@ class NetInfo < Puppet::Provider::NameService if refresh or (! defined? @infohash or ! @infohash) states = [:name] + self.class.model.validstates states.delete(:ensure) if states.include? :ensure - @infohash = report(*states) + @infohash = single_report(*states) end return @infohash @@ -115,73 +184,12 @@ class NetInfo < Puppet::Provider::NameService # Determine the flag to pass to our command. def netinfokey(name) - name = symbolize(name) - self.class.option(name, :key) || name + self.class.netinfokey(name) end - - # Retrieve the data, yo. - # FIXME This should retrieve as much information as possible, - # rather than retrieving it one at a time. - def report(*params) - dir = self.class.netinfodir() - cmd = [command(:nireport), "/", "/%s" % dir] - - # We require the name in order to know if we match. There's no - # way to just report on our individual object, we have to get the - # whole list. - params.unshift :name unless params.include? :name - - params.each do |param| - if key = netinfokey(param) - cmd << key.to_s - else - raise Puppet::DevError, - "Could not find netinfokey for state %s" % - self.class.name - end - end - - begin - output = execute(cmd.join(" ")) - rescue Puppet::ExecutionFailure => detail - Puppet.err "Failed to call nireport: %s" % detail - return nil - end - - output.split("\n").each { |line| - values = line.split(/\t/) - - hash = {} - params.zip(values).each do |param, value| - next if value == '#NoValue#' - hash[param] = if value =~ /^[-0-9]+$/ - Integer(value) - else - value - end - end - - if hash[:name] == @model[:name] - return hash - else - next - end - -# -# if line =~ /^(\w+)\s+(.+)$/ -# name = $1 -# value = $2.sub(/\s+$/, '') -# -# if name == @model[:name] -# if value =~ /^[-0-9]+$/ -# return Integer(value) -# else -# return value -# end -# end - } - - return nil + + # Get a report for a single resource, not the whole table + def single_report(*states) + self.class.report(*states).find do |hash| hash[:name] == @model[:name] end end def setuserlist(group, list) diff --git a/lib/puppet/provider/parsedfile.rb b/lib/puppet/provider/parsedfile.rb index cdcc49b20..144267623 100755 --- a/lib/puppet/provider/parsedfile.rb +++ b/lib/puppet/provider/parsedfile.rb @@ -188,6 +188,7 @@ class Puppet::Provider::ParsedFile < Puppet::Provider target_records(target).find_all { |i| i.is_a?(Hash) }.each do |record| # Find any model instances whose names match our instances. if instance = self.model[record[:name]] + next unless instance.provider.is_a?(self) instance.provider.state_hash = record elsif self.respond_to?(:match) if instance = self.match(record) diff --git a/test/providers/netinfo_host.rb b/test/providers/netinfo_host.rb new file mode 100755 index 000000000..e6bbc22d6 --- /dev/null +++ b/test/providers/netinfo_host.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby +# +# Created by Luke Kanies on 2006-11-12. +# Copyright (c) 2006. All rights reserved. + +$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'puppettest' + +if Puppet::Type.type(:host).provider(:netinfo).suitable? +class TestNetinfoHostProvider < Test::Unit::TestCase + include PuppetTest + + def setup + super + @host = Puppet::Type.type(:host) + @provider = @host.provider(:netinfo) + end + + def test_list + list = nil + assert_nothing_raised do + list = @provider.list + end + assert(list.length > 0) + list.each do |obj| + prov = obj.provider + assert_instance_of(@host, obj) + assert(prov.name, "objects do not have names") + assert(prov.ip, "Did not get value for device in %s" % prov.ip) + end + + assert(list.detect { |m| m.provider.name == "localhost"}, "Could not find localhost") + end + + if Process.uid == 0 + def test_simple + localhost = nil + assert_nothing_raised do + localhost = @host.create :name => "localhost", :check => [:ip], :provider => :netinfo + end + + assert_nothing_raised do + localhost.retrieve + end + + prov = localhost.provider + + assert_nothing_raised do + assert(prov.ip, "Did not find value for ip") + assert(prov.ip != :absent, "Netinfo thinks the localhost is missing") + end + end +end +end +end + +# $Id$
\ No newline at end of file |
