diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-11-08 05:22:24 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-11-08 05:22:24 +0000 |
| commit | 744ded30a02883dd8ce5fbf2b847f10acb226d6e (patch) | |
| tree | d962b7b21f3a5d20dafd8e7f862c23a2449c2c9b /lib | |
| parent | dc4d98091a5566be289830839f1d6eb39367b42c (diff) | |
| download | puppet-744ded30a02883dd8ce5fbf2b847f10acb226d6e.tar.gz puppet-744ded30a02883dd8ce5fbf2b847f10acb226d6e.tar.xz puppet-744ded30a02883dd8ce5fbf2b847f10acb226d6e.zip | |
Merging the code over from the oscar branch. I will now be doing all development in the trunk again, except for larger changes, which will still get their own branch. This is a merge of the changes from revision 1826 to revision 1834.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1835 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
29 files changed, 423 insertions, 340 deletions
diff --git a/lib/puppet.rb b/lib/puppet.rb index b385d86d0..fda428360 100644 --- a/lib/puppet.rb +++ b/lib/puppet.rb @@ -5,7 +5,9 @@ require 'puppet/error' require 'puppet/event-loop' require 'puppet/util' require 'puppet/log' +require 'puppet/autoload' require 'puppet/config' +require 'puppet/feature' require 'puppet/suidmanager' #------------------------------------------------------------ @@ -17,7 +19,7 @@ require 'puppet/suidmanager' # it's also a place to find top-level commands like 'debug' module Puppet - PUPPETVERSION = '0.20.0' + PUPPETVERSION = '0.20.0svn' def Puppet.version return PUPPETVERSION @@ -32,6 +34,7 @@ module Puppet # To keep a copy of arguments. Set within Config#addargs, because I'm # lazy. attr_accessor :args + attr_reader :features end @@ -66,6 +69,10 @@ module Puppet # I keep wanting to use Puppet.error # XXX this isn't actually working right now alias :error :err + + # The feature collection + @features = Puppet::Feature.new('puppet/feature') + @features.load # Store a new default value. def self.setdefaults(section, hash) diff --git a/lib/puppet/configuration.rb b/lib/puppet/configuration.rb index cfcda7120..074e656e0 100644 --- a/lib/puppet/configuration.rb +++ b/lib/puppet/configuration.rb @@ -80,7 +80,10 @@ module Puppet exits. Comma-separate multiple values. For a list of all values, specify 'all'. This feature is only available in Puppet versions higher than 0.18.4."], - :color => [true, "Whether to use ANSI colors when logging to the console."], + :color => ["ansi", "Whether to use colors when logging to the console. + Valid values are ``ansi`` (equivalent to ``true``), ``html`` (mostly + used during testing with TextMate), and ``false``, which produces + no color."], :mkusers => [false, "Whether to create the necessary user and group that puppetd will run as."], diff --git a/lib/puppet/element.rb b/lib/puppet/element.rb index 934fafeb9..a3cefaf94 100644 --- a/lib/puppet/element.rb +++ b/lib/puppet/element.rb @@ -42,31 +42,38 @@ class Puppet::Element # some classes (e.g., FileTypeRecords) will have to override this def path unless defined? @path - if defined? @parent and @parent - if self.is_a?(Puppet.type(:component)) - @path = [@parent.path, self.name] - else - @path = [@parent.path, self.class.name.to_s + "=" + self.name] - end + @path = pathbuilder + end + + #puts "%s[%s]: %s" % [self.class.name, self.title, @path] + + return @path.join("/") + end + + def pathbuilder + tmp = if defined? @parent and @parent + if self.is_a?(Puppet.type(:component)) + [@parent.path, self.name] + else + [@parent.path, self.class.name.to_s + "=" + self.name] + end + else + # The top-level name is always main[top], so we don't bother with + # that. And we don't add the hostname here, it gets added + # in the log server thingy. + if self.name == "main[top]" + ["/"] else - # The top-level name is always main[top], so we don't bother with - # that. And we don't add the hostname here, it gets added - # in the log server thingy. - if self.name == "main[top]" - @path = ["/"] + if self.is_a?(Puppet.type(:component)) + [self.name] else - if self.is_a?(Puppet.type(:component)) - @path = [self.name] - else - @path = [self.class.name.to_s + "=" + self.name.to_s] - end + [self.class.name.to_s + "=" + self.name.to_s] end end end - return @path.join("/") + return tmp end - end # $Id$ diff --git a/lib/puppet/feature.rb b/lib/puppet/feature.rb new file mode 100644 index 000000000..55fab5d3c --- /dev/null +++ b/lib/puppet/feature.rb @@ -0,0 +1,64 @@ +# Created by Luke Kanies on 2006-11-07. +# Copyright (c) 2006. All rights reserved. + +class Puppet::Feature + # Create a new feature test. You have to pass the feature name, + # and it must be unique. You can either provide a block that + # will get executed immediately to determine if the feature + # is present, or you can pass an option to determine it. + # Currently, the only supported option is 'libs' (must be + # passed as a symbol), which will make sure that each lib loads + # successfully. + def add(name, options = {}) + method = name.to_s + "?" + if self.class.respond_to?(method) + raise ArgumentError, "Feature %s is already defined" % name + end + + result = true + if block_given? + begin + result = yield + rescue => detail + if Puppet[:trace] + puts detail.backtrace + Puppet.err "Failed to load %s: %s" % [name, detail] + end + result = false + end + end + + if ary = options[:libs] + ary = [ary] unless ary.is_a?(Array) + + ary.each do |lib| + unless lib.is_a?(String) + raise ArgumentError, "Libraries must be passed as strings not %s" % lib.class + end + + begin + require lib + rescue Exception + Puppet.debug "Failed to load library '%s' for feature '%s'" % [lib, name] + result = false + end + end + end + + meta_def(method) do + result + end + end + + # Create a new feature collection. + def initialize(path) + @path = path + end + + def load + loader = Puppet::Autoload.new(self, @path) + loader.loadall + end +end + +# $Id$
\ No newline at end of file diff --git a/lib/puppet/feature/usage.rb b/lib/puppet/feature/usage.rb new file mode 100644 index 000000000..c4d1c2745 --- /dev/null +++ b/lib/puppet/feature/usage.rb @@ -0,0 +1,8 @@ +# Created by Luke Kanies on 2006-11-07. +# Copyright (c) 2006. All rights reserved. + +require 'puppet/feature' + +Puppet.features.add(:usage, :libs => %w{rdoc/ri/ri_paths rdoc/usage}) + +# $Id$
\ No newline at end of file diff --git a/lib/puppet/log.rb b/lib/puppet/log.rb index c76dd945c..8362e8d4d 100644 --- a/lib/puppet/log.rb +++ b/lib/puppet/log.rb @@ -6,13 +6,6 @@ module Puppet # multiple destinations, one of which is a remote server. class Log include Puppet::Util - PINK="[0;31m" - GREEN="[0;32m" - YELLOW="[0;33m" - SLATE="[0;34m" - ORANGE="[0;35m" - BLUE="[0;36m" - RESET="[0m" @levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit] @loglevel = 2 @@ -250,7 +243,17 @@ module Puppet end newdesttype :console do - @@colors = { + + + PINK = {:console => "[0;31m", :html => "FFA0A0"} + GREEN = {:console => "[0;32m", :html => "00CD00"} + YELLOW = {:console => "[0;33m", :html => "FFFF60"} + SLATE = {:console => "[0;34m", :html => "80A0FF"} + ORANGE = {:console => "[0;35m", :html => "FFA500"} + BLUE = {:console => "[0;36m", :html => "40FFFF"} + RESET = {:console => "[0m", :html => ""} + + @@colormap = { :debug => SLATE, :info => GREEN, :notice => PINK, @@ -260,6 +263,22 @@ module Puppet :emerg => RESET, :crit => RESET } + + def colorize(level, str) + case Puppet[:color] + when false: str + when true, :ansi, "ansi": console_color(level, str) + when :html, "html": html_color(level, str) + end + end + + def console_color(level, str) + @@colormap[level][:console] + str + RESET[:console] + end + + def html_color(level, str) + %{<span style="color: %s">%s</span>} % [@@colormap[level][:html], str] + end def initialize # Flush output immediately. @@ -267,20 +286,10 @@ module Puppet end def handle(msg) - color = "" - reset = "" - if Puppet[:color] - color = @@colors[msg.level] - reset = RESET - end if msg.source == "Puppet" - puts color + "%s: %s" % [ - msg.level, msg.to_s - ] + reset + puts colorize(msg.level, "%s: %s" % [msg.level, msg.to_s]) else - puts color + "%s: %s: %s" % [ - msg.level, msg.source, msg.to_s - ] + reset + puts colorize(msg.level, "%s: %s: %s" % [msg.level, msg.source, msg.to_s]) end end end diff --git a/lib/puppet/metric.rb b/lib/puppet/metric.rb index 6356871b6..6702018dc 100644 --- a/lib/puppet/metric.rb +++ b/lib/puppet/metric.rb @@ -16,17 +16,9 @@ module Puppet :rrdinterval => ["$runinterval", "How often RRD should expect data. This should match how often the hosts report back to the server."] ) - - @@haverrd = false - begin - require 'RRD' - @@haverrd = true - rescue LoadError - end - - def self.haverrd? - @@haverrd - end + + # Load the library as a feature, so we can test its presence. + Puppet.features.add :rrd, :libs => 'RRD' attr_accessor :type, :name, :value, :label @@ -63,7 +55,7 @@ module Puppet end def graph(range = nil) - unless @@haverrd + unless Puppet.features.rrd? Puppet.warning "RRD library is missing; cannot graph metrics" return end @@ -120,7 +112,7 @@ module Puppet end def store(time) - unless @@haverrd + unless Puppet.features.rrd? Puppet.warning "RRD library is missing; cannot store metrics" return end diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb index f6f2457d9..1c712e896 100644 --- a/lib/puppet/parser/ast/caseopt.rb +++ b/lib/puppet/parser/ast/caseopt.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # Each individual option in a case statement. class CaseOpt < AST::Branch diff --git a/lib/puppet/parser/ast/else.rb b/lib/puppet/parser/ast/else.rb index a29623f56..ff2f233b7 100644 --- a/lib/puppet/parser/ast/else.rb +++ b/lib/puppet/parser/ast/else.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # A separate ElseIf statement; can function as an 'else' if there's no # test. @@ -24,3 +26,5 @@ class Puppet::Parser::AST end end end + +# $Id$ diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb index 6729431b7..052b8a8b1 100644 --- a/lib/puppet/parser/ast/function.rb +++ b/lib/puppet/parser/ast/function.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # An AST object to call a function. class Function < AST::Branch diff --git a/lib/puppet/parser/ast/resourcedefaults.rb b/lib/puppet/parser/ast/resourcedefaults.rb index 44db4d465..df16b1b59 100644 --- a/lib/puppet/parser/ast/resourcedefaults.rb +++ b/lib/puppet/parser/ast/resourcedefaults.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # A statement syntactically similar to an ResourceDef, but uses a # capitalized object type and cannot have a name. diff --git a/lib/puppet/parser/ast/tag.rb b/lib/puppet/parser/ast/tag.rb index 0807d207e..4a2015cde 100644 --- a/lib/puppet/parser/ast/tag.rb +++ b/lib/puppet/parser/ast/tag.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # The code associated with a class. This is different from components # in that each class is a singleton -- only one will exist for a given diff --git a/lib/puppet/parser/ast/vardef.rb b/lib/puppet/parser/ast/vardef.rb index 145700e27..6093952d4 100644 --- a/lib/puppet/parser/ast/vardef.rb +++ b/lib/puppet/parser/ast/vardef.rb @@ -1,3 +1,5 @@ +require 'puppet/parser/ast/branch' + class Puppet::Parser::AST # Define a variable. Stores the value in the current scope. class VarDef < AST::Branch diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra index 6fcc4b1d7..aea9b404d 100644 --- a/lib/puppet/parser/grammar.ra +++ b/lib/puppet/parser/grammar.ra @@ -487,16 +487,9 @@ import: IMPORT quotedtext { ) next end - # push the results into the main result array - # We always return an array when we parse. - ast = parser.parse - - # Things that just get added to the classtable or whatever return nil - if ast - ast.each do |child| - result.push child - end - end + + # This will normally add code to the 'main' class. + parser.parse } } } diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb index 54772bec8..c69829718 100644 --- a/lib/puppet/parser/parser.rb +++ b/lib/puppet/parser/parser.rb @@ -29,7 +29,7 @@ module Puppet class Parser < Racc::Parser -module_eval <<'..end grammar.ra modeval..idee2a7240ef', 'grammar.ra', 635 +module_eval <<'..end grammar.ra modeval..id4401d72c60', 'grammar.ra', 628 require 'puppet/parser/functions' attr_reader :file, :interp @@ -199,7 +199,7 @@ end # $Id$ -..end grammar.ra modeval..idee2a7240ef +..end grammar.ra modeval..id4401d72c60 ##### racc 1.4.5 generates ### @@ -1457,7 +1457,7 @@ module_eval <<'.,.,', 'grammar.ra', 440 end .,., -module_eval <<'.,.,', 'grammar.ra', 502 +module_eval <<'.,.,', 'grammar.ra', 495 def _reduce_116( val, _values, result ) # importing files # yuk, i hate keywords @@ -1506,23 +1506,16 @@ module_eval <<'.,.,', 'grammar.ra', 502 ) next end - # push the results into the main result array - # We always return an array when we parse. - ast = parser.parse - - # Things that just get added to the classtable or whatever return nil - if ast - ast.each do |child| - result.push child - end - end + + # This will normally add code to the 'main' class. + parser.parse } } result end .,., -module_eval <<'.,.,', 'grammar.ra', 512 +module_eval <<'.,.,', 'grammar.ra', 505 def _reduce_117( val, _values, result ) interp.newdefine fqname(val[1]), :arguments => val[2], :code => val[4] @lexer.indefine = false @@ -1533,7 +1526,7 @@ module_eval <<'.,.,', 'grammar.ra', 512 end .,., -module_eval <<'.,.,', 'grammar.ra', 516 +module_eval <<'.,.,', 'grammar.ra', 509 def _reduce_118( val, _values, result ) interp.newdefine fqname(val[1]), :arguments => val[2] @lexer.indefine = false @@ -1542,7 +1535,7 @@ module_eval <<'.,.,', 'grammar.ra', 516 end .,., -module_eval <<'.,.,', 'grammar.ra', 524 +module_eval <<'.,.,', 'grammar.ra', 517 def _reduce_119( val, _values, result ) # Our class gets defined in the parent namespace, not our own. @lexer.namepop @@ -1552,7 +1545,7 @@ module_eval <<'.,.,', 'grammar.ra', 524 end .,., -module_eval <<'.,.,', 'grammar.ra', 529 +module_eval <<'.,.,', 'grammar.ra', 522 def _reduce_120( val, _values, result ) # Our class gets defined in the parent namespace, not our own. @lexer.namepop @@ -1562,7 +1555,7 @@ module_eval <<'.,.,', 'grammar.ra', 529 end .,., -module_eval <<'.,.,', 'grammar.ra', 534 +module_eval <<'.,.,', 'grammar.ra', 527 def _reduce_121( val, _values, result ) interp.newnode val[1], :parent => val[2], :code => val[4] result = nil @@ -1570,7 +1563,7 @@ module_eval <<'.,.,', 'grammar.ra', 534 end .,., -module_eval <<'.,.,', 'grammar.ra', 537 +module_eval <<'.,.,', 'grammar.ra', 530 def _reduce_122( val, _values, result ) interp.newnode val[1], :parent => val[2] result = nil @@ -1584,7 +1577,7 @@ module_eval <<'.,.,', 'grammar.ra', 537 # reduce 125 omitted -module_eval <<'.,.,', 'grammar.ra', 549 +module_eval <<'.,.,', 'grammar.ra', 542 def _reduce_126( val, _values, result ) result = val[0] result = [result] unless result.is_a?(Array) @@ -1599,14 +1592,14 @@ module_eval <<'.,.,', 'grammar.ra', 549 # reduce 129 omitted -module_eval <<'.,.,', 'grammar.ra', 557 +module_eval <<'.,.,', 'grammar.ra', 550 def _reduce_130( val, _values, result ) result = nil result end .,., -module_eval <<'.,.,', 'grammar.ra', 561 +module_eval <<'.,.,', 'grammar.ra', 554 def _reduce_131( val, _values, result ) result = ast AST::ASTArray, :children => [] result @@ -1615,14 +1608,14 @@ module_eval <<'.,.,', 'grammar.ra', 561 # reduce 132 omitted -module_eval <<'.,.,', 'grammar.ra', 566 +module_eval <<'.,.,', 'grammar.ra', 559 def _reduce_133( val, _values, result ) result = nil result end .,., -module_eval <<'.,.,', 'grammar.ra', 570 +module_eval <<'.,.,', 'grammar.ra', 563 def _reduce_134( val, _values, result ) result = val[1] result = [result] unless result[0].is_a?(Array) @@ -1632,7 +1625,7 @@ module_eval <<'.,.,', 'grammar.ra', 570 # reduce 135 omitted -module_eval <<'.,.,', 'grammar.ra', 577 +module_eval <<'.,.,', 'grammar.ra', 570 def _reduce_136( val, _values, result ) result = val[0] result = [result] unless result[0].is_a?(Array) @@ -1641,7 +1634,7 @@ module_eval <<'.,.,', 'grammar.ra', 577 end .,., -module_eval <<'.,.,', 'grammar.ra', 582 +module_eval <<'.,.,', 'grammar.ra', 575 def _reduce_137( val, _values, result ) Puppet.warning addcontext("Deprecation notice: #{val[0].value} must now include '$' in prototype") result = [val[0], val[2]] @@ -1649,7 +1642,7 @@ module_eval <<'.,.,', 'grammar.ra', 582 end .,., -module_eval <<'.,.,', 'grammar.ra', 586 +module_eval <<'.,.,', 'grammar.ra', 579 def _reduce_138( val, _values, result ) Puppet.warning addcontext("Deprecation notice: #{val[0].value} must now include '$' in prototype") result = [val[0]] @@ -1657,14 +1650,14 @@ module_eval <<'.,.,', 'grammar.ra', 586 end .,., -module_eval <<'.,.,', 'grammar.ra', 588 +module_eval <<'.,.,', 'grammar.ra', 581 def _reduce_139( val, _values, result ) result = [val[0], val[2]] result end .,., -module_eval <<'.,.,', 'grammar.ra', 590 +module_eval <<'.,.,', 'grammar.ra', 583 def _reduce_140( val, _values, result ) result = [val[0]] result @@ -1673,21 +1666,21 @@ module_eval <<'.,.,', 'grammar.ra', 590 # reduce 141 omitted -module_eval <<'.,.,', 'grammar.ra', 595 +module_eval <<'.,.,', 'grammar.ra', 588 def _reduce_142( val, _values, result ) result = val[1] result end .,., -module_eval <<'.,.,', 'grammar.ra', 599 +module_eval <<'.,.,', 'grammar.ra', 592 def _reduce_143( val, _values, result ) result = ast AST::Variable, :value => val[0] result end .,., -module_eval <<'.,.,', 'grammar.ra', 607 +module_eval <<'.,.,', 'grammar.ra', 600 def _reduce_144( val, _values, result ) if val[1].instance_of?(AST::ASTArray) result = val[1] @@ -1698,7 +1691,7 @@ module_eval <<'.,.,', 'grammar.ra', 607 end .,., -module_eval <<'.,.,', 'grammar.ra', 609 +module_eval <<'.,.,', 'grammar.ra', 602 def _reduce_145( val, _values, result ) result = ast AST::ASTArray result @@ -1711,7 +1704,7 @@ module_eval <<'.,.,', 'grammar.ra', 609 # reduce 148 omitted -module_eval <<'.,.,', 'grammar.ra', 614 +module_eval <<'.,.,', 'grammar.ra', 607 def _reduce_149( val, _values, result ) result = nil result diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb index 0cd774c35..36c685990 100644 --- a/lib/puppet/provider.rb +++ b/lib/puppet/provider.rb @@ -149,8 +149,10 @@ class Puppet::Provider found = values.find do |v| result == v.to_s.downcase.intern end - debug "Not suitable: %s not in %s" % [check, values] - return false unless found + unless found + debug "Not suitable: %s not in %s" % [check, values] + return false + end else return false end diff --git a/lib/puppet/provider/nameservice/netinfo.rb b/lib/puppet/provider/nameservice/netinfo.rb index 5d6c19969..f6822b087 100644 --- a/lib/puppet/provider/nameservice/netinfo.rb +++ b/lib/puppet/provider/nameservice/netinfo.rb @@ -68,7 +68,6 @@ class NetInfo < Puppet::Provider::NameService val = autogen() else # No value, and it's not required, so skip it. - info "No value for %s" % name next end end diff --git a/lib/puppet/reports/store.rb b/lib/puppet/reports/store.rb index a2ab797e1..e4a2b1fe5 100644 --- a/lib/puppet/reports/store.rb +++ b/lib/puppet/reports/store.rb @@ -49,7 +49,7 @@ Puppet::Server::Report.newreport(:store, :useyaml => true) do begin File.open(file, "w", 0640) do |f| - f.puts yaml + f.print yaml end rescue => detail if Puppet[:trace] diff --git a/lib/puppet/server/servlet.rb b/lib/puppet/server/servlet.rb index d562078e1..81219ef44 100644 --- a/lib/puppet/server/servlet.rb +++ b/lib/puppet/server/servlet.rb @@ -144,7 +144,7 @@ class Server error = XMLRPC::FaultException.new( 1, detail.to_s ) - error.set_backtrace = detail.backtrace + error.set_backtrace detail.backtrace raise error rescue => detail #Puppet.warning obj.inspect diff --git a/lib/puppet/sslcertificates/inventory.rb b/lib/puppet/sslcertificates/inventory.rb index 4dbf60410..045780a69 100644 --- a/lib/puppet/sslcertificates/inventory.rb +++ b/lib/puppet/sslcertificates/inventory.rb @@ -3,48 +3,51 @@ module Puppet::SSLCertificates module Inventory + Puppet.config.setdefaults(:ca, + :cert_inventory => { + :default => "$cadir/inventory.txt", + :mode => 0644, + :owner => "$user", + :group => "$group", + :desc => "A Complete listing of all certificates" + } + ) + # Add CERT to the inventory of issued certs in '$cadir/inventory.txt' # If no inventory exists yet, build an inventory and list all the # certificates that have been signed so far - def Inventory.add(cert) - f = open - format(f, cert) - f.close() - end + def self.add(cert) + unless FileTest.exists?(Puppet[:cert_inventory]) + inited = false + end - def Inventory.filename - File::join(Puppet[:cadir], "inventory.txt") + Puppet.config.write(:cert_inventory, "a") do |f| + unless inited + f.puts self.init + end + f.puts format(cert) + end end private - def Inventory.open - if File::exist?(filename) - File::open(filename, "a") - else - init - end - end - def Inventory.init - if File::exist?(filename) - raise Puppet::Error, - "Inventory file #{filename} already exists" - end - inv = File.open(filename, "w") - inv.puts "# Inventory of signed certificates" - inv.puts "# SERIAL NOT_BEFORE _NOT_AFTER SUBJECT" + def self.init + inv = "# Inventory of signed certificates\n" + inv += "# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n" Dir.glob(File::join(Puppet[:signeddir], "*.pem")) do |f| - format(inv, OpenSSL::X509::Certificate.new(File::read(f))) + inv += format(OpenSSL::X509::Certificate.new(File::read(f))) + "\n" end return inv end - def Inventory.format(f, cert) + def self.format(cert) iso = '%Y-%m-%dT%H:%M:%S%Z' - f.puts "0x%04x %s %s %s" % [cert.serial, + return "0x%04x %s %s %s" % [cert.serial, cert.not_before.strftime(iso), cert.not_after.strftime(iso), cert.subject] end end end + +# $Id$ diff --git a/lib/puppet/storage.rb b/lib/puppet/storage.rb index 38fea42bb..5f71c171b 100644 --- a/lib/puppet/storage.rb +++ b/lib/puppet/storage.rb @@ -21,7 +21,15 @@ module Puppet unless object.is_a? Puppet::Type raise Puppet::DevFail, "Must pass a Type instance to Storage.cache" end - return @@state[object.path] ||= {} + + # We used to store things by path, now we store them by ref. + # In oscar(0.20.0) this changed to using the ref. + if @@state.include?(object.path) + @@state[object.ref] = @@state[object.path] + @@state.delete(object.path) + end + + return @@state[object.ref] ||= {} end def self.clear diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 75f8c02c3..8df86ee81 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -284,9 +284,8 @@ class Type < Puppet::Element hash.delete attr end } - - # While this could theoretically be set after all of the objects are - # created, it seems to make more sense to set them immediately. + + # Set all default values. self.setdefaults if hash.length > 0 @@ -335,6 +334,11 @@ class Type < Puppet::Element return self[:name] end + # Return the "type[name]" style reference. + def ref + "%s[%s]" % [self.class.name, self.title] + end + # Retrieve the title of an object. If no title was set separately, # then use the object's name. def title diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index 5bf82b933..aa982c247 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -187,7 +187,7 @@ module Puppet end def retrieve - if @provider.exists? + if self.provider and @provider.exists? super else # the group does not exist diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index 233d01da6..15367a0c2 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -629,39 +629,34 @@ module Puppet return child end - # Paths are special for files, because we don't actually want to show - # the parent's full path. - def path - unless defined? @path - if defined? @parent - # We only need to behave specially when our parent is also - # a file - if @parent.is_a?(self.class) - # Remove the parent file name - ppath = @parent.path.sub(/\/?file=.+/, '') - @path = [] - if ppath != "/" and ppath != "" - @path << ppath - end - @path << self.class.name.to_s + "=" + self.name - else - super + def pathbuilder + if defined? @parent + # We only need to behave specially when our parent is also + # a file + if @parent.is_a?(self.class) + # Remove the parent file name + ppath = @parent.path.sub(/\/?file=.+/, '') + tmp = [] + if ppath != "/" and ppath != "" + tmp << ppath end + tmp << self.class.name.to_s + "=" + self.name + return tmp else - # The top-level name is always puppet[top], so we don't - # bother with that. And we don't add the hostname - # here, it gets added in the log server thingy. - if self.name == "puppet[top]" - @path = ["/"] - else - # We assume that if we don't have a parent that we - # should not cache the path - @path = [self.class.name.to_s + "=" + self.name] - end + return super + end + else + # The top-level name is always puppet[top], so we don't + # bother with that. And we don't add the hostname + # here, it gets added in the log server thingy. + if self.name == "puppet[top]" + return ["/"] + else + # We assume that if we don't have a parent that we + # should not cache the path + return [self.class.name.to_s + "=" + self.name] end end - - return @path.join("/") end # Recurse into the directory. This basically just calls 'localrecurse' @@ -837,7 +832,7 @@ module Puppet server = sourceobj.server sum = "md5" if state = self.state(:checksum) - sum = state.checktype + sum = state.should end r = false if recurse diff --git a/lib/puppet/type/pfile/checksum.rb b/lib/puppet/type/pfile/checksum.rb index a37ccf9dc..355d211a5 100755 --- a/lib/puppet/type/pfile/checksum.rb +++ b/lib/puppet/type/pfile/checksum.rb @@ -40,35 +40,48 @@ module Puppet :nochange end - # Convert from the sum type to the stored checksum. + # If they pass us a sum type, behave normally, but if they pass + # us a sum type + sum, stick the sum in the cache. munge do |value| - unless defined? @checktypes - @checktypes = [] - end - if value =~ /^\{(\w+)\}(.+)$/ - @checktypes << $1 - #return $2 - return value + type = symbolize($1) + sum = $2 + cache(type, sum) + return type else if FileTest.directory?(@parent[:path]) - value = "time" + return :time + else + return symbolize(value) end - value = super(value) - @checktypes << value - return getcachedsum() end end - def checktype - @checktypes[0] + # Store the checksum in the data cache, or retrieve it if only the + # sum type is provided. + def cache(type, sum = nil) + type = symbolize(type) + unless state = @parent.cached(:checksums) + self.debug "Initializing checksum hash" + state = {} + @parent.cache(:checksums, state) + end + + if sum + unless sum =~ /\{\w+\}/ + sum = "{%s}%s" % [type, sum] + end + state[type] = sum + else + return state[type] + end end # Because source and content and whomever else need to set the checksum # and do the updating, we provide a simple mechanism for doing so. def checksum=(value) @is = value - @should = [value] + munge(@should) self.updatesum end @@ -77,13 +90,13 @@ module Puppet begin if @is == :absent return "defined '%s' as '%s'" % - [self.name, self.should_to_s] + [self.name, self.currentsum] elsif self.should == :absent return "undefined %s from '%s'" % [self.name, self.is_to_s] else return "%s changed '%s' to '%s'" % - [self.name, self.should_to_s, self.is_to_s] + [self.name, self.currentsum, self.is_to_s] end rescue Puppet::Error, Puppet::DevError raise @@ -93,6 +106,11 @@ module Puppet end end + def currentsum + #"{%s}%s" % [self.should, cache(self.should)] + cache(self.should) + end + # Retrieve the cached sum def getcachedsum hash = nil @@ -101,11 +119,7 @@ module Puppet @parent.cache(:checksums, hash) end - sumtype = @checktypes[0] - - #unless state - # self.devfail "Did not get state back from Storage" - #end + sumtype = self.should if hash.include?(sumtype) #self.notice "Found checksum %s for %s" % @@ -133,14 +147,10 @@ module Puppet checktype = checktype.intern if checktype.is_a? String case checktype when :md5, :md5lite: - unless FileTest.file?(@parent[:path]) - @parent.info "Cannot MD5 sum directory %s" % - @parent[:path] - - @should = [nil] - @is = nil - #@parent.delete(self[:path]) - return + if ! FileTest.file?(@parent[:path]) + @parent.debug "Cannot MD5 sum %s; using mtime" % + [@parent.stat.ftype] + sum = @parent.stat.mtime.to_s else begin File.open(@parent[:path]) { |file| @@ -165,7 +175,7 @@ module Puppet @parent[:path] @parent.delete(self.class.name) rescue => detail - self.notice "Cannot checksum %s: %s" % + self.notice "Cannot checksum: %s" % detail @parent.delete(self.class.name) end @@ -181,7 +191,6 @@ module Puppet end return "{#{checktype}}" + sum.to_s - #return sum.to_s end # At this point, we don't actually modify the system, we modify @@ -226,6 +235,16 @@ module Puppet end end + def insync? + if cache(self.should) + return @is == currentsum() + else + # If there's no cached sum, then we don't want to generate + # an event. + return true + end + end + # Even though they can specify multiple checksums, the insync? # mechanism can really only test against one, so we'll just retrieve # the first specified sum type. @@ -236,10 +255,6 @@ module Puppet return @is end - unless defined? @checktypes - @checktypes = ["md5"] - end - stat = nil unless stat = @parent.stat self.is = :absent @@ -249,29 +264,20 @@ module Puppet if stat.ftype == "link" and @parent[:links] != :follow self.debug "Not checksumming symlink" #@parent.delete(:checksum) - self.is = self.should + self.is = self.currentsum return end - if stat.ftype == "directory" and @checktypes[0] =~ /md5/ - @checktypes = ["time"] - end + checktype = self.should || :md5 # Just use the first allowed check type - @is = getsum(@checktypes[0]) - - # @should should always be set, so if it's not set at all, we - # know we haven't looked in the cache yet. - unless defined? @should and ! @should.nil? - @should = [getcachedsum()] - end + @is = getsum(checktype) - # If there is no should defined, then store the current value - # into the 'should' value, so that we're not marked as being + # If there is no sum defined, then store the current value + # into the cache, so that we're not marked as being # out of sync. We don't want to generate an event the first # time we get a sum. - if @should == [:nosum] - @should = [@is] + unless cache(self.should) # FIXME we should support an updatechecksums-like mechanism self.updatesum end @@ -282,36 +288,37 @@ module Puppet # Store the new sum to the state db. def updatesum result = false - state = nil - unless state = @parent.cached(:checksums) - self.debug "Initializing checksum hash for %s" % @parent.title - state = {} - @parent.cache(:checksums, state) - end if @is.is_a?(Symbol) - error = Puppet::Error.new("%s has invalid checksum" % - @parent.title) - raise error + raise Puppet::Error, "%s has invalid checksum" % @parent.title end # if we're replacing, vs. updating - if state.include?(@checktypes[0]) + if sum = cache(self.should) unless defined? @should raise Puppet::Error.new( ("@should is not initialized for %s, even though we " + "found a checksum") % @parent[:path] ) end + + if @is == sum + info "Sums are already equal" + return false + end + + #if cache(self.should) == @is + # raise Puppet::Error, "Got told to update same sum twice" + #end self.debug "Replacing %s checksum %s with %s" % - [@parent.title, state[@checktypes[0]],@is] + [@parent.title, sum, @is] #@parent.debug "@is: %s; @should: %s" % [@is,@should] result = true else @parent.debug "Creating checksum %s" % @is result = false end - state[@checktypes[0]] = @is + cache(self.should, @is) return result end end diff --git a/lib/puppet/type/pfile/group.rb b/lib/puppet/type/pfile/group.rb index 9431b0e65..27ca5c2ff 100755 --- a/lib/puppet/type/pfile/group.rb +++ b/lib/puppet/type/pfile/group.rb @@ -54,24 +54,21 @@ module Puppet self.is = stat.gid end - # Determine if the group is valid, and if so, return the UID + # Determine if the group is valid, and if so, return the GID def validgroup?(value) if value =~ /^\d+$/ value = value.to_i end - - if value = Puppet::Util.gid(value) - return value + + if gid = Puppet::Util.gid(value) + return gid else + warning "could not find %s" % value return false end end - + munge do |value| - method = nil - gid = nil - gname = nil - if val = validgroup?(value) return val else diff --git a/lib/puppet/type/state.rb b/lib/puppet/type/state.rb index 61c1a85e2..d8578eb0a 100644 --- a/lib/puppet/type/state.rb +++ b/lib/puppet/type/state.rb @@ -218,11 +218,11 @@ class State < Puppet::Parameter # return the full path to us, for logging and rollback; not currently # used - def path + def pathbuilder if defined? @parent and @parent - return [@parent.path, self.name].join("/") + return [@parent.path, self.name] else - return self.name + return [self.name] end end diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index b4e8eb253..b0fb51e98 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -9,6 +9,9 @@ module Puppet end module Util require 'benchmark' + + require 'puppet/util/posix' + extend Puppet::Util::POSIX # Create a hash to store the different sync objects. @@syncresources = {} @@ -97,109 +100,6 @@ module Util end end - # Get the GID of a given group, provided either a GID or a name - def self.gid(group) - if group =~ /^\d+$/ - group = Integer(group) - end - unless group - raise Puppet::DevError, "Invalid group %s" % group.inspect - end - gid = nil - obj = nil - - # We want to look the group up either way - if group.is_a?(Integer) - # If this doesn't find anything - obj = Puppet.type(:group).find { |gobj| - gobj.should(:gid) == group || - gobj.is(:gid) == group - } - - unless obj - begin - gobj = Etc.getgrgid(group) - gid = gobj.gid - rescue ArgumentError => detail - # ignore it; we couldn't find the group - end - end - else - if obj = Puppet.type(:group)[group] - obj[:check] = [:gid] - else - obj = Puppet.type(:group).create( - :name => group, - :check => [:gid] - ) - end - obj.retrieve - end - if obj - gid = obj.should(:gid) || obj.is(:gid) - if gid == :absent - gid = nil - end - end - - return gid - end - - # Get the UID of a given user, whether a UID or name is provided - def self.uid(user) - uid = nil - - # if we don't have any user info, warn and GTFO. - if !user - Puppet.warning "Username provided for lookup is nil" - return nil - end - - # One of the unit tests was passing a Passwd struct - unless user.is_a?(String) or user.is_a?(Integer) - raise Puppet::DevError, "Invalid value for uid: %s" % user.class - end - - if user =~ /^\d+$/ - user = Integer(user) - end - - if user.is_a?(Integer) - # If this doesn't find anything - obj = Puppet.type(:user).find { |uobj| - uobj.should(:uid) == user || - uobj.is(:uid) == user - } - - unless obj - begin - uobj = Etc.getpwuid(user) - uid = uobj.uid - rescue ArgumentError => detail - # ignore it; we couldn't find the user - end - end - else - unless obj = Puppet.type(:user)[user] - obj = Puppet.type(:user).create( - :name => user - ) - end - obj[:check] = [:uid, :gid] - end - - if obj - obj.retrieve - uid = obj.should(:uid) || obj.is(:uid) - if uid == :absent - uid = nil - end - end - - return uid - end - - # Create instance methods for each of the log levels. This allows # the messages to be a little richer. Most classes will be calling this # method. diff --git a/lib/puppet/util/posix.rb b/lib/puppet/util/posix.rb new file mode 100755 index 000000000..75726b3da --- /dev/null +++ b/lib/puppet/util/posix.rb @@ -0,0 +1,78 @@ +# Utility methods for interacting with POSIX objects; mostly user and group +module Puppet::Util::POSIX + # Retrieve a field from a POSIX Etc object. The id can be either an integer + # or a name. This only works for users and groups. + def get_posix_field(space, field, id) + if id =~ /^\d+$/ + id = Integer(id) + end + prefix = "get" + space.to_s + if id.is_a?(Integer) + method = (prefix + idfield(space).to_s).intern + else + method = (prefix + "nam").intern + end + + begin + return Etc.send(method, id).send(field) + rescue ArgumentError => detail + # ignore it; we couldn't find the object + return nil + end + end + + # Look in memory for an already-managed type and use its info if available. + def get_provider_value(type, field, id) + unless typeklass = Puppet::Type.type(type) + raise ArgumentError, "Invalid type %s" % type + end + + id = id.to_s + + chkfield = idfield(type) + obj = typeklass.find { |obj| + if id =~ /^\d+$/ + obj.should(chkfield).to_s == id || + obj.is(chkfield).to_s == id + else + obj[:name] == id + end + } + + return nil unless obj + + if obj.provider + begin + return obj.provider.send(field) + rescue => detail + if Puppet[:trace] + puts detail.backtrace + Puppet.err detail + return nil + end + end + end + end + + # Determine what the field name is for users and groups. + def idfield(space) + case Puppet::Util.symbolize(space) + when :gr, :group: return :gid + when :pw, :user: return :uid + else + raise ArgumentError.new("Can only handle users and groups") + end + end + + # Get the GID of a given group, provided either a GID or a name + def gid(group) + get_provider_value(:group, :gid, group) or get_posix_field(:gr, :gid, group) + end + + # Get the UID of a given user, whether a UID or name is provided + def uid(user) + get_provider_value(:user, :uid, user) or get_posix_field(:pw, :uid, user) + end +end + +# $Id$
\ No newline at end of file |
