summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util
diff options
context:
space:
mode:
authorDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
committerDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
commitafe2d014feb2210a8666c93465d11e9c9d555f8b (patch)
tree208f5ac82b2c29610d2021821c8fca9b079e638b /lib/puppet/util
parent143fc744a839affd328234fca26246d49d15d3d8 (diff)
parent4b35402ba85d8842d757becec5c8a7bf4d6f6654 (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.rb22
-rw-r--r--lib/puppet/util/cacher.rb25
-rw-r--r--lib/puppet/util/command_line.rb2
-rwxr-xr-xlib/puppet/util/command_line/puppetdoc10
-rwxr-xr-xlib/puppet/util/command_line/puppetrun2
-rwxr-xr-xlib/puppet/util/command_line/ralsh26
-rw-r--r--lib/puppet/util/docs.rb17
-rw-r--r--lib/puppet/util/file_locking.rb9
-rw-r--r--lib/puppet/util/log.rb1
-rw-r--r--lib/puppet/util/log/destinations.rb14
-rw-r--r--lib/puppet/util/metric.rb57
-rw-r--r--lib/puppet/util/monkey_patches.rb30
-rw-r--r--lib/puppet/util/nagios_maker.rb9
-rw-r--r--lib/puppet/util/provider_features.rb4
-rw-r--r--lib/puppet/util/rdoc.rb11
-rw-r--r--lib/puppet/util/rdoc/generators/puppet_generator.rb6
-rw-r--r--lib/puppet/util/rdoc/parser.rb56
-rw-r--r--lib/puppet/util/reference.rb66
-rw-r--r--lib/puppet/util/suidmanager.rb2
-rw-r--r--lib/puppet/util/zaml.rb29
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