summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/puppetdoc2
-rw-r--r--lib/puppet/parser/collector.rb2
-rw-r--r--lib/puppet/parser/functions.rb92
-rw-r--r--lib/puppet/rails.rb18
-rw-r--r--lib/puppet/reports/tagmail.rb2
-rwxr-xr-xlib/puppet/server/report.rb26
-rw-r--r--lib/puppet/util/docs.rb28
-rwxr-xr-xtest/language/functions.rb4
8 files changed, 149 insertions, 25 deletions
diff --git a/bin/puppetdoc b/bin/puppetdoc
index 1ee7406c2..ff4e8f4ec 100755
--- a/bin/puppetdoc
+++ b/bin/puppetdoc
@@ -217,7 +217,7 @@ Below is a list of all documented parameters. Any default values are in ``block
end
# Print the docs for types
-def self.types
+def self.typedocs
puts %{---
inMenu: true
title: Type Reference
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index 61807717d..2b4e71d77 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -27,7 +27,7 @@ class Puppet::Parser::Collector
# and such, we'll need to vary the conditions, but this works with no
# attributes, anyway.
Puppet::Util.benchmark(:debug, "Collected #{self.type} resources") do
- Puppet::Rails::RailsResource.find_all_by_restype_and_exported(@type, true,
+ Puppet::Rails::Resource.find_all_by_restype_and_exported(@type, true,
args
).each do |obj|
count += 1
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index 7fb19475e..35c51da7c 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -11,8 +11,19 @@ module Functions
include Puppet::Util
end
+ def self.autoloader
+ unless defined? @autoloader
+ @autoloader = Puppet::Autoload.new(self,
+ "puppet/parser/functions",
+ :wrap => false
+ )
+ end
+
+ @autoloader
+ end
+
# Create a new function type.
- def self.newfunction(name, ftype = :statement, doc = nil, &block)
+ def self.newfunction(name, options = {}, &block)
@functions ||= {}
name = symbolize(name)
@@ -26,6 +37,8 @@ module Functions
eval("module FCollection; end")
end
+ ftype = options[:type] || :statement
+
unless ftype == :statement or ftype == :rvalue
raise Puppet::DevError, "Invalid statement type %s" % ftype.inspect
end
@@ -36,21 +49,17 @@ module Functions
# Someday we'll support specifying an arity, but for now, nope
#@functions[name] = {:arity => arity, :type => ftype}
@functions[name] = {:type => ftype, :name => fname}
+ if options[:doc]
+ @functions[name][:doc] = options[:doc]
+ end
end
# Determine if a given name is a function
def self.function(name)
name = symbolize(name)
- unless defined? @autoloader
- @autoloader = Puppet::Autoload.new(self,
- "puppet/parser/functions",
- :wrap => false
- )
- end
-
unless @functions.include? name
- @autoloader.load(name)
+ autoloader.load(name)
end
if @functions.include? name
@@ -60,6 +69,42 @@ module Functions
end
end
+ def self.functiondocs
+ autoloader.loadall
+
+ header = %{inMenu: true
+title: Function Reference
+orderInfo: 40
+
+There are two types of functions in Puppet: Statements and rvalues.
+Statements stand on their own and do not return arguments; they are used for
+performing stand-alone work like importing. Rvalues return values and can
+only be used in a statement requiring a value, such as an assignment or a case
+statement.
+
+Here are the functions available in Puppet:
+
+}
+
+ ret = header.dup
+
+ @functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
+ ret += "* **%s** (*%s*)" % [name, hash[:type]]
+ if hash[:doc]
+ ret += ": " + hash[:doc].gsub(/\n\s*/, ' ')
+ else
+ ret += ": ``undocumented``"
+ end
+ ret += "\n\n"
+ end
+
+ return ret
+ end
+
+ def self.functions
+ @functions.keys
+ end
+
# Determine if a given function returns a value or not.
def self.rvalue?(name)
name = symbolize(name)
@@ -75,7 +120,7 @@ module Functions
end
# Include the specified classes
- newfunction(:include) do |vals|
+ newfunction(:include, :doc => "Evaluate one or more classes.") do |vals|
klasses = evalclasses(*vals)
missing = vals.find_all do |klass|
@@ -93,13 +138,18 @@ module Functions
end
# Tag the current scope with each passed name
- newfunction(:tag) do |vals|
+ newfunction(:tag, :doc => "Add the specified tags to the containing class
+ or definition. All contained objects will then acquire that tag, also.
+ ") do |vals|
self.tag(*vals)
end
# Test whether a given tag is set. This functions as a big OR -- if any of the
# specified tags are unset, we return false.
- newfunction(:tagged, :rvalue) do |vals|
+ newfunction(:tagged, :type => :rvalue, :doc => "A boolean function that
+ tells you whether the current container is tagged with the specified tags.
+ The tags are ANDed, so thta all of the specified tags must be included for
+ the function to return true.") do |vals|
classlist = self.classlist
retval = true
@@ -114,7 +164,8 @@ module Functions
end
# Test whether a given class or definition is defined
- newfunction(:defined, :rvalue) do |vals|
+ newfunction(:defined, :type => :rvalue, :doc => "Determine whether a given
+ type is defined, either as a native type or a defined type.") do |vals|
# For some reason, it doesn't want me to return from here.
if vals.detect do |val| Puppet::Type.type(val) or finddefine(val) end
true
@@ -124,19 +175,22 @@ module Functions
end
- newfunction(:fail, :statement) do |vals|
+ newfunction(:fail, :doc => "Fail with a parse error.") do |vals|
vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
raise Puppet::ParseError, vals.to_s
end
# Runs a newfunction to create a function for each of the log levels
Puppet::Log.levels.each do |level|
- newfunction(level, :statement) do |vals|
+ newfunction(level, :doc => "Log a message on the server at level
+ #{level.to_s}.") do |vals|
send(level, vals.join(" "))
end
end
- newfunction(:template, :rvalue) do |vals|
+ newfunction(:template, :type => :rvalue, :doc => "Evaluate a template and
+ return its value. See [the templating docs](../advanced/templating.html)
+ for more information.") do |vals|
require 'erb'
vals.collect do |file|
@@ -157,7 +211,11 @@ module Functions
# This is just syntactic sugar for a collection, although it will generally
# be a good bit faster.
- newfunction(:realize, :statement) do |vals|
+ newfunction(:realize, :doc => "Make a virtual object real. This is useful
+ when you want to know the name of the virtual object and don't want to
+ bother with a full collection. It is slightly faster than a collection,
+ and, of course, is a bit shorter. You must pass the object using a
+ reference; e.g.: ``realize User[luke]``." ) do |vals|
coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, :virtual)
vals = [vals] unless vals.is_a?(Array)
coll.resources = vals
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index e041f8342..42baee8bb 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -38,7 +38,7 @@ require 'puppet/rails/database/schema_init'
Puppet.config.setdefaults(:puppetmaster,
#this should be changed to use $statedir, but for now it only works this way.
- :dblocation => { :default => "#{Puppet[:statedir]}/clientconfigs.sqlite3",
+ :dblocation => { :default => "$statedir/clientconfigs.sqlite3",
:mode => 0600,
:owner => "$user",
:group => "$group",
@@ -54,14 +54,13 @@ require 'puppet/rails/database/schema_init'
:dbpassword => [ "puppet", "The database password for Client caching. Only
used when networked databases are used."],
#this should be changed to use $logdir, but for now it only works this way.
- :railslog => {:default => "#{Puppet[:logdir]}/puppetrails.log",
+ :railslog => {:default => "$logdir/puppetrails.log",
:mode => 0600,
:owner => "$user",
:group => "$group",
:desc => "Where Rails-specific logs are sent"
}
)
- ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
def self.clear
@inited = false
@@ -85,6 +84,12 @@ require 'puppet/rails/database/schema_init'
case Puppet[:dbadapter]
when "sqlite3":
args[:database] = Puppet[:dblocation]
+ unless FileTest.exists?(Puppet[:dblocation])
+ Puppet.config.use(:puppet)
+ Puppet.config.write(:dblocation) do |f|
+ f.print ""
+ end
+ end
when "mysql":
args[:host] = Puppet[:dbserver]
@@ -101,7 +106,11 @@ require 'puppet/rails/database/schema_init'
end
raise Puppet::Error, "Could not connect to database: %s" % detail
end
- @inited = true if ActiveRecord::Base.connection.tables.include? "resources"
+ begin
+ @inited = true if ActiveRecord::Base.connection.tables.include? "resources"
+ rescue SQLite3::CantOpenException => detail
+ @inited = false
+ end
#puts "Database initialized: #{@inited.inspect} "
end
@@ -130,6 +139,7 @@ require 'puppet/rails/database/schema_init'
Puppet::Rails::Schema.init
end
Puppet.config.use(:puppet)
+ ActiveRecord::Base.logger = Logger.new(Puppet[:railslog])
end
end
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index 6018c6424..6c1dca675 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -36,6 +36,8 @@ Puppet::Server::Report.newreport(:tagmail) do
all: me@domain.com
webserver, !mailserver: httpadmins@domain.com
+ This will send all messages to ``me@domain.com``, and all messages from
+ webservers that are not also from mailservers to ``httpadmins@domain.com``.
"
def process
diff --git a/lib/puppet/server/report.rb b/lib/puppet/server/report.rb
index 6253f6a0e..bbc8e7ddb 100755
--- a/lib/puppet/server/report.rb
+++ b/lib/puppet/server/report.rb
@@ -72,6 +72,32 @@ class Server
@reports[symbolize(name)]
end
+ def self.reportdocs
+ docs = %{Puppet clients can report back to the server after each
+transaction. This transaction report is sent as a YAML dump and includes every
+log message that was generated during the transaction along with as many metrics
+as Puppet knows how to collect.
+
+Currently, clients default to not sending in reports; you can enable reporting
+by setting the ``report`` parameter to true.
+
+To use a report, set the ``reports`` parameter on the server; multiple
+reports must be comma-separated.
+
+Puppet provides multiple report handlers that will process client reports:
+
+}
+ # Use this method so they all get loaded
+ reports.sort { |a,b| a.to_s <=> b.to_s }.each do |name|
+ mod = self.report(name)
+ docs += "## %s\n\n" % name
+
+ docs += Puppet::Util::Docs.scrub(mod.doc) + "\n\n"
+ end
+
+ docs
+ end
+
def self.reports
@reportloader.loadall
@reports.keys
diff --git a/lib/puppet/util/docs.rb b/lib/puppet/util/docs.rb
index 01aea7d3d..ebbce7317 100644
--- a/lib/puppet/util/docs.rb
+++ b/lib/puppet/util/docs.rb
@@ -26,6 +26,34 @@ module Puppet::Util::Docs
extra
end
end
+
+ # Handle the inline indentation in the docs.
+ def scrub(text)
+ # Stupid markdown
+ #text = text.gsub("<%=", "&lt;%=")
+ # For text with no carriage returns, there's nothing to do.
+ if text !~ /\n/
+ return text
+ end
+ indent = nil
+
+ # If we can match an indentation, then just remove that same level of
+ # indent from every line.
+ if text =~ /^(\s+)/
+ indent = $1
+ begin
+ return text.gsub(/^#{indent}/,'')
+ rescue => detail
+ puts detail.backtrace
+ puts detail
+ end
+ else
+ return text
+ end
+
+ end
+
+ module_function :scrub
end
# $Id$
diff --git a/test/language/functions.rb b/test/language/functions.rb
index bd7143db6..b69c2bfa2 100755
--- a/test/language/functions.rb
+++ b/test/language/functions.rb
@@ -23,7 +23,7 @@ class TestLangFunctions < Test::Unit::TestCase
end
assert_nothing_raised do
- Puppet::Parser::Functions.newfunction(:fakefunction, :rvalue) do |input|
+ Puppet::Parser::Functions.newfunction(:fakefunction, :type => :rvalue) do |input|
return "output %s" % input[0]
end
end
@@ -289,7 +289,7 @@ class TestLangFunctions < Test::Unit::TestCase
File.open(File.join(newpath, "autofunc.rb"), "w") { |f|
f.puts %{
- Puppet::Parser::Functions.newfunction(:autofunc, :rvalue) do |vals|
+ Puppet::Parser::Functions.newfunction(:autofunc, :type => :rvalue) do |vals|
Puppet.wanring vals.inspect
end
}