diff options
| author | Dominic Cleal <dcleal@redhat.com> | 2010-11-27 13:36:04 +0000 |
|---|---|---|
| committer | Dominic Cleal <dcleal@redhat.com> | 2010-11-27 13:36:04 +0000 |
| commit | afe2d014feb2210a8666c93465d11e9c9d555f8b (patch) | |
| tree | 208f5ac82b2c29610d2021821c8fca9b079e638b /lib/puppet/util | |
| parent | 143fc744a839affd328234fca26246d49d15d3d8 (diff) | |
| parent | 4b35402ba85d8842d757becec5c8a7bf4d6f6654 (diff) | |
Merge branch 'master' of github.com:domcleal/puppet into master-old
Diffstat (limited to 'lib/puppet/util')
| -rw-r--r-- | lib/puppet/util/autoload.rb | 22 | ||||
| -rw-r--r-- | lib/puppet/util/cacher.rb | 25 | ||||
| -rw-r--r-- | lib/puppet/util/command_line.rb | 2 | ||||
| -rwxr-xr-x | lib/puppet/util/command_line/puppetdoc | 10 | ||||
| -rwxr-xr-x | lib/puppet/util/command_line/puppetrun | 2 | ||||
| -rwxr-xr-x | lib/puppet/util/command_line/ralsh | 26 | ||||
| -rw-r--r-- | lib/puppet/util/docs.rb | 17 | ||||
| -rw-r--r-- | lib/puppet/util/file_locking.rb | 9 | ||||
| -rw-r--r-- | lib/puppet/util/log.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/util/log/destinations.rb | 14 | ||||
| -rw-r--r-- | lib/puppet/util/metric.rb | 57 | ||||
| -rw-r--r-- | lib/puppet/util/monkey_patches.rb | 30 | ||||
| -rw-r--r-- | lib/puppet/util/nagios_maker.rb | 9 | ||||
| -rw-r--r-- | lib/puppet/util/provider_features.rb | 4 | ||||
| -rw-r--r-- | lib/puppet/util/rdoc.rb | 11 | ||||
| -rw-r--r-- | lib/puppet/util/rdoc/generators/puppet_generator.rb | 6 | ||||
| -rw-r--r-- | lib/puppet/util/rdoc/parser.rb | 56 | ||||
| -rw-r--r-- | lib/puppet/util/reference.rb | 66 | ||||
| -rw-r--r-- | lib/puppet/util/suidmanager.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/util/zaml.rb | 29 |
20 files changed, 217 insertions, 181 deletions
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb index c293ac14a..f0dd0a5c5 100644 --- a/lib/puppet/util/autoload.rb +++ b/lib/puppet/util/autoload.rb @@ -131,11 +131,23 @@ class Puppet::Util::Autoload # We have to require this late in the process because otherwise we might have # load order issues. require 'puppet/node/environment' - Puppet::Node::Environment.new(env).modulepath.collect do |dir| - Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) } - end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d| - FileTest.directory?(d) - end + + real_env = Puppet::Node::Environment.new(env) + + # We're using a per-thread cache of said module directories, so that + # we don't scan the filesystem each time we try to load something with + # this autoload instance. But since we don't want to cache for the eternity + # this env_module_directories gets reset after the compilation on the master. + # This is also reset after an agent ran. + # One of the side effect of this change is that this module directories list will be + # shared among all autoload that we have running at a time. But that won't be an issue + # as by definition those directories are shared by all autoload. + Thread.current[:env_module_directories] ||= {} + Thread.current[:env_module_directories][real_env] ||= real_env.modulepath.collect do |dir| + Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) } + end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d| + FileTest.directory?(d) + end end def search_directories(env=nil) diff --git a/lib/puppet/util/cacher.rb b/lib/puppet/util/cacher.rb index 8785c694f..3dddec0d4 100644 --- a/lib/puppet/util/cacher.rb +++ b/lib/puppet/util/cacher.rb @@ -1,3 +1,5 @@ +require 'monitor' + module Puppet::Util::Cacher module Expirer attr_reader :timestamp @@ -49,7 +51,7 @@ module Puppet::Util::Cacher define_method(name.to_s + "=") do |value| # Make sure the cache timestamp is set cache_timestamp - value_cache[name] = value + value_cache.synchronize { value_cache[name] = value } end if ttl = options[:ttl] @@ -70,6 +72,7 @@ module Puppet::Util::Cacher # Methods that get added to instances. module InstanceMethods + def expire # Only expire if we have an expirer. This is # mostly so that we can comfortably handle cases @@ -92,15 +95,17 @@ module Puppet::Util::Cacher end def cached_value(name) - # Allow a nil expirer, in which case we regenerate the value every time. - if expired_by_expirer?(name) - value_cache.clear - @cache_timestamp = Time.now - elsif expired_by_ttl?(name) - value_cache.delete(name) + value_cache.synchronize do + # Allow a nil expirer, in which case we regenerate the value every time. + if expired_by_expirer?(name) + value_cache.clear + @cache_timestamp = Time.now + elsif expired_by_ttl?(name) + value_cache.delete(name) + end + value_cache[name] = send("init_#{name}") unless value_cache.include?(name) + value_cache[name] end - value_cache[name] = send("init_#{name}") unless value_cache.include?(name) - value_cache[name] end def expired_by_expirer?(name) @@ -121,7 +126,7 @@ module Puppet::Util::Cacher end def value_cache - @value_cache ||= {} + @value_cache ||= {}.extend(MonitorMixin) end end end diff --git a/lib/puppet/util/command_line.rb b/lib/puppet/util/command_line.rb index 2a97ee069..3562a3dc0 100644 --- a/lib/puppet/util/command_line.rb +++ b/lib/puppet/util/command_line.rb @@ -62,7 +62,7 @@ module Puppet external_command = "puppet-#{subcommand_name}" require 'puppet/util' - path_to_subcommand = Puppet::Util.binary( external_command ) + path_to_subcommand = Puppet::Util.which( external_command ) return false unless path_to_subcommand system( path_to_subcommand, *args ) diff --git a/lib/puppet/util/command_line/puppetdoc b/lib/puppet/util/command_line/puppetdoc index d9bbbec33..0fa1830d6 100755 --- a/lib/puppet/util/command_line/puppetdoc +++ b/lib/puppet/util/command_line/puppetdoc @@ -8,15 +8,15 @@ # # = Usage # -# puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc outputdir>] [-m|--mode <text|pdf|markdown|trac|rdoc>] +# puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc outputdir>] [-m|--mode <text|pdf|rdoc>] # [-r|--reference <[type]|configuration|..>] [--charset CHARSET] [manifest-file] # # = Description # -# If mode is not 'rdoc', then this command generates a restructured-text document describing all installed +# If mode is not 'rdoc', then this command generates a Markdown document describing all installed # Puppet types or all allowable arguments to puppet executables. It is largely # meant for internal use and is used to generate the reference document -# available on the Reductive Labs web site. +# available on the Puppet Labs web site. # # In 'rdoc' mode, this command generates an html RDoc hierarchy describing the manifests that # are in 'manifestdir' and 'modulepath' configuration directives. @@ -37,7 +37,7 @@ # Specifies the directory where to output the rdoc documentation in 'rdoc' mode. # # mode:: -# Determine the output mode. Valid modes are 'text', 'trac', 'pdf', 'markdown' and 'rdoc'. The 'pdf' and 'markdown' modes create PDF or Markdown formatted files in the /tmp directory. Note that 'trac' mode only works on Reductive Labs servers. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' +# Determine the output mode. Valid modes are 'text', 'trac', 'pdf' and 'rdoc'. The 'pdf' mode creates PDF formatted files in the /tmp directory. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' # # reference:: # Build a particular reference. Get a list of references by running +puppet doc --list+. @@ -53,7 +53,7 @@ # or # $ puppet doc /etc/puppet/manifests/site.pp # or -# $ puppet doc -m markdown -r configuration +# $ puppet doc -m pdf -r configuration # # = Author # diff --git a/lib/puppet/util/command_line/puppetrun b/lib/puppet/util/command_line/puppetrun index ee95c47eb..27cd775b9 100755 --- a/lib/puppet/util/command_line/puppetrun +++ b/lib/puppet/util/command_line/puppetrun @@ -54,8 +54,6 @@ # This is what you would install on your Puppet master; non-master hosts could # leave off the 'fileserver' and 'puppetmaster' namespaces. # -# Expect more documentation on this eventually. -# # = Options # # Note that any configuration parameter that's valid in the configuration file diff --git a/lib/puppet/util/command_line/ralsh b/lib/puppet/util/command_line/ralsh index 68ad92d84..83338fcbc 100755 --- a/lib/puppet/util/command_line/ralsh +++ b/lib/puppet/util/command_line/ralsh @@ -59,23 +59,23 @@ # types: # List all available types. # -# verbose:: +# verbose: # Print extra information. # # = Example # -# This example uses ``puppet resource`` to return Puppet configuration for the user ``luke``:: -# -# $ puppet resource user luke -# user { 'luke': -# home => '/home/luke', -# uid => '100', -# ensure => 'present', -# comment => 'Luke Kanies,,,', -# gid => '1000', -# shell => '/bin/bash', -# groups => ['sysadmin','audio','video','puppet'] -# } +# This example uses `puppet resource` to return Puppet configuration for the user `luke`: +# +# $ puppet resource user luke +# user { 'luke': +# home => '/home/luke', +# uid => '100', +# ensure => 'present', +# comment => 'Luke Kanies,,,', +# gid => '1000', +# shell => '/bin/bash', +# groups => ['sysadmin','audio','video','puppet'] +# } # # = Author # diff --git a/lib/puppet/util/docs.rb b/lib/puppet/util/docs.rb index efd054d85..4344d67ab 100644 --- a/lib/puppet/util/docs.rb +++ b/lib/puppet/util/docs.rb @@ -47,25 +47,19 @@ module Puppet::Util::Docs lengths[i] = value.to_s.length if value.to_s.length > lengths[i] end - # Add the top header row - str += lengths.collect { |num| "=" * num }.join(" ") + "\n" + # Add the header names + str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" | ") + " |" + "\n" - # And the header names - str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" ") + "\n" - - # And the second header row - str += lengths.collect { |num| "=" * num }.join(" ") + "\n" + # And the header row + str += lengths.collect { |num| "-" * num }.join(" | ") + " |" + "\n" # Now each data row data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows| str += [name, rows].flatten.zip(lengths).collect do |value, length| pad(value, length) - end.join(" ") + "\n" + end.join(" | ") + " |" + "\n" end - # And the bottom line row - str += lengths.collect { |num| "=" * num }.join(" ") + "\n" - str + "\n" end @@ -111,4 +105,3 @@ module Puppet::Util::Docs module_function :scrub end - diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb index 8b194ed83..18744cab7 100644 --- a/lib/puppet/util/file_locking.rb +++ b/lib/puppet/util/file_locking.rb @@ -6,7 +6,7 @@ module Puppet::Util::FileLocking # Create a shared lock for reading def readlock(file) raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file) - Puppet::Util.sync(file).synchronize(Sync::SH) do + Puppet::Util.synchronize_on(file,Sync::SH) do File.open(file) { |f| f.lock_shared { |lf| yield lf } } @@ -33,9 +33,12 @@ module Puppet::Util::FileLocking end end - Puppet::Util.sync(file).synchronize(Sync::EX) do - File.open(file, "w", mode) do |rf| + Puppet::Util.synchronize_on(file,Sync::EX) do + File.open(file, File::Constants::CREAT | File::Constants::WRONLY, mode) do |rf| rf.lock_exclusive do |lrf| + # poor's man open(2) O_EXLOCK|O_TRUNC + lrf.seek(0, IO::SEEK_SET) + lrf.truncate(0) yield lrf end end diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb index 36a765c61..a5aacc265 100644 --- a/lib/puppet/util/log.rb +++ b/lib/puppet/util/log.rb @@ -57,6 +57,7 @@ class Puppet::Util::Log destinations.keys.each { |dest| close(dest) } + raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty? end # Flush any log destinations that support such operations. diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb index 22b3dedb2..2e2f9a5b7 100644 --- a/lib/puppet/util/log/destinations.rb +++ b/lib/puppet/util/log/destinations.rb @@ -203,8 +203,20 @@ Puppet::Util::Log.newdesttype :report do end # Log to an array, just for testing. +module Puppet::Test + class LogCollector + def initialize(logs) + @logs = logs + end + + def <<(value) + @logs << value + end + end +end + Puppet::Util::Log.newdesttype :array do - match "Array" + match "Puppet::Test::LogCollector" def initialize(messages) @messages = messages diff --git a/lib/puppet/util/metric.rb b/lib/puppet/util/metric.rb index 7e14a5fec..7fdc6951f 100644 --- a/lib/puppet/util/metric.rb +++ b/lib/puppet/util/metric.rb @@ -31,9 +31,12 @@ class Puppet::Util::Metric start ||= Time.now.to_i - 5 - @rrd = RRDtool.new(self.path) args = [] + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + @rrd = RRDtool.new(self.path) + end + values.each { |value| # the 7200 is the heartbeat -- this means that any data that isn't # more frequently than every two hours gets thrown away @@ -42,18 +45,26 @@ class Puppet::Util::Metric args.push "RRA:AVERAGE:0.5:1:300" begin - @rrd.create( Puppet[:rrdinterval].to_i, start, args) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + @rrd.create( Puppet[:rrdinterval].to_i, start, args) + else + RRD.create( self.path, '-s', Puppet[:rrdinterval].to_i.to_s, '-b', start.to_i.to_s, *args) + end rescue => detail raise "Could not create RRD file #{path}: #{detail}" end end def dump - puts @rrd.info + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + puts @rrd.info + else + puts RRD.info(self.path) + end end def graph(range = nil) - unless Puppet.features.rrd? + unless Puppet.features.rrd? || Puppet.features.rrd_legacy? Puppet.warning "RRD library is missing; cannot graph metrics" return end @@ -82,14 +93,26 @@ class Puppet::Util::Metric args << lines args.flatten! if range - args.push("--start",range[0],"--end",range[1]) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + args.push("--start",range[0],"--end",range[1]) + else + args.push("--start",range[0].to_i.to_s,"--end",range[1].to_i.to_s) + end else - args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + args.push("--start", Time.now.to_i - time, "--end", Time.now.to_i) + else + args.push("--start", (Time.now.to_i - time).to_s, "--end", Time.now.to_i.to_s) + end end begin #Puppet.warning "args = #{args}" - RRDtool.graph( args ) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + RRDtool.graph( args ) + else + RRD.graph( *args ) + end rescue => detail Puppet.err "Failed to graph #{self.name}: #{detail}" end @@ -99,7 +122,7 @@ class Puppet::Util::Metric def initialize(name,label = nil) @name = name.to_s - @label = label || labelize(name) + @label = label || self.class.labelize(name) @values = [] end @@ -109,18 +132,20 @@ class Puppet::Util::Metric end def newvalue(name,value,label = nil) - label ||= labelize(name) + label ||= self.class.labelize(name) @values.push [name,label,value] end def store(time) - unless Puppet.features.rrd? + unless Puppet.features.rrd? || Puppet.features.rrd_legacy? Puppet.warning "RRD library is missing; cannot store metrics" return end self.create(time - 5) unless FileTest.exists?(self.path) - @rrd ||= RRDtool.new(self.path) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + @rrd ||= RRDtool.new(self.path) + end # XXX this is not terribly error-resistant args = [time] @@ -133,7 +158,11 @@ class Puppet::Util::Metric arg = args.join(":") template = temps.join(":") begin - @rrd.update( template, [ arg ] ) + if Puppet.features.rrd_legacy? && ! Puppet.features.rrd? + @rrd.update( template, [ arg ] ) + else + RRD.update( self.path, '-t', template, arg ) + end #system("rrdtool updatev #{self.path} '#{arg}'") rescue => detail raise Puppet::Error, "Failed to update #{self.name}: #{detail}" @@ -144,10 +173,8 @@ class Puppet::Util::Metric @values.sort { |a, b| a[1] <=> b[1] } end - private - # Convert a name into a label. - def labelize(name) + def self.labelize(name) name.to_s.capitalize.gsub("_", " ") end end diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb index e035afd9f..1c35ae523 100644 --- a/lib/puppet/util/monkey_patches.rb +++ b/lib/puppet/util/monkey_patches.rb @@ -1,4 +1,7 @@ -Process.maxgroups = 1024 + +unless defined? JRUBY_VERSION + Process.maxgroups = 1024 +end module RDoc def self.caller(skip=nil) @@ -22,7 +25,7 @@ end [Object, Exception, Integer, Struct, Date, Time, Range, Regexp, Hash, Array, Float, String, FalseClass, TrueClass, Symbol, NilClass, Class].each { |cls| cls.class_eval do - def to_yaml + def to_yaml(ignored=nil) ZAML.dump(self) end end @@ -45,3 +48,26 @@ if RUBY_VERSION == '1.8.7' end end + +class Object + # ActiveSupport 2.3.x mixes in a dangerous method + # that can cause rspec to fork bomb + # and other strange things like that. + def daemonize + raise NotImplementedError, "Kernel.daemonize is too dangerous, please don't try to use it." + end +end + +# Workaround for yaml_initialize, which isn't supported before Ruby +# 1.8.3. +if RUBY_VERSION == '1.8.1' || RUBY_VERSION == '1.8.2' + YAML.add_ruby_type( /^object/ ) { |tag, val| + type, obj_class = YAML.read_type_class( tag, Object ) + r = YAML.object_maker( obj_class, val ) + if r.respond_to? :yaml_initialize + r.instance_eval { instance_variables.each { |name| remove_instance_variable name } } + r.yaml_initialize(tag, val) + end + r + } +end diff --git a/lib/puppet/util/nagios_maker.rb b/lib/puppet/util/nagios_maker.rb index 59ed820f9..863fe24fa 100644 --- a/lib/puppet/util/nagios_maker.rb +++ b/lib/puppet/util/nagios_maker.rb @@ -45,17 +45,16 @@ module Puppet::Util::NagiosMaker provider.nagios_type type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the - model developed in Naginator_, and all of the Nagios types are generated using the + model developed in Naginator, and all of the Nagios types are generated using the same code and the same library. This type generates Nagios configuration statements in Nagios-parseable configuration - files. By default, the statements will be added to ``#{target}``, but - you can send them to a different file by setting their ``target`` attribute. + files. By default, the statements will be added to `#{target}`, but + you can send them to a different file by setting their `target` attribute. - You can purge Nagios resources using the ``resources`` type, but *only* + You can purge Nagios resources using the `resources` type, but *only* in the default file locations. This is an architectural limitation. - .. _naginator: http://projects.reductivelabs.com/projects/naginator " end end diff --git a/lib/puppet/util/provider_features.rb b/lib/puppet/util/provider_features.rb index ac294d20d..30e8dcb39 100644 --- a/lib/puppet/util/provider_features.rb +++ b/lib/puppet/util/provider_features.rb @@ -72,7 +72,7 @@ module Puppet::Util::ProviderFeatures names = @features.keys.sort { |a,b| a.to_s <=> b.to_s } names.each do |name| doc = @features[name].docs.gsub(/\n\s+/, " ") - str += "- **#{name}**: #{doc}\n" + str += "- *#{name}*: #{doc}\n" end if providers.length > 0 @@ -83,7 +83,7 @@ module Puppet::Util::ProviderFeatures prov = provider(provname) names.each do |name| if prov.feature?(name) - data[provname] << "**X**" + data[provname] << "*X*" else data[provname] << "" end diff --git a/lib/puppet/util/rdoc.rb b/lib/puppet/util/rdoc.rb index 4a80b069b..bdac579d6 100644 --- a/lib/puppet/util/rdoc.rb +++ b/lib/puppet/util/rdoc.rb @@ -10,24 +10,25 @@ module Puppet::Util::RDoc # then rdoc require 'rdoc/rdoc' + require 'rdoc/options' # load our parser require 'puppet/util/rdoc/parser' r = RDoc::RDoc.new - RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new( + RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new( "puppet/util/rdoc/generators/puppet_generator.rb", - "PuppetGenerator".intern, + "PuppetGenerator".intern, + "puppet") - "puppet") # specify our own format & where to output options = [ "--fmt", "puppet", "--quiet", - "--force-update", "--exclude", "/modules/[^/]*/files/.*\.pp$", "--op", outputdir ] + options << "--force-update" if Options::OptionList.options.any? { |o| o[0] == "--force-update" } options += [ "--charset", charset] if charset options += files @@ -41,7 +42,7 @@ module Puppet::Util::RDoc def manifestdoc(files) Puppet[:ignoreimport] = true files.select { |f| FileTest.file?(f) }.each do |f| - parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment]) + parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new(Puppet[:environment])) parser.file = f ast = parser.parse output(f, ast) diff --git a/lib/puppet/util/rdoc/generators/puppet_generator.rb b/lib/puppet/util/rdoc/generators/puppet_generator.rb index 9caeacd5e..e6bbb2e1e 100644 --- a/lib/puppet/util/rdoc/generators/puppet_generator.rb +++ b/lib/puppet/util/rdoc/generators/puppet_generator.rb @@ -88,6 +88,12 @@ module Generators @modules = {} @allclasses = {} + # remove unknown toplevels + # it can happen that RDoc triggers a different parser for some files (ie .c, .cc or .h) + # in this case RDoc generates a RDoc::TopLevel which we do not support in this generator + # So let's make sure we don't generate html for those. + @toplevels = @toplevels.select { |tl| tl.is_a? RDoc::PuppetTopLevel } + # build the modules, classes and per modules classes and define list @toplevels.each do |toplevel| next unless toplevel.document_self diff --git a/lib/puppet/util/rdoc/parser.rb b/lib/puppet/util/rdoc/parser.rb index 573d1766f..ce34442ab 100644 --- a/lib/puppet/util/rdoc/parser.rb +++ b/lib/puppet/util/rdoc/parser.rb @@ -15,7 +15,9 @@ module RDoc class Parser extend ParserFactory - attr_accessor :ast, :input_file_name, :top_level + SITE = "__site__" + + attr_accessor :input_file_name, :top_level # parser registration into RDoc parse_files_matching(/\.(rb|pp)$/) @@ -31,13 +33,19 @@ class Parser # main entry point def scan - Puppet.info "rdoc: scanning #{@input_file_name}" - if @input_file_name =~ /\.pp$/ - @parser = Puppet::Parser::Parser.new(Puppet[:environment]) - @parser.file = @input_file_name - @ast = @parser.parse + environment = Puppet::Node::Environment.new + unless environment.known_resource_types.watching_file?(@input_file_name) + Puppet.info "rdoc: scanning #{@input_file_name}" + if @input_file_name =~ /\.pp$/ + @parser = Puppet::Parser::Parser.new(environment) + @parser.file = @input_file_name + @known_resource_types = environment.known_resource_types + @parser.parse.instantiate('').each do |type| + @known_resource_types.add type + end + scan_top_level(@top_level) + end end - scan_top_level(@top_level) @top_level end @@ -74,7 +82,7 @@ class Parser # split_module tries to find if +path+ belongs to the module path # if it does, it returns the module name, otherwise if we are sure - # it is part of the global manifest path, "<site>" is returned. + # it is part of the global manifest path, "__site__" is returned. # And finally if this path couldn't be mapped anywhere, nil is returned. def split_module(path) # find a module @@ -105,7 +113,7 @@ class Parser end # we are under a global manifests Puppet.debug "rdoc: global manifests" - "<site>" + SITE end # create documentation for the top level +container+ @@ -128,7 +136,7 @@ class Parser Puppet.debug "rdoc: scanning for #{name}" container.module_name = name - container.global=true if name == "<site>" + container.global=true if name == SITE @stats.num_modules += 1 container, name = get_class_or_module(container,name) @@ -199,19 +207,21 @@ class Parser if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil? begin type = stmt.type.split("::").collect { |s| s.capitalize }.join("::") - title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s - Puppet.debug "rdoc: found resource: #{type}[#{title}]" + stmt.instances.each do |inst| + title = inst.title.is_a?(Puppet::Parser::AST::ASTArray) ? inst.title.to_s.gsub(/\[(.*)\]/,'\1') : inst.title.to_s + Puppet.debug "rdoc: found resource: #{type}[#{title}]" - param = [] - stmt.params.children.each do |p| - res = {} - res["name"] = p.param - res["value"] = "#{p.value.to_s}" unless p.value.nil? + param = [] + inst.parameters.children.each do |p| + res = {} + res["name"] = p.param + res["value"] = "#{p.value.to_s}" unless p.value.nil? - param << res - end + param << res + end - container.add_resource(PuppetResource.new(type, title, stmt.doc, param)) + container.add_resource(PuppetResource.new(type, title, stmt.doc, param)) + end rescue => detail raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}" end @@ -332,7 +342,7 @@ class Parser # that contains the documentation def parse_elements(container) Puppet.debug "rdoc: scanning manifest" - @ast.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass| + @known_resource_types.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass| name = klass.name if klass.file == @input_file_name unless name.empty? @@ -345,13 +355,13 @@ class Parser end end - @ast.definitions.each do |name, define| + @known_resource_types.definitions.each do |name, define| if define.file == @input_file_name document_define(name,define,container) end end - @ast.nodes.each do |name, node| + @known_resource_types.nodes.each do |name, node| if node.file == @input_file_name document_node(name.to_s,node,container) end diff --git a/lib/puppet/util/reference.rb b/lib/puppet/util/reference.rb index 62bab643e..95efeb1c1 100644 --- a/lib/puppet/util/reference.rb +++ b/lib/puppet/util/reference.rb @@ -15,7 +15,7 @@ class Puppet::Util::Reference end def self.modes - %w{pdf trac text markdown} + %w{pdf text} end def self.newreference(name, options = {}, &block) @@ -32,7 +32,6 @@ class Puppet::Util::Reference section = reference(name) or raise "Could not find section #{name}" depth = section.depth if section.depth < depth end - text = ".. contents:: :depth: 2\n\n" end def self.pdf(text) @@ -40,14 +39,7 @@ class Puppet::Util::Reference Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f| f.puts text end - rst2latex = %x{which rst2latex} - if $CHILD_STATUS != 0 or rst2latex =~ /no / - rst2latex = %x{which rst2latex.py} - end - if $CHILD_STATUS != 0 or rst2latex =~ /no / - raise "Could not find rst2latex" - end - rst2latex.chomp! + rst2latex = which('rst2latex') || which('rst2latex.py') || raise("Could not find rst2latex") cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex} Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f| # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink @@ -67,38 +59,12 @@ class Puppet::Util::Reference end - def self.markdown(name, text) - puts "Creating markdown for #{name} reference." - dir = "/tmp/#{Puppet::PUPPETVERSION}" - FileUtils.mkdir(dir) unless File.directory?(dir) - Puppet::Util.secure_open(dir + "/#{name}.rst", "w") do |f| - f.puts text - end - pandoc = %x{which pandoc} - if $CHILD_STATUS != 0 or pandoc =~ /no / - pandoc = %x{which pandoc} - end - if $CHILD_STATUS != 0 or pandoc =~ /no / - raise "Could not find pandoc" - end - pandoc.chomp! - cmd = %{#{pandoc} -s -r rst -w markdown #{dir}/#{name}.rst -o #{dir}/#{name}.mdwn} - output = %x{#{cmd}} - unless $CHILD_STATUS == 0 - $stderr.puts "Pandoc failed to create #{name} reference." - $stderr.puts output - exit(1) - end - - File.unlink(dir + "/#{name}.rst") - end - def self.references instance_loader(:reference).loadall loaded_instances(:reference).sort { |a,b| a.to_s <=> b.to_s } end - HEADER_LEVELS = [nil, "=", "-", "+", "'", "~"] + HEADER_LEVELS = [nil, "#", "##", "###", "####", "#####"] attr_accessor :page, :depth, :header, :title, :dynamic attr_writer :doc @@ -116,7 +82,7 @@ class Puppet::Util::Reference end def h(name, level) - "#{name}\n#{HEADER_LEVELS[level] * name.to_s.length}\n\n" + "#{HEADER_LEVELS[level]} #{name}\n\n" end def initialize(name, options = {}, &block) @@ -167,7 +133,6 @@ class Puppet::Util::Reference # First the header text = h(@title, 1) text += "\n\n**This page is autogenerated; any changes will get overwritten** *(last generated on #{Time.now.to_s})*\n\n" - text += ".. contents:: :depth: #{@depth}\n\n" if withcontents text += @header @@ -181,27 +146,4 @@ class Puppet::Util::Reference def to_text(withcontents = true) strip_trac(to_rest(withcontents)) end - - def to_trac(with_contents = true) - "{{{\n#!rst\n#{self.to_rest(with_contents)}\n}}}" - end - - def trac - Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f| - f.puts self.to_trac - end - - puts "Writing #{@name} reference to trac as #{@page}" - cmd = %{sudo trac-admin /opt/rl/trac/puppet wiki import %s /tmp/puppetdoc.txt} % self.page - output = %x{#{cmd}} - unless $CHILD_STATUS == 0 - $stderr.puts "trac-admin failed" - $stderr.puts output - exit(1) - end - unless output =~ /^\s+/ - $stderr.puts output - end - end end - diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb index 4d2c32217..6633de002 100644 --- a/lib/puppet/util/suidmanager.rb +++ b/lib/puppet/util/suidmanager.rb @@ -88,7 +88,7 @@ module Puppet::Util::SUIDManager module_function :initgroups def run_and_capture(command, new_uid=nil, new_gid=nil) - output = Puppet::Util.execute(command, :failonfail => false, :uid => new_uid, :gid => new_gid) + output = Puppet::Util.execute(command, :failonfail => false, :combine => true, :uid => new_uid, :gid => new_gid) [output, $CHILD_STATUS.dup] end module_function :run_and_capture diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb index 8ecc2c8bd..2155e989c 100644 --- a/lib/puppet/util/zaml.rb +++ b/lib/puppet/util/zaml.rb @@ -29,7 +29,8 @@ class ZAML @result = [] @indent = nil @structured_key_prefix = nil - Label.counter_reset + @previously_emitted_object = {} + @next_free_label_number = 0 emit('--- ') end def nested(tail=' ') @@ -55,31 +56,29 @@ class ZAML # which we will encounter a reference to the object as we serialize # it can be handled). # - def self.counter_reset - @@previously_emitted_object = {} - @@next_free_label_number = 0 - end + attr_accessor :this_label_number def initialize(obj,indent) @indent = indent @this_label_number = nil - @@previously_emitted_object[obj.object_id] = self end def to_s @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : '' end def reference - @this_label_number ||= (@@next_free_label_number += 1) @reference ||= '*id%03d' % @this_label_number end - def self.for(obj) - @@previously_emitted_object[obj.object_id] - end + end + def label_for(obj) + @previously_emitted_object[obj.object_id] end def new_label_for(obj) - Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ') + label = Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ') + @previously_emitted_object[obj.object_id] = label + label end def first_time_only(obj) - if label = Label.for(obj) + if label = label_for(obj) + label.this_label_number ||= (@next_free_label_number += 1) emit(label.reference) else if @structured_key_prefix and not obj.is_a? String @@ -120,6 +119,9 @@ class Object def to_yaml_properties instance_variables.sort # Default YAML behavior end + def yaml_property_munge(x) + x + end def zamlized_class_name(root) cls = self.class "!ruby/#{root.name.downcase}#{cls == root ? '' : ":#{cls.respond_to?(:name) ? cls.name : cls}"}" @@ -136,7 +138,7 @@ class Object z.nl v[1..-1].to_zaml(z) # Remove leading '@' z.emit(': ') - instance_variable_get(v).to_zaml(z) + yaml_property_munge(instance_variable_get(v)).to_zaml(z) } end } @@ -243,7 +245,6 @@ class String when self =~ /\n/ if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } - z.nl else z.emit(self) end |
