summaryrefslogtreecommitdiffstats
path: root/lib
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
parent143fc744a839affd328234fca26246d49d15d3d8 (diff)
parent4b35402ba85d8842d757becec5c8a7bf4d6f6654 (diff)
downloadpuppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.tar.gz
puppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.tar.xz
puppet-afe2d014feb2210a8666c93465d11e9c9d555f8b.zip
Merge branch 'master' of github.com:domcleal/puppet into master-old
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet.rb2
-rw-r--r--lib/puppet/agent.rb4
-rw-r--r--lib/puppet/application.rb41
-rw-r--r--lib/puppet/application/agent.rb6
-rw-r--r--lib/puppet/application/apply.rb23
-rw-r--r--lib/puppet/application/describe.rb2
-rw-r--r--lib/puppet/application/doc.rb38
-rw-r--r--lib/puppet/application/master.rb3
-rw-r--r--lib/puppet/application/queue.rb1
-rw-r--r--lib/puppet/configurer.rb27
-rwxr-xr-xlib/puppet/daemon.rb6
-rw-r--r--lib/puppet/defaults.rb130
-rw-r--r--lib/puppet/dsl.rb4
-rw-r--r--lib/puppet/dsl/resource_type_api.rb48
-rw-r--r--lib/puppet/external/event-loop/event-loop.rb26
-rw-r--r--lib/puppet/external/pson/pure/generator.rb30
-rw-r--r--lib/puppet/feature/base.rb3
-rw-r--r--lib/puppet/feature/rails.rb4
-rw-r--r--lib/puppet/file_serving/indirection_hooks.rb4
-rw-r--r--lib/puppet/indirector/catalog/compiler.rb13
-rw-r--r--lib/puppet/indirector/facts/memory.rb2
-rw-r--r--lib/puppet/indirector/facts/rest.rb2
-rw-r--r--lib/puppet/indirector/indirection.rb1
-rw-r--r--lib/puppet/indirector/inventory/yaml.rb81
-rw-r--r--lib/puppet/indirector/node/exec.rb2
-rw-r--r--lib/puppet/indirector/node/ldap.rb62
-rw-r--r--lib/puppet/indirector/node/memory.rb2
-rw-r--r--lib/puppet/indirector/report/yaml.rb11
-rw-r--r--lib/puppet/indirector/yaml.rb15
-rw-r--r--lib/puppet/network/format_handler.rb6
-rw-r--r--lib/puppet/network/formats.rb8
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb4
-rw-r--r--lib/puppet/network/http/api/v1.rb5
-rw-r--r--lib/puppet/network/http/handler.rb46
-rw-r--r--lib/puppet/network/http/rack.rb3
-rw-r--r--lib/puppet/network/http/rack/rest.rb2
-rw-r--r--lib/puppet/network/http/webrick/rest.rb1
-rw-r--r--lib/puppet/network/http_pool.rb12
-rw-r--r--lib/puppet/network/rest_authconfig.rb31
-rw-r--r--lib/puppet/network/rest_authorization.rb4
-rw-r--r--lib/puppet/network/server.rb4
-rw-r--r--lib/puppet/node.rb1
-rw-r--r--lib/puppet/node/environment.rb50
-rwxr-xr-xlib/puppet/node/facts.rb37
-rw-r--r--lib/puppet/node/inventory.rb7
-rw-r--r--lib/puppet/parameter/value_collection.rb6
-rw-r--r--lib/puppet/parser/ast.rb8
-rw-r--r--lib/puppet/parser/ast/astarray.rb35
-rw-r--r--lib/puppet/parser/ast/caseopt.rb36
-rw-r--r--lib/puppet/parser/ast/collection.rb85
-rw-r--r--lib/puppet/parser/ast/definition.rb17
-rw-r--r--lib/puppet/parser/ast/function.rb3
-rw-r--r--lib/puppet/parser/ast/hostclass.rb29
-rw-r--r--lib/puppet/parser/ast/leaf.rb14
-rw-r--r--lib/puppet/parser/ast/node.rb20
-rw-r--r--lib/puppet/parser/ast/resource.rb92
-rw-r--r--lib/puppet/parser/ast/resource_instance.rb9
-rw-r--r--lib/puppet/parser/ast/resource_override.rb5
-rw-r--r--lib/puppet/parser/ast/resource_reference.rb11
-rw-r--r--lib/puppet/parser/ast/top_level_construct.rb4
-rw-r--r--lib/puppet/parser/compiler.rb30
-rw-r--r--lib/puppet/parser/files.rb2
-rw-r--r--lib/puppet/parser/functions.rb10
-rw-r--r--lib/puppet/parser/functions/defined.rb2
-rw-r--r--lib/puppet/parser/functions/extlookup.rb157
-rw-r--r--lib/puppet/parser/functions/file.rb2
-rw-r--r--lib/puppet/parser/functions/inline_template.rb11
-rw-r--r--lib/puppet/parser/functions/md5.rb5
-rw-r--r--lib/puppet/parser/functions/realize.rb2
-rw-r--r--lib/puppet/parser/functions/regsubst.rb38
-rw-r--r--lib/puppet/parser/functions/require.rb5
-rw-r--r--lib/puppet/parser/functions/split.rb2
-rw-r--r--lib/puppet/parser/functions/sprintf.rb2
-rw-r--r--lib/puppet/parser/functions/template.rb6
-rw-r--r--lib/puppet/parser/functions/versioncmp.rb24
-rw-r--r--lib/puppet/parser/grammar.ra205
-rw-r--r--lib/puppet/parser/lexer.rb32
-rw-r--r--lib/puppet/parser/parser.rb2775
-rw-r--r--lib/puppet/parser/parser_support.rb131
-rw-r--r--lib/puppet/parser/resource.rb17
-rw-r--r--lib/puppet/parser/resource/param.rb2
-rw-r--r--lib/puppet/parser/scope.rb35
-rw-r--r--lib/puppet/parser/templatewrapper.rb1
-rw-r--r--lib/puppet/parser/type_loader.rb159
-rw-r--r--lib/puppet/property.rb10
-rw-r--r--lib/puppet/provider.rb10
-rw-r--r--lib/puppet/provider/confine/exists.rb5
-rw-r--r--lib/puppet/provider/group/groupadd.rb2
-rw-r--r--lib/puppet/provider/group/ldap.rb6
-rw-r--r--lib/puppet/provider/group/pw.rb2
-rw-r--r--lib/puppet/provider/host/parsed.rb76
-rwxr-xr-xlib/puppet/provider/maillist/mailman.rb11
-rw-r--r--lib/puppet/provider/mcx/mcxcontent.rb134
-rw-r--r--lib/puppet/provider/mount.rb2
-rw-r--r--lib/puppet/provider/nameservice.rb3
-rw-r--r--lib/puppet/provider/nameservice/directoryservice.rb34
-rw-r--r--lib/puppet/provider/nameservice/objectadd.rb3
-rwxr-xr-xlib/puppet/provider/package/apple.rb2
-rwxr-xr-xlib/puppet/provider/package/apt.rb6
-rwxr-xr-xlib/puppet/provider/package/aptitude.rb2
-rw-r--r--lib/puppet/provider/package/aptrpm.rb2
-rwxr-xr-xlib/puppet/provider/package/blastwave.rb2
-rwxr-xr-xlib/puppet/provider/package/dpkg.rb4
-rwxr-xr-xlib/puppet/provider/package/fink.rb2
-rwxr-xr-xlib/puppet/provider/package/gem.rb2
-rwxr-xr-xlib/puppet/provider/package/openbsd.rb18
-rwxr-xr-xlib/puppet/provider/package/rpm.rb2
-rw-r--r--lib/puppet/provider/package/rug.rb2
-rwxr-xr-xlib/puppet/provider/package/sunfreeware.rb4
-rw-r--r--lib/puppet/provider/package/up2date.rb2
-rw-r--r--lib/puppet/provider/package/urpmi.rb2
-rwxr-xr-xlib/puppet/provider/package/yum.rb11
-rw-r--r--lib/puppet/provider/package/zypper.rb2
-rwxr-xr-xlib/puppet/provider/service/base.rb2
-rw-r--r--lib/puppet/provider/service/bsd.rb4
-rwxr-xr-xlib/puppet/provider/service/debian.rb4
-rw-r--r--lib/puppet/provider/service/freebsd.rb7
-rw-r--r--lib/puppet/provider/service/gentoo.rb4
-rwxr-xr-xlib/puppet/provider/service/init.rb4
-rw-r--r--lib/puppet/provider/service/launchd.rb25
-rwxr-xr-xlib/puppet/provider/service/redhat.rb4
-rwxr-xr-xlib/puppet/provider/service/upstart.rb73
-rw-r--r--lib/puppet/provider/ssh_authorized_key/parsed.rb7
-rw-r--r--lib/puppet/provider/user/hpux.rb1
-rw-r--r--lib/puppet/provider/user/ldap.rb6
-rw-r--r--lib/puppet/provider/user/pw.rb2
-rw-r--r--lib/puppet/provider/user/user_role_add.rb34
-rw-r--r--lib/puppet/provider/user/useradd.rb48
-rw-r--r--lib/puppet/rails.rb14
-rw-r--r--lib/puppet/rails/host.rb72
-rw-r--r--lib/puppet/reference/configuration.rb90
-rw-r--r--lib/puppet/reference/indirection.rb9
-rw-r--r--lib/puppet/reference/metaparameter.rb27
-rw-r--r--lib/puppet/reference/network.rb8
-rw-r--r--lib/puppet/reference/providers.rb8
-rw-r--r--lib/puppet/reference/report.rb11
-rw-r--r--lib/puppet/reference/type.rb28
-rw-r--r--lib/puppet/reports/http.rb2
-rw-r--r--lib/puppet/reports/rrdgraph.rb19
-rw-r--r--lib/puppet/reports/store.rb4
-rw-r--r--lib/puppet/reports/tagmail.rb27
-rw-r--r--lib/puppet/resource.rb152
-rw-r--r--lib/puppet/resource/catalog.rb2
-rw-r--r--lib/puppet/resource/type.rb66
-rw-r--r--lib/puppet/resource/type_collection.rb115
-rw-r--r--lib/puppet/simple_graph.rb426
-rw-r--r--lib/puppet/ssl/certificate_request.rb2
-rw-r--r--lib/puppet/sslcertificates/ca.rb14
-rw-r--r--lib/puppet/transaction/report.rb39
-rw-r--r--lib/puppet/transaction/resource_harness.rb2
-rw-r--r--lib/puppet/type.rb198
-rw-r--r--lib/puppet/type/augeas.rb89
-rw-r--r--lib/puppet/type/computer.rb4
-rwxr-xr-xlib/puppet/type/cron.rb60
-rwxr-xr-xlib/puppet/type/exec.rb141
-rw-r--r--lib/puppet/type/file.rb50
-rwxr-xr-xlib/puppet/type/file/content.rb8
-rwxr-xr-xlib/puppet/type/file/ensure.rb26
-rwxr-xr-xlib/puppet/type/file/mode.rb12
-rw-r--r--lib/puppet/type/file/selcontext.rb10
-rwxr-xr-xlib/puppet/type/file/source.rb62
-rwxr-xr-xlib/puppet/type/filebucket.rb11
-rwxr-xr-xlib/puppet/type/group.rb3
-rwxr-xr-xlib/puppet/type/host.rb37
-rw-r--r--lib/puppet/type/k5login.rb6
-rw-r--r--lib/puppet/type/macauthorization.rb3
-rwxr-xr-xlib/puppet/type/mailalias.rb1
-rwxr-xr-xlib/puppet/type/maillist.rb1
-rw-r--r--lib/puppet/type/mcx.rb18
-rwxr-xr-xlib/puppet/type/mount.rb21
-rw-r--r--lib/puppet/type/notify.rb1
-rw-r--r--lib/puppet/type/package.rb70
-rw-r--r--lib/puppet/type/resources.rb6
-rwxr-xr-xlib/puppet/type/schedule.rb31
-rw-r--r--lib/puppet/type/selboolean.rb9
-rw-r--r--lib/puppet/type/selmodule.rb7
-rw-r--r--lib/puppet/type/service.rb20
-rw-r--r--lib/puppet/type/ssh_authorized_key.rb5
-rwxr-xr-xlib/puppet/type/sshkey.rb11
-rw-r--r--lib/puppet/type/stage.rb9
-rwxr-xr-xlib/puppet/type/tidy.rb17
-rwxr-xr-xlib/puppet/type/user.rb58
-rw-r--r--lib/puppet/type/whit.rb11
-rw-r--r--lib/puppet/type/yumrepo.rb19
-rwxr-xr-xlib/puppet/type/zfs.rb3
-rw-r--r--lib/puppet/type/zone.rb56
-rwxr-xr-xlib/puppet/type/zpool.rb15
-rw-r--r--lib/puppet/util.rb46
-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
208 files changed, 4190 insertions, 3931 deletions
diff --git a/lib/puppet.rb b/lib/puppet.rb
index 902f5bf5c..78fb5138b 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -24,7 +24,7 @@ require 'puppet/util/run_mode'
# it's also a place to find top-level commands like 'debug'
module Puppet
- PUPPETVERSION = '2.6.0'
+ PUPPETVERSION = '2.6.3'
def Puppet.version
PUPPETVERSION
diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb
index 52acc64aa..47dd44a0e 100644
--- a/lib/puppet/agent.rb
+++ b/lib/puppet/agent.rb
@@ -37,7 +37,9 @@ class Puppet::Agent
with_client do |client|
begin
sync.synchronize { lock { result = client.run(*args) } }
- rescue => detail
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not run #{client_class}: #{detail}"
end
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb
index 05b7d466f..f0159a65d 100644
--- a/lib/puppet/application.rb
+++ b/lib/puppet/application.rb
@@ -254,20 +254,6 @@ class Application
def preinit
end
- def option_parser
- return @option_parser if defined?(@option_parser)
-
- @option_parser = OptionParser.new(self.class.banner)
-
- self.class.option_parser_commands.each do |options, fname|
- @option_parser.on(*options) do |value|
- self.send(fname, value)
- end
- end
- @option_parser.default_argv = self.command_line.args
- @option_parser
- end
-
def initialize(command_line = nil)
require 'puppet/util/command_line'
@command_line = command_line || Puppet::Util::CommandLine.new
@@ -286,7 +272,7 @@ class Application
Puppet.settings.set_value(:name, Puppet.application_name.to_s, :mutable_defaults)
Puppet.settings.set_value(:logdir, Puppet.run_mode.logopts, :mutable_defaults)
Puppet.settings.set_value(:rundir, Puppet.run_mode.run_dir, :mutable_defaults)
- Puppet.settings.set_value(:mode, Puppet.run_mode.name.to_s, :mutable_defaults)
+ Puppet.settings.set_value(:run_mode, Puppet.run_mode.name.to_s, :mutable_defaults)
end
require 'puppet'
@@ -324,20 +310,29 @@ class Application
end
def parse_options
- # get all puppet options
- optparse_opt = []
- optparse_opt = Puppet.settings.optparse_addargs(optparse_opt)
+ # Create an option parser
+ option_parser = OptionParser.new(self.class.banner)
- # convert them to OptionParser format
- optparse_opt.each do |option|
- self.option_parser.on(*option) do |arg|
+ # Add all global options to it.
+ Puppet.settings.optparse_addargs([]).each do |option|
+ option_parser.on(*option) do |arg|
handlearg(option[0], arg)
end
end
- # scan command line argument
+ # Add options that are local to this application, which were
+ # created using the "option()" metaprogramming method. If there
+ # are any conflicts, this application's options will be favored.
+ self.class.option_parser_commands.each do |options, fname|
+ option_parser.on(*options) do |value|
+ # Call the method that "option()" created.
+ self.send(fname, value)
+ end
+ end
+
+ # scan command line.
begin
- self.option_parser.parse!
+ option_parser.parse!(self.command_line.args)
rescue OptionParser::ParseError => detail
$stderr.puts detail
$stderr.puts "Try 'puppet #{command_line.subcommand_name} --help'"
diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb
index f0e7f4d8f..c5ad72068 100644
--- a/lib/puppet/application/agent.rb
+++ b/lib/puppet/application/agent.rb
@@ -219,12 +219,18 @@ class Puppet::Application::Agent < Puppet::Application
Puppet.settings.use :main, :agent, :ssl
+ # Always ignoreimport for agent. It really shouldn't even try to import,
+ # but this is just a temporary band-aid.
+ Puppet[:ignoreimport] = true
+
# We need to specify a ca location for all of the SSL-related i
# indirected classes to work; in fingerprint mode we just need
# access to the local files and we don't need a ca.
Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote
Puppet::Transaction::Report.terminus_class = :rest
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
# Override the default; puppetd needs this, usually.
# You can still override this on the command-line with, e.g., :compiler.
diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb
index bb4186dbd..8ec3fab6b 100644
--- a/lib/puppet/application/apply.rb
+++ b/lib/puppet/application/apply.rb
@@ -78,7 +78,10 @@ class Puppet::Application::Apply < Puppet::Application
if options[:code] or command_line.args.length == 0
Puppet[:code] = options[:code] || STDIN.read
else
- Puppet[:manifest] = command_line.args.shift
+ manifest = command_line.args.shift
+ raise "Could not find file #{manifest}" unless File.exist?(manifest)
+ Puppet.warning("Only one file can be applied per run. Skipping #{command_line.args.join(', ')}") if command_line.args.size > 0
+ Puppet[:manifest] = manifest
end
# Collect our facts.
@@ -120,20 +123,9 @@ class Puppet::Application::Apply < Puppet::Application
require 'puppet/configurer'
configurer = Puppet::Configurer.new
- configurer.execute_prerun_command
-
- # And apply it
- transaction = catalog.apply
-
- configurer.execute_postrun_command
+ report = configurer.run(:skip_plugin_download => true, :catalog => catalog)
- status = 0
- if not Puppet[:noop] and options[:detailed_exitcodes]
- transaction.generate_report
- exit(transaction.report.exit_status)
- else
- exit(0)
- end
+ exit( Puppet[:noop] ? 0 : options[:detailed_exitcodes] ? report.exit_status : 0 )
rescue => detail
puts detail.backtrace if Puppet[:trace]
$stderr.puts detail.message
@@ -156,6 +148,9 @@ class Puppet::Application::Apply < Puppet::Application
exit(1)
end
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
+
if options[:debug]
Puppet::Util::Log.level = :debug
elsif options[:verbose]
diff --git a/lib/puppet/application/describe.rb b/lib/puppet/application/describe.rb
index 5abe3ea14..e76b347f6 100644
--- a/lib/puppet/application/describe.rb
+++ b/lib/puppet/application/describe.rb
@@ -130,7 +130,7 @@ class TypeDoc
a[0].to_s <=> b[0].to_s
}.each { |name, doc|
print "\n- **#{name}**"
- if type.namevar == name and name != :name
+ if type.key_attributes.include?(name) and name != :name
puts " (*namevar*)"
else
puts ""
diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb
index 66aa6c8a1..1f6c63286 100644
--- a/lib/puppet/application/doc.rb
+++ b/lib/puppet/application/doc.rb
@@ -56,7 +56,7 @@ class Puppet::Application::Doc < Puppet::Application
end
def run_command
- return[:rdoc, :trac, :markdown].include?(options[:mode]) ? send(options[:mode]) : other
+ return[:rdoc].include?(options[:mode]) ? send(options[:mode]) : other
end
def rdoc
@@ -72,7 +72,7 @@ class Puppet::Application::Doc < Puppet::Application
Puppet.settings.setdefaults(
"puppetdoc",
-
+
"document_all" => [false, "Document all resources"]
)
Puppet.settings[:document_all] = options[:all] || false
@@ -92,40 +92,6 @@ class Puppet::Application::Doc < Puppet::Application
exit exit_code
end
- def trac
- require 'puppet/util/reference'
- options[:references].each do |name|
- section = Puppet::Util::Reference.reference(name) or raise "Could not find section #{name}"
- section.trac unless options[:mode] == :pdf
- end
- end
-
- def markdown
- text = ""
- with_contents = false
- exit_code = 0
- require 'puppet/util/reference'
- options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name)
-
- begin
- # Add the per-section text, but with no ToC
- text += section.send(options[:format], with_contents)
- text += Puppet::Util::Reference.footer
- text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
- Puppet::Util::Reference.markdown(name, text)
- text = ""
- rescue => detail
- puts detail.backtrace
- $stderr.puts "Could not generate reference #{name}: #{detail}"
- exit_code = 1
- next
- end
- end
-
- exit exit_code
- end
-
def other
text = ""
with_contents = options[:references].length <= 1
diff --git a/lib/puppet/application/master.rb b/lib/puppet/application/master.rb
index 777a50eaa..fde474907 100644
--- a/lib/puppet/application/master.rb
+++ b/lib/puppet/application/master.rb
@@ -138,9 +138,6 @@ class Puppet::Application::Master < Puppet::Application
Puppet.settings.use :main, :master, :ssl
- # A temporary solution, to at least make the master work for now.
- Puppet::Node::Facts.terminus_class = :yaml
-
# Cache our nodes in yaml. Currently not configurable.
Puppet::Node.cache_class = :yaml
diff --git a/lib/puppet/application/queue.rb b/lib/puppet/application/queue.rb
index 6df825dd1..239f6b2ad 100644
--- a/lib/puppet/application/queue.rb
+++ b/lib/puppet/application/queue.rb
@@ -38,6 +38,7 @@ class Puppet::Application::Queue < Puppet::Application
option("--verbose","-v")
def main
+ require 'puppet/indirector/catalog/queue' # provides Puppet::Indirector::Queue.subscribe
Puppet.notice "Starting puppetqd #{Puppet.version}"
Puppet::Resource::Catalog::Queue.subscribe do |catalog|
# Once you have a Puppet::Resource::Catalog instance, calling save on it should suffice
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index 327955b03..1c0639029 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -77,12 +77,12 @@ class Puppet::Configurer
end
# Prepare for catalog retrieval. Downloads everything necessary, etc.
- def prepare
+ def prepare(options)
dostorage
- download_plugins
+ download_plugins unless options[:skip_plugin_download]
- download_fact_plugins
+ download_fact_plugins unless options[:skip_plugin_download]
execute_prerun_command
end
@@ -126,7 +126,7 @@ class Puppet::Configurer
# which accepts :tags and :ignoreschedules.
def run(options = {})
begin
- prepare
+ prepare(options)
rescue SystemExit,NoMemoryError
raise
rescue Exception => detail
@@ -158,25 +158,40 @@ class Puppet::Configurer
return
end
ensure
+ # Make sure we forget the retained module_directories of any autoload
+ # we might have used.
+ Thread.current[:env_module_directories] = nil
+
# Now close all of our existing http connections, since there's no
# reason to leave them lying open.
Puppet::Network::HttpPool.clear_http_instances
execute_postrun_command
Puppet::Util::Log.close(report)
-
send_report(report, transaction)
end
def send_report(report, trans = nil)
trans.generate_report if trans
puts report.summary if Puppet[:summarize]
- report.save if Puppet[:report]
+ save_last_run_summary(report)
+ if Puppet[:report]
+ report.save
+ end
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not send report: #{detail}"
end
+ def save_last_run_summary(report)
+ Puppet::Util::FileLocking.writelock(Puppet[:lastrunfile], 0660) do |file|
+ file.print YAML.dump(report.raw_summary)
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not save last run local report: #{detail}"
+ end
+
private
def self.timeout
diff --git a/lib/puppet/daemon.rb b/lib/puppet/daemon.rb
index aa4a12bfa..c76d63a54 100755
--- a/lib/puppet/daemon.rb
+++ b/lib/puppet/daemon.rb
@@ -43,7 +43,7 @@ class Puppet::Daemon
# Create a pidfile for our daemon, so we can be stopped and others
# don't try to start.
def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
end
end
@@ -73,7 +73,7 @@ class Puppet::Daemon
# Remove the pid file for our daemon.
def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
locker = Puppet::Util::Pidlock.new(pidfile)
locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
end
@@ -121,8 +121,8 @@ class Puppet::Daemon
create_pidfile
raise Puppet::DevError, "Daemons must have an agent, server, or both" unless agent or server
- agent.start if agent
server.start if server
+ agent.start if agent
EventLoop.current.run
end
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 84e2d93fc..8bf1cd84d 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -2,12 +2,12 @@
module Puppet
setdefaults(:main,
:confdir => [Puppet.run_mode.conf_dir, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process
- is running as root or the user that ``puppet master`` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
- it defaults to being in ``~``."],
+ is running as root or the user that `puppet master` is supposed to run as, it defaults to a system directory, but if it's running as any other user,
+ it defaults to being in `~`."],
:vardir => [Puppet.run_mode.var_dir, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."],
:name => [Puppet.application_name.to_s, "The name of the application, if we are running as one. The
- default is essentially $0 without the path or ``.rb``."],
- :mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
+ default is essentially $0 without the path or `.rb`."],
+ :run_mode => [Puppet.run_mode.name.to_s, "The effective 'run mode' of the application: master, agent, or user."]
)
setdefaults(:main, :logdir => Puppet.run_mode.logopts)
@@ -44,8 +44,8 @@ module Puppet
specify 'all'. This feature is only available in Puppet versions
higher than 0.18.4."],
: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
+ 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 puppet agent will
@@ -92,18 +92,18 @@ module Puppet
:authconfig => [ "$confdir/namespaceauth.conf",
"The configuration file that defines the rights to the different
namespaces and methods. This can be used as a coarse-grained
- authorization system for both ``puppet agent`` and ``puppet master``."
+ authorization system for both `puppet agent` and `puppet master`."
],
:environment => {:default => "production", :desc => "The environment Puppet is running in. For clients
- (e.g., ``puppet agent``) this determines the environment itself, which
- is used to find modules and much more. For servers (i.e., ``puppet master``) this provides the default environment for nodes
+ (e.g., `puppet agent`) this determines the environment itself, which
+ is used to find modules and much more. For servers (i.e., `puppet master`) this provides the default environment for nodes
we know nothing about."
},
:diff_args => ["-u", "Which arguments to pass to the diff command when printing differences between files."],
:diff => ["diff", "Which diff command to use when printing differences between files."],
:show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff
is printed on stdout, so this option is meaningless unless you are running Puppet interactively.
- This feature currently requires the ``diff/lcs`` Ruby library."],
+ This feature currently requires the `diff/lcs` Ruby library."],
:daemonize => { :default => true,
:desc => "Send the process into the background. This is the default.",
:short => "D"
@@ -115,7 +115,17 @@ module Puppet
:node_terminus => ["plain", "Where to find information about nodes."],
:catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
- :facts_terminus => ["facter", "Where to get node facts."],
+ :facts_terminus => {
+ :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter',
+ :desc => "The node facts terminus.",
+ :hook => proc do |value|
+ require 'puppet/node/facts'
+ if value.to_s == "rest"
+ Puppet::Node::Facts.cache_class = :yaml
+ end
+ end
+ },
+ :inventory_terminus => [ "$facts_terminus", "Should usually be the same as the facts terminus" ],
:httplog => { :default => "$logdir/http.log",
:owner => "root",
:mode => 0640,
@@ -135,7 +145,7 @@ module Puppet
:queue_source => ["stomp://localhost:61613/", "Which type of queue to use for asynchronous processing. If your stomp server requires
authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1"],
:async_storeconfigs => {:default => false, :desc => "Whether to use a queueing system to provide asynchronous database integration.
- Requires that ``puppetqd`` be running and that 'PSON' support for ruby be installed.",
+ Requires that `puppetqd` be running and that 'PSON' support for ruby be installed.",
:hook => proc do |value|
if value
# This reconfigures the terminii for Node, Facts, and Catalog
@@ -266,10 +276,9 @@ module Puppet
to all clients. If enabled, CA chaining will almost definitely not work."]
)
-
setdefaults(
:ca,
- :ca_name => ["$certname", "The name to use the Certificate Authority certificate."],
+ :ca_name => ["Puppet CA: $certname", "The name to use the Certificate Authority certificate."],
:cadir => { :default => "$ssldir/ca",
:owner => "service",
:group => "service",
@@ -385,7 +394,7 @@ module Puppet
:manifestdir => ["$confdir/manifests", "Where puppet master looks for its manifests."],
:manifest => ["$manifestdir/site.pp", "The entry-point manifest for puppet master."],
:code => ["", "Code to parse directly. This is essentially only used
- by ``puppet``, and should only be set if you're writing your own Puppet
+ by `puppet`, and should only be set if you're writing your own Puppet
executable"],
:masterlog => { :default => "$logdir/puppetmaster.log",
:owner => "service",
@@ -419,7 +428,7 @@ module Puppet
:rest_authconfig => [ "$confdir/auth.conf",
"The configuration file that defines the rights to the different
rest indirections. This can be used as a fine-grained
- authorization system for ``puppet master``."
+ authorization system for `puppet master`."
],
:ca => [true, "Wether the master should function as a certificate authority."],
:modulepath => {:default => "$confdir/modules:/usr/share/puppet/modules",
@@ -427,7 +436,7 @@ module Puppet
directories.", :type => :setting }, # We don't want this to be considered a file, since it's multiple files.
:ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
client's SSL DN. Only used with Mongrel. This header must be set by the proxy
- to the authenticated client's SSL DN (e.g., ``/CN=puppet.puppetlabs.com``).
+ to the authenticated client's SSL DN (e.g., `/CN=puppet.puppetlabs.com`).
See http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel for more information."],
:ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
message of the client verification. Only used with Mongrel. This header must be set by the proxy
@@ -441,10 +450,25 @@ module Puppet
:desc => "The directory in which serialized data is stored, usually in a subdirectory."},
:reports => ["store",
"The list of reports to generate. All reports are looked for
- in puppet/reports/name.rb, and multiple report names should be
+ in `puppet/reports/name.rb`, and multiple report names should be
comma-separated (whitespace is okay)."
],
+ :reportdir => {:default => "$vardir/reports",
+ :mode => 0750,
+ :owner => "service",
+ :group => "service",
+ :desc => "The directory in which to store reports
+ received from the client. Each client gets a separate
+ subdirectory."},
+ :reporturl => ["http://localhost:3000/reports",
+ "The URL used by the http reports processor to send reports"],
:fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."],
+ :strict_hostname_checking => [false, "Whether to only search for the complete
+ hostname as it is in the certificate when searching for node information
+ in the catalogs."]
+ )
+
+ setdefaults(:metrics,
:rrddir => {:default => "$vardir/rrd",
:owner => "service",
:group => "service",
@@ -453,10 +477,7 @@ module Puppet
this directory."
},
:rrdinterval => ["$runinterval", "How often RRD should expect data.
- This should match how often the hosts report back to the server."],
- :strict_hostname_checking => [false, "Whether to only search for the complete
- hostname as it is in the certificate when searching for node information
- in the catalogs."]
+ This should match how often the hosts report back to the server."]
)
setdefaults(:agent,
@@ -479,7 +500,7 @@ module Puppet
:mode => 0644,
:desc => "The file in which puppet agent stores a list of the classes
associated with the retrieved configuration. Can be loaded in
- the separate ``puppet`` executable using the ``--loadclasses``
+ the separate `puppet` executable using the `--loadclasses`
option."},
:puppetdlog => { :default => "$logdir/puppetd.log",
:owner => "root",
@@ -496,8 +517,8 @@ module Puppet
"How often puppet agent applies the client configuration; in seconds."],
:listen => [false, "Whether puppet agent should listen for
connections. If this is true, then by default only the
- ``runner`` server is started, which allows remote authorized
- and authenticated nodes to connect and trigger ``puppet agent``
+ `runner` server is started, which allows remote authorized
+ and authenticated nodes to connect and trigger `puppet agent`
runs."],
:ca_server => ["$server", "The server to use for certificate
authority requests. It's a separate server because it cannot
@@ -567,14 +588,28 @@ module Puppet
end
},
:report_server => ["$server",
- "The server to which to send transaction reports."
+ "The server to send transaction reports to."
],
:report_port => ["$masterport",
"The port to communicate with the report_server."
],
- :report => [false,
+ :inventory_server => ["$server",
+ "The server to send facts to."
+ ],
+ :inventory_port => ["$masterport",
+ "The port to communicate with the inventory_server."
+ ],
+ :report => [true,
"Whether to send reports after every transaction."
],
+ :lastrunfile => { :default => "$statedir/last_run_summary.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report summary in yaml format."
+ },
+ :lastrunreport => { :default => "$statedir/last_run_report.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report in yaml format."
+ },
:graph => [false, "Whether to create dot graph files for the different
configuration graphs. These dot files can be interpreted by tools
like OmniGraffle or dot (which is part of ImageMagick)."],
@@ -595,7 +630,7 @@ module Puppet
"Where Puppet should store plugins that it pulls down from the central
server."],
:pluginsource => ["puppet://$server/plugins",
- "From where to retrieve plugins. The standard Puppet ``file`` type
+ "From where to retrieve plugins. The standard Puppet `file` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:pluginsync => [false, "Whether plugins should be synced with the central server."],
@@ -607,7 +642,7 @@ module Puppet
setdefaults(
:main,
- :factpath => {:default => "$vardir/lib/facter/${File::PATH_SEPARATOR}$vardir/facts",
+ :factpath => {:default => "$vardir/lib/facter:$vardir/facts",
:desc => "Where Puppet should look for facts. Multiple directories should
be colon-separated, like normal PATH variables.",
@@ -618,33 +653,23 @@ module Puppet
"Where Puppet should store facts that it pulls down from the central
server."],
:factsource => ["puppet://$server/facts/",
- "From where to retrieve facts. The standard Puppet ``file`` type
+ "From where to retrieve facts. The standard Puppet `file` type
is used for retrieval, so anything that is a valid file source can
be used here."],
:factsync => [false, "Whether facts should be synced with the central server."],
- :factsignore => [".svn CVS", "What files to ignore when pulling down facts."],
- :reportdir => {:default => "$vardir/reports",
- :mode => 0750,
- :owner => "service",
- :group => "service",
- :desc => "The directory in which to store reports
- received from the client. Each client gets a separate
- subdirectory."},
- :reporturl => ["http://localhost:3000/reports",
- "The URL used by the http reports processor to send reports"]
+ :factsignore => [".svn CVS", "What files to ignore when pulling down facts."]
)
setdefaults(
:tagmail,
:tagmap => ["$confdir/tagmail.conf", "The mapping between reporting tags and email addresses."],
- :sendmail => [%x{which sendmail 2>/dev/null}.chomp, "Where to find the sendmail binary with which to send email."],
+ :sendmail => [which('sendmail') || '', "Where to find the sendmail binary with which to send email."],
:reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."), "The 'from' email address for the reports."],
:smtpserver => ["none", "The server through which to send email reports."]
)
-
setdefaults(
:rails,
:dblocation => { :default => "$statedir/clientconfigs.sqlite3",
@@ -665,11 +690,10 @@ module Puppet
used when networked databases are used."],
:dbpassword => [ "puppet", "The database password for caching. Only
used when networked databases are used."],
+ :dbconnections => [ '', "The number of database connections for networked
+ databases. Will be ignored unless the value is a positive integer."],
:dbsocket => [ "", "The database socket location. Only used when networked
databases are used. Will be ignored if the value is an empty string."],
- :dbconnections => [ 0, "The number of database connections. Only used when
- networked databases are used. Will be ignored if the value is an empty
- string or is less than 1."],
:railslog => {:default => "$logdir/rails.log",
:mode => 0600,
:owner => "service",
@@ -678,18 +702,16 @@ module Puppet
},
:rails_loglevel => ["info", "The log level for Rails connections. The value must be
- a valid log level within Rails. Production environments normally use ``info``
- and other environments normally use ``debug``."]
+ a valid log level within Rails. Production environments normally use `info`
+ and other environments normally use `debug`."]
)
-
setdefaults(
:couchdb,
:couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"]
)
-
setdefaults(
:transaction,
:tags => ["", "Tags to use to find resources. If this is set, then
@@ -704,21 +726,19 @@ module Puppet
]
)
-
setdefaults(
:main,
:external_nodes => ["none",
"An external command that can produce node information. The output
must be a YAML dump of a hash, and that hash must have one or both of
- ``classes`` and ``parameters``, where ``classes`` is an array and
- ``parameters`` is a hash. For unknown nodes, the commands should
+ `classes` and `parameters`, where `classes` is an array and
+ `parameters` is a hash. For unknown nodes, the commands should
exit with a non-zero exit code.
This command makes it straightforward to store your node mapping
information in other data sources like databases."])
-
setdefaults(
:ldap,
:ldapnodes => [false,
@@ -733,9 +753,9 @@ module Puppet
Defaults to false because TLS usually requires certificates
to be set up on the client side."],
:ldapserver => ["ldap",
- "The LDAP server. Only used if ``ldapnodes`` is enabled."],
+ "The LDAP server. Only used if `ldapnodes` is enabled."],
:ldapport => [389,
- "The LDAP port. Only used if ``ldapnodes`` is enabled."],
+ "The LDAP port. Only used if `ldapnodes` is enabled."],
:ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
"The search string used to find an LDAP node."],
diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb
index abdb78f67..97a310436 100644
--- a/lib/puppet/dsl.rb
+++ b/lib/puppet/dsl.rb
@@ -5,7 +5,3 @@ end
require 'puppet/dsl/resource_type_api'
require 'puppet/dsl/resource_api'
-
-class Object
- include Puppet::DSL::ResourceTypeAPI
-end
diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb
index 487aab99d..8810d5368 100644
--- a/lib/puppet/dsl/resource_type_api.rb
+++ b/lib/puppet/dsl/resource_type_api.rb
@@ -1,34 +1,15 @@
require 'puppet/resource/type'
-module Puppet::DSL::ResourceTypeAPI
- def define(name, *args, &block)
- result = mk_resource_type(:definition, name, Hash.new, block)
- result.set_arguments(munge_type_arguments(args))
- result
- end
-
- def hostclass(name, options = {}, &block)
- mk_resource_type(:hostclass, name, options, block)
- end
-
- def node(name, options = {}, &block)
- mk_resource_type(:node, name, options, block)
- end
-
- private
-
- def mk_resource_type(type, name, options, code)
- klass = Puppet::Resource::Type.new(type, name, options)
-
- klass.ruby_code = code if code
-
- Puppet::Node::Environment.new.known_resource_types.add klass
-
- klass
+# Type of the objects inside of which pure ruby manifest files are
+# executed. Provides methods for creating defines, hostclasses, and
+# nodes.
+class Puppet::DSL::ResourceTypeAPI
+ def initialize
+ @__created_ast_objects__ = []
end
- def munge_type_arguments(args)
- args.inject([]) do |result, item|
+ def define(name, *args, &block)
+ args = args.inject([]) do |result, item|
if item.is_a?(Hash)
item.each { |p, v| result << [p, v] }
else
@@ -36,5 +17,18 @@ module Puppet::DSL::ResourceTypeAPI
end
result
end
+ @__created_ast_objects__.push Puppet::Parser::AST::Definition.new(name, {:arguments => args}, &block)
+ nil
+ end
+
+ def hostclass(name, options = {}, &block)
+ @__created_ast_objects__.push Puppet::Parser::AST::Hostclass.new(name, options, &block)
+ nil
+ end
+
+ def node(name, options = {}, &block)
+ name = [name] unless name.is_a?(Array)
+ @__created_ast_objects__.push Puppet::Parser::AST::Node.new(name, options, &block)
+ nil
end
end
diff --git a/lib/puppet/external/event-loop/event-loop.rb b/lib/puppet/external/event-loop/event-loop.rb
index dc51a55ae..3b40f6e71 100644
--- a/lib/puppet/external/event-loop/event-loop.rb
+++ b/lib/puppet/external/event-loop/event-loop.rb
@@ -75,8 +75,10 @@ class EventLoop
@notify_src, @notify_snk = IO.pipe
# prevent file descriptor leaks
- @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ if @notify_src.respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_SETFD) and defined?(Fcntl::FD_CLOEXEC)
+ @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ end
@notify_src.will_block = false
@notify_snk.will_block = false
@@ -234,19 +236,21 @@ class IO
end
def will_block?
- require "fcntl"
- fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK)
+ fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ end
end
def will_block= (wants_blocking)
- require "fcntl"
- flags = fcntl(Fcntl::F_GETFL, 0)
- if wants_blocking
- flags &= ~Fcntl::O_NONBLOCK
- else
- flags |= Fcntl::O_NONBLOCK
+ if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK)
+ flags = fcntl(Fcntl::F_GETFL, 0)
+ if wants_blocking
+ flags &= ~Fcntl::O_NONBLOCK
+ else
+ flags |= Fcntl::O_NONBLOCK
+ end
+ fcntl(Fcntl::F_SETFL, flags)
end
- fcntl(Fcntl::F_SETFL, flags)
end
end
diff --git a/lib/puppet/external/pson/pure/generator.rb b/lib/puppet/external/pson/pure/generator.rb
index ef8b36d31..89a0c62e0 100644
--- a/lib/puppet/external/pson/pure/generator.rb
+++ b/lib/puppet/external/pson/pure/generator.rb
@@ -44,41 +44,13 @@ module PSON
string << '' # XXX workaround: avoid buffer sharing
string.force_encoding(Encoding::ASCII_8BIT)
string.gsub!(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string.force_encoding(Encoding::UTF_8)
string
rescue Iconv::Failure => e
raise GeneratorError, "Caught #{e.class}: #{e}"
end
else
def utf8_to_pson(string) # :nodoc:
- string = string.gsub(/["\\\x0-\x1f]/) { MAP[$MATCH] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = PSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$MATCH] }
end
end
module_function :utf8_to_pson
diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb
index c153fba98..c983f5c12 100644
--- a/lib/puppet/feature/base.rb
+++ b/lib/puppet/feature/base.rb
@@ -27,7 +27,8 @@ Puppet.features.add :diff, :libs => %w{diff/lcs diff/lcs/hunk}
Puppet.features.add(:augeas, :libs => ["augeas"])
# We have RRD available
-Puppet.features.add(:rrd, :libs => ["RRDtool"])
+Puppet.features.add(:rrd_legacy, :libs => ["RRDtool"])
+Puppet.features.add(:rrd, :libs => ["RRD"])
# We have OpenSSL
Puppet.features.add(:openssl, :libs => ["openssl"])
diff --git a/lib/puppet/feature/rails.rb b/lib/puppet/feature/rails.rb
index e0e14ebeb..74ed09aa6 100644
--- a/lib/puppet/feature/rails.rb
+++ b/lib/puppet/feature/rails.rb
@@ -24,9 +24,7 @@ Puppet.features.add(:rails) do
end
end
- if ! (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
- false
- elsif ! (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR >= 1)
+ unless (Puppet::Util.activerecord_version >= 2.1)
Puppet.info "ActiveRecord 2.1 or later required for StoreConfigs"
false
else
diff --git a/lib/puppet/file_serving/indirection_hooks.rb b/lib/puppet/file_serving/indirection_hooks.rb
index 7e0c17916..a85e90ef1 100644
--- a/lib/puppet/file_serving/indirection_hooks.rb
+++ b/lib/puppet/file_serving/indirection_hooks.rb
@@ -19,8 +19,8 @@ module Puppet::FileServing::IndirectionHooks
return PROTOCOL_MAP["file"] if request.key =~ /^#{::File::SEPARATOR}/
return PROTOCOL_MAP["file"] if request.protocol == "file"
- # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'puppet'
- if request.protocol == "puppet" and (request.server or Puppet.settings[:name] != "puppet")
+ # We're heading over the wire the protocol is 'puppet' and we've got a server name or we're not named 'apply' or 'puppet'
+ if request.protocol == "puppet" and (request.server or !["puppet","apply"].include?(Puppet.settings[:name]))
return PROTOCOL_MAP["puppet"]
end
diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb
index c50022fff..78be4caf7 100644
--- a/lib/puppet/indirector/catalog/compiler.rb
+++ b/lib/puppet/indirector/catalog/compiler.rb
@@ -22,6 +22,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
else
facts = Puppet::Node::Facts.convert_from(format, text_facts)
end
+ facts.add_timestamp
facts.save
end
@@ -107,10 +108,14 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
return node
end
- # If the request is authenticated, then the 'node' info will
- # be available; if not, then we use the passed-in key. We rely
- # on our authorization system to determine whether this is allowed.
- name = request.node || request.key
+ # We rely on our authorization system to determine whether the connected
+ # node is allowed to compile the catalog's node referenced by key.
+ # By default the REST authorization system makes sure only the connected node
+ # can compile his catalog.
+ # This allows for instance monitoring systems or puppet-load to check several
+ # node's catalog with only one certificate and a modification to auth.conf
+ # If no key is provided we can only compile the currently connected node.
+ name = request.key || request.node
if node = find_node(name)
return node
end
diff --git a/lib/puppet/indirector/facts/memory.rb b/lib/puppet/indirector/facts/memory.rb
index c4ca19da5..93682f456 100644
--- a/lib/puppet/indirector/facts/memory.rb
+++ b/lib/puppet/indirector/facts/memory.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/memory'
class Puppet::Node::Facts::Memory < Puppet::Indirector::Memory
desc "Keep track of facts in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
+ one-time compiles, such as what the stand-alone `puppet` does.
To use this terminus, you must load it with the data you want it
to contain."
end
diff --git a/lib/puppet/indirector/facts/rest.rb b/lib/puppet/indirector/facts/rest.rb
index 07491fc77..e2afa14b2 100644
--- a/lib/puppet/indirector/facts/rest.rb
+++ b/lib/puppet/indirector/facts/rest.rb
@@ -3,4 +3,6 @@ require 'puppet/indirector/rest'
class Puppet::Node::Facts::Rest < Puppet::Indirector::REST
desc "Find and save facts about nodes over HTTP via REST."
+ use_server_setting(:inventory_server)
+ use_port_setting(:inventory_port)
end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 309eed7b6..9095e48f8 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -238,6 +238,7 @@ class Puppet::Indirector::Indirection
if result = terminus.search(request)
raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array)
result.each do |instance|
+ next unless instance.respond_to? :expiration
instance.expiration ||= self.expiration
end
return result
diff --git a/lib/puppet/indirector/inventory/yaml.rb b/lib/puppet/indirector/inventory/yaml.rb
new file mode 100644
index 000000000..fe3489a95
--- /dev/null
+++ b/lib/puppet/indirector/inventory/yaml.rb
@@ -0,0 +1,81 @@
+require 'puppet/node/inventory'
+require 'puppet/indirector/yaml'
+
+class Puppet::Node::Inventory::Yaml < Puppet::Indirector::Yaml
+ desc "Return node names matching the fact query"
+
+ # Return the path to a given node's file.
+ def yaml_dir_path
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, 'facts', '*.yaml')
+ end
+
+ def node_matches?(facts, options)
+ options.each do |key, value|
+ type, name, operator = key.to_s.split(".")
+ operator ||= 'eq'
+
+ return false unless node_matches_option?(type, name, operator, value, facts)
+ end
+ return true
+ end
+
+ def search(request)
+ node_names = []
+ Dir.glob(yaml_dir_path).each do |file|
+ facts = YAML.load_file(file)
+ node_names << facts.name if node_matches?(facts, request.options)
+ end
+ node_names
+ end
+
+ private
+
+ def node_matches_option?(type, name, operator, value, facts)
+ case type
+ when "meta"
+ case name
+ when "timestamp"
+ compare_timestamp(operator, facts.timestamp, Time.parse(value))
+ end
+ when "facts"
+ compare_facts(operator, facts.values[name], value)
+ end
+ end
+
+ def compare_facts(operator, value1, value2)
+ return false unless value1
+
+ case operator
+ when "eq"
+ value1.to_s == value2.to_s
+ when "le"
+ value1.to_f <= value2.to_f
+ when "ge"
+ value1.to_f >= value2.to_f
+ when "lt"
+ value1.to_f < value2.to_f
+ when "gt"
+ value1.to_f > value2.to_f
+ when "ne"
+ value1.to_s != value2.to_s
+ end
+ end
+
+ def compare_timestamp(operator, value1, value2)
+ case operator
+ when "eq"
+ value1 == value2
+ when "le"
+ value1 <= value2
+ when "ge"
+ value1 >= value2
+ when "lt"
+ value1 < value2
+ when "gt"
+ value1 > value2
+ when "ne"
+ value1 != value2
+ end
+ end
+end
diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb
index c3e690943..6e065c6f3 100644
--- a/lib/puppet/indirector/node/exec.rb
+++ b/lib/puppet/indirector/node/exec.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/exec'
class Puppet::Node::Exec < Puppet::Indirector::Exec
desc "Call an external program to get node information. See
- the `ExternalNodes`:trac: page for more information."
+ the [External Nodes](http://docs.puppetlabs.com/guides/external_nodes.html) page for more information."
include Puppet::Util
def command
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index b9fe35575..5fd738511 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -3,9 +3,9 @@ require 'puppet/indirector/ldap'
class Puppet::Node::Ldap < Puppet::Indirector::Ldap
desc "Search in LDAP for node configuration information. See
- the `LdapNodes`:trac: page for more information. This will first
+ the [LDAP Nodes](http://projects.puppetlabs.com/projects/puppet/wiki/Ldap_Nodes) page for more information. This will first
search for whatever the certificate name is, then (if that name
- contains a '.') for the short name, then 'default'."
+ contains a `.`) for the short name, then `default`."
# The attributes that Puppet class information is stored in.
def class_attributes
@@ -19,30 +19,10 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
# but LDAP::ResultError, even on bad connections, so we are rough handed
# with our error handling.
- def name2hash(name,name_env,node_type)
+ def name2hash(name)
info = nil
- ldapsearch(search_filter(name)) {
- |entry| info = entry2hash(entry)
- if info[:environment]
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- else
- info_env = "production"
- if name_env == info[:environment]
- return info
- else
- info = nil
- end
- end
- }
- if node_type == 'parent'
- raise Puppet::Error.new("Could not find node '#{name}' with environment '#{name_env}'")
- end
-
- info = name2hash('default',name_env,'parent')
+ ldapsearch(search_filter(name)) { |entry| info = entry2hash(entry) }
+ info
end
# Look for our node in ldap.
@@ -53,18 +33,9 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
node = nil
names.each do |name|
- facts = Puppet::Node::Facts.find(name)
- if facts.values["environment"]
- name_env = facts.values["environment"]
- else
- name_env = "production"
- end
- info = name2hash(name,name_env,'child')
- next if info == nil
+ next unless info = name2hash(name)
- if info
- break if node = info2node(request.key, info)
- end
+ break if node = info2node(request.key, info)
end
node
@@ -200,29 +171,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# Find information for our parent and merge it into the current info.
def find_and_merge_parent(parent, information)
-
- if information[:environment]
- name_env = information[:environment]
- else
- name_env = 'production'
- end
-
- parent_info = name2hash(parent,name_env,'parent')
- if parent_info
+ parent_info = name2hash(parent) || raise(Puppet::Error.new("Could not find parent node '#{parent}'"))
information[:classes] += parent_info[:classes]
parent_info[:parameters].each do |param, value|
- # Specifically test for whether it's set, so false values are handled
- # correctly.
+ # Specifically test for whether it's set, so false values are handled correctly.
information[:parameters][param] = value unless information[:parameters].include?(param)
end
-
information[:environment] ||= parent_info[:environment]
parent_info[:parent]
- else
- raise Puppet::Error.new("Could not find parent node '#{parent}'")
- nil
- end
-
end
# Take a name and a hash, and return a node instance.
diff --git a/lib/puppet/indirector/node/memory.rb b/lib/puppet/indirector/node/memory.rb
index ce4a52a8f..029926af8 100644
--- a/lib/puppet/indirector/node/memory.rb
+++ b/lib/puppet/indirector/node/memory.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/memory'
class Puppet::Node::Memory < Puppet::Indirector::Memory
desc "Keep track of nodes in memory but nowhere else. This is used for
- one-time compiles, such as what the stand-alone ``puppet`` does.
+ one-time compiles, such as what the stand-alone `puppet` does.
To use this terminus, you must load it with the data you want it
to contain; it is only useful for developers and should generally not
be chosen by a normal user."
diff --git a/lib/puppet/indirector/report/yaml.rb b/lib/puppet/indirector/report/yaml.rb
new file mode 100644
index 000000000..bf7bf4fe5
--- /dev/null
+++ b/lib/puppet/indirector/report/yaml.rb
@@ -0,0 +1,11 @@
+require 'puppet/transaction/report'
+require 'puppet/indirector/yaml'
+
+class Puppet::Transaction::Report::Yaml < Puppet::Indirector::Yaml
+ desc "Store last report as a flat file, serialized using YAML."
+
+ # Force report to be saved there
+ def path(name,ext='.yaml')
+ Puppet[:lastrunreport]
+ end
+end
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index c7c053f4b..23997e97a 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -41,19 +41,16 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
end
end
- # Get the yaml directory
- def base
- Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
- end
-
# Return the path to a given node's file.
- def path(name)
- File.join(base, self.class.indirection_name.to_s, name.to_s + ".yaml")
+ def path(name,ext='.yaml')
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
end
- # Do a glob on the yaml directory, loading each file found
def search(request)
- Dir.glob(File.join(base, self.class.indirection_name.to_s, request.key)).collect { |f| YAML.load_file(f) }
+ Dir.glob(path(request.key,'')).collect do |file|
+ YAML.load_file(file)
+ end
end
private
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index d378ad6a1..b94a4f902 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -37,6 +37,12 @@ module Puppet::Network::FormatHandler
instance
end
+ def self.create_serialized_formats(name,options = {},&block)
+ ["application/x-#{name}", "application/#{name}", "text/x-#{name}", "text/#{name}"].each { |mime_type|
+ create name, {:mime => mime_type}.update(options), &block
+ }
+ end
+
def self.extended(klass)
klass.extend(ClassMethods)
diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index 8a61ee62a..4ca3240d4 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -1,6 +1,6 @@
require 'puppet/network/format_handler'
-Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
+Puppet::Network::FormatHandler.create_serialized_formats(:yaml) do
# Yaml doesn't need the class name; it's serialized.
def intern(klass, text)
YAML.load(text)
@@ -29,7 +29,7 @@ end
# This is a "special" format which is used for the moment only when sending facts
# as REST GET parameters (see Puppet::Configurer::FactHandler).
# This format combines a yaml serialization, then zlib compression and base64 encoding.
-Puppet::Network::FormatHandler.create(:b64_zlib_yaml, :mime => "text/b64_zlib_yaml") do
+Puppet::Network::FormatHandler.create_serialized_formats(:b64_zlib_yaml) do
require 'base64'
def use_zlib?
@@ -127,7 +127,7 @@ Puppet::Network::FormatHandler.create(:raw, :mime => "application/x-raw", :weigh
end
end
-Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10, :required_methods => [:render_method, :intern_method]) do
+Puppet::Network::FormatHandler.create_serialized_formats(:pson, :weight => 10, :required_methods => [:render_method, :intern_method]) do
confine :true => Puppet.features.pson?
def intern(klass, text)
@@ -159,4 +159,4 @@ Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10
end
# This is really only ever going to be used for Catalogs.
-Puppet::Network::FormatHandler.create(:dot, :mime => "text/dot", :required_methods => [:render_method])
+Puppet::Network::FormatHandler.create_serialized_formats(:dot, :required_methods => [:render_method])
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index 27b913ab9..9abc7ee1a 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -4,9 +4,13 @@ require 'webrick/httpstatus'
require 'cgi'
require 'delegate'
require 'sync'
+require 'xmlrpc/server'
+require 'puppet/network/handler'
+require 'puppet/network/xmlrpc/server'
require 'puppet/file_serving'
require 'puppet/file_serving/metadata'
+require 'puppet/network/handler'
class Puppet::Network::Handler
AuthStoreError = Puppet::AuthStoreError
diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb
index dd4612a14..abbb2dfa9 100644
--- a/lib/puppet/network/http/api/v1.rb
+++ b/lib/puppet/network/http/api/v1.rb
@@ -30,7 +30,7 @@ module Puppet::Network::HTTP::API::V1
key = URI.unescape(key)
- Puppet::Indirector::Request.new(indirection, method, key, params)
+ [indirection, method, key, params]
end
def indirection2uri(request)
@@ -57,9 +57,8 @@ module Puppet::Network::HTTP::API::V1
# fix to not need this, and our goal is to move away from the complication
# that leads to the fix being too long.
return :singular if indirection == "facts"
-
- # "status" really is singular
return :singular if indirection == "status"
+ return :plural if indirection == "inventory"
result = (indirection =~ /s$/) ? :plural : :singular
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 03d24b3fe..82238aa0a 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -61,11 +61,11 @@ module Puppet::Network::HTTP::Handler
# handle an HTTP request
def process(request, response)
- indirection_request = uri2indirection(http_method(request), path(request), params(request))
+ indirection, method, key, params = uri2indirection(http_method(request), path(request), params(request))
- check_authorization(indirection_request)
+ check_authorization(indirection, method, key, params)
- send("do_#{indirection_request.method}", indirection_request, request, response)
+ send("do_#{method}", indirection, key, params, request, response)
rescue SystemExit,NoMemoryError
raise
rescue Exception => e
@@ -96,11 +96,16 @@ module Puppet::Network::HTTP::Handler
set_response(response, exception.to_s, status)
end
+ def model(indirection_name)
+ raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym)
+ indirection.model
+ end
+
# Execute our find.
- def do_find(indirection_request, request, response)
- unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
- Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
- return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404)
+ def do_find(indirection_name, key, params, request, response)
+ unless result = model(indirection_name).find(key, params)
+ Puppet.info("Could not find #{indirection_name} for '#{key}'")
+ return do_exception(response, "Could not find #{indirection_name} #{key}", 404)
end
# The encoding of the result must include the format to use,
@@ -113,34 +118,35 @@ module Puppet::Network::HTTP::Handler
end
# Execute our search.
- def do_search(indirection_request, request, response)
- result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
+ def do_search(indirection_name, key, params, request, response)
+ model = self.model(indirection_name)
+ result = model.search(key, params)
- if result.nil? or (result.is_a?(Array) and result.empty?)
- return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
+ if result.nil?
+ return do_exception(response, "Could not find instances in #{indirection_name} with '#{key}'", 404)
end
format = format_to_use(request)
set_content_type(response, format)
- set_response(response, indirection_request.model.render_multiple(format, result))
+ set_response(response, model.render_multiple(format, result))
end
# Execute our destroy.
- def do_destroy(indirection_request, request, response)
- result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
+ def do_destroy(indirection_name, key, params, request, response)
+ result = model(indirection_name).destroy(key, params)
return_yaml_response(response, result)
end
# Execute our save.
- def do_save(indirection_request, request, response)
+ def do_save(indirection_name, key, params, request, response)
data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
format = request_format(request)
- obj = indirection_request.model.convert_from(format, data)
- result = save_object(indirection_request, obj)
+ obj = model(indirection_name).convert_from(format, data)
+ result = obj.save(key)
return_yaml_response(response, result)
end
@@ -162,12 +168,6 @@ module Puppet::Network::HTTP::Handler
set_response(response, body.to_yaml)
end
- # LAK:NOTE This has to be here for testing; it's a stub-point so
- # we keep infinite recursion from happening.
- def save_object(ind_request, object)
- object.save(ind_request.key)
- end
-
def get?(request)
http_method(request) == 'GET'
end
diff --git a/lib/puppet/network/http/rack.rb b/lib/puppet/network/http/rack.rb
index c18a07559..5b4ef7e1c 100644
--- a/lib/puppet/network/http/rack.rb
+++ b/lib/puppet/network/http/rack.rb
@@ -1,3 +1,6 @@
+require 'rack'
+require 'rack/request'
+require 'rack/response'
require 'puppet/network/http'
require 'puppet/network/http/rack/rest'
diff --git a/lib/puppet/network/http/rack/rest.rb b/lib/puppet/network/http/rack/rest.rb
index e5f50c465..b7e1d9709 100644
--- a/lib/puppet/network/http/rack/rest.rb
+++ b/lib/puppet/network/http/rack/rest.rb
@@ -41,7 +41,7 @@ class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
unless result.is_a?(File)
response.write result
else
- response["Content-Length"] = result.stat.size
+ response["Content-Length"] = result.stat.size.to_s
response.body = RackFile.new(result)
end
end
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index 91008aa1a..d5c146d88 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -1,5 +1,6 @@
require 'puppet/network/http/handler'
require 'resolv'
+require 'webrick'
class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb
index a3b055572..7d227b4d4 100644
--- a/lib/puppet/network/http_pool.rb
+++ b/lib/puppet/network/http_pool.rb
@@ -58,18 +58,6 @@ module Puppet::Network::HttpPool
http.cert = ssl_host.certificate.content
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.key = ssl_host.key.content
- http.verify_callback = self.method(:ssl_verify_callback).to_proc if Puppet[:debug]
- end
-
- def self.ssl_verify_callback(peer_ok, x509_store_ctx)
- if not peer_ok
- Puppet.debug "OpenSSL: Error(#{x509_store_ctx.error}): #{x509_store_ctx.error_string}"
- Puppet.debug "OpenSSL: Cert: #{x509_store_ctx.current_cert.issuer}"
- Puppet.debug "OpenSSL: Current CRL: #{x509_store_ctx.current_crl}"
- Puppet.debug "OpenSSL: Chain:"
- x509_store_ctx.chain.each_index { |i| Puppet.debug "OpenSSL: \t#{i} #{x509_store_ctx.chain[i].issuer}" }
- end
- peer_ok
end
# Retrieve a cached http instance if caching is enabled, else return
diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb
index 38a8f9a09..b6a163316 100644
--- a/lib/puppet/network/rest_authconfig.rb
+++ b/lib/puppet/network/rest_authconfig.rb
@@ -3,6 +3,7 @@ require 'puppet/network/authconfig'
module Puppet
class Network::RestAuthConfig < Network::AuthConfig
+ extend MonitorMixin
attr_accessor :rights
DEFAULT_ACL = [
@@ -20,30 +21,32 @@ module Puppet
]
def self.main
- add_acl = @main.nil?
- super
- @main.insert_default_acl if add_acl and !@main.exists?
+ synchronize do
+ add_acl = @main.nil?
+ super
+ @main.insert_default_acl if add_acl and !@main.exists?
+ end
@main
end
# check wether this request is allowed in our ACL
# raise an Puppet::Network::AuthorizedError if the request
# is denied.
- def allowed?(request)
+ def allowed?(indirection, method, key, params)
read
# we're splitting the request in part because
# fail_on_deny could as well be called in the XMLRPC context
# with a ClientRequest.
- @rights.fail_on_deny(
- build_uri(request),
-
- :node => request.node,
- :ip => request.ip,
- :method => request.method,
- :environment => request.environment,
- :authenticated => request.authenticated)
+ @rights.fail_on_deny(
+ build_uri(indirection, key),
+ :node => params[:node],
+ :ip => params[:ip],
+ :method => method,
+ :environment => params[:environment],
+ :authenticated => params[:authenticated]
+ )
end
def initialize(file = nil, parsenow = true)
@@ -87,8 +90,8 @@ module Puppet
@rights.restrict_authenticated(acl[:acl], acl[:authenticated]) unless acl[:authenticated].nil?
end
- def build_uri(request)
- "/#{request.indirection_name}/#{request.key}"
+ def build_uri(indirection_name, key)
+ "/#{indirection_name}/#{key}"
end
end
end
diff --git a/lib/puppet/network/rest_authorization.rb b/lib/puppet/network/rest_authorization.rb
index e052245eb..50f094e3e 100644
--- a/lib/puppet/network/rest_authorization.rb
+++ b/lib/puppet/network/rest_authorization.rb
@@ -15,8 +15,8 @@ module Puppet::Network
end
# Verify that our client has access.
- def check_authorization(request)
- authconfig.allowed?(request)
+ def check_authorization(indirection, method, key, params)
+ authconfig.allowed?(indirection, method, key, params)
end
end
end
diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb
index d424b9c4a..e4de07dea 100644
--- a/lib/puppet/network/server.rb
+++ b/lib/puppet/network/server.rb
@@ -32,14 +32,14 @@ class Puppet::Network::Server
# Create a pidfile for our daemon, so we can be stopped and others
# don't try to start.
def create_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
end
end
# Remove the pid file for our daemon.
def remove_pidfile
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
locker = Puppet::Util::Pidlock.new(pidfile)
locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
end
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 2453cd1d5..e8d58e6be 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -3,6 +3,7 @@ require 'puppet/indirector'
# A class for managing nodes, including their facts and environment.
class Puppet::Node
require 'puppet/node/facts'
+ require 'puppet/node/inventory'
require 'puppet/node/environment'
# Set up indirection, so that nodes can be looked for in
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index 762599cff..7877b7f73 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -1,4 +1,5 @@
require 'puppet/util/cacher'
+require 'monitor'
# Just define it, so this class has fewer load dependencies.
class Puppet::Node
@@ -67,14 +68,23 @@ class Puppet::Node::Environment
def initialize(name)
@name = name
+ extend MonitorMixin
end
def known_resource_types
- if @known_resource_types.nil? or @known_resource_types.stale?
- @known_resource_types = Puppet::Resource::TypeCollection.new(self)
- @known_resource_types.perform_initial_import
- end
- @known_resource_types
+ # This makes use of short circuit evaluation to get the right thread-safe
+ # per environment semantics with an efficient most common cases; we almost
+ # always just return our thread's known-resource types. Only at the start
+ # of a compilation (after our thread var has been set to nil) or when the
+ # environment has changed do we delve deeper.
+ Thread.current[:known_resource_types] = nil if (krt = Thread.current[:known_resource_types]) && krt.environment != self
+ Thread.current[:known_resource_types] ||= synchronize {
+ if @known_resource_types.nil? or @known_resource_types.stale?
+ @known_resource_types = Puppet::Resource::TypeCollection.new(self)
+ @known_resource_types.import_ast(perform_initial_import, '')
+ end
+ @known_resource_types
+ }
end
def module(name)
@@ -114,6 +124,10 @@ class Puppet::Node::Environment
name.to_s
end
+ def to_sym
+ to_s.to_sym
+ end
+
# The only thing we care about when serializing an environment is its
# identity; everything else is ephemeral and should not be stored or
# transmitted.
@@ -133,5 +147,31 @@ class Puppet::Node::Environment
end
end
+ private
+
+ def perform_initial_import
+ return empty_parse_result if Puppet.settings[:ignoreimport]
+ parser = Puppet::Parser::Parser.new(self)
+ if code = Puppet.settings.uninterpolated_value(:code, name.to_s) and code != ""
+ parser.string = code
+ else
+ file = Puppet.settings.value(:manifest, name.to_s)
+ return empty_parse_result unless File.exist?(file)
+ parser.file = file
+ end
+ parser.parse
+ rescue => detail
+ msg = "Could not parse for environment #{self}: #{detail}"
+ error = Puppet::Error.new(msg)
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
+
+ def empty_parse_result
+ # Return an empty toplevel hostclass to use as the result of
+ # perform_initial_import when no file was actually loaded.
+ return Puppet::Parser::AST::Hostclass.new('')
+ end
+
@root = new(:'*root*')
end
diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb
index b77ad22d5..d84d54113 100755
--- a/lib/puppet/node/facts.rb
+++ b/lib/puppet/node/facts.rb
@@ -1,12 +1,17 @@
+require 'time'
+
require 'puppet/node'
require 'puppet/indirector'
+require 'puppet/util/pson'
+
# Manage a given node's facts. This either accepts facts and stores them, or
# returns facts for a given node.
class Puppet::Node::Facts
# Set up indirection, so that nodes can be looked for in
# the node sources.
extend Puppet::Indirector
+ extend Puppet::Util::Pson
# We want to expire any cached nodes if the facts are saved.
module NodeExpirer
@@ -30,7 +35,7 @@ class Puppet::Node::Facts
@name = name
@values = values
- add_internal
+ add_timestamp
end
def downcase_if_necessary
@@ -54,13 +59,37 @@ class Puppet::Node::Facts
strip_internal == other.send(:strip_internal)
end
- private
+ def self.from_pson(data)
+ result = new(data['name'], data['values'])
+ result.values[:_timestamp] = Time.parse(data['timestamp'])
+ result.expiration = Time.parse(data['expiration'])
+ result
+ end
+
+ def to_pson(*args)
+ {
+ 'expiration' => expiration,
+ 'name' => name,
+ 'timestamp' => values[:_timestamp],
+ 'values' => values.reject {|k,v| k == :_timestamp},
+ }.to_pson(*args)
+ end
# Add internal data to the facts for storage.
- def add_internal
- self.values[:_timestamp] = Time.now
+ def add_timestamp
+ self.timestamp = Time.now
end
+ def timestamp=(time)
+ self.values[:_timestamp] = time
+ end
+
+ def timestamp
+ self.values[:_timestamp]
+ end
+
+ private
+
# Strip out that internal data.
def strip_internal
newvals = values.dup
diff --git a/lib/puppet/node/inventory.rb b/lib/puppet/node/inventory.rb
new file mode 100644
index 000000000..fd99163b0
--- /dev/null
+++ b/lib/puppet/node/inventory.rb
@@ -0,0 +1,7 @@
+require 'puppet/node'
+require 'puppet/indirector'
+
+class Puppet::Node::Inventory
+ extend Puppet::Indirector
+ indirects :inventory, :terminus_setting => :inventory_terminus
+end
diff --git a/lib/puppet/parameter/value_collection.rb b/lib/puppet/parameter/value_collection.rb
index a9fd20233..619e0731d 100644
--- a/lib/puppet/parameter/value_collection.rb
+++ b/lib/puppet/parameter/value_collection.rb
@@ -21,14 +21,14 @@ class Puppet::Parameter::ValueCollection
@doc += " Valid values are "
@doc += @strings.collect do |value|
if aliases = value.aliases and ! aliases.empty?
- "``#{value.name}`` (also called ``#{aliases.join(", ")}``)"
+ "`#{value.name}` (also called `#{aliases.join(", ")}`)"
else
- "``#{value.name}``"
+ "`#{value.name}`"
end
end.join(", ") + "."
end
- @doc += " Values can match ``" + regexes.join("``, ``") + "``." unless regexes.empty?
+ @doc += " Values can match `" + regexes.join("`, `") + "`." unless regexes.empty?
end
@doc
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 54e034acb..03891160b 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -107,28 +107,32 @@ end
require 'puppet/parser/ast/arithmetic_operator'
require 'puppet/parser/ast/astarray'
require 'puppet/parser/ast/asthash'
-require 'puppet/parser/ast/branch'
require 'puppet/parser/ast/boolean_operator'
+require 'puppet/parser/ast/branch'
require 'puppet/parser/ast/caseopt'
require 'puppet/parser/ast/casestatement'
require 'puppet/parser/ast/collection'
require 'puppet/parser/ast/collexpr'
require 'puppet/parser/ast/comparison_operator'
+require 'puppet/parser/ast/definition'
require 'puppet/parser/ast/else'
require 'puppet/parser/ast/function'
+require 'puppet/parser/ast/hostclass'
require 'puppet/parser/ast/ifstatement'
require 'puppet/parser/ast/in_operator'
require 'puppet/parser/ast/leaf'
require 'puppet/parser/ast/match_operator'
require 'puppet/parser/ast/minus'
+require 'puppet/parser/ast/node'
require 'puppet/parser/ast/nop'
require 'puppet/parser/ast/not'
+require 'puppet/parser/ast/relationship'
require 'puppet/parser/ast/resource'
require 'puppet/parser/ast/resource_defaults'
+require 'puppet/parser/ast/resource_instance'
require 'puppet/parser/ast/resource_override'
require 'puppet/parser/ast/resource_reference'
require 'puppet/parser/ast/resourceparam'
require 'puppet/parser/ast/selector'
require 'puppet/parser/ast/tag'
require 'puppet/parser/ast/vardef'
-require 'puppet/parser/ast/relationship'
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb
index 529998e3c..7283a1f6c 100644
--- a/lib/puppet/parser/ast/astarray.rb
+++ b/lib/puppet/parser/ast/astarray.rb
@@ -16,25 +16,20 @@ class Puppet::Parser::AST
# Evaluate our children.
def evaluate(scope)
- # Make a new array, so we don't have to deal with the details of
- # flattening and such
- items = []
-
- # First clean out any AST::ASTArrays
- @children.each { |child|
- if child.instance_of?(AST::ASTArray)
- child.each do |ac|
- items << ac
+ result = []
+ @children.each do |child|
+ # Skip things that respond to :instantiate (classes, nodes,
+ # and definitions), because they have already been
+ # instantiated.
+ if !child.respond_to?(:instantiate)
+ item = child.safeevaluate(scope)
+ if !item.nil?
+ # nil values are implicitly removed.
+ result.push(item)
end
- else
- items << child
end
- }
-
- rets = items.flatten.collect { |child|
- child.safeevaluate(scope)
- }
- rets.reject { |o| o.nil? }
+ end
+ result
end
def push(*ary)
@@ -52,10 +47,4 @@ class Puppet::Parser::AST
"[" + @children.collect { |c| c.to_s }.join(', ') + "]"
end
end
-
- # A simple container class, containing the parameters for an object.
- # Used for abstracting the grammar declarations. Basically unnecessary
- # except that I kept finding bugs because I had too many arrays that
- # meant completely different things.
- class ResourceInstance < ASTArray; end
end
diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb
index 4e296e82f..db4c2b024 100644
--- a/lib/puppet/parser/ast/caseopt.rb
+++ b/lib/puppet/parser/ast/caseopt.rb
@@ -18,16 +18,12 @@ class Puppet::Parser::AST
# Cache the @default value.
return @default if defined?(@default)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- if subval.is_a?(AST::Default)
- @default = true
- break
- end
- }
- else
- @default = true if @value.is_a?(AST::Default)
- end
+ @value.each { |subval|
+ if subval.is_a?(AST::Default)
+ @default = true
+ break
+ end
+ }
@default ||= false
@@ -36,23 +32,15 @@ class Puppet::Parser::AST
# You can specify a list of values; return each in turn.
def eachvalue(scope)
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval.safeevaluate(scope)
- }
- else
- yield @value.safeevaluate(scope)
- end
+ @value.each { |subval|
+ yield subval.safeevaluate(scope)
+ }
end
def eachopt
- if @value.is_a?(AST::ASTArray)
- @value.each { |subval|
- yield subval
- }
- else
- yield @value
- end
+ @value.each { |subval|
+ yield subval
+ }
end
# Evaluate the actual statements; this only gets called if
diff --git a/lib/puppet/parser/ast/collection.rb b/lib/puppet/parser/ast/collection.rb
index 09d5b4eb3..ef36b7143 100644
--- a/lib/puppet/parser/ast/collection.rb
+++ b/lib/puppet/parser/ast/collection.rb
@@ -5,61 +5,44 @@ require 'puppet/parser/collector'
# An object that collects stored objects from the central cache and returns
# them to the current host, yo.
class Puppet::Parser::AST
-class Collection < AST::Branch
- attr_accessor :type, :query, :form
- attr_reader :override
-
- associates_doc
-
- # We return an object that does a late-binding evaluation.
- def evaluate(scope)
- if self.query
- str, code = self.query.safeevaluate scope
- else
- str = code = nil
- end
-
- newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
-
- scope.compiler.add_collection(newcoll)
-
- # overrides if any
- # Evaluate all of the specified params.
- if @override
- params = @override.collect do |param|
- param.safeevaluate(scope)
+ class Collection < AST::Branch
+ attr_accessor :type, :query, :form
+ attr_reader :override
+
+ associates_doc
+
+ # We return an object that does a late-binding evaluation.
+ def evaluate(scope)
+ str, code = query && query.safeevaluate(scope)
+
+ resource_type = scope.find_resource_type(@type)
+ newcoll = Puppet::Parser::Collector.new(scope, resource_type.name, str, code, self.form)
+
+ scope.compiler.add_collection(newcoll)
+
+ # overrides if any
+ # Evaluate all of the specified params.
+ if @override
+ params = @override.collect { |param| param.safeevaluate(scope) }
+ newcoll.add_override(
+ :parameters => params,
+ :file => @file,
+ :line => @line,
+ :source => scope.source,
+ :scope => scope
+ )
end
-
- newcoll.add_override(
-
- :parameters => params,
- :file => @file,
- :line => @line,
- :source => scope.source,
-
- :scope => scope
- )
+ newcoll
end
- newcoll
- end
-
- # Handle our parameter ourselves
- def override=(override)
- if override.is_a?(AST::ASTArray)
- @override = override
- else
-
- @override = AST::ASTArray.new(
-
- :line => override.line,
- :file => override.file,
-
- :children => [override]
- )
+ # Handle our parameter ourselves
+ def override=(override)
+ @override = if override.is_a?(AST::ASTArray)
+ override
+ else
+ AST::ASTArray.new(:line => override.line,:file => override.file,:children => [override])
+ end
end
end
-
-end
end
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
new file mode 100644
index 000000000..c43422f82
--- /dev/null
+++ b/lib/puppet/parser/ast/definition.rb
@@ -0,0 +1,17 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Definition < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :context
+
+ def initialize(name, context = {}, &ruby_code)
+ @name = name
+ @context = context
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ new_definition = Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname))
+ new_definition.ruby_code = @ruby_code if @ruby_code
+ [new_definition]
+ end
+end
diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb
index 602016c75..80e6e6512 100644
--- a/lib/puppet/parser/ast/function.rb
+++ b/lib/puppet/parser/ast/function.rb
@@ -11,7 +11,6 @@ class Puppet::Parser::AST
@settor = true
def evaluate(scope)
-
# Make sure it's a defined function
raise Puppet::ParseError, "Unknown function #{@name}" unless Puppet::Parser::Functions.function(@name)
@@ -29,7 +28,7 @@ class Puppet::Parser::AST
end
# We don't need to evaluate the name, because it's plaintext
- args = @arguments.safeevaluate(scope)
+ args = @arguments.safeevaluate(scope).map { |x| x == :undef ? '' : x }
scope.send("function_#{@name}", args)
end
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
new file mode 100644
index 000000000..cab5e4a24
--- /dev/null
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -0,0 +1,29 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Hostclass < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :name, :context
+
+ def initialize(name, context = {}, &ruby_code)
+ @context = context
+ @name = name
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ new_class = Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname))
+ new_class.ruby_code = @ruby_code if @ruby_code
+ all_types = [new_class]
+ if code
+ code.each do |nested_ast_node|
+ if nested_ast_node.respond_to? :instantiate
+ all_types += nested_ast_node.instantiate(modname)
+ end
+ end
+ end
+ return all_types
+ end
+
+ def code()
+ @context[:code]
+ end
+end
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb
index 49cde63ca..fcdd219d7 100644
--- a/lib/puppet/parser/ast/leaf.rb
+++ b/lib/puppet/parser/ast/leaf.rb
@@ -42,7 +42,7 @@ class Puppet::Parser::AST
# The base string class.
class String < AST::Leaf
def evaluate(scope)
- @value
+ @value.dup
end
def to_s
@@ -148,12 +148,20 @@ class Puppet::Parser::AST
key.respond_to?(:evaluate) ? key.safeevaluate(scope) : key
end
+ def array_index_or_key(object, key)
+ if object.is_a?(Array)
+ raise Puppet::ParserError, "#{key} is not an integer, but is used as an index of an array" unless key = Puppet::Parser::Scope.number?(key)
+ end
+ key
+ end
+
def evaluate(scope)
object = evaluate_container(scope)
+ accesskey = evaluate_key(scope)
raise Puppet::ParseError, "#{variable} is not an hash or array when accessing it with #{accesskey}" unless object.is_a?(Hash) or object.is_a?(Array)
- object[evaluate_key(scope)]
+ object[array_index_or_key(object, accesskey)]
end
# Assign value to this hashkey or array index
@@ -166,7 +174,7 @@ class Puppet::Parser::AST
end
# assign to hash or array
- object[accesskey] = value
+ object[array_index_or_key(object, accesskey)] = value
end
def to_s
diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb
new file mode 100644
index 000000000..b69a5c4e0
--- /dev/null
+++ b/lib/puppet/parser/ast/node.rb
@@ -0,0 +1,20 @@
+require 'puppet/parser/ast/top_level_construct'
+
+class Puppet::Parser::AST::Node < Puppet::Parser::AST::TopLevelConstruct
+ attr_accessor :names, :context
+
+ def initialize(names, context = {}, &ruby_code)
+ raise ArgumentError, "names should be an array" unless names.is_a? Array
+ @names = names
+ @context = context
+ @ruby_code = ruby_code
+ end
+
+ def instantiate(modname)
+ @names.collect do |name|
+ new_node = Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname))
+ new_node.ruby_code = @ruby_code if @ruby_code
+ new_node
+ end
+ end
+end
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb
index 1b063c984..ce3c499c5 100644
--- a/lib/puppet/parser/ast/resource.rb
+++ b/lib/puppet/parser/ast/resource.rb
@@ -3,26 +3,15 @@ require 'puppet/parser/ast/resource_reference'
# Any normal puppet resource declaration. Can point to a definition or a
# builtin type.
class Puppet::Parser::AST
-class Resource < AST::ResourceReference
+class Resource < AST::Branch
associates_doc
- attr_accessor :title, :type, :exported, :virtual
- attr_reader :parameters
+ attr_accessor :type, :instances, :exported, :virtual
# Does not actually return an object; instead sets an object
# in the current scope.
def evaluate(scope)
- # Evaluate all of the specified params.
- paramobjects = parameters.collect { |param|
- param.safeevaluate(scope)
- }
-
- resource_titles = @title.safeevaluate(scope)
-
- # it's easier to always use an array, even for only one name
- resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
-
# We want virtual to be true if exported is true. We can't
# just set :virtual => self.virtual in the initialization,
# because sometimes the :virtual attribute is set *after*
@@ -30,48 +19,49 @@ class Resource < AST::ResourceReference
# is true. Argh, this was a very tough one to track down.
virt = self.virtual || self.exported
- # This is where our implicit iteration takes place; if someone
- # passed an array as the name, then we act just like the called us
- # many times.
- resource_titles.flatten.collect { |resource_title|
- exceptwrap :type => Puppet::ParseError do
+ # First level of implicit iteration: build a resource for each
+ # instance. This handles things like:
+ # file { '/foo': owner => blah; '/bar': owner => blah }
+ @instances.collect { |instance|
- resource = Puppet::Parser::Resource.new(
- type, resource_title,
- :parameters => paramobjects,
- :file => self.file,
- :line => self.line,
- :exported => self.exported,
- :virtual => virt,
- :source => scope.source,
- :scope => scope,
-
- :strict => true
- )
+ # Evaluate all of the specified params.
+ paramobjects = instance.parameters.collect { |param|
+ param.safeevaluate(scope)
+ }
- # And then store the resource in the compiler.
- # At some point, we need to switch all of this to return
- # resources instead of storing them like this.
- scope.compiler.add_resource(scope, resource)
- resource
- end
- }.reject { |resource| resource.nil? }
- end
+ resource_titles = instance.title.safeevaluate(scope)
+
+ # it's easier to always use an array, even for only one name
+ resource_titles = [resource_titles] unless resource_titles.is_a?(Array)
+
+ fully_qualified_type, resource_titles = scope.resolve_type_and_titles(type, resource_titles)
- # Set the parameters for our object.
- def parameters=(params)
- if params.is_a?(AST::ASTArray)
- @parameters = params
- else
+ # Second level of implicit iteration; build a resource for each
+ # title. This handles things like:
+ # file { ['/foo', '/bar']: owner => blah }
+ resource_titles.flatten.collect { |resource_title|
+ exceptwrap :type => Puppet::ParseError do
+ resource = Puppet::Parser::Resource.new(
+ fully_qualified_type, resource_title,
+ :parameters => paramobjects,
+ :file => self.file,
+ :line => self.line,
+ :exported => self.exported,
+ :virtual => virt,
+ :source => scope.source,
+ :scope => scope,
+ :strict => true
+ )
- @parameters = AST::ASTArray.new(
-
- :line => params.line,
- :file => params.file,
-
- :children => [params]
- )
- end
+ if resource.resource_type.is_a? Puppet::Resource::Type
+ resource.resource_type.instantiate_resource(scope, resource)
+ end
+ scope.compiler.add_resource(scope, resource)
+ scope.compiler.evaluate_classes([resource_title],scope,false) if fully_qualified_type == 'class'
+ resource
+ end
+ }
+ }.flatten.reject { |resource| resource.nil? }
end
end
end
diff --git a/lib/puppet/parser/ast/resource_instance.rb b/lib/puppet/parser/ast/resource_instance.rb
new file mode 100644
index 000000000..ebfb17bf1
--- /dev/null
+++ b/lib/puppet/parser/ast/resource_instance.rb
@@ -0,0 +1,9 @@
+require 'puppet/parser/ast/branch'
+
+class Puppet::Parser::AST
+ class ResourceInstance < Branch
+ # A simple container for a parameter for an object. Consists of a
+ # title and a set of parameters.
+ attr_accessor :title, :parameters
+ end
+end
diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb
index e0be889ff..d638202ab 100644
--- a/lib/puppet/parser/ast/resource_override.rb
+++ b/lib/puppet/parser/ast/resource_override.rb
@@ -3,12 +3,11 @@ require 'puppet/parser/ast/resource'
class Puppet::Parser::AST
# Set a parameter on a resource specification created somewhere else in the
# configuration. The object is responsible for verifying that this is allowed.
- class ResourceOverride < Resource
+ class ResourceOverride < AST::Branch
associates_doc
- attr_accessor :object
- attr_reader :parameters
+ attr_accessor :object, :parameters
# Iterate across all of our children.
def each
diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb
index 5d8334335..0f8e655bf 100644
--- a/lib/puppet/parser/ast/resource_reference.rb
+++ b/lib/puppet/parser/ast/resource_reference.rb
@@ -7,8 +7,15 @@ class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch
# Evaluate our object, but just return a simple array of the type
# and name.
def evaluate(scope)
- titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) }
- return(titles.length == 1 ? titles.pop : titles)
+ titles = Array(title.safeevaluate(scope))
+
+ a_type, titles = scope.resolve_type_and_titles(type, titles)
+
+ resources = titles.collect{ |a_title|
+ Puppet::Resource.new(a_type, a_title)
+ }
+
+ return(resources.length == 1 ? resources.pop : resources)
end
def to_s
diff --git a/lib/puppet/parser/ast/top_level_construct.rb b/lib/puppet/parser/ast/top_level_construct.rb
new file mode 100644
index 000000000..901a939c2
--- /dev/null
+++ b/lib/puppet/parser/ast/top_level_construct.rb
@@ -0,0 +1,4 @@
+# The base class for AST nodes representing top level things:
+# hostclasses, definitions, and nodes.
+class Puppet::Parser::AST::TopLevelConstruct < Puppet::Parser::AST
+end
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index a901c0dd6..c60e1d4fb 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -19,7 +19,12 @@ class Puppet::Parser::Compiler
rescue => detail
puts detail.backtrace if Puppet[:trace]
raise Puppet::Error, "#{detail} on node #{node.name}"
- end
+ ensure
+ # We get these from the environment and only cache them in a thread
+ # variable for the duration of the compilation.
+ Thread.current[:known_resource_types] = nil
+ Thread.current[:env_module_directories] = nil
+ end
attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships
@@ -51,13 +56,10 @@ class Puppet::Parser::Compiler
# Note that this will fail if the resource is not unique.
@catalog.add_resource(resource)
- set_container_resource(scope, resource)
- end
- # Add our container edge. If we're a class, then we get treated specially - we can
- # control the stage that the class is applied in. Otherwise, we just
- # get added to our parent container.
- def set_container_resource(scope, resource)
+ # Add our container edge. If we're a class, then we get treated specially - we can
+ # control the stage that the class is applied in. Otherwise, we just
+ # get added to our parent container.
return if resource.type.to_s.downcase == "stage"
if resource.type.to_s.downcase != "class"
@@ -65,15 +67,14 @@ class Puppet::Parser::Compiler
return @catalog.add_edge(scope.resource, resource)
end
- unless stage = @catalog.resource(:stage, resource[:stage] || :main)
+ unless stage = @catalog.resource(:stage, resource[:stage] || (scope && scope.resource && scope.resource[:stage]) || :main)
raise ArgumentError, "Could not find stage #{resource[:stage] || :main} specified by #{resource}"
end
+ resource[:stage] ||= stage.title unless stage.title == :main
@catalog.add_edge(stage, resource)
end
- private :set_container_resource
-
# Do we use nodes found in the code, vs. the external node sources?
def ast_nodes?
known_resource_types.nodes?
@@ -143,7 +144,7 @@ class Puppet::Parser::Compiler
if klass = scope.find_hostclass(name)
found << name and next if scope.class_scope(klass)
- resource = klass.mk_plain_resource(scope)
+ resource = klass.ensure_in_catalog(scope)
# If they've disabled lazy evaluation (which the :include function does),
# then evaluate our resource immediately.
@@ -219,7 +220,7 @@ class Puppet::Parser::Compiler
# Create a resource to model this node, and then add it to the list
# of resources.
- resource = astnode.mk_plain_resource(topscope)
+ resource = astnode.ensure_in_catalog(topscope)
resource.evaluate
@@ -284,10 +285,7 @@ class Puppet::Parser::Compiler
@main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main)
@topscope.resource = @main_resource
- @resources << @main_resource
- @catalog.add_resource(@main_resource)
-
- set_container_resource(@topscope, @main_resource)
+ add_resource(@topscope, @main_resource)
@main_resource.evaluate
end
diff --git a/lib/puppet/parser/files.rb b/lib/puppet/parser/files.rb
index 9ef05e102..f34683153 100644
--- a/lib/puppet/parser/files.rb
+++ b/lib/puppet/parser/files.rb
@@ -24,7 +24,7 @@ module Puppet::Parser::Files
# Than that would be a "no."
end
abspat = File::expand_path(start, cwd)
- [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{,.pp,.rb}' : '' )).uniq.reject { |f| FileTest.directory?(f) }]
+ [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{.pp,.rb}' : '' )).uniq.reject { |f| FileTest.directory?(f) }]
end
# Find the concrete file denoted by +file+. If +file+ is absolute,
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index c238da5d4..5807c0bbe 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -20,7 +20,7 @@ module Puppet::Parser::Functions
@autoloader = Puppet::Util::Autoload.new(
self,
"puppet/parser/functions",
-
+
:wrap => false
)
end
@@ -73,8 +73,10 @@ module Puppet::Parser::Functions
def self.function(name)
name = symbolize(name)
- unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
- autoloader.load(name,Environment.current || Environment.root)
+ @functions.synchronize do
+ unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
+ autoloader.load(name,Environment.current || Environment.root)
+ end
end
( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name]
@@ -94,7 +96,7 @@ module Puppet::Parser::Functions
ret += "Undocumented.\n"
end
- ret += "\n\n- **Type**: #{hash[:type]}\n\n"
+ ret += "\n\n- *Type*: #{hash[:type]}\n\n"
end
ret
diff --git a/lib/puppet/parser/functions/defined.rb b/lib/puppet/parser/functions/defined.rb
index 2930a65cc..90632af2f 100644
--- a/lib/puppet/parser/functions/defined.rb
+++ b/lib/puppet/parser/functions/defined.rb
@@ -3,7 +3,7 @@ Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :doc => "Dete
type is defined, either as a native type or a defined type, or whether a class is defined.
This is useful for checking whether a class is defined and only including it if it is.
This function can also test whether a resource has been defined, using resource references
- (e.g., ``if defined(File['/tmp/myfile']) { ... }``). This function is unfortunately
+ (e.g., `if defined(File['/tmp/myfile']) { ... }`). This function is unfortunately
dependent on the parse order of the configuration when testing whether a resource is defined.") do |vals|
result = false
vals = [vals] unless vals.is_a?(Array)
diff --git a/lib/puppet/parser/functions/extlookup.rb b/lib/puppet/parser/functions/extlookup.rb
new file mode 100644
index 000000000..bc55410b9
--- /dev/null
+++ b/lib/puppet/parser/functions/extlookup.rb
@@ -0,0 +1,157 @@
+require 'csv'
+
+module Puppet::Parser::Functions
+ newfunction(:extlookup,
+ :type => :rvalue,
+ :doc => "This is a parser function to read data from external files, this version
+uses CSV files but the concept can easily be adjust for databases, yaml
+or any other queryable data source.
+
+The object of this is to make it obvious when it's being used, rather than
+magically loading data in when an module is loaded I prefer to look at the code
+and see statements like:
+
+ $snmp_contact = extlookup(\"snmp_contact\")
+
+The above snippet will load the snmp_contact value from CSV files, this in its
+own is useful but a common construct in puppet manifests is something like this:
+
+ case $domain {
+ \"myclient.com\": { $snmp_contact = \"John Doe <john@myclient.com>\" }
+ default: { $snmp_contact = \"My Support <support@my.com>\" }
+ }
+
+Over time there will be a lot of this kind of thing spread all over your manifests
+and adding an additional client involves grepping through manifests to find all the
+places where you have constructs like this.
+
+This is a data problem and shouldn't be handled in code, a using this function you
+can do just that.
+
+First you configure it in site.pp:
+
+ $extlookup_datadir = \"/etc/puppet/manifests/extdata\"
+ $extlookup_precedence = [\"%{fqdn}\", \"domain_%{domain}\", \"common\"]
+
+The array tells the code how to resolve values, first it will try to find it in
+web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv
+
+Now create the following data files in /etc/puppet/manifests/extdata:
+
+ domain_myclient.com.csv:
+ snmp_contact,John Doe <john@myclient.com>
+ root_contact,support@%{domain}
+ client_trusted_ips,192.168.1.130,192.168.10.0/24
+
+ common.csv:
+ snmp_contact,My Support <support@my.com>
+ root_contact,support@my.com
+
+Now you can replace the case statement with the simple single line to achieve
+the exact same outcome:
+
+ $snmp_contact = extlookup(\"snmp_contact\")
+
+The above code shows some other features, you can use any fact or variable that
+is in scope by simply using %{varname} in your data files, you can return arrays
+by just having multiple values in the csv after the initial variable name.
+
+In the event that a variable is nowhere to be found a critical error will be raised
+that will prevent your manifest from compiling, this is to avoid accidentally putting
+in empty values etc. You can however specify a default value:
+
+ $ntp_servers = extlookup(\"ntp_servers\", \"1.${country}.pool.ntp.org\")
+
+In this case it will default to \"1.${country}.pool.ntp.org\" if nothing is defined in
+any data file.
+
+You can also specify an additional data file to search first before any others at use
+time, for example:
+
+ $version = extlookup(\"rsyslog_version\", \"present\", \"packages\")
+ package{\"rsyslog\": ensure => $version }
+
+This will look for a version configured in packages.csv and then in the rest as configured
+by $extlookup_precedence if it's not found anywhere it will default to `present`, this kind
+of use case makes puppet a lot nicer for managing large amounts of packages since you do not
+need to edit a load of manifests to do simple things like adjust a desired version number.
+
+Precedence values can have variables embedded in them in the form %{fqdn}, you could for example do:
+
+ $extlookup_precedence = [\"hosts/%{fqdn}\", \"common\"]
+
+This will result in /path/to/extdata/hosts/your.box.com.csv being searched.
+
+This is for back compatibility to interpolate variables with %. % interpolation is a workaround for a problem that has been fixed: Puppet variable interpolation at top scope used to only happen on each run.") do |args|
+
+ key = args[0]
+
+ default = args[1]
+ datafile = args[2]
+
+ raise Puppet::ParseError, ("extlookup(): wrong number of arguments (#{args.length}; must be <= 3)") if args.length > 3
+
+ extlookup_datadir = lookupvar('extlookup_datadir')
+ extlookup_precedence = Array.new
+
+ extlookup_precedence = lookupvar('extlookup_precedence').collect do |var|
+ var.gsub(/%\{(.+?)\}/) do |capture|
+ lookupvar($1)
+ end
+ end
+
+ datafiles = Array.new
+
+ # if we got a custom data file, put it first in the array of search files
+ if datafile != ""
+ datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv")
+ end
+
+ extlookup_precedence.each do |d|
+ datafiles << extlookup_datadir + "/#{d}.csv"
+ end
+
+ desired = nil
+
+ datafiles.each do |file|
+ if desired.nil?
+ if File.exists?(file)
+ result = CSV.read(file).find_all do |r|
+ r[0] == key
+ end
+
+ # return just the single result if theres just one,
+ # else take all the fields in the csv and build an array
+ if result.length > 0
+ if result[0].length == 2
+ val = result[0][1].to_s
+
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while val =~ /%\{(.+?)\}/
+ val.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ desired = val
+ elsif result[0].length > 1
+ length = result[0].length
+ cells = result[0][1,length]
+
+ # Individual cells in a CSV result are a weird data type and throws
+ # puppets yaml parsing, so just map it all to plain old strings
+ desired = cells.map do |c|
+ # parse %{}'s in the CSV into local variables using lookupvar()
+ while c =~ /%\{(.+?)\}/
+ c.gsub!(/%\{#{$1}\}/, lookupvar($1))
+ end
+
+ c.to_s
+ end
+ end
+ end
+ end
+ end
+ end
+
+ desired || default or raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
+ end
+end
diff --git a/lib/puppet/parser/functions/file.rb b/lib/puppet/parser/functions/file.rb
index 963111260..19ab9ba2e 100644
--- a/lib/puppet/parser/functions/file.rb
+++ b/lib/puppet/parser/functions/file.rb
@@ -2,7 +2,7 @@
Puppet::Parser::Functions::newfunction(
:file, :type => :rvalue,
-
+
:doc => "Return the contents of a file. Multiple files
can be passed, and the first file that exists will be read in.") do |vals|
ret = nil
diff --git a/lib/puppet/parser/functions/inline_template.rb b/lib/puppet/parser/functions/inline_template.rb
index 46e000383..9759ff6e1 100644
--- a/lib/puppet/parser/functions/inline_template.rb
+++ b/lib/puppet/parser/functions/inline_template.rb
@@ -1,9 +1,10 @@
Puppet::Parser::Functions::newfunction(:inline_template, :type => :rvalue, :doc =>
- "Evaluate a template string and return its value. See `the templating docs
- <http://docs.puppetlabs.com/guides/templating.html>`_ for more information. Note that
- if multiple template strings are specified, their output is all concatenated
- and returned as the output of the function.") do |vals|
- require 'erb'
+ "Evaluate a template string and return its value. See
+ [the templating docs](http://docs.puppetlabs.com/guides/templating.html) for
+ more information. Note that if multiple template strings are specified, their
+ output is all concatenated and returned as the output of the function.") do |vals|
+
+ require 'erb'
vals.collect do |string|
# Use a wrapper, so the template can't get access to the full
diff --git a/lib/puppet/parser/functions/md5.rb b/lib/puppet/parser/functions/md5.rb
new file mode 100644
index 000000000..f7a4f7222
--- /dev/null
+++ b/lib/puppet/parser/functions/md5.rb
@@ -0,0 +1,5 @@
+Puppet::Parser::Functions::newfunction(:md5, :type => :rvalue, :doc => "Returns a MD5 hash value from a provided string.") do |args|
+ require 'md5'
+
+ Digest::MD5.hexdigest(args[0])
+end
diff --git a/lib/puppet/parser/functions/realize.rb b/lib/puppet/parser/functions/realize.rb
index 4247b8af8..c21ccd14a 100644
--- a/lib/puppet/parser/functions/realize.rb
+++ b/lib/puppet/parser/functions/realize.rb
@@ -5,7 +5,7 @@ Puppet::Parser::Functions::newfunction(:realize, :doc => "Make a virtual object
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|
+ 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.flatten
diff --git a/lib/puppet/parser/functions/regsubst.rb b/lib/puppet/parser/functions/regsubst.rb
index c0aeef222..f655db7b3 100644
--- a/lib/puppet/parser/functions/regsubst.rb
+++ b/lib/puppet/parser/functions/regsubst.rb
@@ -6,37 +6,37 @@ module Puppet::Parser::Functions
:doc => "
Perform regexp replacement on a string or array of strings.
-- **Parameters** (in order):
+* *Parameters* (in order):
-:target: The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
+ _target_ The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
-:regexp: The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
+ _regexp_ The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
-:replacement: Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
+ _replacement_ Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
-:flags: Optional. String of single letter flags for how the regexp is interpreted:
+ _flags_ Optional. String of single letter flags for how the regexp is interpreted:
- - **E** Extended regexps
- - **I** Ignore case in regexps
- - **M** Multiline regexps
- - **G** Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
+ - *E* Extended regexps
+ - *I* Ignore case in regexps
+ - *M* Multiline regexps
+ - *G* Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
-:lang: Optional. How to handle multibyte characters. A single-character string with the following values:
+ _lang_ Optional. How to handle multibyte characters. A single-character string with the following values:
- - **N** None
- - **E** EUC
- - **S** SJIS
- - **U** UTF-8
+ - *N* None
+ - *E* EUC
+ - *S* SJIS
+ - *U* UTF-8
-- **Examples**
+* *Examples*
-Get the third octet from the node's IP address::
+Get the third octet from the node's IP address:
- $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
+ $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')
-Put angle brackets around each octet in the node's IP address::
+Put angle brackets around each octet in the node's IP address:
- $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
+ $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
") \
do |args|
unless args.length.between?(3, 5)
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
index 3f98c9523..64285307e 100644
--- a/lib/puppet/parser/functions/require.rb
+++ b/lib/puppet/parser/functions/require.rb
@@ -12,9 +12,8 @@ relationships between classes. This function is a superset of the
class depends on the required class.
Warning: using require in place of include can lead to unwanted dependency cycles.
- For instance the following manifest, with 'require' instead of 'include'
- would produce a nasty dependence cycle, because notify imposes a before
- between File[/foo] and Service[foo]::
+
+For instance the following manifest, with 'require' instead of 'include' would produce a nasty dependence cycle, because notify imposes a before between File[/foo] and Service[foo]:
class myservice {
service { foo: ensure => running }
diff --git a/lib/puppet/parser/functions/split.rb b/lib/puppet/parser/functions/split.rb
index 5d0a9dabc..52394095a 100644
--- a/lib/puppet/parser/functions/split.rb
+++ b/lib/puppet/parser/functions/split.rb
@@ -6,7 +6,7 @@ module Puppet::Parser::Functions
:doc => "\
Split a string variable into an array using the specified split regexp.
- Usage::
+ Usage:
$string = 'v1.v2:v3.v4'
$array_var1 = split($string, ':')
diff --git a/lib/puppet/parser/functions/sprintf.rb b/lib/puppet/parser/functions/sprintf.rb
index 5ada0fed7..5eb4a4f9d 100644
--- a/lib/puppet/parser/functions/sprintf.rb
+++ b/lib/puppet/parser/functions/sprintf.rb
@@ -5,7 +5,7 @@ module Puppet::Parser::Functions
:doc => "Perform printf-style formatting of text.
- The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the ``Kernel::sprintf`` function in Ruby for all the details.") do |args|
+ The first parameter is format string describing how the rest of the parameters should be formatted. See the documentation for the `Kernel::sprintf` function in Ruby for all the details.") do |args|
raise Puppet::ParseError, 'sprintf() needs at least one argument' if args.length < 1
fmt = args.shift
return sprintf(fmt, *args)
diff --git a/lib/puppet/parser/functions/template.rb b/lib/puppet/parser/functions/template.rb
index f51bcc1e2..6fa110332 100644
--- a/lib/puppet/parser/functions/template.rb
+++ b/lib/puppet/parser/functions/template.rb
@@ -1,6 +1,8 @@
Puppet::Parser::Functions::newfunction(:template, :type => :rvalue, :doc =>
- "Evaluate a template and return its value. See `the templating docs
- <http://docs.puppetlabs.com/guides/templating.html>`_ for more information.
+ "Evaluate a template and return its value. See
+ [the templating docs](http://docs.puppetlabs.com/guides/templating.html) for
+ more information.
+
Note that if multiple templates are specified, their output is all
concatenated and returned as the output of the function.") do |vals|
require 'erb'
diff --git a/lib/puppet/parser/functions/versioncmp.rb b/lib/puppet/parser/functions/versioncmp.rb
index b38406532..6091e0923 100644
--- a/lib/puppet/parser/functions/versioncmp.rb
+++ b/lib/puppet/parser/functions/versioncmp.rb
@@ -3,26 +3,26 @@ require 'puppet/util/package'
Puppet::Parser::Functions::newfunction(
:versioncmp, :type => :rvalue,
-
+
:doc => "Compares two versions
-Prototype::
+Prototype:
- \$result = versioncmp(a, b)
+ \$result = versioncmp(a, b)
- where a and b are arbitrary version strings
+Where a and b are arbitrary version strings
-This functions returns a number::
+This functions returns a number:
- * > 0 if version a is greater than version b
- * == 0 if both version are equals
- * < 0 if version a is less than version b
+* Greater than 0 if version a is greater than version b
+* Equal to 0 if both version are equals
+* Less than 0 if version a is less than version b
-Example::
+Example:
- if versioncmp('2.6-1', '2.4.5') > 0 {
- notice('2.6-1 is > than 2.4.5')
- }
+ if versioncmp('2.6-1', '2.4.5') > 0 {
+ notice('2.6-1 is > than 2.4.5')
+ }
") do |args|
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 7a316d4d7..ecb27f363 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -28,41 +28,33 @@ prechigh
preclow
rule
-program: statements {
- if val[0]
- # Make sure we always return an array.
- if val[0].is_a?(AST::ASTArray)
- if val[0].children.empty?
- result = nil
- else
- result = val[0]
- end
- else
- result = aryfy(val[0])
- end
- else
- result = nil
- end
-}
+program: statements_and_declarations
| nil
-statements: statement
- | statements statement {
- if val[0] and val[1]
- if val[0].instance_of?(AST::ASTArray)
+ statements_and_declarations: statement_or_declaration {
+ result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : [])
+ }
+ | statements_and_declarations statement_or_declaration {
+ if val[1]
val[0].push(val[1])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[1]]
end
- elsif obj = (val[0] || val[1])
- result = obj
- else result = nil
+ result = val[0]
+ }
+
+# statements is like statements_and_declarations, but it doesn't allow
+# nested definitions, classes, or nodes.
+statements: statements_and_declarations {
+ val[0].each do |stmt|
+ if stmt.is_a?(AST::TopLevelConstruct)
+ error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \
+ :line => stmt.context[:line], :file => stmt.context[:file]
+ end
end
+ result = val[0]
}
# The main list of valid statements
-statement: resource
+statement_or_declaration: resource
| virtualresource
| collection
| assignment
@@ -89,19 +81,17 @@ relationship_side: resource | resourceref | collection
edge: IN_EDGE | OUT_EDGE | IN_EDGE_SUB | OUT_EDGE_SUB
fstatement: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :statement
}
| NAME LPAREN funcvalues COMMA RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :statement
} | NAME LPAREN RPAREN {
result = ast AST::Function,
@@ -111,29 +101,22 @@ fstatement: NAME LPAREN funcvalues RPAREN {
:ftype => :statement
}
| NAME funcvalues {
- args = aryfy(val[1])
result = ast AST::Function,
:name => val[0][:value],
:line => val[0][:line],
- :arguments => args,
+ :arguments => val[1],
:ftype => :statement
}
-funcvalues: namestring
- | resourceref
+funcvalues: namestring { result = aryfy(val[0]) }
+ | resourceref { result = aryfy(val[0]) }
| funcvalues COMMA namestring {
- result = aryfy(val[0], val[2])
- result.line = @lexer.line
- result.file = @lexer.file
+ val[0].push(val[2])
+ result = val[0]
}
| funcvalues COMMA resourceref {
- unless val[0].is_a?(AST::ASTArray)
- val[0] = aryfy(val[0])
- end
-
- val[0].push(val[2])
-
- result = val[0]
+ val[0].push(val[2])
+ result = val[0]
}
# This is *almost* an rvalue, but I couldn't get a full
@@ -152,23 +135,7 @@ namestring: name
resource: classname LBRACE resourceinstances endsemi RBRACE {
@lexer.commentpop
- array = val[2]
- array = [array] if array.instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray
-
- # this iterates across each specified resourceinstance
- array.each { |instance|
- raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance)
- # now, i need to somehow differentiate between those things with
- # arrays in their names, and normal things
-
- result.push ast(
- AST::Resource,
- :type => val[0],
- :title => instance[0],
-
- :parameters => instance[1])
- }
+ result = ast(AST::Resource, :type => val[0], :instances => val[2])
} | classname LBRACE params endcomma RBRACE {
# This is a deprecated syntax.
error "All resource specifications require names"
@@ -197,14 +164,8 @@ virtualresource: at resource {
method = type.to_s + "="
- # Just mark our resources as exported and pass them through.
- if val[1].instance_of?(AST::ASTArray)
- val[1].each do |obj|
- obj.send(method, true)
- end
- else
- val[1].send(method, true)
- end
+ # Just mark our resource as exported and pass it through.
+ val[1].send(method, true)
result = val[1]
}
@@ -303,17 +264,13 @@ colllval: variable
| name
resourceinst: resourcename COLON params endcomma {
- result = ast AST::ResourceInstance, :children => [val[0],val[2]]
+ result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2]
}
-resourceinstances: resourceinst
+resourceinstances: resourceinst { result = aryfy(val[0]) }
| resourceinstances SEMIC resourceinst {
- if val[0].instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- else
val[0].push val[2]
result = val[0]
- end
}
endsemi: # nothing
@@ -358,14 +315,10 @@ params: # nothing
{
result = ast AST::ASTArray
}
- | param { result = val[0] }
+ | param { result = aryfy(val[0]) }
| params COMMA param {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
param: NAME FARROW rvalue {
@@ -384,24 +337,14 @@ anyparams: # nothing
{
result = ast AST::ASTArray
}
- | anyparam { result = val[0] }
+ | anyparam { result = aryfy(val[0]) }
| anyparams COMMA anyparam {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
-rvalues: rvalue
- | rvalues comma rvalue {
- if val[0].instance_of?(AST::ASTArray)
- result = val[0].push(val[2])
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
-}
+rvalues: rvalue { result = aryfy(val[0]) }
+ | rvalues comma rvalue { result = val[0].push(val[2]) }
simplervalue: quotedtext
| name
@@ -425,10 +368,9 @@ rvalue: quotedtext
# We currently require arguments in these functions.
funcrvalue: NAME LPAREN funcvalues RPAREN {
- args = aryfy(val[2])
result = ast AST::Function,
:name => val[0][:value], :line => val[0][:line],
- :arguments => args,
+ :arguments => val[2],
:ftype => :rvalue
} | NAME LPAREN RPAREN {
result = ast AST::Function,
@@ -572,19 +514,13 @@ expression: rvalue
casestatement: CASE rvalue LBRACE caseopts RBRACE {
@lexer.commentpop
- options = val[3]
- options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray)
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ result = ast AST::CaseStatement, :test => val[1], :options => val[3]
}
-caseopts: caseopt
+caseopts: caseopt { result = aryfy(val[0]) }
| caseopts caseopt {
- if val[0].instance_of?(AST::ASTArray)
val[0].push val[1]
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0], val[1]]
- end
}
caseopt: casevalues COLON LBRACE statements RBRACE {
@@ -601,14 +537,10 @@ caseopt: casevalues COLON LBRACE statements RBRACE {
)
}
-casevalues: selectlhand
+casevalues: selectlhand { result = aryfy(val[0]) }
| casevalues COMMA selectlhand {
- if val[0].instance_of?(AST::ASTArray)
val[0].push(val[2])
result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
}
selector: selectlhand QMARK svalues {
@@ -657,48 +589,51 @@ import: IMPORT strings {
import(file)
end
- result = AST::ASTArray.new(:children => [])
+ result = nil
}
# Disable definition inheritance for now. 8/27/06, luke
#definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE {
definition: DEFINE classname argumentlist LBRACE statements RBRACE {
@lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :code => val[4],
+ :line => val[0][:line]))
@lexer.indefine = false
- result = nil
#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
} | DEFINE classname argumentlist LBRACE RBRACE {
@lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :line => val[0][:line]))
@lexer.indefine = false
- result = nil
}
#hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE {
-hostclass: CLASS classname argumentlist classparent LBRACE statements RBRACE {
+hostclass: CLASS classname argumentlist classparent LBRACE statements_and_declarations RBRACE {
@lexer.commentpop
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :code => val[5], :line => val[0][:line]))
} | CLASS classname argumentlist classparent LBRACE RBRACE {
@lexer.commentpop
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :line => val[0][:line]))
}
nodedef: NODE hostnames nodeparent LBRACE statements RBRACE {
@lexer.commentpop
- newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Node.new(val[1],
+ ast_context(true).merge(:parent => val[2], :code => val[4],
+ :line => val[0][:line]))
} | NODE hostnames nodeparent LBRACE RBRACE {
@lexer.commentpop
- newnode val[1], :parent => val[2], :line => val[0][:line]
- result = nil
+ result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line]))
}
classref: CLASSREF { result = val[0][:value] }
@@ -709,10 +644,11 @@ classname: NAME { result = val[0][:value] }
# Multiple hostnames, as used for node names. These are all literal
# strings, not AST objects.
-hostnames: nodename
+hostnames: nodename {
+ result = [result]
+}
| hostnames COMMA nodename {
result = val[0]
- result = [result] unless result.is_a?(Array)
result << val[2]
}
@@ -778,22 +714,9 @@ variable: VARIABLE {
result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
}
-array: LBRACK rvalues RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
-}
- | LBRACK rvalues COMMA RBRACK {
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
-} | LBRACK RBRACK {
- result = ast AST::ASTArray
-}
+array: LBRACK rvalues RBRACK { result = val[1] }
+ | LBRACK rvalues COMMA RBRACK { result = val[1] }
+ | LBRACK RBRACK { result = ast AST::ASTArray }
comma: FARROW
| COMMA
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 1e10ff96c..31d39ae2f 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -221,7 +221,7 @@ class Puppet::Parser::Lexer
TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
TOKENS.add_token :SQUOTE, "'" do |lexer, value|
- [TOKENS[:STRING], lexer.slurpstring(value).first ]
+ [TOKENS[:STRING], lexer.slurpstring(value,["'"],:ignore_invalid_escapes).first ]
end
DQ_initial_token_types = {'$' => :DQPRE,'"' => :STRING}
@@ -483,7 +483,7 @@ class Puppet::Parser::Lexer
yield [final_token.name, token_value]
if @previous_token
- namestack(value) if @previous_token.name == :CLASS
+ namestack(value) if @previous_token.name == :CLASS and value != '{'
if @previous_token.name == :DEFINE
if indefine?
@@ -517,24 +517,24 @@ class Puppet::Parser::Lexer
# we've encountered the start of a string...
# slurp in the rest of the string and return it
- Valid_escapes_in_strings = %w{ \\ $ ' " n t s }+["\n"]
- def slurpstring(terminators)
+ def slurpstring(terminators,escapes=%w{ \\ $ ' " n t s }+["\n"],ignore_invalid_escapes=false)
# we search for the next quote that isn't preceded by a
# backslash; the caret is there to match empty strings
- str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
+ str = @scanner.scan_until(/([^\\]|^|[^\\])([\\]{2})*[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
@line += str.count("\n") # literal carriage returns add to the line count.
- str.gsub!(/\\(.)/) {
- case ch=$1
- when 'n'; "\n"
- when 't'; "\t"
- when 's'; " "
- else
- if Valid_escapes_in_strings.include? ch and not (ch == '"' and terminators == "'")
- ch
- else
- Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}"
- "\\#{ch}"
+ str.gsub!(/\\(.)/m) {
+ ch = $1
+ if escapes.include? ch
+ case ch
+ when 'n'; "\n"
+ when 't'; "\t"
+ when 's'; " "
+ when "\n": ''
+ else ch
end
+ else
+ Puppet.warning "Unrecognised escape sequence '\\#{ch}'#{file && " in file #{file}"}#{line && " at line #{line}"}" unless ignore_invalid_escapes
+ "\\#{ch}"
end
}
[ str[0..-2],str[-1,1] ]
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index 5be9e5a3f..60b272e76 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -13,9 +13,9 @@ require 'puppet/parser/lexer'
require 'puppet/parser/ast'
module Puppet
- class ParseError < Puppet::Error; end
- class ImportError < Racc::ParseError; end
- class AlreadyImportedError < ImportError; end
+ class ParseError < Puppet::Error; end
+ class ImportError < Racc::ParseError; end
+ class AlreadyImportedError < ImportError; end
end
@@ -25,7 +25,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..id7145220b1b', 'grammar.ra', 876
+module_eval <<'..end grammar.ra modeval..id6362f948d9', 'grammar.ra', 788
# It got too annoying having code in a file that needs to be compiled.
require 'puppet/parser/parser_support'
@@ -37,16 +37,17 @@ require 'puppet/parser/parser_support'
# $Id$
-..end grammar.ra modeval..id7145220b1b
+..end grammar.ra modeval..id6362f948d9
##### racc 1.4.5 generates ###
racc_reduce_table = [
0, 0, :racc_error,
- 1, 70, :_reduce_1,
1, 70, :_reduce_none,
- 1, 71, :_reduce_none,
+ 1, 70, :_reduce_none,
+ 1, 71, :_reduce_3,
2, 71, :_reduce_4,
+ 1, 74, :_reduce_5,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
@@ -61,864 +62,820 @@ racc_reduce_table = [
1, 73, :_reduce_none,
1, 73, :_reduce_none,
1, 73, :_reduce_none,
- 3, 87, :_reduce_19,
- 3, 87, :_reduce_20,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 89, :_reduce_none,
+ 3, 88, :_reduce_20,
+ 3, 88, :_reduce_21,
1, 89, :_reduce_none,
1, 89, :_reduce_none,
1, 89, :_reduce_none,
- 4, 81, :_reduce_28,
- 5, 81, :_reduce_29,
- 3, 81, :_reduce_30,
- 2, 81, :_reduce_31,
- 1, 91, :_reduce_none,
- 1, 91, :_reduce_none,
- 3, 91, :_reduce_34,
- 3, 91, :_reduce_35,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_none,
- 1, 92, :_reduce_44,
- 5, 74, :_reduce_45,
- 5, 74, :_reduce_46,
- 5, 74, :_reduce_47,
- 5, 85, :_reduce_48,
- 2, 75, :_reduce_49,
- 1, 108, :_reduce_50,
- 2, 108, :_reduce_51,
- 6, 76, :_reduce_52,
- 2, 76, :_reduce_53,
- 3, 109, :_reduce_54,
- 3, 109, :_reduce_55,
- 1, 110, :_reduce_none,
- 1, 110, :_reduce_none,
- 3, 110, :_reduce_58,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 1, 90, :_reduce_none,
+ 4, 82, :_reduce_29,
+ 5, 82, :_reduce_30,
+ 3, 82, :_reduce_31,
+ 2, 82, :_reduce_32,
+ 1, 92, :_reduce_33,
+ 1, 92, :_reduce_34,
+ 3, 92, :_reduce_35,
+ 3, 92, :_reduce_36,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_none,
+ 1, 93, :_reduce_45,
+ 5, 75, :_reduce_46,
+ 5, 75, :_reduce_47,
+ 5, 75, :_reduce_48,
+ 5, 86, :_reduce_49,
+ 2, 76, :_reduce_50,
+ 1, 109, :_reduce_51,
+ 2, 109, :_reduce_52,
+ 6, 77, :_reduce_53,
+ 2, 77, :_reduce_54,
+ 3, 110, :_reduce_55,
+ 3, 110, :_reduce_56,
1, 111, :_reduce_none,
- 3, 111, :_reduce_60,
- 1, 112, :_reduce_61,
- 1, 112, :_reduce_62,
- 3, 113, :_reduce_63,
- 3, 113, :_reduce_64,
- 1, 114, :_reduce_none,
- 1, 114, :_reduce_none,
- 4, 116, :_reduce_67,
- 1, 102, :_reduce_none,
- 3, 102, :_reduce_69,
- 0, 103, :_reduce_none,
- 1, 103, :_reduce_none,
- 1, 118, :_reduce_72,
- 1, 93, :_reduce_73,
- 1, 95, :_reduce_74,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 1, 117, :_reduce_none,
- 3, 77, :_reduce_82,
- 3, 77, :_reduce_83,
- 3, 86, :_reduce_84,
- 0, 104, :_reduce_85,
- 1, 104, :_reduce_86,
- 3, 104, :_reduce_87,
- 3, 122, :_reduce_88,
- 3, 124, :_reduce_89,
- 1, 125, :_reduce_none,
- 1, 125, :_reduce_none,
- 0, 107, :_reduce_92,
- 1, 107, :_reduce_93,
- 3, 107, :_reduce_94,
- 1, 126, :_reduce_none,
- 3, 126, :_reduce_96,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
+ 1, 111, :_reduce_none,
+ 3, 111, :_reduce_59,
+ 1, 112, :_reduce_none,
+ 3, 112, :_reduce_61,
+ 1, 113, :_reduce_62,
+ 1, 113, :_reduce_63,
+ 3, 114, :_reduce_64,
+ 3, 114, :_reduce_65,
1, 115, :_reduce_none,
1, 115, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 4, 97, :_reduce_115,
- 3, 97, :_reduce_116,
- 1, 99, :_reduce_117,
- 2, 99, :_reduce_118,
- 2, 129, :_reduce_119,
- 1, 130, :_reduce_120,
- 2, 130, :_reduce_121,
- 1, 96, :_reduce_122,
- 4, 90, :_reduce_123,
- 4, 90, :_reduce_124,
- 2, 79, :_reduce_125,
- 5, 131, :_reduce_126,
- 4, 131, :_reduce_127,
- 0, 132, :_reduce_none,
- 2, 132, :_reduce_129,
- 4, 132, :_reduce_130,
- 3, 132, :_reduce_131,
- 1, 120, :_reduce_none,
- 3, 120, :_reduce_133,
- 3, 120, :_reduce_134,
- 3, 120, :_reduce_135,
- 3, 120, :_reduce_136,
- 3, 120, :_reduce_137,
- 3, 120, :_reduce_138,
- 3, 120, :_reduce_139,
- 3, 120, :_reduce_140,
- 3, 120, :_reduce_141,
- 2, 120, :_reduce_142,
- 3, 120, :_reduce_143,
- 3, 120, :_reduce_144,
- 3, 120, :_reduce_145,
- 3, 120, :_reduce_146,
- 3, 120, :_reduce_147,
- 3, 120, :_reduce_148,
- 2, 120, :_reduce_149,
- 3, 120, :_reduce_150,
- 3, 120, :_reduce_151,
- 3, 120, :_reduce_152,
- 5, 78, :_reduce_153,
- 1, 134, :_reduce_none,
- 2, 134, :_reduce_155,
- 5, 135, :_reduce_156,
- 4, 135, :_reduce_157,
- 1, 136, :_reduce_none,
- 3, 136, :_reduce_159,
- 3, 98, :_reduce_160,
+ 4, 117, :_reduce_68,
+ 1, 103, :_reduce_69,
+ 3, 103, :_reduce_70,
+ 0, 104, :_reduce_none,
+ 1, 104, :_reduce_none,
+ 1, 119, :_reduce_73,
+ 1, 94, :_reduce_74,
+ 1, 96, :_reduce_75,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 1, 118, :_reduce_none,
+ 3, 78, :_reduce_83,
+ 3, 78, :_reduce_84,
+ 3, 87, :_reduce_85,
+ 0, 105, :_reduce_86,
+ 1, 105, :_reduce_87,
+ 3, 105, :_reduce_88,
+ 3, 123, :_reduce_89,
+ 3, 125, :_reduce_90,
+ 1, 126, :_reduce_none,
+ 1, 126, :_reduce_none,
+ 0, 108, :_reduce_93,
+ 1, 108, :_reduce_94,
+ 3, 108, :_reduce_95,
+ 1, 127, :_reduce_96,
+ 3, 127, :_reduce_97,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 116, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 1, 124, :_reduce_none,
+ 4, 98, :_reduce_116,
+ 3, 98, :_reduce_117,
+ 1, 100, :_reduce_118,
+ 2, 100, :_reduce_119,
+ 2, 130, :_reduce_120,
+ 1, 131, :_reduce_121,
+ 2, 131, :_reduce_122,
+ 1, 97, :_reduce_123,
+ 4, 91, :_reduce_124,
+ 4, 91, :_reduce_125,
+ 2, 80, :_reduce_126,
+ 5, 132, :_reduce_127,
+ 4, 132, :_reduce_128,
+ 0, 133, :_reduce_none,
+ 2, 133, :_reduce_130,
+ 4, 133, :_reduce_131,
+ 3, 133, :_reduce_132,
+ 1, 121, :_reduce_none,
+ 3, 121, :_reduce_134,
+ 3, 121, :_reduce_135,
+ 3, 121, :_reduce_136,
+ 3, 121, :_reduce_137,
+ 3, 121, :_reduce_138,
+ 3, 121, :_reduce_139,
+ 3, 121, :_reduce_140,
+ 3, 121, :_reduce_141,
+ 3, 121, :_reduce_142,
+ 2, 121, :_reduce_143,
+ 3, 121, :_reduce_144,
+ 3, 121, :_reduce_145,
+ 3, 121, :_reduce_146,
+ 3, 121, :_reduce_147,
+ 3, 121, :_reduce_148,
+ 3, 121, :_reduce_149,
+ 2, 121, :_reduce_150,
+ 3, 121, :_reduce_151,
+ 3, 121, :_reduce_152,
+ 3, 121, :_reduce_153,
+ 5, 79, :_reduce_154,
+ 1, 135, :_reduce_155,
+ 2, 135, :_reduce_156,
+ 5, 136, :_reduce_157,
+ 4, 136, :_reduce_158,
+ 1, 137, :_reduce_159,
+ 3, 137, :_reduce_160,
+ 3, 99, :_reduce_161,
+ 1, 139, :_reduce_none,
+ 4, 139, :_reduce_163,
+ 1, 141, :_reduce_none,
+ 3, 141, :_reduce_165,
+ 3, 140, :_reduce_166,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
1, 138, :_reduce_none,
- 4, 138, :_reduce_162,
- 1, 140, :_reduce_none,
- 3, 140, :_reduce_164,
- 3, 139, :_reduce_165,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_173,
- 1, 137, :_reduce_none,
- 1, 141, :_reduce_175,
- 1, 142, :_reduce_none,
- 3, 142, :_reduce_177,
- 2, 80, :_reduce_178,
- 6, 82, :_reduce_179,
- 5, 82, :_reduce_180,
- 7, 83, :_reduce_181,
- 6, 83, :_reduce_182,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_none,
+ 1, 138, :_reduce_174,
+ 1, 138, :_reduce_none,
+ 1, 142, :_reduce_176,
+ 1, 143, :_reduce_none,
+ 3, 143, :_reduce_178,
+ 2, 81, :_reduce_179,
+ 6, 83, :_reduce_180,
+ 5, 83, :_reduce_181,
+ 7, 84, :_reduce_182,
6, 84, :_reduce_183,
- 5, 84, :_reduce_184,
- 1, 106, :_reduce_185,
- 1, 101, :_reduce_186,
- 1, 101, :_reduce_187,
- 1, 101, :_reduce_188,
- 1, 145, :_reduce_none,
- 3, 145, :_reduce_190,
- 1, 147, :_reduce_191,
+ 6, 85, :_reduce_184,
+ 5, 85, :_reduce_185,
+ 1, 107, :_reduce_186,
+ 1, 102, :_reduce_187,
+ 1, 102, :_reduce_188,
+ 1, 102, :_reduce_189,
+ 1, 146, :_reduce_190,
+ 3, 146, :_reduce_191,
1, 148, :_reduce_192,
- 1, 148, :_reduce_193,
- 1, 148, :_reduce_194,
- 1, 148, :_reduce_none,
- 0, 72, :_reduce_196,
- 0, 149, :_reduce_197,
- 1, 143, :_reduce_none,
- 3, 143, :_reduce_199,
- 3, 143, :_reduce_200,
- 1, 150, :_reduce_none,
- 3, 150, :_reduce_202,
- 3, 151, :_reduce_203,
- 1, 151, :_reduce_204,
- 3, 151, :_reduce_205,
- 1, 151, :_reduce_206,
- 1, 146, :_reduce_none,
- 2, 146, :_reduce_208,
+ 1, 149, :_reduce_193,
+ 1, 149, :_reduce_194,
+ 1, 149, :_reduce_195,
+ 1, 149, :_reduce_none,
+ 0, 72, :_reduce_197,
+ 0, 150, :_reduce_198,
1, 144, :_reduce_none,
- 2, 144, :_reduce_210,
- 1, 152, :_reduce_none,
- 1, 152, :_reduce_none,
- 1, 94, :_reduce_213,
- 3, 119, :_reduce_214,
- 4, 119, :_reduce_215,
- 2, 119, :_reduce_216,
- 1, 127, :_reduce_none,
- 1, 127, :_reduce_none,
- 0, 105, :_reduce_none,
- 1, 105, :_reduce_220,
- 1, 133, :_reduce_221,
- 3, 128, :_reduce_222,
- 4, 128, :_reduce_223,
- 2, 128, :_reduce_224,
+ 3, 144, :_reduce_200,
+ 3, 144, :_reduce_201,
+ 1, 151, :_reduce_none,
+ 3, 151, :_reduce_203,
+ 3, 152, :_reduce_204,
+ 1, 152, :_reduce_205,
+ 3, 152, :_reduce_206,
+ 1, 152, :_reduce_207,
+ 1, 147, :_reduce_none,
+ 2, 147, :_reduce_209,
+ 1, 145, :_reduce_none,
+ 2, 145, :_reduce_211,
1, 153, :_reduce_none,
- 3, 153, :_reduce_226,
+ 1, 153, :_reduce_none,
+ 1, 95, :_reduce_214,
+ 3, 120, :_reduce_215,
+ 4, 120, :_reduce_216,
+ 2, 120, :_reduce_217,
+ 1, 128, :_reduce_none,
+ 1, 128, :_reduce_none,
+ 0, 106, :_reduce_none,
+ 1, 106, :_reduce_221,
+ 1, 134, :_reduce_222,
+ 3, 129, :_reduce_223,
+ 4, 129, :_reduce_224,
+ 2, 129, :_reduce_225,
+ 1, 154, :_reduce_none,
3, 154, :_reduce_227,
- 1, 155, :_reduce_228,
- 1, 155, :_reduce_229,
- 4, 121, :_reduce_230,
- 1, 100, :_reduce_none,
- 4, 100, :_reduce_232 ]
+ 3, 155, :_reduce_228,
+ 1, 156, :_reduce_229,
+ 1, 156, :_reduce_230,
+ 4, 122, :_reduce_231,
+ 1, 101, :_reduce_none,
+ 4, 101, :_reduce_233 ]
-racc_reduce_n = 233
+racc_reduce_n = 234
-racc_shift_n = 384
+racc_shift_n = 385
racc_action_table = [
- 256, 257, 228, 82, 54, 72, 75, 181, 251, 48,
- 72, 75, 194, 205, 210, 163, 156, 348, 46, 47,
- 344, 184, 201, 203, 206, 209, 162, 352, 54, 182,
- 351, 169, 54, -168, 72, 75, 241, 242, 102, 305,
- 106, 158, 58, 193, 230, 60, 204, 208, 193, 306,
- 213, 196, 197, 198, 200, 202, 97, 207, 211, 72,
- 75, 72, 75, 163, 199, 59, 58, 71, 245, 60,
- 58, 83, 86, 60, 162, 92, 244, 72, 75, 169,
- 78, 100, 352, 269, 89, 351, 63, 94, 64, 59,
- 228, 326, 71, 59, 162, 59, 83, 86, 83, 268,
- 92, 65, 92, 184, 76, 78, 307, 137, 163, 89,
- 162, 89, 72, 75, 83, 268, 241, 242, 92, 162,
- 59, 163, 59, 137, 169, 62, 254, 89, 207, 211,
- 72, 75, 162, 308, 102, 199, 106, 169, 59, 255,
- 213, 196, 197, 198, -166, 162, 309, 207, 211, 83,
- 268, 310, 97, 92, 199, 72, 75, 355, 137, 102,
- -170, 106, 89, 71, 218, 356, 173, 83, 86, 220,
- 313, 92, -171, 59, 72, 75, 78, 100, 37, 218,
- 89, 249, 38, 94, 220, 246, 247, 173, 71, 11,
- 210, 59, 83, 86, 246, 367, 92, 271, 201, 37,
- -167, 78, 37, 38, 270, 89, 38, 71, 246, 247,
- 11, 83, 86, 11, 14, 92, 59, 72, 75, 76,
- 78, 102, 278, 106, 89, 277, 213, 196, 197, 198,
- 200, 202, 275, 207, 211, 59, 246, 274, 152, 97,
- 199, 37, 318, 72, 75, 127, 319, 102, -169, 106,
- 71, 63, 11, 14, 83, 86, -167, 37, 92, 207,
- 211, 127, -169, 78, 100, 97, 199, 89, 11, 14,
- 94, -166, 117, 72, 75, -185, 71, 82, 59, 336,
- 83, 86, 197, 198, 92, 231, 338, 207, 211, 78,
- 100, 181, 48, 89, 199, 74, 94, 240, -168, 72,
- 75, 241, 242, 102, 59, 106, 71, 184, 176, 37,
- 83, 86, 59, 38, 92, 345, 322, 175, 76, 78,
- 11, 97, -172, 89, -171, 72, 75, -170, 59, 102,
- 214, 106, 71, 64, 59, 215, 83, 86, 173, 217,
- 92, -23, -23, -23, -23, 78, 100, 97, 155, 89,
- 72, 75, 94, 122, 102, 152, 106, 82, 71, 223,
- 59, 122, 83, 86, 72, 75, 92, -168, 102, 225,
- 106, 78, 100, -166, 276, 89, 226, 117, 94, 44,
- 45, 41, 42, 71, -169, -167, 59, 83, 86, 72,
- 75, 92, 226, 102, 229, 106, 78, 71, 52, -168,
- 89, 83, 86, 72, 75, 92, -166, 102, -169, 106,
- 78, 59, 197, 198, 89, -167, -171, 207, 211, 365,
- 231, 152, 71, 234, 199, 59, 83, 86, 50, 210,
- 92, -21, -21, -21, -21, 78, 71, 201, 372, 89,
- 83, 86, 49, 374, 92, 72, 75, 228, -220, 78,
- 59, 226, 354, 89, 377, 72, 75, 40, 39, 102,
- 237, 106, 341, nil, 59, 213, 196, 197, 198, 200,
- 202, nil, 207, 211, nil, nil, nil, 97, 162, 199,
- nil, nil, 83, 268, nil, nil, 92, nil, 71, nil,
- nil, 137, 83, 86, nil, 89, 92, 44, 45, 41,
- 42, 78, 100, 72, 75, 89, 59, 102, 94, 106,
- 213, 196, 197, 198, 200, 202, 59, 207, 211, nil,
- 213, 196, 197, 198, 199, 97, nil, 207, 211, 72,
- 75, nil, nil, 102, 199, 106, 71, nil, nil, nil,
- 83, 86, nil, nil, 92, nil, nil, nil, nil, 78,
- 100, 97, nil, 89, nil, nil, 94, nil, nil, 72,
- 75, nil, 71, 102, 59, 106, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, 100, nil, nil, 89,
- nil, 97, 94, nil, nil, 72, 75, nil, nil, 102,
- 59, 106, 71, nil, nil, nil, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, 100, 97, nil, 89,
- 72, 75, 94, nil, 102, nil, 106, nil, 71, nil,
- 59, nil, 83, 86, 72, 75, 92, nil, 102, nil,
- nil, 78, 100, nil, nil, 89, nil, nil, 94, nil,
- nil, nil, nil, 71, nil, nil, 59, 83, 86, 72,
- 75, 92, nil, 102, nil, 106, 78, 71, nil, nil,
- 89, 83, 143, nil, nil, 92, nil, nil, nil, nil,
- 137, 59, nil, nil, 89, 72, 75, nil, nil, 102,
- nil, 106, 71, nil, nil, 59, 83, 86, nil, nil,
- 92, nil, nil, nil, nil, 78, nil, 97, nil, 89,
- nil, 72, 75, nil, nil, 102, nil, 106, 71, nil,
- 59, nil, 83, 86, nil, nil, 92, nil, nil, nil,
- nil, 78, 100, 97, nil, 89, nil, nil, 94, nil,
- nil, 72, 75, nil, 71, 102, 59, 106, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, nil,
- nil, 89, nil, 97, 94, nil, nil, 72, 75, nil,
- nil, 102, 59, 106, 71, nil, nil, nil, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, 97,
- nil, 89, 72, 75, 94, nil, 102, nil, 106, nil,
- 71, nil, 59, nil, 83, 86, nil, nil, 92, nil,
- nil, nil, nil, 78, 100, nil, nil, 89, 72, 75,
- 94, nil, 102, nil, 106, 71, nil, nil, 59, 83,
- 86, nil, nil, 92, nil, nil, nil, nil, 78, nil,
- 97, nil, 89, nil, 72, 75, nil, nil, 102, nil,
- 106, 71, nil, 59, nil, 83, 86, nil, nil, 92,
- nil, nil, 72, 75, 78, 100, 97, nil, 89, 72,
- 75, 94, nil, 102, nil, 106, nil, 71, nil, 59,
- nil, 83, 86, nil, nil, 92, nil, nil, nil, nil,
- 78, 100, nil, nil, 89, 162, nil, 94, nil, 83,
- 268, nil, 71, 92, nil, 59, 83, 86, 137, nil,
- 92, nil, 89, nil, nil, 78, 72, 75, nil, 89,
- 102, nil, 106, 59, nil, nil, nil, nil, nil, nil,
- 59, nil, nil, nil, nil, 72, 75, nil, 97, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 71,
- nil, nil, nil, 83, 86, nil, nil, 92, 177, nil,
- 72, 75, 78, 100, nil, nil, 89, nil, 71, 94,
- nil, nil, 83, 86, nil, nil, 92, 59, 72, 75,
- 76, 78, 102, 339, 106, 89, nil, nil, nil, nil,
- nil, nil, nil, 71, nil, nil, 59, 83, 86, nil,
- 97, 92, nil, 72, 75, 76, 78, 102, nil, 106,
- 89, 71, nil, 72, 75, 83, 86, nil, nil, 92,
- nil, 59, nil, nil, 78, 100, nil, nil, 89, 72,
- 75, 94, nil, nil, nil, nil, 71, nil, nil, 59,
- 83, 86, nil, nil, 92, nil, 162, nil, nil, 78,
- 83, 268, nil, 89, 92, nil, 72, 75, nil, 137,
- 102, nil, 162, 89, 59, nil, 83, 268, nil, nil,
- 92, nil, 72, 75, 59, 137, 102, nil, 106, 89,
- nil, nil, 72, 75, nil, nil, 102, nil, 106, 71,
- 59, nil, nil, 83, 268, nil, nil, 92, nil, nil,
- nil, nil, 137, nil, 97, 71, 89, nil, nil, 83,
- 86, nil, nil, 92, nil, 71, nil, 59, 78, 83,
- 86, nil, 89, 92, nil, nil, nil, nil, 78, 100,
- 72, 75, 89, 59, 102, 94, 106, 213, 196, 197,
- 198, 200, 202, 59, 207, 211, nil, nil, nil, 72,
- 75, 199, 97, 102, 189, 106, 72, 75, nil, nil,
- 102, nil, 106, 71, nil, nil, nil, 83, 86, nil,
- nil, 92, nil, nil, nil, nil, 78, 100, 72, 75,
- 89, nil, 71, 94, nil, nil, 83, 86, nil, 71,
- 92, 59, nil, 83, 86, 78, nil, 92, nil, 89,
- nil, nil, 78, 72, 75, nil, 89, 102, nil, 106,
- 59, 162, nil, nil, nil, 83, 268, 59, nil, 92,
- nil, 72, 75, nil, 137, 102, nil, 106, 89, nil,
- nil, nil, nil, nil, nil, nil, 71, nil, nil, 59,
- 83, 86, nil, 97, 92, nil, nil, nil, nil, 78,
- nil, 72, 75, 89, 71, 102, nil, 106, 83, 86,
- nil, nil, 92, nil, 59, nil, nil, 78, 100, nil,
- nil, 89, nil, 97, 94, nil, nil, 72, 75, nil,
- nil, 102, 59, 106, 71, nil, nil, nil, 83, 86,
- nil, nil, 92, nil, nil, nil, nil, 78, 100, 97,
- nil, 89, nil, nil, 94, nil, nil, nil, nil, nil,
- 71, nil, 59, nil, 83, 86, 212, nil, 92, nil,
- nil, nil, nil, 78, 100, 205, 210, 89, nil, nil,
- 94, nil, nil, nil, 201, 203, 206, 209, 59, nil,
- 205, 210, nil, nil, nil, nil, nil, nil, nil, 201,
- 203, 206, 209, nil, nil, nil, nil, nil, 204, 208,
- nil, nil, 213, 196, 197, 198, 200, 202, nil, 207,
- 211, nil, nil, 204, 208, nil, 199, 213, 196, 197,
- 198, 200, 202, nil, 207, 211, 205, 210, nil, nil,
- nil, 199, nil, nil, nil, 201, 203, 206, 209, nil,
- nil, 205, 210, nil, nil, nil, nil, nil, nil, nil,
- 201, 203, 206, 209, nil, nil, nil, nil, nil, 204,
- 208, nil, nil, 213, 196, 197, 198, 200, 202, nil,
- 207, 211, nil, nil, 204, 208, nil, 199, 213, 196,
- 197, 198, 200, 202, nil, 207, 211, 205, 210, nil,
- nil, nil, 199, nil, nil, nil, 201, 203, 206, 209,
- nil, nil, 205, 210, nil, nil, nil, nil, nil, nil,
- 273, 201, 203, 206, 209, nil, nil, nil, nil, nil,
- nil, 208, nil, nil, 213, 196, 197, 198, 200, 202,
- nil, 207, 211, nil, nil, 204, 208, nil, 199, 213,
- 196, 197, 198, 200, 202, nil, 207, 211, 205, 210,
- nil, nil, nil, 199, nil, nil, nil, 201, 203, 206,
- 209, nil, nil, 26, 210, 33, 1, nil, 7, 12,
- nil, 17, 201, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, nil, 210, nil, 213, 196, 197, 198, 200,
- 202, 201, 207, 211, nil, nil, nil, nil, nil, 199,
- 213, 196, 197, 198, 200, 202, nil, 207, 211, nil,
- nil, 324, nil, nil, 199, nil, nil, nil, nil, 213,
- 196, 197, 198, 200, 202, nil, 207, 211, nil, nil,
- 379, nil, 26, 199, 33, 1, nil, 7, 12, nil,
- 17, nil, 23, nil, 29, nil, 3, nil, nil, 11,
- 14, 26, 382, 33, 1, nil, 7, 12, nil, 17,
- nil, 23, nil, 29, nil, 3, nil, nil, 11, 14,
- nil, 296, nil, 26, nil, 33, 1, nil, 7, 12,
- nil, 17, nil, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, 26, 364, 33, 1, nil, 7, 12, nil,
- 17, nil, 23, nil, 29, nil, 3, nil, nil, 11,
- 14, nil, 381, nil, 26, nil, 33, 1, nil, 7,
- 12, nil, 17, nil, 23, nil, 29, nil, 3, nil,
- nil, 11, 14, 26, 383, 33, 1, nil, 7, 12,
- nil, 17, nil, 23, nil, 29, nil, 3, nil, nil,
- 11, 14, nil, 357, nil, 26, nil, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14, 26, 363, 33, 1, nil, 7,
- 12, nil, 17, nil, 23, nil, 29, nil, 3, nil,
- nil, 11, 14, nil, 375, nil, 26, nil, 33, 1,
- nil, 7, 12, nil, 17, nil, 23, nil, 29, nil,
- 3, nil, nil, 11, 14, 26, 304, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14, nil, 349, nil, 26, nil, 33,
- 1, nil, 7, 12, nil, 17, nil, 23, nil, 29,
- nil, 3, nil, nil, 11, 14, 26, nil, 33, 1,
- nil, 7, 12, nil, 17, nil, 23, nil, 29, nil,
- 3, nil, nil, 11, 14, 26, nil, 33, 1, nil,
- 7, 12, nil, 17, nil, 23, nil, 29, nil, 3,
- nil, nil, 11, 14 ]
+ 242, 243, 55, 231, 356, 112, 157, 113, 78, 298,
+ 68, 71, 357, 181, 186, 326, 344, 340, 55, 295,
+ 114, 231, 177, 179, 182, 185, 170, 294, 68, 71,
+ 286, 158, 100, 285, 103, 68, 71, 291, 292, 55,
+ 59, 291, 292, 61, 111, 233, 180, 184, 198, 231,
+ 189, 172, 173, 174, 176, 178, 59, 183, 187, 61,
+ -168, 66, 170, 60, 175, 79, 81, 186, 202, 88,
+ 112, 166, 79, 252, 74, 177, 88, 59, 84, 60,
+ 61, 139, 68, 71, 333, 84, 100, 117, 103, 60,
+ 36, -170, 68, 71, 38, 306, 60, 307, 203, 240,
+ 60, 10, 203, 189, 172, 173, 174, 176, 178, 202,
+ 183, 187, 241, 202, 209, 66, 218, 175, 209, 79,
+ 81, 219, 284, 88, 309, 202, 256, 283, 74, 79,
+ 252, 308, 84, 88, 203, 68, 71, 310, 139, 100,
+ 203, 103, 84, 60, 218, 202, 256, 367, 36, 219,
+ 209, 202, 38, 60, 68, 71, 209, 95, 100, 10,
+ 103, 68, 71, 68, 71, 100, 337, 103, 66, 335,
+ 199, 154, 79, 81, 173, 174, 88, 183, 187, 183,
+ 187, 74, 99, 95, 175, 84, 175, 66, 90, 311,
+ 337, 79, 81, 335, 66, 88, 60, 287, 79, 81,
+ 74, 198, 88, 315, 84, 68, 71, 74, 99, -172,
+ 213, 84, 68, 71, 90, 60, 100, 36, 103, 68,
+ 71, 38, 60, 100, 318, 103, 68, 71, 10, 15,
+ 36, -167, 213, 355, 38, 167, 36, 313, 202, 154,
+ 127, 10, 79, 252, 323, 66, 88, 10, 15, 79,
+ 81, 139, 66, 88, 166, 84, 79, 81, 74, 202,
+ 88, 229, 84, 79, 252, 74, 60, 88, 49, 84,
+ 68, 71, 139, 60, 78, -186, 84, 47, 48, 49,
+ 60, 329, 36, 170, 183, 187, 127, 60, -169, 68,
+ 71, 175, 70, 10, 15, 68, 71, 161, -171, 100,
+ 289, 103, -169, 66, 291, 292, 60, 79, 81, 258,
+ -167, 88, -170, 256, 257, 72, 74, 95, -168, 60,
+ 84, 156, 66, 154, 68, 71, 79, 81, 66, 122,
+ 88, 60, 79, 81, 72, 74, 88, -170, -173, 84,
+ -172, 74, 99, 68, 71, 84, -171, 100, 90, 103,
+ 60, 200, 334, 68, 71, 213, 60, 202, 215, 254,
+ 338, 79, 252, 173, 174, 88, 122, 296, 183, 187,
+ 139, 256, 257, 216, 84, 175, 66, 234, 68, 71,
+ 79, 81, 113, 117, 88, 60, 202, 217, 78, 74,
+ 79, 252, 353, 84, 88, 53, 68, 71, 223, 139,
+ 100, 260, 103, 84, 60, 43, 44, 40, 41, 358,
+ 52, 66, 51, 225, 60, 79, 81, -169, 229, 88,
+ 365, 68, 71, 72, 74, 100, 238, 103, 84, 66,
+ 228, -167, 234, 79, 81, 372, 373, 88, -169, 60,
+ -167, -170, 74, 95, -168, -172, 84, 68, 71, 45,
+ 375, 100, 229, 103, 66, -221, 232, 60, 79, 81,
+ 378, 39, 88, -24, -24, -24, -24, 74, 99, 95,
+ -168, 84, 383, 384, 90, nil, nil, 68, 71, nil,
+ 66, 100, 60, 103, 79, 81, nil, nil, 88, -22,
+ -22, -22, -22, 74, 99, nil, nil, 84, nil, 95,
+ 90, nil, nil, 68, 71, nil, nil, 100, 60, 103,
+ 66, nil, nil, nil, 79, 81, nil, nil, 88, 43,
+ 44, 40, 41, 74, 99, 95, nil, 84, nil, nil,
+ 90, nil, nil, 68, 71, nil, 66, 100, 60, 103,
+ 79, 81, nil, nil, 88, nil, nil, nil, nil, 74,
+ 99, nil, nil, 84, nil, 95, 90, nil, nil, 68,
+ 71, nil, nil, 100, 60, 103, 66, nil, nil, nil,
+ 79, 81, nil, nil, 88, nil, nil, 68, 71, 74,
+ 99, 100, nil, 84, 68, 71, 90, nil, 100, nil,
+ 103, nil, 66, nil, 60, nil, 79, 81, nil, nil,
+ 88, nil, nil, nil, nil, 74, 95, nil, nil, 84,
+ 66, nil, nil, nil, 79, 144, nil, 66, 88, nil,
+ 60, 79, 81, 139, nil, 88, nil, 84, nil, nil,
+ 74, 99, nil, nil, 84, 68, 71, 90, 60, 100,
+ nil, 103, nil, nil, nil, 60, nil, nil, nil, nil,
+ nil, nil, nil, nil, 68, 71, nil, 95, 100, nil,
+ 103, 68, 71, nil, nil, 100, nil, 103, 66, nil,
+ nil, nil, 79, 81, nil, nil, 88, nil, nil, 68,
+ 71, 74, 99, nil, nil, 84, nil, 66, 90, nil,
+ nil, 79, 81, nil, 66, 88, 60, nil, 79, 81,
+ 74, nil, 88, nil, 84, 68, 71, 74, nil, nil,
+ nil, 84, 202, nil, nil, 60, 79, 252, nil, nil,
+ 88, nil, 60, nil, nil, 139, 68, 71, 162, 84,
+ 100, nil, 103, nil, nil, nil, nil, nil, 66, nil,
+ 60, nil, 79, 81, nil, nil, 88, nil, 95, nil,
+ 72, 74, 68, 71, nil, 84, 100, nil, 103, 66,
+ nil, nil, nil, 79, 81, nil, 60, 88, nil, nil,
+ nil, nil, 74, 99, 95, nil, 84, 68, 71, 90,
+ nil, nil, nil, nil, nil, 66, nil, 60, nil, 79,
+ 81, nil, nil, 88, nil, nil, nil, nil, 74, 99,
+ 327, nil, 84, 68, 71, 90, nil, 100, nil, 103,
+ 66, nil, nil, 60, 79, 81, nil, nil, 88, nil,
+ nil, nil, 72, 74, nil, 95, nil, 84, 68, 71,
+ nil, nil, 100, nil, 103, nil, 66, nil, 60, nil,
+ 79, 81, 68, 71, 88, nil, 100, nil, 103, 74,
+ 99, nil, nil, 84, nil, nil, 90, nil, nil, nil,
+ nil, 66, nil, nil, 60, 79, 81, 68, 71, 88,
+ nil, 100, nil, 103, 74, 66, nil, nil, 84, 79,
+ 81, 68, 71, 88, nil, 100, nil, nil, 74, 60,
+ nil, nil, 84, nil, nil, nil, nil, nil, nil, nil,
+ 66, nil, nil, 60, 79, 81, nil, nil, 88, nil,
+ nil, 68, 71, 74, 66, nil, nil, 84, 79, 252,
+ nil, nil, 88, nil, nil, nil, nil, 139, 60, 68,
+ 71, 84, nil, 100, nil, 103, nil, nil, nil, nil,
+ nil, nil, 60, nil, 202, nil, nil, nil, 79, 252,
+ nil, 95, 88, nil, nil, nil, nil, 139, nil, 68,
+ 71, 84, 66, 100, nil, 103, 79, 81, nil, nil,
+ 88, nil, 60, nil, nil, 74, 99, nil, nil, 84,
+ nil, 95, 90, nil, nil, 68, 71, nil, nil, 100,
+ 60, 103, 66, nil, nil, nil, 79, 81, nil, nil,
+ 88, nil, nil, nil, nil, 74, 99, 95, nil, 84,
+ nil, nil, 90, nil, nil, 68, 71, nil, 66, 100,
+ 60, 103, 79, 81, nil, nil, 88, nil, nil, nil,
+ nil, 74, 99, nil, nil, 84, nil, 95, 90, nil,
+ nil, 68, 71, nil, nil, 100, 60, 103, 66, nil,
+ nil, nil, 79, 81, nil, nil, 88, nil, nil, nil,
+ nil, 74, 99, 95, nil, 84, nil, nil, 90, nil,
+ nil, 68, 71, nil, 66, 100, 60, 103, 79, 81,
+ nil, nil, 88, nil, nil, nil, nil, 74, 99, nil,
+ nil, 84, nil, 95, 90, nil, nil, 68, 71, nil,
+ nil, 100, 60, 103, 66, nil, nil, nil, 79, 81,
+ nil, nil, 88, nil, nil, nil, nil, 74, 99, 95,
+ nil, 84, nil, nil, 90, nil, nil, 68, 71, nil,
+ 66, 100, 60, 103, 79, 81, nil, nil, 88, nil,
+ nil, nil, nil, 74, 99, nil, nil, 84, nil, 95,
+ 90, nil, nil, 68, 71, nil, nil, 100, 60, 103,
+ 66, nil, nil, nil, 79, 81, nil, nil, 88, nil,
+ nil, nil, nil, 74, 99, 95, nil, 84, 68, 71,
+ 90, nil, 100, 193, 103, nil, 66, nil, 60, nil,
+ 79, 81, nil, nil, 88, nil, nil, nil, nil, 74,
+ 99, nil, nil, 84, 68, 71, 90, nil, 100, nil,
+ 103, 66, nil, nil, 60, 79, 81, nil, nil, 88,
+ nil, nil, nil, nil, 74, nil, 95, nil, 84, nil,
+ 68, 71, nil, nil, 100, nil, 103, 66, nil, 60,
+ nil, 79, 81, nil, nil, 88, nil, nil, nil, nil,
+ 74, 99, 95, nil, 84, nil, nil, 90, nil, nil,
+ nil, nil, nil, 66, nil, 60, nil, 79, 81, 188,
+ nil, 88, nil, nil, nil, nil, 74, 99, 181, 186,
+ 84, nil, nil, 90, nil, nil, nil, 177, 179, 182,
+ 185, 60, nil, 181, 186, nil, nil, nil, nil, nil,
+ nil, 282, 177, 179, 182, 185, nil, nil, nil, nil,
+ nil, 180, 184, nil, nil, 189, 172, 173, 174, 176,
+ 178, nil, 183, 187, nil, nil, 180, 184, nil, 175,
+ 189, 172, 173, 174, 176, 178, nil, 183, 187, 181,
+ 186, nil, nil, nil, 175, nil, nil, nil, 177, 179,
+ 182, 185, nil, nil, 181, 186, nil, nil, nil, nil,
+ nil, nil, nil, 177, 179, 182, 185, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, 189, 172, 173, 174,
+ 176, 178, nil, 183, 187, nil, nil, 180, 184, nil,
+ 175, 189, 172, 173, 174, 176, 178, nil, 183, 187,
+ 181, 186, nil, nil, nil, 175, nil, nil, nil, 177,
+ 179, 182, 185, nil, nil, 181, 186, nil, nil, nil,
+ nil, nil, nil, nil, 177, 179, 182, 185, nil, nil,
+ nil, nil, nil, 180, 184, nil, nil, 189, 172, 173,
+ 174, 176, 178, nil, 183, 187, nil, nil, nil, 184,
+ nil, 175, 189, 172, 173, 174, 176, 178, nil, 183,
+ 187, 181, 186, nil, nil, nil, 175, nil, nil, nil,
+ 177, 179, 182, 185, nil, nil, nil, 186, nil, 189,
+ 172, 173, 174, 176, 178, 177, 183, 187, nil, nil,
+ nil, nil, nil, 175, 180, 184, 186, nil, 189, 172,
+ 173, 174, 176, 178, 177, 183, 187, nil, nil, nil,
+ nil, 186, 175, 189, 172, 173, 174, 176, 178, 177,
+ 183, 187, nil, nil, nil, nil, nil, 175, nil, nil,
+ nil, nil, 189, 172, 173, 174, 176, 178, nil, 183,
+ 187, 280, nil, nil, nil, nil, 175, 189, 172, 173,
+ 174, 176, 178, nil, 183, 187, nil, nil, nil, nil,
+ 325, 175, 26, nil, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, 26, 363, 32, 1, nil, 8, 11, nil, 18,
+ nil, 23, nil, 29, nil, 2, nil, nil, 10, 15,
+ nil, 382, nil, 26, nil, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, 26, 380, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, nil, 376, nil, 26, nil, 32, 1, nil, 8,
+ 11, nil, 18, nil, 23, nil, 29, nil, 2, nil,
+ nil, 10, 15, 26, 305, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, nil, nil, nil, 26, nil, 32, 1, nil,
+ 8, 11, nil, 18, nil, 23, nil, 29, nil, 2,
+ nil, nil, 10, 15, 26, nil, 32, 1, nil, 8,
+ 11, nil, 18, nil, 23, nil, 29, nil, 2, nil,
+ nil, 10, 15, 26, nil, 32, 1, nil, 8, 11,
+ nil, 18, nil, 23, nil, 29, nil, 2, nil, nil,
+ 10, 15, 26, nil, 32, 1, nil, 8, 11, nil,
+ 18, nil, 23, nil, 29, nil, 2, nil, nil, 10,
+ 15, 189, 172, 173, 174, 176, 178, nil, 183, 187,
+ 189, 172, 173, 174, nil, 175, nil, 183, 187, 189,
+ 172, 173, 174, nil, 175, nil, 183, 187, nil, nil,
+ nil, nil, nil, 175 ]
racc_action_check = [
- 180, 180, 152, 86, 156, 106, 106, 272, 174, 7,
- 277, 277, 106, 180, 180, 65, 55, 277, 7, 7,
- 272, 86, 180, 180, 180, 180, 65, 296, 17, 80,
- 296, 65, 158, 95, 202, 202, 174, 174, 202, 218,
- 202, 55, 156, 106, 152, 156, 180, 180, 277, 219,
- 180, 180, 180, 180, 180, 180, 202, 180, 180, 181,
- 181, 368, 368, 239, 180, 156, 17, 202, 165, 17,
- 158, 202, 202, 158, 239, 202, 165, 182, 182, 239,
- 202, 202, 349, 182, 202, 349, 22, 202, 22, 17,
- 143, 243, 181, 158, 368, 202, 181, 181, 368, 368,
- 181, 22, 368, 143, 181, 181, 220, 368, 163, 181,
- 182, 368, 355, 355, 182, 182, 243, 243, 182, 163,
- 181, 62, 368, 182, 163, 22, 178, 182, 281, 281,
- 351, 351, 62, 221, 351, 281, 351, 62, 182, 178,
- 285, 285, 285, 285, 101, 355, 221, 285, 285, 355,
- 355, 224, 351, 355, 285, 341, 341, 300, 355, 341,
- 91, 341, 355, 351, 308, 300, 226, 351, 351, 308,
- 227, 351, 90, 355, 184, 184, 351, 351, 12, 122,
- 351, 171, 12, 351, 122, 171, 171, 229, 341, 12,
- 286, 351, 341, 341, 343, 343, 341, 184, 286, 1,
- 87, 341, 30, 1, 183, 341, 30, 184, 183, 183,
- 1, 184, 184, 30, 30, 184, 341, 196, 196, 184,
- 184, 196, 195, 196, 184, 195, 286, 286, 286, 286,
- 286, 286, 188, 286, 286, 184, 188, 188, 231, 196,
- 286, 120, 232, 197, 197, 120, 233, 197, 103, 197,
- 196, 85, 120, 120, 196, 196, 105, 43, 196, 280,
- 280, 43, 84, 196, 196, 197, 280, 196, 43, 43,
- 196, 81, 215, 23, 23, 78, 197, 23, 196, 250,
- 197, 197, 279, 279, 197, 252, 253, 279, 279, 197,
- 197, 77, 71, 197, 279, 23, 197, 160, 68, 26,
- 26, 160, 160, 26, 197, 26, 23, 268, 67, 234,
- 23, 23, 211, 234, 23, 274, 234, 66, 23, 23,
- 234, 26, 107, 23, 108, 198, 198, 109, 207, 198,
- 114, 198, 26, 115, 23, 119, 26, 26, 64, 121,
- 26, 35, 35, 35, 35, 26, 26, 198, 52, 26,
- 29, 29, 26, 51, 29, 50, 29, 127, 198, 132,
- 26, 36, 198, 198, 307, 307, 198, 133, 307, 136,
- 307, 198, 198, 138, 192, 198, 139, 33, 198, 34,
- 34, 34, 34, 29, 140, 142, 198, 29, 29, 305,
- 305, 29, 315, 305, 144, 305, 29, 307, 16, 327,
- 29, 307, 307, 199, 199, 307, 328, 199, 330, 199,
- 307, 29, 297, 297, 307, 331, 332, 297, 297, 337,
- 153, 175, 305, 154, 297, 307, 305, 305, 9, 288,
- 305, 28, 28, 28, 28, 305, 199, 288, 352, 305,
- 199, 199, 8, 356, 199, 298, 298, 173, 367, 199,
- 305, 172, 298, 199, 369, 200, 200, 3, 2, 200,
- 157, 200, 263, nil, 199, 288, 288, 288, 288, 288,
- 288, nil, 288, 288, nil, nil, nil, 200, 298, 288,
- nil, nil, 298, 298, nil, nil, 298, nil, 200, nil,
- nil, 298, 200, 200, nil, 298, 200, 4, 4, 4,
- 4, 200, 200, 39, 39, 200, 298, 39, 200, 39,
- 293, 293, 293, 293, 293, 293, 200, 293, 293, nil,
- 283, 283, 283, 283, 293, 39, nil, 283, 283, 201,
- 201, nil, nil, 201, 283, 201, 39, nil, nil, nil,
- 39, 39, nil, nil, 39, nil, nil, nil, nil, 39,
- 39, 201, nil, 39, nil, nil, 39, nil, nil, 46,
- 46, nil, 201, 46, 39, 46, 201, 201, nil, nil,
- 201, nil, nil, nil, nil, 201, 201, nil, nil, 201,
- nil, 46, 201, nil, nil, 47, 47, nil, nil, 47,
- 201, 47, 46, nil, nil, nil, 46, 46, nil, nil,
- 46, nil, nil, nil, nil, 46, 46, 47, nil, 46,
- 48, 48, 46, nil, 48, nil, 48, nil, 47, nil,
- 46, nil, 47, 47, 49, 49, 47, nil, 49, nil,
- nil, 47, 47, nil, nil, 47, nil, nil, 47, nil,
- nil, nil, nil, 48, nil, nil, 47, 48, 48, 176,
- 176, 48, nil, 176, nil, 176, 48, 49, nil, nil,
- 48, 49, 49, nil, nil, 49, nil, nil, nil, nil,
- 49, 48, nil, nil, 49, 203, 203, nil, nil, 203,
- nil, 203, 176, nil, nil, 49, 176, 176, nil, nil,
- 176, nil, nil, nil, nil, 176, nil, 203, nil, 176,
- nil, 204, 204, nil, nil, 204, nil, 204, 203, nil,
- 176, nil, 203, 203, nil, nil, 203, nil, nil, nil,
- nil, 203, 203, 204, nil, 203, nil, nil, 203, nil,
- nil, 205, 205, nil, 204, 205, 203, 205, 204, 204,
- nil, nil, 204, nil, nil, nil, nil, 204, 204, nil,
- nil, 204, nil, 205, 204, nil, nil, 100, 100, nil,
- nil, 100, 204, 100, 205, nil, nil, nil, 205, 205,
- nil, nil, 205, nil, nil, nil, nil, 205, 205, 100,
- nil, 205, 63, 63, 205, nil, 63, nil, 63, nil,
- 100, nil, 205, nil, 100, 100, nil, nil, 100, nil,
- nil, nil, nil, 100, 100, nil, nil, 100, 208, 208,
- 100, nil, 208, nil, 208, 63, nil, nil, 100, 63,
- 63, nil, nil, 63, nil, nil, nil, nil, 63, nil,
- 208, nil, 63, nil, 209, 209, nil, nil, 209, nil,
- 209, 208, nil, 63, nil, 208, 208, nil, nil, 208,
- nil, nil, 269, 269, 208, 208, 209, nil, 208, 276,
- 276, 208, nil, 276, nil, 276, nil, 209, nil, 208,
- nil, 209, 209, nil, nil, 209, nil, nil, nil, nil,
- 209, 209, nil, nil, 209, 269, nil, 209, nil, 269,
- 269, nil, 276, 269, nil, 209, 276, 276, 269, nil,
- 276, nil, 269, nil, nil, 276, 256, 256, nil, 276,
- 256, nil, 256, 269, nil, nil, nil, nil, nil, nil,
- 276, nil, nil, nil, nil, 74, 74, nil, 256, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 256,
- nil, nil, nil, 256, 256, nil, nil, 256, 74, nil,
- 254, 254, 256, 256, nil, nil, 256, nil, 74, 256,
- nil, nil, 74, 74, nil, nil, 74, 256, 75, 75,
- 74, 74, 75, 254, 75, 74, nil, nil, nil, nil,
- nil, nil, nil, 254, nil, nil, 74, 254, 254, nil,
- 75, 254, nil, 248, 248, 254, 254, 248, nil, 248,
- 254, 75, nil, 245, 245, 75, 75, nil, nil, 75,
- nil, 254, nil, nil, 75, 75, nil, nil, 75, 244,
- 244, 75, nil, nil, nil, nil, 248, nil, nil, 75,
- 248, 248, nil, nil, 248, nil, 245, nil, nil, 248,
- 245, 245, nil, 248, 245, nil, 225, 225, nil, 245,
- 225, nil, 244, 245, 248, nil, 244, 244, nil, nil,
- 244, nil, 82, 82, 245, 244, 82, nil, 82, 244,
- nil, nil, 210, 210, nil, nil, 210, nil, 210, 225,
- 244, nil, nil, 225, 225, nil, nil, 225, nil, nil,
- nil, nil, 225, nil, 210, 82, 225, nil, nil, 82,
- 82, nil, nil, 82, nil, 210, nil, 225, 82, 210,
- 210, nil, 82, 210, nil, nil, nil, nil, 210, 210,
- 213, 213, 210, 82, 213, 210, 213, 284, 284, 284,
- 284, 284, 284, 210, 284, 284, nil, nil, nil, 102,
- 102, 284, 213, 102, 102, 102, 230, 230, nil, nil,
- 230, nil, 230, 213, nil, nil, nil, 213, 213, nil,
- nil, 213, nil, nil, nil, nil, 213, 213, 214, 214,
- 213, nil, 102, 213, nil, nil, 102, 102, nil, 230,
- 102, 213, nil, 230, 230, 102, nil, 230, nil, 102,
- nil, nil, 230, 228, 228, nil, 230, 228, nil, 228,
- 102, 214, nil, nil, nil, 214, 214, 230, nil, 214,
- nil, 94, 94, nil, 214, 94, nil, 94, 214, nil,
- nil, nil, nil, nil, nil, nil, 228, nil, nil, 214,
- 228, 228, nil, 94, 228, nil, nil, nil, nil, 228,
- nil, 97, 97, 228, 94, 97, nil, 97, 94, 94,
- nil, nil, 94, nil, 228, nil, nil, 94, 94, nil,
- nil, 94, nil, 97, 94, nil, nil, 206, 206, nil,
- nil, 206, 94, 206, 97, nil, nil, nil, 97, 97,
- nil, nil, 97, nil, nil, nil, nil, 97, 97, 206,
- nil, 97, nil, nil, 97, nil, nil, nil, nil, nil,
- 206, nil, 97, nil, 206, 206, 111, nil, 206, nil,
- nil, nil, nil, 206, 206, 111, 111, 206, nil, nil,
- 206, nil, nil, nil, 111, 111, 111, 111, 206, nil,
- 124, 124, nil, nil, nil, nil, nil, nil, nil, 124,
- 124, 124, 124, nil, nil, nil, nil, nil, 111, 111,
- nil, nil, 111, 111, 111, 111, 111, 111, nil, 111,
- 111, nil, nil, 124, 124, nil, 111, 124, 124, 124,
- 124, 124, 124, nil, 124, 124, 130, 130, nil, nil,
- nil, 124, nil, nil, nil, 130, 130, 130, 130, nil,
- nil, 131, 131, nil, nil, nil, nil, nil, nil, nil,
- 131, 131, 131, 131, nil, nil, nil, nil, nil, 130,
- 130, nil, nil, 130, 130, 130, 130, 130, 130, nil,
- 130, 130, nil, nil, 131, 131, nil, 130, 131, 131,
- 131, 131, 131, 131, nil, 131, 131, 287, 287, nil,
- nil, nil, 131, nil, nil, nil, 287, 287, 287, 287,
- nil, nil, 186, 186, nil, nil, nil, nil, nil, nil,
- 186, 186, 186, 186, 186, nil, nil, nil, nil, nil,
- nil, 287, nil, nil, 287, 287, 287, 287, 287, 287,
- nil, 287, 287, nil, nil, 186, 186, nil, 287, 186,
- 186, 186, 186, 186, 186, nil, 186, 186, 291, 291,
- nil, nil, nil, 186, nil, nil, nil, 291, 291, 291,
- 291, nil, nil, 19, 292, 19, 19, nil, 19, 19,
- nil, 19, 292, 19, nil, 19, nil, 19, nil, nil,
- 19, 19, nil, 289, nil, 291, 291, 291, 291, 291,
- 291, 289, 291, 291, nil, nil, nil, nil, nil, 291,
- 292, 292, 292, 292, 292, 292, nil, 292, 292, nil,
- nil, 237, nil, nil, 292, nil, nil, nil, nil, 289,
- 289, 289, 289, 289, 289, nil, 289, 289, nil, nil,
- 372, nil, 237, 289, 237, 237, nil, 237, 237, nil,
- 237, nil, 237, nil, 237, nil, 237, nil, nil, 237,
- 237, 372, 378, 372, 372, nil, 372, 372, nil, 372,
- nil, 372, nil, 372, nil, 372, nil, nil, 372, 372,
- nil, 212, nil, 378, nil, 378, 378, nil, 378, 378,
- nil, 378, nil, 378, nil, 378, nil, 378, nil, nil,
- 378, 378, 212, 323, 212, 212, nil, 212, 212, nil,
- 212, nil, 212, nil, 212, nil, 212, nil, nil, 212,
- 212, nil, 374, nil, 323, nil, 323, 323, nil, 323,
- 323, nil, 323, nil, 323, nil, 323, nil, 323, nil,
- nil, 323, 323, 374, 380, 374, 374, nil, 374, 374,
- nil, 374, nil, 374, nil, 374, nil, 374, nil, nil,
- 374, 374, nil, 303, nil, 380, nil, 380, 380, nil,
- 380, 380, nil, 380, nil, 380, nil, 380, nil, 380,
- nil, nil, 380, 380, 303, 319, 303, 303, nil, 303,
- 303, nil, 303, nil, 303, nil, 303, nil, 303, nil,
- nil, 303, 303, nil, 362, nil, 319, nil, 319, 319,
- nil, 319, 319, nil, 319, nil, 319, nil, 319, nil,
- 319, nil, nil, 319, 319, 362, 217, 362, 362, nil,
- 362, 362, nil, 362, nil, 362, nil, 362, nil, 362,
- nil, nil, 362, 362, nil, 295, nil, 217, nil, 217,
- 217, nil, 217, 217, nil, 217, nil, 217, nil, 217,
- nil, 217, nil, nil, 217, 217, 295, nil, 295, 295,
- nil, 295, 295, nil, 295, nil, 295, nil, 295, nil,
- 295, nil, nil, 295, 295, 0, nil, 0, 0, nil,
- 0, 0, nil, 0, nil, 0, nil, 0, nil, 0,
- nil, nil, 0, 0 ]
+ 164, 164, 158, 154, 301, 27, 56, 27, 81, 214,
+ 285, 285, 301, 164, 164, 239, 293, 285, 18, 206,
+ 27, 213, 164, 164, 164, 164, 81, 206, 175, 175,
+ 194, 56, 175, 194, 175, 368, 368, 214, 214, 157,
+ 158, 293, 293, 158, 27, 154, 164, 164, 285, 144,
+ 164, 164, 164, 164, 164, 164, 18, 164, 164, 18,
+ 85, 175, 144, 158, 164, 175, 175, 272, 368, 175,
+ 83, 261, 368, 368, 175, 272, 368, 157, 175, 18,
+ 157, 368, 161, 161, 261, 368, 161, 216, 161, 175,
+ 1, 82, 356, 356, 1, 218, 368, 219, 203, 163,
+ 157, 1, 114, 272, 272, 272, 272, 272, 272, 203,
+ 272, 272, 163, 114, 203, 161, 122, 272, 114, 161,
+ 161, 122, 192, 161, 221, 356, 192, 192, 161, 356,
+ 356, 220, 161, 356, 290, 335, 335, 221, 356, 335,
+ 111, 335, 356, 161, 309, 290, 331, 331, 11, 309,
+ 290, 111, 11, 356, 329, 329, 111, 335, 329, 11,
+ 329, 48, 48, 103, 103, 48, 334, 48, 335, 334,
+ 103, 200, 335, 335, 262, 262, 335, 263, 263, 262,
+ 262, 335, 335, 48, 263, 335, 262, 329, 335, 224,
+ 280, 329, 329, 280, 48, 329, 335, 197, 48, 48,
+ 329, 103, 48, 227, 329, 295, 295, 48, 48, 87,
+ 229, 48, 307, 307, 48, 329, 307, 33, 307, 306,
+ 306, 33, 48, 306, 230, 306, 299, 299, 33, 33,
+ 225, 80, 232, 299, 225, 77, 46, 225, 295, 234,
+ 46, 225, 295, 295, 235, 307, 295, 46, 46, 307,
+ 307, 295, 306, 307, 75, 295, 306, 306, 307, 299,
+ 306, 212, 307, 299, 299, 306, 295, 299, 8, 306,
+ 23, 23, 299, 307, 23, 74, 299, 8, 8, 66,
+ 306, 249, 42, 252, 264, 264, 42, 299, 65, 166,
+ 166, 264, 23, 42, 42, 26, 26, 64, 89, 26,
+ 201, 26, 94, 23, 201, 201, 187, 23, 23, 169,
+ 101, 23, 102, 169, 169, 23, 23, 26, 105, 183,
+ 23, 53, 166, 52, 294, 294, 166, 166, 26, 50,
+ 166, 23, 26, 26, 166, 166, 26, 143, 106, 166,
+ 107, 26, 26, 29, 29, 26, 108, 29, 26, 29,
+ 166, 110, 279, 167, 167, 113, 26, 294, 115, 167,
+ 283, 294, 294, 281, 281, 294, 37, 211, 281, 281,
+ 294, 211, 211, 116, 294, 281, 29, 288, 170, 170,
+ 29, 29, 119, 32, 29, 294, 167, 121, 127, 29,
+ 167, 167, 297, 29, 167, 17, 287, 287, 133, 167,
+ 287, 170, 287, 167, 29, 3, 3, 3, 3, 304,
+ 13, 170, 12, 134, 167, 170, 170, 136, 320, 170,
+ 324, 172, 172, 170, 170, 172, 159, 172, 170, 287,
+ 140, 141, 155, 287, 287, 337, 342, 287, 346, 170,
+ 347, 349, 287, 172, 350, 351, 287, 45, 45, 5,
+ 357, 45, 142, 45, 172, 367, 147, 287, 172, 172,
+ 369, 2, 172, 4, 4, 4, 4, 172, 172, 45,
+ 146, 172, 379, 381, 172, nil, nil, 173, 173, nil,
+ 45, 173, 172, 173, 45, 45, nil, nil, 45, 31,
+ 31, 31, 31, 45, 45, nil, nil, 45, nil, 173,
+ 45, nil, nil, 47, 47, nil, nil, 47, 45, 47,
+ 173, nil, nil, nil, 173, 173, nil, nil, 173, 6,
+ 6, 6, 6, 173, 173, 47, nil, 173, nil, nil,
+ 173, nil, nil, 174, 174, nil, 47, 174, 173, 174,
+ 47, 47, nil, nil, 47, nil, nil, nil, nil, 47,
+ 47, nil, nil, 47, nil, 174, 47, nil, nil, 49,
+ 49, nil, nil, 49, 47, 49, 174, nil, nil, nil,
+ 174, 174, nil, nil, 174, nil, nil, 51, 51, 174,
+ 174, 51, nil, 174, 176, 176, 174, nil, 176, nil,
+ 176, nil, 49, nil, 174, nil, 49, 49, nil, nil,
+ 49, nil, nil, nil, nil, 49, 176, nil, nil, 49,
+ 51, nil, nil, nil, 51, 51, nil, 176, 51, nil,
+ 49, 176, 176, 51, nil, 176, nil, 51, nil, nil,
+ 176, 176, nil, nil, 176, 177, 177, 176, 51, 177,
+ nil, 177, nil, nil, nil, 176, nil, nil, nil, nil,
+ nil, nil, nil, nil, 112, 112, nil, 177, 112, nil,
+ 112, 259, 259, nil, nil, 259, nil, 259, 177, nil,
+ nil, nil, 177, 177, nil, nil, 177, nil, nil, 254,
+ 254, 177, 177, nil, nil, 177, nil, 112, 177, nil,
+ nil, 112, 112, nil, 259, 112, 177, nil, 259, 259,
+ 112, nil, 259, nil, 112, 70, 70, 259, nil, nil,
+ nil, 259, 254, nil, nil, 112, 254, 254, nil, nil,
+ 254, nil, 259, nil, nil, 254, 242, 242, 70, 254,
+ 242, nil, 242, nil, nil, nil, nil, nil, 70, nil,
+ 254, nil, 70, 70, nil, nil, 70, nil, 242, nil,
+ 70, 70, 71, 71, nil, 70, 71, nil, 71, 242,
+ nil, nil, nil, 242, 242, nil, 70, 242, nil, nil,
+ nil, nil, 242, 242, 71, nil, 242, 240, 240, 242,
+ nil, nil, nil, nil, nil, 71, nil, 242, nil, 71,
+ 71, nil, nil, 71, nil, nil, nil, nil, 71, 71,
+ 240, nil, 71, 178, 178, 71, nil, 178, nil, 178,
+ 240, nil, nil, 71, 240, 240, nil, nil, 240, nil,
+ nil, nil, 240, 240, nil, 178, nil, 240, 233, 233,
+ nil, nil, 233, nil, 233, nil, 178, nil, 240, nil,
+ 178, 178, 78, 78, 178, nil, 78, nil, 78, 178,
+ 178, nil, nil, 178, nil, nil, 178, nil, nil, nil,
+ nil, 233, nil, nil, 178, 233, 233, 231, 231, 233,
+ nil, 231, nil, 231, 233, 78, nil, nil, 233, 78,
+ 78, 228, 228, 78, nil, 228, nil, nil, 78, 233,
+ nil, nil, 78, nil, nil, nil, nil, nil, nil, nil,
+ 231, nil, nil, 78, 231, 231, nil, nil, 231, nil,
+ nil, 215, 215, 231, 228, nil, nil, 231, 228, 228,
+ nil, nil, 228, nil, nil, nil, nil, 228, 231, 179,
+ 179, 228, nil, 179, nil, 179, nil, nil, nil, nil,
+ nil, nil, 228, nil, 215, nil, nil, nil, 215, 215,
+ nil, 179, 215, nil, nil, nil, nil, 215, nil, 185,
+ 185, 215, 179, 185, nil, 185, 179, 179, nil, nil,
+ 179, nil, 215, nil, nil, 179, 179, nil, nil, 179,
+ nil, 185, 179, nil, nil, 181, 181, nil, nil, 181,
+ 179, 181, 185, nil, nil, nil, 185, 185, nil, nil,
+ 185, nil, nil, nil, nil, 185, 185, 181, nil, 185,
+ nil, nil, 185, nil, nil, 189, 189, nil, 181, 189,
+ 185, 189, 181, 181, nil, nil, 181, nil, nil, nil,
+ nil, 181, 181, nil, nil, 181, nil, 189, 181, nil,
+ nil, 90, 90, nil, nil, 90, 181, 90, 189, nil,
+ nil, nil, 189, 189, nil, nil, 189, nil, nil, nil,
+ nil, 189, 189, 90, nil, 189, nil, nil, 189, nil,
+ nil, 182, 182, nil, 90, 182, 189, 182, 90, 90,
+ nil, nil, 90, nil, nil, nil, nil, 90, 90, nil,
+ nil, 90, nil, 182, 90, nil, nil, 184, 184, nil,
+ nil, 184, 90, 184, 182, nil, nil, nil, 182, 182,
+ nil, nil, 182, nil, nil, nil, nil, 182, 182, 184,
+ nil, 182, nil, nil, 182, nil, nil, 95, 95, nil,
+ 184, 95, 182, 95, 184, 184, nil, nil, 184, nil,
+ nil, nil, nil, 184, 184, nil, nil, 184, nil, 95,
+ 184, nil, nil, 99, 99, nil, nil, 99, 184, 99,
+ 95, nil, nil, nil, 95, 95, nil, nil, 95, nil,
+ nil, nil, nil, 95, 95, 99, nil, 95, 100, 100,
+ 95, nil, 100, 100, 100, nil, 99, nil, 95, nil,
+ 99, 99, nil, nil, 99, nil, nil, nil, nil, 99,
+ 99, nil, nil, 99, 186, 186, 99, nil, 186, nil,
+ 186, 100, nil, nil, 99, 100, 100, nil, nil, 100,
+ nil, nil, nil, nil, 100, nil, 186, nil, 100, nil,
+ 180, 180, nil, nil, 180, nil, 180, 186, nil, 100,
+ nil, 186, 186, nil, nil, 186, nil, nil, nil, nil,
+ 186, 186, 180, nil, 186, nil, nil, 186, nil, nil,
+ nil, nil, nil, 180, nil, 186, nil, 180, 180, 91,
+ nil, 180, nil, nil, nil, nil, 180, 180, 91, 91,
+ 180, nil, nil, 180, nil, nil, nil, 91, 91, 91,
+ 91, 180, nil, 190, 190, nil, nil, nil, nil, nil,
+ nil, 190, 190, 190, 190, 190, nil, nil, nil, nil,
+ nil, 91, 91, nil, nil, 91, 91, 91, 91, 91,
+ 91, nil, 91, 91, nil, nil, 190, 190, nil, 91,
+ 190, 190, 190, 190, 190, 190, nil, 190, 190, 274,
+ 274, nil, nil, nil, 190, nil, nil, nil, 274, 274,
+ 274, 274, nil, nil, 132, 132, nil, nil, nil, nil,
+ nil, nil, nil, 132, 132, 132, 132, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, 274, 274, 274, 274,
+ 274, 274, nil, 274, 274, nil, nil, 132, 132, nil,
+ 274, 132, 132, 132, 132, 132, 132, nil, 132, 132,
+ 131, 131, nil, nil, nil, 132, nil, nil, nil, 131,
+ 131, 131, 131, nil, nil, 270, 270, nil, nil, nil,
+ nil, nil, nil, nil, 270, 270, 270, 270, nil, nil,
+ nil, nil, nil, 131, 131, nil, nil, 131, 131, 131,
+ 131, 131, 131, nil, 131, 131, nil, nil, nil, 270,
+ nil, 131, 270, 270, 270, 270, 270, 270, nil, 270,
+ 270, 129, 129, nil, nil, nil, 270, nil, nil, nil,
+ 129, 129, 129, 129, nil, nil, nil, 269, nil, 276,
+ 276, 276, 276, 276, 276, 269, 276, 276, nil, nil,
+ nil, nil, nil, 276, 129, 129, 275, nil, 129, 129,
+ 129, 129, 129, 129, 275, 129, 129, nil, nil, nil,
+ nil, 271, 129, 269, 269, 269, 269, 269, 269, 271,
+ 269, 269, nil, nil, nil, nil, nil, 269, nil, nil,
+ nil, nil, 275, 275, 275, 275, 275, 275, nil, 275,
+ 275, 188, nil, nil, nil, nil, 275, 271, 271, 271,
+ 271, 271, 271, nil, 271, 271, nil, nil, nil, nil,
+ 238, 271, 188, nil, 188, 188, nil, 188, 188, nil,
+ 188, nil, 188, nil, 188, nil, 188, nil, nil, 188,
+ 188, 238, 311, 238, 238, nil, 238, 238, nil, 238,
+ nil, 238, nil, 238, nil, 238, nil, nil, 238, 238,
+ nil, 375, nil, 311, nil, 311, 311, nil, 311, 311,
+ nil, 311, nil, 311, nil, 311, nil, 311, nil, nil,
+ 311, 311, 375, 372, 375, 375, nil, 375, 375, nil,
+ 375, nil, 375, nil, 375, nil, 375, nil, nil, 375,
+ 375, nil, 362, nil, 372, nil, 372, 372, nil, 372,
+ 372, nil, 372, nil, 372, nil, 372, nil, 372, nil,
+ nil, 372, 372, 362, 217, 362, 362, nil, 362, 362,
+ nil, 362, nil, 362, nil, 362, nil, 362, nil, nil,
+ 362, 362, nil, nil, nil, 217, nil, 217, 217, nil,
+ 217, 217, nil, 217, nil, 217, nil, 217, nil, 217,
+ nil, nil, 217, 217, 0, nil, 0, 0, nil, 0,
+ 0, nil, 0, nil, 0, nil, 0, nil, 0, nil,
+ nil, 0, 0, 20, nil, 20, 20, nil, 20, 20,
+ nil, 20, nil, 20, nil, 20, nil, 20, nil, nil,
+ 20, 20, 278, nil, 278, 278, nil, 278, 278, nil,
+ 278, nil, 278, nil, 278, nil, 278, nil, nil, 278,
+ 278, 267, 267, 267, 267, 267, 267, nil, 267, 267,
+ 266, 266, 266, 266, nil, 267, nil, 266, 266, 268,
+ 268, 268, 268, nil, 266, nil, 268, 268, nil, nil,
+ nil, nil, nil, 268 ]
racc_action_pointer = [
- 1795, 163, 443, 413, 433, nil, nil, 3, 434, 420,
- nil, nil, 142, nil, nil, nil, 398, 26, nil, 1483,
- nil, nil, 80, 271, nil, nil, 297, nil, 367, 348,
- 166, nil, nil, 375, 315, 277, 337, nil, nil, 501,
- nil, nil, nil, 221, nil, nil, 557, 583, 608, 622,
- 315, 329, 348, nil, nil, 4, nil, nil, nil, nil,
- nil, nil, 97, 780, 298, -9, 309, 302, 275, nil,
- nil, 286, nil, nil, 923, 966, nil, 279, 269, nil,
- 6, 248, 1060, nil, 239, 245, -3, 177, nil, nil,
- 149, 137, nil, nil, 1209, 10, nil, 1239, nil, nil,
- 755, 121, 1137, 225, nil, 233, 3, 299, 301, 304,
- nil, 1298, nil, nil, 322, 325, nil, nil, nil, 323,
- 205, 331, 144, nil, 1313, nil, nil, 351, nil, nil,
- 1359, 1374, 352, 344, nil, nil, 328, nil, 350, 364,
- 361, nil, 362, 79, 374, nil, nil, nil, nil, nil,
- nil, nil, -9, 408, 386, nil, 2, 452, 30, nil,
- 251, nil, nil, 84, nil, 50, nil, nil, nil, nil,
- nil, 174, 439, 436, -14, 381, 647, nil, 114, nil,
- -4, 57, 75, 197, 172, nil, 1435, nil, 225, nil,
- nil, nil, 363, nil, nil, 213, 215, 241, 323, 401,
- 453, 527, 32, 673, 699, 729, 1265, 265, 806, 832,
- 1070, 249, 1612, 1118, 1166, 270, nil, 1757, 24, 24,
- 91, 121, nil, nil, 142, 1044, 126, 161, 1191, 147,
- 1144, 198, 233, 238, 273, nil, nil, 1552, nil, 39,
- nil, nil, nil, 66, 1017, 1001, nil, nil, 991, nil,
- 270, nil, 273, 279, 948, nil, 904, nil, nil, nil,
- nil, nil, nil, 451, nil, nil, nil, nil, 283, 850,
- nil, nil, -5, nil, 308, nil, 857, 8, nil, 226,
- 198, 67, nil, 466, 1073, 86, 172, 1420, 411, 1515,
- nil, 1481, 1496, 456, nil, 1776, -4, 356, 443, nil,
- 145, nil, nil, 1694, nil, 387, nil, 362, 129, nil,
- nil, nil, nil, nil, nil, 380, nil, nil, nil, 1716,
- nil, nil, nil, 1634, nil, nil, nil, 376, 383, nil,
- 385, 392, 393, nil, nil, nil, nil, 410, nil, nil,
- nil, 153, nil, 183, nil, nil, nil, nil, nil, 51,
- nil, 128, 430, nil, nil, 110, 435, nil, nil, nil,
- nil, nil, 1735, nil, nil, nil, nil, 439, 59, 445,
- nil, nil, 1571, nil, 1653, nil, nil, nil, 1593, nil,
- 1675, nil, nil, nil ]
+ 1674, 54, 417, 341, 399, 434, 455, nil, 262, nil,
+ nil, 112, 404, 402, nil, nil, nil, 395, 16, nil,
+ 1693, nil, nil, 268, nil, nil, 293, -1, nil, 341,
+ nil, 425, 381, 181, nil, nil, nil, 342, nil, nil,
+ nil, nil, 246, nil, nil, 445, 200, 501, 159, 557,
+ 305, 575, 283, 321, nil, nil, -6, nil, nil, nil,
+ nil, nil, nil, nil, 291, 265, 273, nil, nil, nil,
+ 703, 750, nil, nil, 269, 242, nil, 212, 840, nil,
+ 208, 2, 68, 64, nil, 37, nil, 186, nil, 275,
+ 1039, 1261, nil, nil, 279, 1125, nil, nil, nil, 1151,
+ 1176, 287, 289, 161, nil, 295, 315, 317, 323, nil,
+ 343, 116, 652, 315, 78, 350, 361, nil, nil, 374,
+ nil, 379, 81, nil, nil, nil, nil, 382, nil, 1444,
+ nil, 1383, 1337, 391, 376, nil, 394, nil, nil, nil,
+ 389, 408, 440, 314, 38, nil, 447, 436, nil, nil,
+ nil, nil, nil, nil, -8, 420, nil, 37, 0, 418,
+ nil, 80, nil, 87, -4, nil, 287, 351, nil, 302,
+ 376, nil, 419, 475, 531, 26, 582, 633, 801, 927,
+ 1228, 983, 1069, 256, 1095, 957, 1202, 243, 1532, 1013,
+ 1276, nil, 115, nil, 21, nil, nil, 186, nil, nil,
+ 131, 254, nil, 74, nil, nil, 1, nil, nil, nil,
+ nil, 360, 249, 10, -13, 909, 85, 1655, 80, 82,
+ 106, 112, nil, nil, 181, 194, nil, 194, 879, 170,
+ 215, 865, 192, 826, 199, 235, nil, nil, 1551, 8,
+ 775, nil, 724, nil, nil, nil, nil, nil, nil, 270,
+ nil, nil, 259, nil, 677, nil, nil, nil, nil, 659,
+ nil, 59, 118, 116, 223, nil, 1716, 1707, 1725, 1459,
+ 1398, 1493, 49, nil, 1322, 1478, 1425, nil, 1712, 343,
+ 159, 307, nil, 353, nil, 8, nil, 394, 365, nil,
+ 110, nil, nil, -9, 322, 203, nil, 383, nil, 224,
+ nil, -8, nil, nil, 400, nil, 217, 210, nil, 109,
+ nil, 1573, nil, nil, nil, nil, nil, nil, nil, nil,
+ 406, nil, nil, nil, 411, nil, nil, nil, nil, 152,
+ nil, 135, nil, nil, 135, 133, nil, 427, nil, nil,
+ nil, nil, 427, nil, nil, nil, 415, 417, nil, 418,
+ 421, 422, nil, nil, nil, nil, 90, 442, nil, nil,
+ nil, nil, 1633, nil, nil, nil, nil, 446, 33, 451,
+ nil, nil, 1614, nil, nil, 1592, nil, nil, nil, 463,
+ nil, 464, nil, nil, nil ]
racc_action_default = [
- -196, -233, -233, -50, -233, -8, -9, -233, -233, -22,
- -10, -187, -188, -11, -185, -12, -233, -233, -13, -1,
- -14, -2, -233, -186, -15, -3, -233, -16, -5, -233,
- -233, -17, -6, -233, -18, -7, -196, -188, -186, -233,
- -51, -26, -27, -233, -24, -25, -233, -233, -233, -85,
- -92, -196, -233, -195, -193, -196, -189, -191, -192, -221,
- -194, -4, -196, -233, -85, -196, -53, -231, -42, -174,
- -43, -213, -117, -33, -233, -233, -44, -31, -74, -32,
- -233, -36, -233, -122, -37, -233, -73, -38, -172, -72,
- -39, -40, -173, -41, -233, -103, -111, -233, -132, -112,
- -233, -104, -233, -108, -110, -105, -233, -114, -106, -113,
- -109, -233, -125, -107, -233, -233, -49, -175, -176, -178,
- -233, -233, -197, -198, -83, -19, -22, -186, -21, -23,
- -82, -84, -233, -75, -86, -81, -70, -74, -76, -219,
- -79, -68, -77, -73, -233, -171, -170, -80, -78, -90,
- -91, -93, -233, -219, -196, 384, -233, -233, -233, -207,
- -233, -57, -213, -196, -59, -233, -66, -65, -56, -73,
- -95, -233, -219, -233, -233, -92, -233, -30, -233, -118,
- -233, -233, -233, -233, -233, -142, -233, -149, -233, -216,
- -229, -225, -233, -228, -224, -233, -233, -233, -233, -233,
- -233, -233, -233, -233, -233, -233, -233, -233, -233, -233,
- -233, -233, -233, -233, -233, -233, -20, -233, -206, -233,
- -204, -233, -201, -230, -233, -71, -220, -233, -233, -85,
- -233, -220, -233, -233, -233, -209, -190, -233, -208, -233,
- -54, -62, -61, -233, -233, -233, -217, -218, -233, -124,
- -233, -55, -219, -233, -233, -28, -233, -120, -119, -35,
- -34, -168, -166, -233, -169, -160, -167, -161, -73, -233,
- -123, -116, -233, -152, -218, -214, -233, -233, -222, -137,
- -139, -138, -133, -140, -144, -141, -146, -151, -148, -145,
- -134, -150, -147, -143, -135, -233, -128, -136, -233, -154,
- -233, -158, -177, -233, -180, -233, -199, -233, -233, -200,
- -45, -69, -87, -46, -88, -219, -89, -94, -48, -233,
- -211, -210, -212, -233, -184, -58, -60, -97, -98, -63,
- -102, -99, -100, -101, -64, -96, -47, -233, -232, -29,
- -121, -233, -163, -219, -115, -215, -227, -226, -223, -128,
- -127, -233, -233, -155, -153, -233, -233, -179, -205, -203,
- -202, -67, -233, -182, -183, -52, -165, -218, -233, -233,
- -126, -129, -233, -159, -233, -181, -164, -162, -233, -131,
- -233, -157, -130, -156 ]
+ -197, -234, -51, -19, -8, -234, -234, -9, -234, -10,
+ -188, -189, -234, -23, -11, -186, -12, -234, -234, -13,
+ -1, -14, -2, -187, -15, -3, -234, -234, -16, -234,
+ -17, -6, -234, -234, -18, -7, -189, -197, -187, -52,
+ -27, -28, -234, -25, -26, -234, -234, -234, -234, -234,
+ -197, -86, -93, -234, -196, -194, -197, -190, -192, -193,
+ -222, -195, -4, -42, -232, -43, -214, -175, -118, -44,
+ -234, -234, -45, -34, -75, -32, -33, -234, -234, -123,
+ -37, -74, -38, -234, -73, -39, -173, -40, -174, -41,
+ -234, -234, -126, -108, -104, -234, -112, -133, -113, -234,
+ -234, -105, -109, -234, -111, -106, -115, -107, -114, -110,
+ -54, -197, -234, -86, -197, -234, -179, -176, -177, -234,
+ -50, -234, -198, -199, -24, -21, -23, -187, -22, -84,
+ -20, -83, -85, -234, -197, -79, -76, -87, -82, -75,
+ -71, -77, -220, -80, -74, -69, -78, -234, -172, -171,
+ -81, -91, -92, -94, -234, -220, 385, -234, -234, -234,
+ -208, -234, -31, -234, -234, -119, -234, -234, -96, -234,
+ -234, -143, -234, -234, -234, -234, -234, -234, -234, -234,
+ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
+ -234, -150, -234, -217, -234, -230, -226, -234, -229, -225,
+ -93, -234, -214, -197, -58, -60, -234, -67, -57, -74,
+ -66, -234, -220, -234, -234, -234, -234, -234, -207, -205,
+ -234, -234, -202, -231, -234, -234, -210, -234, -72, -221,
+ -234, -234, -86, -234, -221, -234, -191, -209, -234, -234,
+ -234, -29, -234, -121, -120, -36, -35, -169, -167, -234,
+ -170, -161, -74, -168, -234, -162, -218, -219, -124, -234,
+ -117, -234, -138, -140, -139, -134, -141, -145, -142, -147,
+ -152, -149, -146, -135, -151, -148, -144, -136, -5, -234,
+ -129, -137, -153, -219, -215, -234, -223, -234, -220, -55,
+ -234, -63, -62, -234, -234, -234, -125, -234, -56, -234,
+ -155, -234, -159, -178, -234, -181, -234, -234, -200, -234,
+ -201, -234, -212, -213, -211, -46, -70, -88, -47, -89,
+ -220, -90, -95, -49, -234, -185, -233, -30, -122, -234,
+ -164, -220, -97, -116, -129, -234, -128, -234, -216, -227,
+ -224, -228, -234, -59, -61, -102, -98, -99, -64, -103,
+ -100, -101, -65, -48, -156, -154, -234, -234, -180, -206,
+ -204, -203, -234, -183, -68, -184, -166, -219, -234, -234,
+ -127, -130, -234, -53, -160, -234, -182, -165, -163, -234,
+ -132, -234, -158, -131, -157 ]
racc_goto_table = [
- 22, 9, 68, 112, 53, 118, 61, 36, 91, 222,
- 19, 267, 70, 93, 2, 227, 139, 191, 51, 22,
- 9, 179, 77, 56, 73, 149, 21, 141, 133, 232,
- 115, 172, 153, 2, 146, 263, 125, 116, 135, 148,
- 147, 299, 129, 22, 126, 260, 160, 350, 250, 174,
- 128, 171, 43, 68, 121, 329, 334, 298, 368, 91,
- 258, 265, 123, 70, 93, 317, 343, 301, 136, 154,
- 183, 119, 224, 178, 233, 73, 55, 123, 157, 66,
- 238, 159, 120, 219, 221, 190, 325, 321, 195, 16,
- 188, nil, nil, nil, nil, nil, nil, nil, 342, nil,
- 370, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 216, nil, nil, nil, nil, 260, 129,
- 22, 126, 263, nil, nil, 353, nil, 128, 337, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 81,
- nil, nil, nil, 53, nil, 53, nil, 243, nil, nil,
- 149, 301, nil, nil, nil, nil, nil, 252, nil, nil,
- 68, 261, 236, 68, nil, 138, 91, 146, nil, 91,
- 70, 93, nil, 70, 93, nil, nil, nil, 166, nil,
- 235, 166, 259, 272, nil, 73, nil, 302, 347, nil,
- 81, 361, nil, 261, 290, 360, 315, 376, 294, 146,
- nil, 312, 340, 311, 133, nil, 149, nil, 373, nil,
- 146, nil, 22, 9, 135, 148, 147, 22, 9, 369,
- nil, 263, 295, 327, 327, nil, 2, 303, nil, 146,
- 146, 2, nil, 68, 333, 333, nil, 22, 9, 91,
- 320, 88, nil, 70, 93, nil, nil, 323, 261, nil,
- nil, 2, nil, nil, 146, 259, 190, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 88, nil, nil,
- nil, nil, nil, nil, nil, 87, nil, 261, nil, 166,
- nil, nil, 61, 146, nil, nil, nil, nil, nil, nil,
- 61, nil, 88, nil, nil, 22, 9, 81, 262, nil,
- 81, 142, nil, 22, 9, nil, nil, nil, nil, 2,
- 61, nil, nil, nil, nil, nil, nil, 2, nil, 22,
- 9, nil, nil, 22, 9, nil, 87, nil, 371, 362,
- 262, nil, nil, 2, 261, nil, nil, 2, nil, nil,
- 146, 138, nil, nil, nil, nil, nil, 261, nil, 61,
- nil, nil, nil, 146, nil, 166, nil, nil, nil, nil,
- 328, 328, 22, 9, 114, 61, nil, 61, nil, 84,
- 81, nil, 22, 9, 22, 9, 2, 90, 22, 9,
- 22, 9, 378, 132, 380, 262, 2, nil, 2, nil,
- nil, nil, 2, nil, 2, 140, nil, nil, 170, 88,
- 88, nil, 88, 145, nil, nil, nil, nil, 167, nil,
- nil, 167, nil, nil, 262, nil, nil, 170, nil, nil,
- 84, nil, nil, nil, nil, nil, nil, nil, 90, nil,
- nil, nil, 88, 87, 266, nil, 87, 170, nil, nil,
- nil, nil, nil, 88, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 88, 88, nil, nil, 266, nil, nil, nil,
- nil, 262, 88, nil, nil, nil, nil, 142, nil, nil,
- nil, nil, nil, nil, 262, nil, nil, 88, nil, nil,
- nil, nil, nil, nil, nil, nil, 331, 331, nil, nil,
- nil, nil, nil, nil, nil, nil, 87, nil, nil, 167,
- nil, 253, nil, nil, nil, nil, 88, nil, nil, nil,
- nil, 266, nil, nil, nil, nil, nil, 84, 264, nil,
- 84, nil, nil, nil, 282, 90, 145, nil, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 266, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 264, nil, nil, 314, nil, 316, nil, 124, 145, nil,
- nil, 140, nil, 88, 130, 131, nil, nil, nil, 145,
- nil, nil, nil, 335, nil, 167, 88, nil, nil, nil,
- 330, 330, nil, nil, nil, nil, nil, nil, 332, 332,
- 84, nil, nil, 180, nil, nil, nil, 266, 90, nil,
- nil, 346, nil, nil, nil, 264, nil, nil, nil, nil,
- 266, nil, 185, 145, nil, 186, nil, nil, 187, nil,
+ 27, 13, 5, 37, 62, 255, 249, 20, 118, 196,
+ 92, 89, 142, 50, 155, 300, 69, 63, 222, 336,
+ 27, 13, 5, 165, 73, 75, 57, 279, 348, 352,
+ 246, 151, 145, 119, 343, 150, 121, 230, 65, 149,
+ 299, 22, 27, 126, 138, 135, 27, 126, 201, 134,
+ 235, 214, 120, 87, 302, 86, 304, 244, 89, 42,
+ 169, 128, 46, 69, 63, 128, 136, 251, 368, 331,
+ 322, 73, 163, 370, 212, 125, 124, 324, 123, 130,
+ 124, 148, 192, 86, 116, 65, 140, 224, 56, 159,
+ 227, 123, 330, 249, 211, 237, 220, 160, 221, 354,
+ 87, 110, 86, 115, 246, 314, 194, 297, 17, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 195, nil,
+ nil, nil, nil, 133, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 54, nil, nil, nil, 302, nil,
+ 293, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, 168, nil, 89, 149, nil, nil, 89, 69,
+ 63, nil, 288, 69, 63, 236, nil, 245, nil, nil,
+ nil, 73, 261, 82, 168, 226, nil, nil, nil, 151,
+ nil, 65, 247, 342, nil, 65, 168, nil, 27, 13,
+ 5, 339, 303, 320, 328, 374, 87, 148, 86, 86,
+ 87, 143, 86, 149, 80, 361, 377, 249, 317, 316,
+ nil, 379, 150, 151, 381, 364, 149, 27, 13, 5,
+ 82, 138, 135, nil, nil, nil, 369, 312, 89, nil,
+ 247, nil, 141, 69, 63, 239, nil, nil, 27, 13,
+ 5, 245, 149, 136, nil, 148, nil, 86, nil, 265,
+ nil, 80, nil, nil, nil, 65, nil, nil, 148, nil,
+ 86, 210, 62, nil, 210, nil, nil, nil, 85, 247,
+ 87, nil, 86, 54, 54, nil, nil, nil, 27, 13,
+ 5, nil, 149, 149, 148, nil, 86, 149, 345, 345,
+ nil, nil, 207, nil, nil, 207, 146, nil, nil, 273,
+ 195, nil, nil, 277, nil, 319, nil, 321, nil, 346,
+ 346, 27, 13, 5, 247, 85, 82, 250, 362, 371,
+ 82, nil, nil, nil, 351, 351, 86, 86, nil, 148,
+ nil, 86, nil, 332, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 149, nil, 62, 80, 248, nil,
+ nil, 80, nil, 210, nil, nil, 149, nil, nil, nil,
+ nil, 341, 27, 13, 5, 250, nil, nil, nil, nil,
+ nil, 247, 27, 13, 5, 27, 13, 5, 143, nil,
+ 359, 360, nil, 247, 207, nil, 148, nil, 86, nil,
+ 82, nil, 129, nil, 131, 132, 248, nil, 148, nil,
+ 86, nil, nil, 366, 250, nil, nil, nil, nil, 141,
+ nil, 85, 253, nil, nil, 85, nil, nil, 164, nil,
+ nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, 248, nil, 171, nil, nil,
+ 210, nil, 190, nil, 349, 349, 191, nil, nil, 250,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 358, nil, 359, nil, 264, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, nil, nil, nil, nil, nil, nil,
+ 253, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, 207, nil, 146, nil, 347, 347, nil, nil, nil,
+ 248, nil, nil, nil, nil, 85, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 253,
+ nil, nil, nil, nil, nil, nil, 250, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 250, 262,
+ 263, 264, nil, 266, 267, 268, 269, 270, 271, 272,
+ nil, 274, 275, 276, nil, nil, 281, 248, nil, 350,
+ 350, nil, nil, nil, 253, nil, nil, nil, nil, 248,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 366, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 264, nil, nil, nil, nil, nil, nil, nil, 145,
- nil, nil, nil, nil, 264, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, 279, 280, 281, nil, 283, 284,
- 285, 286, 287, 288, 289, nil, 291, 292, 293, nil,
- nil, 297, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 164,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 180 ]
+ nil, 253, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 253 ]
racc_goto_check = [
- 37, 21, 30, 62, 64, 72, 4, 32, 28, 82,
- 2, 70, 31, 29, 52, 36, 35, 85, 32, 37,
- 21, 60, 22, 78, 21, 53, 3, 47, 30, 36,
- 37, 35, 38, 52, 28, 68, 19, 5, 31, 29,
- 50, 66, 7, 37, 21, 23, 41, 63, 36, 41,
- 5, 57, 20, 30, 74, 46, 46, 65, 58, 28,
- 61, 69, 3, 31, 29, 56, 71, 68, 33, 74,
- 57, 73, 34, 22, 75, 21, 76, 3, 77, 40,
- 79, 3, 20, 80, 81, 30, 42, 83, 84, 1,
- 57, nil, nil, nil, nil, nil, nil, nil, 70, nil,
- 63, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 19, nil, nil, nil, nil, 23, 7,
- 37, 21, 68, nil, nil, 66, nil, 5, 36, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 24,
- nil, nil, nil, 64, nil, 64, nil, 41, nil, nil,
- 53, 68, nil, nil, nil, nil, nil, 38, nil, nil,
- 30, 30, 78, 30, nil, 24, 28, 28, nil, 28,
- 31, 29, nil, 31, 29, nil, nil, nil, 24, nil,
- 3, 24, 21, 22, nil, 21, nil, 72, 85, nil,
- 24, 36, nil, 30, 64, 82, 35, 70, 64, 28,
- nil, 53, 60, 47, 30, nil, 53, nil, 68, nil,
- 28, nil, 37, 21, 31, 29, 50, 37, 21, 36,
- nil, 68, 2, 30, 30, nil, 52, 2, nil, 28,
- 28, 52, nil, 30, 29, 29, nil, 37, 21, 28,
- 32, 49, nil, 31, 29, nil, nil, 2, 30, nil,
- nil, 52, nil, nil, 28, 21, 30, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 49, nil, nil,
- nil, nil, nil, nil, nil, 26, nil, 30, nil, 24,
- nil, nil, 4, 28, nil, nil, nil, nil, nil, nil,
- 4, nil, 49, nil, nil, 37, 21, 24, 24, nil,
- 24, 26, nil, 37, 21, nil, nil, nil, nil, 52,
- 4, nil, nil, nil, nil, nil, nil, 52, nil, 37,
- 21, nil, nil, 37, 21, nil, 26, nil, 62, 2,
- 24, nil, nil, 52, 30, nil, nil, 52, nil, nil,
- 28, 24, nil, nil, nil, nil, nil, 30, nil, 4,
- nil, nil, nil, 28, nil, 24, nil, nil, nil, nil,
- 24, 24, 37, 21, 54, 4, nil, 4, nil, 25,
- 24, nil, 37, 21, 37, 21, 52, 27, 37, 21,
- 37, 21, 2, 54, 2, 24, 52, nil, 52, nil,
- nil, nil, 52, nil, 52, 25, nil, nil, 54, 49,
- 49, nil, 49, 27, nil, nil, nil, nil, 25, nil,
- nil, 25, nil, nil, 24, nil, nil, 54, nil, nil,
- 25, nil, nil, nil, nil, nil, nil, nil, 27, nil,
- nil, nil, 49, 26, 26, nil, 26, 54, nil, nil,
- nil, nil, nil, 49, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 49, 49, nil, nil, 26, nil, nil, nil,
- nil, 24, 49, nil, nil, nil, nil, 26, nil, nil,
- nil, nil, nil, nil, 24, nil, nil, 49, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, 26, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, nil, nil, 25,
- nil, 54, nil, nil, nil, nil, 49, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, 25, 25, nil,
- 25, nil, nil, nil, 54, 27, 27, nil, 27, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 26, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 25, nil, nil, 54, nil, 54, nil, 51, 27, nil,
- nil, 25, nil, 49, 51, 51, nil, nil, nil, 27,
- nil, nil, nil, 54, nil, 25, 49, nil, nil, nil,
- 25, 25, nil, nil, nil, nil, nil, nil, 27, 27,
- 25, nil, nil, 51, nil, nil, nil, 26, 27, nil,
- nil, 54, nil, nil, nil, 25, nil, nil, nil, nil,
- 26, nil, 51, 27, nil, 51, nil, nil, 51, nil,
+ 38, 22, 53, 33, 4, 71, 69, 2, 73, 86,
+ 63, 29, 36, 33, 39, 67, 32, 30, 83, 64,
+ 38, 22, 53, 61, 22, 23, 79, 5, 47, 47,
+ 24, 54, 48, 38, 43, 51, 75, 37, 31, 29,
+ 66, 3, 38, 22, 32, 30, 38, 22, 42, 75,
+ 37, 42, 6, 28, 69, 50, 5, 62, 29, 21,
+ 58, 6, 21, 32, 30, 6, 31, 70, 59, 72,
+ 57, 22, 23, 64, 36, 20, 8, 5, 3, 20,
+ 8, 28, 58, 50, 74, 31, 34, 76, 77, 78,
+ 35, 3, 71, 69, 58, 80, 81, 3, 82, 67,
+ 28, 41, 50, 55, 24, 84, 85, 37, 1, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 31, nil,
+ nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 65, nil, nil, nil, 69, nil,
+ 42, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, 55, nil, 29, 29, nil, nil, 29, 32,
+ 30, nil, 39, 32, 30, 79, nil, 22, nil, nil,
+ nil, 22, 23, 26, 55, 3, nil, nil, nil, 54,
+ nil, 31, 31, 37, nil, 31, 55, nil, 38, 22,
+ 53, 86, 73, 36, 61, 69, 28, 28, 50, 50,
+ 28, 26, 50, 29, 25, 83, 71, 69, 54, 48,
+ nil, 5, 51, 54, 5, 37, 29, 38, 22, 53,
+ 26, 32, 30, nil, nil, nil, 37, 33, 29, nil,
+ 31, nil, 25, 32, 30, 55, nil, nil, 38, 22,
+ 53, 22, 29, 31, nil, 28, nil, 50, nil, 55,
+ nil, 25, nil, nil, nil, 31, nil, nil, 28, nil,
+ 50, 26, 4, nil, 26, nil, nil, nil, 27, 31,
+ 28, nil, 50, 65, 65, nil, nil, nil, 38, 22,
+ 53, nil, 29, 29, 28, nil, 50, 29, 30, 30,
+ nil, nil, 25, nil, nil, 25, 27, nil, nil, 65,
+ 31, nil, nil, 65, nil, 55, nil, 55, nil, 31,
+ 31, 38, 22, 53, 31, 27, 26, 26, 2, 63,
+ 26, nil, nil, nil, 28, 28, 50, 50, nil, 28,
+ nil, 50, nil, 55, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, 29, nil, 4, 25, 25, nil,
+ nil, 25, nil, 26, nil, nil, 29, nil, nil, nil,
+ nil, 55, 38, 22, 53, 26, nil, nil, nil, nil,
+ nil, 31, 38, 22, 53, 38, 22, 53, 26, nil,
+ 55, 55, nil, 31, 25, nil, 28, nil, 50, nil,
+ 26, nil, 52, nil, 52, 52, 25, nil, 28, nil,
+ 50, nil, nil, 55, 26, nil, nil, nil, nil, 25,
+ nil, 27, 27, nil, nil, 27, nil, nil, 52, nil,
+ nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, 25, nil, 52, nil, nil,
+ 26, nil, 52, nil, 26, 26, 52, nil, nil, 26,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 54, nil, 25, nil, nil, nil, nil, nil,
- nil, nil, 27, nil, nil, nil, nil, nil, nil, nil,
+ 27, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, 25, nil, 27, nil, 25, 25, nil, nil, nil,
+ 25, nil, nil, nil, nil, 27, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 27,
+ nil, nil, nil, nil, nil, nil, 26, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, 26, 52,
+ 52, 52, nil, 52, 52, 52, 52, 52, 52, 52,
+ nil, 52, 52, 52, nil, nil, 52, 25, nil, 27,
+ 27, nil, nil, nil, 27, nil, nil, nil, nil, 25,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, 27,
- nil, nil, nil, nil, 25, nil, nil, nil, nil, nil,
- nil, nil, 27, nil, 51, 51, 51, nil, 51, 51,
- 51, 51, 51, 51, 51, nil, 51, 51, 51, nil,
- nil, 51, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 52,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 51 ]
+ nil, 27, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, 27 ]
racc_goto_pointer = [
- nil, 89, 10, 26, -13, 7, nil, -1, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, -7,
- 48, 1, -1, -136, 116, 346, 252, 354, -15, -10,
- -21, -11, 6, 19, -64, -33, -124, 0, -18, nil,
- 57, -16, -153, nil, nil, nil, -189, -22, nil, 218,
- -9, 528, 14, -25, 335, nil, -166, -12, -285, nil,
- -54, -120, -23, -249, -13, -157, -173, nil, -147, -121,
- -171, -203, -28, 38, 18, -80, 59, 23, 6, -78,
- -39, -38, -113, -147, -18, -89, nil ]
+ nil, 108, 7, 41, -16, -161, 19, nil, 34, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ 33, 56, 1, 2, -136, 181, 150, 245, 30, -12,
+ -6, 15, -7, 2, 35, -50, -39, -105, 0, -38,
+ nil, 74, -63, -256, nil, nil, nil, -266, -19, nil,
+ 32, -16, 347, 2, -21, 74, nil, -164, -18, -263,
+ nil, -48, -107, -16, -261, 116, -175, -200, nil, -161,
+ -100, -162, -185, -24, 52, -1, -47, 70, 33, 8,
+ -63, -26, -24, -104, -120, 3, -94, nil ]
racc_goto_default = [
- nil, nil, nil, 168, 25, 28, 32, 35, 5, 6,
- 10, 13, 15, 18, 20, 24, 27, 31, 34, 4,
- nil, 99, nil, 79, 101, 103, 105, 108, 109, 113,
- 95, 96, 8, nil, nil, nil, nil, 85, nil, 30,
- nil, nil, 161, 239, 164, 165, nil, nil, 144, 107,
- 110, 111, 67, 134, 98, 150, 151, nil, 248, 104,
- nil, nil, nil, nil, 69, nil, nil, 300, 80, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 57,
- nil, nil, nil, nil, nil, nil, 192 ]
+ nil, nil, 278, 208, 25, nil, 31, 35, 4, 7,
+ 9, 14, 16, 19, 21, 24, 28, 30, 34, 3,
+ 6, nil, 98, nil, 76, 101, 102, 105, 107, 108,
+ 93, 94, 96, 12, nil, nil, nil, nil, 83, nil,
+ 33, nil, nil, 204, 290, 205, 206, nil, nil, 147,
+ 106, 109, 91, 64, 137, 97, 152, 153, nil, 259,
+ 104, nil, nil, nil, nil, 67, nil, nil, 301, 77,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ 58, nil, nil, nil, nil, nil, nil, 197 ]
racc_token_table = {
false => 0,
@@ -1083,9 +1040,10 @@ Racc_token_to_s_table = [
'IN',
'$start',
'program',
-'statements',
+'statements_and_declarations',
'nil',
-'statement',
+'statement_or_declaration',
+'statements',
'resource',
'virtualresource',
'collection',
@@ -1175,48 +1133,39 @@ Racc_debug_parser = false
# reduce 0 omitted
-module_eval <<'.,.,', 'grammar.ra', 46
- def _reduce_1( val, _values, result )
- if val[0]
- # Make sure we always return an array.
- if val[0].is_a?(AST::ASTArray)
- if val[0].children.empty?
- result = nil
- else
- result = val[0]
- end
- else
- result = aryfy(val[0])
- end
- else
- result = nil
- end
- result
- end
-.,.,
+ # reduce 1 omitted
# reduce 2 omitted
- # reduce 3 omitted
+module_eval <<'.,.,', 'grammar.ra', 36
+ def _reduce_3( val, _values, result )
+ result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : [])
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 62
+module_eval <<'.,.,', 'grammar.ra', 42
def _reduce_4( val, _values, result )
- if val[0] and val[1]
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[1])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[1]]
- end
- elsif obj = (val[0] || val[1])
- result = obj
- else result = nil
+ if val[1]
+ val[0].push(val[1])
end
+ result = val[0]
result
end
.,.,
- # reduce 5 omitted
+module_eval <<'.,.,', 'grammar.ra', 54
+ def _reduce_5( val, _values, result )
+ val[0].each do |stmt|
+ if stmt.is_a?(AST::TopLevelConstruct)
+ error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \
+ :line => stmt.context[:line], :file => stmt.context[:file]
+ end
+ end
+ result = val[0]
+ result
+ end
+.,.,
# reduce 6 omitted
@@ -1244,22 +1193,22 @@ module_eval <<'.,.,', 'grammar.ra', 62
# reduce 18 omitted
-module_eval <<'.,.,', 'grammar.ra', 82
- def _reduce_19( val, _values, result )
- result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
+ # reduce 19 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 74
+ def _reduce_20( val, _values, result )
+ result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 85
- def _reduce_20( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 77
+ def _reduce_21( val, _values, result )
result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context)
result
end
.,.,
- # reduce 21 omitted
-
# reduce 22 omitted
# reduce 23 omitted
@@ -1272,80 +1221,81 @@ module_eval <<'.,.,', 'grammar.ra', 85
# reduce 27 omitted
-module_eval <<'.,.,', 'grammar.ra', 98
- def _reduce_28( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
- result
- end
-.,.,
+ # reduce 28 omitted
-module_eval <<'.,.,', 'grammar.ra', 106
+module_eval <<'.,.,', 'grammar.ra', 89
def _reduce_29( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :statement
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 112
+module_eval <<'.,.,', 'grammar.ra', 96
def _reduce_30( val, _values, result )
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :statement
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 120
+module_eval <<'.,.,', 'grammar.ra', 102
def _reduce_31( val, _values, result )
- args = aryfy(val[1])
- result = ast AST::Function,
- :name => val[0][:value],
- :line => val[0][:line],
- :arguments => args,
- :ftype => :statement
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :statement
result
end
.,.,
- # reduce 32 omitted
+module_eval <<'.,.,', 'grammar.ra', 109
+ def _reduce_32( val, _values, result )
+ result = ast AST::Function,
+ :name => val[0][:value],
+ :line => val[0][:line],
+ :arguments => val[1],
+ :ftype => :statement
+ result
+ end
+.,.,
- # reduce 33 omitted
+module_eval <<'.,.,', 'grammar.ra', 110
+ def _reduce_33( val, _values, result )
+ result = aryfy(val[0])
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 128
+module_eval <<'.,.,', 'grammar.ra', 111
def _reduce_34( val, _values, result )
- result = aryfy(val[0], val[2])
- result.line = @lexer.line
- result.file = @lexer.file
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 137
+module_eval <<'.,.,', 'grammar.ra', 116
def _reduce_35( val, _values, result )
- unless val[0].is_a?(AST::ASTArray)
- val[0] = aryfy(val[0])
- end
-
val[0].push(val[2])
-
result = val[0]
result
end
.,.,
- # reduce 36 omitted
+module_eval <<'.,.,', 'grammar.ra', 120
+ def _reduce_36( val, _values, result )
+ val[0].push(val[2])
+ result = val[0]
+ result
+ end
+.,.,
# reduce 37 omitted
@@ -1361,223 +1311,198 @@ module_eval <<'.,.,', 'grammar.ra', 137
# reduce 43 omitted
-module_eval <<'.,.,', 'grammar.ra', 151
- def _reduce_44( val, _values, result )
- result = ast AST::Name, :value => val[0][:value]
- result
- end
-.,.,
+ # reduce 44 omitted
-module_eval <<'.,.,', 'grammar.ra', 173
+module_eval <<'.,.,', 'grammar.ra', 134
def _reduce_45( val, _values, result )
- @lexer.commentpop
- array = val[2]
- if array.instance_of?(AST::ResourceInstance)
- array = [array]
- end
- result = ast AST::ASTArray
-
- # this iterates across each specified resourceinstance
- array.each { |instance|
- unless instance.instance_of?(AST::ResourceInstance)
- raise Puppet::Dev, "Got something that isn't an instance"
- end
- # now, i need to somehow differentiate between those things with
- # arrays in their names, and normal things
- result.push ast(AST::Resource,
- :type => val[0],
- :title => instance[0],
- :parameters => instance[1])
- }
+ result = ast AST::Name, :value => val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 176
+module_eval <<'.,.,', 'grammar.ra', 139
def _reduce_46( val, _values, result )
- # This is a deprecated syntax.
- error "All resource specifications require names"
+ @lexer.commentpop
+ result = ast(AST::Resource, :type => val[0], :instances => val[2])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 180
+module_eval <<'.,.,', 'grammar.ra', 142
def _reduce_47( val, _values, result )
- # a defaults setting for a type
- @lexer.commentpop
- result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
+ # This is a deprecated syntax.
+ error "All resource specifications require names"
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 186
+module_eval <<'.,.,', 'grammar.ra', 146
def _reduce_48( val, _values, result )
- @lexer.commentpop
- result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
+ # a defaults setting for a type
+ @lexer.commentpop
+ result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 213
+module_eval <<'.,.,', 'grammar.ra', 152
def _reduce_49( val, _values, result )
- type = val[0]
+ @lexer.commentpop
+ result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2]
+ result
+ end
+.,.,
- if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect without storeconfigs being set")
- end
+module_eval <<'.,.,', 'grammar.ra', 171
+ def _reduce_50( val, _values, result )
+ type = val[0]
- if val[1].is_a? AST::ResourceDefaults
- error "Defaults are not virtualizable"
- end
+ if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect without storeconfigs being set")
+ end
- method = type.to_s + "="
+ error "Defaults are not virtualizable" if val[1].is_a? AST::ResourceDefaults
- # Just mark our resources as exported and pass them through.
- if val[1].instance_of?(AST::ASTArray)
- val[1].each do |obj|
- obj.send(method, true)
- end
- else
- val[1].send(method, true)
- end
+ method = type.to_s + "="
- result = val[1]
+ # Just mark our resource as exported and pass it through.
+ val[1].send(method, true)
+
+ result = val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 214
- def _reduce_50( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 172
+ def _reduce_51( val, _values, result )
result = :virtual
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 215
- def _reduce_51( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 173
+ def _reduce_52( val, _values, result )
result = :exported
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 240
- def _reduce_52( val, _values, result )
- @lexer.commentpop
- if val[0] =~ /^[a-z]/
- Puppet.warning addcontext("Collection names must now be capitalized")
- end
- type = val[0].downcase
- args = {:type => type}
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- args[:override] = val[3]
- result = ast AST::Collection, args
+module_eval <<'.,.,', 'grammar.ra', 196
+ def _reduce_53( val, _values, result )
+ @lexer.commentpop
+ Puppet.warning addcontext("Collection names must now be capitalized") if val[0] =~ /^[a-z]/
+ type = val[0].downcase
+ args = {:type => type}
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ args[:override] = val[3]
+ result = ast AST::Collection, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 259
- def _reduce_53( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 215
+ def _reduce_54( val, _values, result )
if val[0] =~ /^[a-z]/
- Puppet.warning addcontext("Collection names must now be capitalized")
- end
- type = val[0].downcase
- args = {:type => type }
-
- if val[1].is_a?(AST::CollExpr)
- args[:query] = val[1]
- args[:query].type = type
- args[:form] = args[:query].form
- else
- args[:form] = val[1]
- end
- if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
- Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
- end
- result = ast AST::Collection, args
+ Puppet.warning addcontext("Collection names must now be capitalized")
+ end
+ type = val[0].downcase
+ args = {:type => type }
+
+ if val[1].is_a?(AST::CollExpr)
+ args[:query] = val[1]
+ args[:query].type = type
+ args[:form] = args[:query].form
+ else
+ args[:form] = val[1]
+ end
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
+ Puppet.warning addcontext("You cannot collect exported resources without storeconfigs being set; the collection will be ignored")
+ end
+ result = ast AST::Collection, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 269
- def _reduce_54( val, _values, result )
- if val[1]
- result = val[1]
- result.form = :virtual
- else
- result = :virtual
- end
+module_eval <<'.,.,', 'grammar.ra', 225
+ def _reduce_55( val, _values, result )
+ if val[1]
+ result = val[1]
+ result.form = :virtual
+ else
+ result = :virtual
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 277
- def _reduce_55( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 233
+ def _reduce_56( val, _values, result )
if val[1]
- result = val[1]
- result.form = :exported
- else
- result = :exported
- end
+ result = val[1]
+ result.form = :exported
+ else
+ result = :exported
+ end
result
end
.,.,
- # reduce 56 omitted
-
# reduce 57 omitted
-module_eval <<'.,.,', 'grammar.ra', 285
- def _reduce_58( val, _values, result )
+ # reduce 58 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 241
+ def _reduce_59( val, _values, result )
result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2]
result
end
.,.,
- # reduce 59 omitted
+ # reduce 60 omitted
-module_eval <<'.,.,', 'grammar.ra', 291
- def _reduce_60( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 247
+ def _reduce_61( val, _values, result )
result = val[1]
result.parens = true
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 292
- def _reduce_61( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 248
+ def _reduce_62( val, _values, result )
result=val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 293
- def _reduce_62( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 249
+ def _reduce_63( val, _values, result )
result=val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 300
- def _reduce_63( val, _values, result )
- result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
- #result = ast AST::CollExpr
- #result.push *val
+module_eval <<'.,.,', 'grammar.ra', 256
+ def _reduce_64( val, _values, result )
+ result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
+ #result = ast AST::CollExpr
+ #result.push *val
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 305
- def _reduce_64( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 261
+ def _reduce_65( val, _values, result )
result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2]
#result = ast AST::CollExpr
#result.push *val
@@ -1585,57 +1510,56 @@ module_eval <<'.,.,', 'grammar.ra', 305
end
.,.,
- # reduce 65 omitted
-
# reduce 66 omitted
-module_eval <<'.,.,', 'grammar.ra', 312
- def _reduce_67( val, _values, result )
- result = ast AST::ResourceInstance, :children => [val[0],val[2]]
+ # reduce 67 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 268
+ def _reduce_68( val, _values, result )
+ result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2]
result
end
.,.,
- # reduce 68 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 322
+module_eval <<'.,.,', 'grammar.ra', 269
def _reduce_69( val, _values, result )
- if val[0].instance_of?(AST::ResourceInstance)
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- else
- val[0].push val[2]
- result = val[0]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 70 omitted
-
- # reduce 71 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 329
- def _reduce_72( val, _values, result )
- result = ast AST::Undef, :value => :undef
+module_eval <<'.,.,', 'grammar.ra', 274
+ def _reduce_70( val, _values, result )
+ val[0].push val[2]
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 333
+ # reduce 71 omitted
+
+ # reduce 72 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 281
def _reduce_73( val, _values, result )
- result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Undef, :value => :undef
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 337
+module_eval <<'.,.,', 'grammar.ra', 285
def _reduce_74( val, _values, result )
- result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
- # reduce 75 omitted
+module_eval <<'.,.,', 'grammar.ra', 289
+ def _reduce_75( val, _values, result )
+ result = ast AST::Type, :value => val[0][:value], :line => val[0][:line]
+ result
+ end
+.,.,
# reduce 76 omitted
@@ -1649,118 +1573,109 @@ module_eval <<'.,.,', 'grammar.ra', 337
# reduce 81 omitted
-module_eval <<'.,.,', 'grammar.ra', 354
- def _reduce_82( val, _values, result )
- if val[0][:value] =~ /::/
- raise Puppet::ParseError, "Cannot assign to variables in other namespaces"
- end
- # this is distinct from referencing a variable
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
- result
- end
-.,.,
+ # reduce 82 omitted
-module_eval <<'.,.,', 'grammar.ra', 357
+module_eval <<'.,.,', 'grammar.ra', 304
def _reduce_83( val, _values, result )
- result = ast AST::VarDef, :name => val[0], :value => val[2]
+ raise Puppet::ParseError, "Cannot assign to variables in other namespaces" if val[0][:value] =~ /::/
+ # this is distinct from referencing a variable
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 362
+module_eval <<'.,.,', 'grammar.ra', 307
def _reduce_84( val, _values, result )
- variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
- result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
+ result = ast AST::VarDef, :name => val[0], :value => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 367
+module_eval <<'.,.,', 'grammar.ra', 312
def _reduce_85( val, _values, result )
- result = ast AST::ASTArray
+ variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 367
+module_eval <<'.,.,', 'grammar.ra', 317
def _reduce_86( val, _values, result )
- result = val[0]
+ result = ast AST::ASTArray
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 376
+module_eval <<'.,.,', 'grammar.ra', 317
def _reduce_87( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 380
+module_eval <<'.,.,', 'grammar.ra', 322
def _reduce_88( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
+ val[0].push(val[2])
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 385
+module_eval <<'.,.,', 'grammar.ra', 326
def _reduce_89( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
- :add => true
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2]
result
end
.,.,
- # reduce 90 omitted
-
- # reduce 91 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 393
- def _reduce_92( val, _values, result )
- result = ast AST::ASTArray
+module_eval <<'.,.,', 'grammar.ra', 331
+ def _reduce_90( val, _values, result )
+ result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2],
+ :add => true
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 393
+ # reduce 91 omitted
+
+ # reduce 92 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 339
def _reduce_93( val, _values, result )
- result = val[0]
+ result = ast AST::ASTArray
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 402
+module_eval <<'.,.,', 'grammar.ra', 339
def _reduce_94( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 95 omitted
+module_eval <<'.,.,', 'grammar.ra', 344
+ def _reduce_95( val, _values, result )
+ val[0].push(val[2])
+ result = val[0]
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 411
+module_eval <<'.,.,', 'grammar.ra', 345
def _reduce_96( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- result = val[0].push(val[2])
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
- # reduce 97 omitted
+module_eval <<'.,.,', 'grammar.ra', 346
+ def _reduce_97( val, _values, result )
+ result = val[0].push(val[2])
+ result
+ end
+.,.,
# reduce 98 omitted
@@ -1796,392 +1711,387 @@ module_eval <<'.,.,', 'grammar.ra', 411
# reduce 114 omitted
-module_eval <<'.,.,', 'grammar.ra', 440
- def _reduce_115( val, _values, result )
- args = aryfy(val[2])
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => args,
- :ftype => :rvalue
- result
- end
-.,.,
+ # reduce 115 omitted
-module_eval <<'.,.,', 'grammar.ra', 445
+module_eval <<'.,.,', 'grammar.ra', 375
def _reduce_116( val, _values, result )
- result = ast AST::Function,
- :name => val[0][:value], :line => val[0][:line],
- :arguments => AST::ASTArray.new({}),
- :ftype => :rvalue
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => val[2],
+ :ftype => :rvalue
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 446
+module_eval <<'.,.,', 'grammar.ra', 380
def _reduce_117( val, _values, result )
- result = ast AST::String, :value => val[0][:value], :line => val[0][:line]
+ result = ast AST::Function,
+ :name => val[0][:value], :line => val[0][:line],
+ :arguments => AST::ASTArray.new({}),
+ :ftype => :rvalue
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 447
+module_eval <<'.,.,', 'grammar.ra', 381
def _reduce_118( val, _values, result )
- result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line]
+ result = ast AST::String, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 449
+module_eval <<'.,.,', 'grammar.ra', 382
def _reduce_119( val, _values, result )
- result = [val[0]] + val[1]
+ result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 451
+module_eval <<'.,.,', 'grammar.ra', 384
def _reduce_120( val, _values, result )
- result = [ast(AST::String,val[0])]
+ result = [val[0]] + val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 452
+module_eval <<'.,.,', 'grammar.ra', 386
def _reduce_121( val, _values, result )
- result = [ast(AST::String,val[0])] + val[1]
+ result = [ast(AST::String,val[0])]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 457
+module_eval <<'.,.,', 'grammar.ra', 387
def _reduce_122( val, _values, result )
- result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
+ result = [ast(AST::String,val[0])] + val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 462
+module_eval <<'.,.,', 'grammar.ra', 392
def _reduce_123( val, _values, result )
- Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
- result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
+ result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 464
+module_eval <<'.,.,', 'grammar.ra', 397
def _reduce_124( val, _values, result )
- result = ast AST::ResourceReference, :type => val[0], :title => val[2]
+ Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized")
+ result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 468
+module_eval <<'.,.,', 'grammar.ra', 399
def _reduce_125( val, _values, result )
- result = val[1]
+ result = ast AST::ResourceReference, :type => val[0], :title => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 482
+module_eval <<'.,.,', 'grammar.ra', 403
def _reduce_126( val, _values, result )
- @lexer.commentpop
- args = {
- :test => val[0],
- :statements => val[2]
- }
+ result = val[1]
+ result
+ end
+.,.,
- if val[4]
- args[:else] = val[4]
- end
+module_eval <<'.,.,', 'grammar.ra', 415
+ def _reduce_127( val, _values, result )
+ @lexer.commentpop
+ args = {
+ :test => val[0],
+ :statements => val[2]
+ }
+
+ args[:else] = val[4] if val[4]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 495
- def _reduce_127( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 426
+ def _reduce_128( val, _values, result )
@lexer.commentpop
args = {
- :test => val[0],
- :statements => ast(AST::Nop)
- }
+ :test => val[0],
+ :statements => ast(AST::Nop)
+ }
- if val[3]
- args[:else] = val[3]
- end
+ args[:else] = val[3] if val[3]
- result = ast AST::IfStatement, args
+ result = ast AST::IfStatement, args
result
end
.,.,
- # reduce 128 omitted
+ # reduce 129 omitted
-module_eval <<'.,.,', 'grammar.ra', 501
- def _reduce_129( val, _values, result )
- #@lexer.commentpop
+module_eval <<'.,.,', 'grammar.ra', 431
+ def _reduce_130( val, _values, result )
result = ast AST::Else, :statements => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 505
- def _reduce_130( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 435
+ def _reduce_131( val, _values, result )
@lexer.commentpop
result = ast AST::Else, :statements => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 509
- def _reduce_131( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 439
+ def _reduce_132( val, _values, result )
@lexer.commentpop
result = ast AST::Else, :statements => ast(AST::Nop)
result
end
.,.,
- # reduce 132 omitted
+ # reduce 133 omitted
-module_eval <<'.,.,', 'grammar.ra', 526
- def _reduce_133( val, _values, result )
- result = ast AST::InOperator, :lval => val[0], :rval => val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'grammar.ra', 529
+module_eval <<'.,.,', 'grammar.ra', 456
def _reduce_134( val, _values, result )
- result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::InOperator, :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 532
+module_eval <<'.,.,', 'grammar.ra', 459
def _reduce_135( val, _values, result )
result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 535
+module_eval <<'.,.,', 'grammar.ra', 462
def _reduce_136( val, _values, result )
- result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 538
+module_eval <<'.,.,', 'grammar.ra', 465
def _reduce_137( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 541
+module_eval <<'.,.,', 'grammar.ra', 468
def _reduce_138( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 544
+module_eval <<'.,.,', 'grammar.ra', 471
def _reduce_139( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 547
+module_eval <<'.,.,', 'grammar.ra', 474
def _reduce_140( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 550
+module_eval <<'.,.,', 'grammar.ra', 477
def _reduce_141( val, _values, result )
result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 553
+module_eval <<'.,.,', 'grammar.ra', 480
def _reduce_142( val, _values, result )
- result = ast AST::Minus, :value => val[1]
+ result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 556
+module_eval <<'.,.,', 'grammar.ra', 483
def _reduce_143( val, _values, result )
- result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::Minus, :value => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 559
+module_eval <<'.,.,', 'grammar.ra', 486
def _reduce_144( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 562
+module_eval <<'.,.,', 'grammar.ra', 489
def _reduce_145( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 565
+module_eval <<'.,.,', 'grammar.ra', 492
def _reduce_146( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 568
+module_eval <<'.,.,', 'grammar.ra', 495
def _reduce_147( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 571
+module_eval <<'.,.,', 'grammar.ra', 498
def _reduce_148( val, _values, result )
result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 574
+module_eval <<'.,.,', 'grammar.ra', 501
def _reduce_149( val, _values, result )
- result = ast AST::Not, :value => val[1]
+ result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 577
+module_eval <<'.,.,', 'grammar.ra', 504
def _reduce_150( val, _values, result )
- result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
+ result = ast AST::Not, :value => val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 580
+module_eval <<'.,.,', 'grammar.ra', 507
def _reduce_151( val, _values, result )
result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 583
+module_eval <<'.,.,', 'grammar.ra', 510
def _reduce_152( val, _values, result )
- result = val[1]
+ result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 592
+module_eval <<'.,.,', 'grammar.ra', 513
def _reduce_153( val, _values, result )
- @lexer.commentpop
- options = val[3]
- unless options.instance_of?(AST::ASTArray)
- options = ast AST::ASTArray, :children => [val[3]]
- end
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ result = val[1]
result
end
.,.,
- # reduce 154 omitted
+module_eval <<'.,.,', 'grammar.ra', 518
+ def _reduce_154( val, _values, result )
+ @lexer.commentpop
+ result = ast AST::CaseStatement, :test => val[1], :options => val[3]
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 602
+module_eval <<'.,.,', 'grammar.ra', 519
def _reduce_155( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push val[1]
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0], val[1]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 607
+module_eval <<'.,.,', 'grammar.ra', 524
def _reduce_156( val, _values, result )
- @lexer.commentpop
- result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
+ val[0].push val[1]
+ result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 613
+module_eval <<'.,.,', 'grammar.ra', 529
def _reduce_157( val, _values, result )
- @lexer.commentpop
- result = ast(AST::CaseOpt,
- :value => val[0],
- :statements => ast(AST::ASTArray)
- )
+ @lexer.commentpop
+ result = ast AST::CaseOpt, :value => val[0], :statements => val[3]
result
end
.,.,
- # reduce 158 omitted
+module_eval <<'.,.,', 'grammar.ra', 538
+ def _reduce_158( val, _values, result )
+ @lexer.commentpop
-module_eval <<'.,.,', 'grammar.ra', 623
+ result = ast(
+ AST::CaseOpt,
+ :value => val[0],
+
+ :statements => ast(AST::ASTArray)
+ )
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ra', 539
def _reduce_159( val, _values, result )
- if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ result = aryfy(val[0])
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 627
+module_eval <<'.,.,', 'grammar.ra', 544
def _reduce_160( val, _values, result )
- result = ast AST::Selector, :param => val[0], :values => val[2]
+ val[0].push(val[2])
+ result = val[0]
result
end
.,.,
- # reduce 161 omitted
+module_eval <<'.,.,', 'grammar.ra', 548
+ def _reduce_161( val, _values, result )
+ result = ast AST::Selector, :param => val[0], :values => val[2]
+ result
+ end
+.,.,
+
+ # reduce 162 omitted
-module_eval <<'.,.,', 'grammar.ra', 633
- def _reduce_162( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 554
+ def _reduce_163( val, _values, result )
@lexer.commentpop
result = val[1]
result
end
.,.,
- # reduce 163 omitted
+ # reduce 164 omitted
-module_eval <<'.,.,', 'grammar.ra', 643
- def _reduce_164( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 564
+ def _reduce_165( val, _values, result )
if val[0].instance_of?(AST::ASTArray)
- val[0].push(val[2])
- result = val[0]
- else
- result = ast AST::ASTArray, :children => [val[0],val[2]]
- end
+ val[0].push(val[2])
+ result = val[0]
+ else
+ result = ast AST::ASTArray, :children => [val[0],val[2]]
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 647
- def _reduce_165( val, _values, result )
- result = ast AST::ResourceParam, :param => val[0], :value => val[2]
+module_eval <<'.,.,', 'grammar.ra', 568
+ def _reduce_166( val, _values, result )
+ result = ast AST::ResourceParam, :param => val[0], :value => val[2]
result
end
.,.,
- # reduce 166 omitted
-
# reduce 167 omitted
# reduce 168 omitted
@@ -2194,208 +2104,217 @@ module_eval <<'.,.,', 'grammar.ra', 647
# reduce 172 omitted
-module_eval <<'.,.,', 'grammar.ra', 658
- def _reduce_173( val, _values, result )
+ # reduce 173 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 579
+ def _reduce_174( val, _values, result )
result = ast AST::Default, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
- # reduce 174 omitted
+ # reduce 175 omitted
-module_eval <<'.,.,', 'grammar.ra', 661
- def _reduce_175( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 582
+ def _reduce_176( val, _values, result )
result = [val[0][:value]]
result
end
.,.,
- # reduce 176 omitted
+ # reduce 177 omitted
-module_eval <<'.,.,', 'grammar.ra', 663
- def _reduce_177( val, _values, result )
- result = val[0] += val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'grammar.ra', 672
+module_eval <<'.,.,', 'grammar.ra', 584
def _reduce_178( val, _values, result )
- val[1].each do |file|
- import(file)
- end
-
- result = AST::ASTArray.new(:children => [])
+ result = val[0] += val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 683
+module_eval <<'.,.,', 'grammar.ra', 593
def _reduce_179( val, _values, result )
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ val[1].each do |file|
+ import(file)
+ end
-#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
+ result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 688
+module_eval <<'.,.,', 'grammar.ra', 605
def _reduce_180( val, _values, result )
- @lexer.commentpop
- newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line]
- @lexer.indefine = false
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :code => val[4],
+ :line => val[0][:line]))
+ @lexer.indefine = false
+
+#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 697
+module_eval <<'.,.,', 'grammar.ra', 610
def _reduce_181( val, _values, result )
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Definition.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :line => val[0][:line]))
+ @lexer.indefine = false
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 703
+module_eval <<'.,.,', 'grammar.ra', 620
def _reduce_182( val, _values, result )
- @lexer.commentpop
- # Our class gets defined in the parent namespace, not our own.
- @lexer.namepop
- newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :code => val[5], :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 709
+module_eval <<'.,.,', 'grammar.ra', 627
def _reduce_183( val, _values, result )
- @lexer.commentpop
- newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ # Our class gets defined in the parent namespace, not our own.
+ @lexer.namepop
+ result = Puppet::Parser::AST::Hostclass.new(classname(val[1]),
+ ast_context(true).merge(:arguments => val[2], :parent => val[3],
+ :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 713
+module_eval <<'.,.,', 'grammar.ra', 634
def _reduce_184( val, _values, result )
- @lexer.commentpop
- newnode val[1], :parent => val[2], :line => val[0][:line]
- result = nil
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Node.new(val[1],
+ ast_context(true).merge(:parent => val[2], :code => val[4],
+ :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 714
+module_eval <<'.,.,', 'grammar.ra', 637
def _reduce_185( val, _values, result )
- result = val[0][:value]
+ @lexer.commentpop
+ result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line]))
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 716
+module_eval <<'.,.,', 'grammar.ra', 638
def _reduce_186( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 717
+module_eval <<'.,.,', 'grammar.ra', 640
def _reduce_187( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 718
+module_eval <<'.,.,', 'grammar.ra', 641
def _reduce_188( val, _values, result )
- result = "class"
+ result = val[0][:value]
result
end
.,.,
- # reduce 189 omitted
+module_eval <<'.,.,', 'grammar.ra', 642
+ def _reduce_189( val, _values, result )
+ result = "class"
+ result
+ end
+.,.,
-module_eval <<'.,.,', 'grammar.ra', 728
+module_eval <<'.,.,', 'grammar.ra', 649
def _reduce_190( val, _values, result )
- result = val[0]
- result = [result] unless result.is_a?(Array)
- result << val[2]
+ result = [result]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 732
+module_eval <<'.,.,', 'grammar.ra', 653
def _reduce_191( val, _values, result )
- result = ast AST::HostName, :value => val[0]
+ result = val[0]
+ result << val[2]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 733
+module_eval <<'.,.,', 'grammar.ra', 657
def _reduce_192( val, _values, result )
- result = val[0][:value]
+ result = ast AST::HostName, :value => val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 734
+module_eval <<'.,.,', 'grammar.ra', 658
def _reduce_193( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 735
+module_eval <<'.,.,', 'grammar.ra', 659
def _reduce_194( val, _values, result )
result = val[0][:value]
result
end
.,.,
- # reduce 195 omitted
-
-module_eval <<'.,.,', 'grammar.ra', 741
- def _reduce_196( val, _values, result )
- result = nil
+module_eval <<'.,.,', 'grammar.ra', 660
+ def _reduce_195( val, _values, result )
+ result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 745
+ # reduce 196 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 666
def _reduce_197( val, _values, result )
- result = ast AST::ASTArray, :children => []
+ result = nil
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ra', 670
+ def _reduce_198( val, _values, result )
+ result = ast AST::ASTArray, :children => []
result
end
.,.,
- # reduce 198 omitted
+ # reduce 199 omitted
-module_eval <<'.,.,', 'grammar.ra', 750
- def _reduce_199( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 675
+ def _reduce_200( val, _values, result )
result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 754
- def _reduce_200( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 679
+ def _reduce_201( val, _values, result )
result = val[1]
result = [result] unless result[0].is_a?(Array)
result
end
.,.,
- # reduce 201 omitted
+ # reduce 202 omitted
-module_eval <<'.,.,', 'grammar.ra', 761
- def _reduce_202( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 686
+ def _reduce_203( val, _values, result )
result = val[0]
result = [result] unless result[0].is_a?(Array)
result << val[2]
@@ -2403,189 +2322,181 @@ module_eval <<'.,.,', 'grammar.ra', 761
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 766
- def _reduce_203( val, _values, result )
- Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
- result = [val[0][:value], val[2]]
+module_eval <<'.,.,', 'grammar.ra', 691
+ def _reduce_204( val, _values, result )
+ Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
+ result = [val[0][:value], val[2]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 770
- def _reduce_204( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 695
+ def _reduce_205( val, _values, result )
Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype")
result = [val[0][:value]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 772
- def _reduce_205( val, _values, result )
- result = [val[0][:value], val[2]]
+module_eval <<'.,.,', 'grammar.ra', 697
+ def _reduce_206( val, _values, result )
+ result = [val[0][:value], val[2]]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 774
- def _reduce_206( val, _values, result )
- result = [val[0][:value]]
+module_eval <<'.,.,', 'grammar.ra', 699
+ def _reduce_207( val, _values, result )
+ result = [val[0][:value]]
result
end
.,.,
- # reduce 207 omitted
+ # reduce 208 omitted
-module_eval <<'.,.,', 'grammar.ra', 779
- def _reduce_208( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 704
+ def _reduce_209( val, _values, result )
result = val[1]
result
end
.,.,
- # reduce 209 omitted
+ # reduce 210 omitted
-module_eval <<'.,.,', 'grammar.ra', 784
- def _reduce_210( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 709
+ def _reduce_211( val, _values, result )
result = val[1]
result
end
.,.,
- # reduce 211 omitted
-
# reduce 212 omitted
-module_eval <<'.,.,', 'grammar.ra', 790
- def _reduce_213( val, _values, result )
- result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
- result
- end
-.,.,
+ # reduce 213 omitted
-module_eval <<'.,.,', 'grammar.ra', 798
+module_eval <<'.,.,', 'grammar.ra', 715
def _reduce_214( val, _values, result )
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 805
+module_eval <<'.,.,', 'grammar.ra', 716
def _reduce_215( val, _values, result )
- if val[1].instance_of?(AST::ASTArray)
- result = val[1]
- else
- result = ast AST::ASTArray, :children => [val[1]]
- end
+ result = val[1]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 807
+module_eval <<'.,.,', 'grammar.ra', 717
def _reduce_216( val, _values, result )
- result = ast AST::ASTArray
+ result = val[1]
result
end
.,.,
- # reduce 217 omitted
+module_eval <<'.,.,', 'grammar.ra', 718
+ def _reduce_217( val, _values, result )
+ result = ast AST::ASTArray
+ result
+ end
+.,.,
# reduce 218 omitted
# reduce 219 omitted
-module_eval <<'.,.,', 'grammar.ra', 812
- def _reduce_220( val, _values, result )
+ # reduce 220 omitted
+
+module_eval <<'.,.,', 'grammar.ra', 724
+ def _reduce_221( val, _values, result )
result = nil
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 817
- def _reduce_221( val, _values, result )
- result = ast AST::Regex, :value => val[0][:value]
+module_eval <<'.,.,', 'grammar.ra', 729
+ def _reduce_222( val, _values, result )
+ result = ast AST::Regex, :value => val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 825
- def _reduce_222( val, _values, result )
- if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+module_eval <<'.,.,', 'grammar.ra', 737
+ def _reduce_223( val, _values, result )
+ if val[1].instance_of?(AST::ASTHash)
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 832
- def _reduce_223( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 744
+ def _reduce_224( val, _values, result )
if val[1].instance_of?(AST::ASTHash)
- result = val[1]
- else
- result = ast AST::ASTHash, { :value => val[1] }
- end
+ result = val[1]
+ else
+ result = ast AST::ASTHash, { :value => val[1] }
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 834
- def _reduce_224( val, _values, result )
- result = ast AST::ASTHash
+module_eval <<'.,.,', 'grammar.ra', 746
+ def _reduce_225( val, _values, result )
+ result = ast AST::ASTHash
result
end
.,.,
- # reduce 225 omitted
+ # reduce 226 omitted
-module_eval <<'.,.,', 'grammar.ra', 844
- def _reduce_226( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 756
+ def _reduce_227( val, _values, result )
if val[0].instance_of?(AST::ASTHash)
- result = val[0].merge(val[2])
- else
- result = ast AST::ASTHash, :value => val[0]
- result.merge(val[2])
- end
+ result = val[0].merge(val[2])
+ else
+ result = ast AST::ASTHash, :value => val[0]
+ result.merge(val[2])
+ end
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 848
- def _reduce_227( val, _values, result )
- result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
+module_eval <<'.,.,', 'grammar.ra', 760
+ def _reduce_228( val, _values, result )
+ result = ast AST::ASTHash, { :value => { val[0] => val[2] } }
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 849
- def _reduce_228( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 761
+ def _reduce_229( val, _values, result )
result = val[0][:value]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 850
- def _reduce_229( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 762
+ def _reduce_230( val, _values, result )
result = val[0]
result
end
.,.,
-module_eval <<'.,.,', 'grammar.ra', 855
- def _reduce_230( val, _values, result )
- result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
+module_eval <<'.,.,', 'grammar.ra', 767
+ def _reduce_231( val, _values, result )
+ result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2]
result
end
.,.,
- # reduce 231 omitted
+ # reduce 232 omitted
-module_eval <<'.,.,', 'grammar.ra', 860
- def _reduce_232( val, _values, result )
+module_eval <<'.,.,', 'grammar.ra', 772
+ def _reduce_233( val, _values, result )
result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2]
result
end
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index c0fd37178..746aa0f90 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -29,29 +29,20 @@ class Puppet::Parser::Parser
message
end
- # Create an AST array out of all of the args
- def aryfy(*args)
- if args[0].instance_of?(AST::ASTArray)
- result = args.shift
- args.each { |arg|
- result.push arg
- }
- else
- result = ast AST::ASTArray, :children => args
- end
-
- result
+ # Create an AST array containing a single element
+ def aryfy(arg)
+ ast AST::ASTArray, :children => [arg]
end
# Create an AST object, and automatically add the file and line information if
# available.
def ast(klass, hash = {})
- klass.new ast_context(klass.use_docs).merge(hash)
+ klass.new ast_context(klass.use_docs, hash[:line]).merge(hash)
end
- def ast_context(include_docs = false)
+ def ast_context(include_docs = false, ast_line = nil)
result = {
- :line => lexer.line,
+ :line => ast_line || lexer.line,
:file => lexer.file
}
result[:doc] = lexer.getcomment(result[:line]) if include_docs
@@ -68,13 +59,13 @@ class Puppet::Parser::Parser
end
# Raise a Parse error.
- def error(message)
+ def error(message, options = {})
if brace = @lexer.expected
message += "; expected '%s'"
end
except = Puppet::ParseError.new(message)
- except.line = @lexer.line
- except.file = @lexer.file if @lexer.file
+ except.line = options[:line] || @lexer.line
+ except.file = options[:file] || @lexer.file
raise except
end
@@ -103,15 +94,15 @@ class Puppet::Parser::Parser
end
def find_hostclass(namespace, name)
- known_resource_types.find_or_load(namespace, name, :hostclass)
+ known_resource_types.find_hostclass(namespace, name)
end
def find_definition(namespace, name)
- known_resource_types.find_or_load(namespace, name, :definition)
+ known_resource_types.find_definition(namespace, name)
end
def import(file)
- known_resource_types.loader.import_if_possible(file, @lexer.file)
+ known_resource_types.loader.import(file, @lexer.file)
end
def initialize(env)
@@ -133,26 +124,6 @@ class Puppet::Parser::Parser
return ns, n
end
- # Create a new class, or merge with an existing class.
- def newclass(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true).merge(options))
- end
-
- # Create a new definition.
- def newdefine(name, options = {})
- known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true).merge(options))
- end
-
- # Create a new node. Nodes are special, because they're stored in a global
- # table, not according to namespaces.
- def newnode(names, options = {})
- names = [names] unless names.instance_of?(Array)
- context = ast_context(true)
- names.collect do |name|
- known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options)))
- end
- end
-
def on_error(token,value,stack)
if token == 0 # denotes end of file
value = 'end of file'
@@ -174,48 +145,54 @@ class Puppet::Parser::Parser
# how should I do error handling here?
def parse(string = nil)
- return parse_ruby_file if self.file =~ /\.rb$/
- self.string = string if string
- begin
- @yydebug = false
- main = yyparse(@lexer,:scan)
- rescue Racc::ParseError => except
- error = Puppet::ParseError.new(except)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- rescue Puppet::ParseError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::Error => except
- # and this is a framework error
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue Puppet::DevError => except
- except.line ||= @lexer.line
- except.file ||= @lexer.file
- raise except
- rescue => except
- error = Puppet::DevError.new(except.message)
- error.line = @lexer.line
- error.file = @lexer.file
- error.set_backtrace except.backtrace
- raise error
- end
- if main
- # Store the results as the top-level class.
- newclass("", :code => main)
+ if self.file =~ /\.rb$/
+ main = parse_ruby_file
+ else
+ self.string = string if string
+ begin
+ @yydebug = false
+ main = yyparse(@lexer,:scan)
+ rescue Racc::ParseError => except
+ error = Puppet::ParseError.new(except)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ rescue Puppet::ParseError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::Error => except
+ # and this is a framework error
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue Puppet::DevError => except
+ except.line ||= @lexer.line
+ except.file ||= @lexer.file
+ raise except
+ rescue => except
+ error = Puppet::DevError.new(except.message)
+ error.line = @lexer.line
+ error.file = @lexer.file
+ error.set_backtrace except.backtrace
+ raise error
+ end
end
- return known_resource_types
+ # Store the results as the top-level class.
+ return Puppet::Parser::AST::Hostclass.new('', :code => main)
ensure
@lexer.clear
end
def parse_ruby_file
- require self.file
+ # Execute the contents of the file inside its own "main" object so
+ # that it can call methods in the resource type API.
+ main_object = Puppet::DSL::ResourceTypeAPI.new
+ main_object.instance_eval(File.read(self.file))
+
+ # Then extract any types that were created.
+ Puppet::Parser::AST::ASTArray.new :children => main_object.instance_eval { @__created_ast_objects__ }
end
def string=(string)
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index c956a1106..c007d4dbe 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -64,6 +64,8 @@ class Puppet::Parser::Resource < Puppet::Resource
# Retrieve the associated definition and evaluate it.
def evaluate
+ return if evaluated?
+ @evaluated = true
if klass = resource_type and ! builtin_type?
finish
return klass.evaluate_code(self)
@@ -72,8 +74,6 @@ class Puppet::Parser::Resource < Puppet::Resource
else
self.fail "Cannot find definition #{type}"
end
- ensure
- @evaluated = true
end
# Mark this resource as both exported and virtual,
@@ -94,6 +94,7 @@ class Puppet::Parser::Resource < Puppet::Resource
@finished = true
add_defaults
add_metaparams
+ add_scope_tags
validate
end
@@ -103,9 +104,9 @@ class Puppet::Parser::Resource < Puppet::Resource
end
def initialize(*args)
+ raise ArgumentError, "Resources require a scope" unless args.last[:scope]
super
- raise ArgumentError, "Resources require a scope" unless scope
@source ||= scope.source
end
@@ -141,10 +142,6 @@ class Puppet::Parser::Resource < Puppet::Resource
self[:name] || self.title
end
- def namespaces
- scope.namespaces
- end
-
# A temporary occasion, until I get paths in the scopes figured out.
def path
to_s
@@ -264,6 +261,12 @@ class Puppet::Parser::Resource < Puppet::Resource
end
end
+ def add_scope_tags
+ if scope_resource = scope.resource
+ tag(*scope_resource.tags)
+ end
+ end
+
# Accept a parameter from an override.
def override_parameter(param)
# This can happen if the override is defining a new parameter, rather
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index af2d98fe8..c28322337 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -13,7 +13,7 @@ class Puppet::Parser::Resource::Param
def initialize(hash)
set_options(hash)
- requiredopts(:name, :value, :source)
+ requiredopts(:name, :value)
@name = symbolize(@name)
end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index ae0f9ea4a..24f1d01f7 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -474,6 +474,41 @@ class Puppet::Parser::Scope
end
end
+ def find_resource_type(type)
+ # It still works fine without the type == 'class' short-cut, but it is a lot slower.
+ return nil if ["class", "node"].include? type.to_s.downcase
+ find_builtin_resource_type(type) || find_defined_resource_type(type)
+ end
+
+ def find_builtin_resource_type(type)
+ Puppet::Type.type(type.to_s.downcase.to_sym)
+ end
+
+ def find_defined_resource_type(type)
+ environment.known_resource_types.find_definition(namespaces, type.to_s.downcase)
+ end
+
+ def resolve_type_and_titles(type, titles)
+ raise ArgumentError, "titles must be an array" unless titles.is_a?(Array)
+
+ case type.downcase
+ when "class"
+ # resolve the titles
+ titles = titles.collect do |a_title|
+ hostclass = find_hostclass(a_title)
+ hostclass ? hostclass.name : a_title
+ end
+ when "node"
+ # no-op
+ else
+ # resolve the type
+ resource_type = find_resource_type(type)
+ type = resource_type.name if resource_type
+ end
+
+ return [type, titles]
+ end
+
private
def extend_with_functions_module
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb
index 73a4ad8aa..6864aa1a9 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -1,6 +1,7 @@
# A simple wrapper for templates, so they don't have full access to
# the scope objects.
require 'puppet/parser/files'
+require 'erb'
class Puppet::Parser::TemplateWrapper
attr_writer :scope
diff --git a/lib/puppet/parser/type_loader.rb b/lib/puppet/parser/type_loader.rb
index 35ad49593..140c9f2ca 100644
--- a/lib/puppet/parser/type_loader.rb
+++ b/lib/puppet/parser/type_loader.rb
@@ -3,25 +3,56 @@ require 'puppet/node/environment'
class Puppet::Parser::TypeLoader
include Puppet::Node::Environment::Helper
- class Helper < Hash
+ # Helper class that makes sure we don't try to import the same file
+ # more than once from either the same thread or different threads.
+ class Helper
include MonitorMixin
- def done_with(item)
- synchronize do
- delete(item)[:busy].signal if self.has_key?(item) and self[item][:loader] == Thread.current
- end
+ def initialize
+ super
+ # These hashes are indexed by filename
+ @state = {} # :doing or :done
+ @thread = {} # if :doing, thread that's doing the parsing
+ @cond_var = {} # if :doing, condition var that will be signaled when done.
end
- def owner_of(item)
- synchronize do
- if !self.has_key? item
- self[item] = { :loader => Thread.current, :busy => self.new_cond}
- :nobody
- elsif self[item][:loader] == Thread.current
- :this_thread
+
+ # Execute the supplied block exactly once per file, no matter how
+ # many threads have asked for it to run. If another thread is
+ # already executing it, wait for it to finish. If this thread is
+ # already executing it, return immediately without executing the
+ # block.
+ #
+ # Note: the reason for returning immediately if this thread is
+ # already executing the block is to handle the case of a circular
+ # import--when this happens, we attempt to recursively re-parse a
+ # file that we are already in the process of parsing. To prevent
+ # an infinite regress we need to simply do nothing when the
+ # recursive import is attempted.
+ def do_once(file)
+ need_to_execute = synchronize do
+ case @state[file]
+ when :doing
+ if @thread[file] != Thread.current
+ @cond_var[file].wait
+ end
+ false
+ when :done
+ false
else
- flag = self[item][:busy]
- flag.wait
- flag.signal
- :another_thread
+ @state[file] = :doing
+ @thread[file] = Thread.current
+ @cond_var[file] = new_cond
+ true
+ end
+ end
+ if need_to_execute
+ begin
+ yield
+ ensure
+ synchronize do
+ @state[file] = :done
+ @thread.delete(file)
+ @cond_var.delete(file).broadcast
+ end
end
end
end
@@ -47,21 +78,18 @@ class Puppet::Parser::TypeLoader
raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'")
end
+ loaded_asts = []
files.each do |file|
unless file =~ /^#{File::SEPARATOR}/
file = File.join(dir, file)
end
- unless imported? file
- @imported[file] = true
- parse_file(file)
+ @loading_helper.do_once(file) do
+ loaded_asts << parse_file(file)
end
end
-
- modname
- end
-
- def imported?(file)
- @imported.has_key?(file)
+ loaded_asts.inject([]) do |loaded_types, ast|
+ loaded_types + known_resource_types.import_ast(ast, modname)
+ end
end
def known_resource_types
@@ -70,77 +98,48 @@ class Puppet::Parser::TypeLoader
def initialize(env)
self.environment = env
- @loaded = {}
- @loading = Helper.new
-
- @imported = {}
+ @loading_helper = Helper.new
end
- def load_until(namespaces, name)
- return nil if name == "" # special-case main.
- name2files(namespaces, name).each do |filename|
- modname = begin
- import_if_possible(filename)
+ # Try to load the object with the given fully qualified name.
+ def try_load_fqname(type, fqname)
+ return nil if fqname == "" # special-case main.
+ name2files(fqname).each do |filename|
+ begin
+ imported_types = import(filename)
+ if result = imported_types.find { |t| t.type == type and t.name == fqname }
+ Puppet.debug "Automatically imported #{fqname} from #{filename} into #{environment}"
+ return result
+ end
rescue Puppet::ImportError => detail
# We couldn't load the item
# I'm not convienced we should just drop these errors, but this
# preserves existing behaviours.
- nil
- end
- if result = yield(filename)
- Puppet.info "Automatically imported #{name} from #{filename} into #{environment}"
- result.module_name = modname if modname and result.respond_to?(:module_name=)
- return result
end
end
- nil
- end
-
- def loaded?(name)
- @loaded.include?(name)
- end
-
- def name2files(namespaces, name)
- return [name.sub(/^::/, '').gsub("::", File::SEPARATOR)] if name =~ /^::/
-
- result = namespaces.inject([]) do |names_to_try, namespace|
- fullname = (namespace + "::#{name}").sub(/^::/, '')
-
- # Try to load the module init file if we're a qualified name
- names_to_try << fullname.split("::")[0] if fullname.include?("::")
-
- # Then the fully qualified name
- names_to_try << fullname
- end
-
- # Otherwise try to load the bare name on its own. This
- # is appropriate if the class we're looking for is in a
- # module that's different from our namespace.
- result << name
- result.uniq.collect { |f| f.gsub("::", File::SEPARATOR) }
+ # Nothing found.
+ return nil
end
def parse_file(file)
Puppet.debug("importing '#{file}' in environment #{environment}")
parser = Puppet::Parser::Parser.new(environment)
parser.file = file
- parser.parse
+ return parser.parse
end
- # Utility method factored out of load for handling thread-safety.
- # This isn't tested in the specs, because that's basically impossible.
- def import_if_possible(file, current_file = nil)
- @loaded[file] || begin
- case @loading.owner_of(file)
- when :this_thread
- nil
- when :another_thread
- import_if_possible(file,current_file)
- when :nobody
- @loaded[file] = import(file,current_file)
- end
- ensure
- @loading.done_with(file)
+ private
+
+ # Return a list of all file basenames that should be tried in order
+ # to load the object with the given fully qualified name.
+ def name2files(fqname)
+ result = []
+ ary = fqname.split("::")
+ while ary.length > 0
+ result << ary.join(File::SEPARATOR)
+ ary.pop
end
+ return result
end
+
end
diff --git a/lib/puppet/property.rb b/lib/puppet/property.rb
index 282a52cf4..84e1a0360 100644
--- a/lib/puppet/property.rb
+++ b/lib/puppet/property.rb
@@ -55,10 +55,10 @@ class Puppet::Property < Puppet::Parameter
# * <tt>:required_features</tt>: A list of features this value requires.
# * <tt>:event</tt>: The event that should be returned when this value is set.
# * <tt>:call</tt>: When to call any associated block. The default value
- # is ``instead``, which means to call the value instead of calling the
- # provider. You can also specify ``before`` or ``after``, which will
+ # is `instead`, which means to call the value instead of calling the
+ # provider. You can also specify `before` or `after`, which will
# call both the block and the provider, according to the order you specify
- # (the ``first`` refers to when the block is called, not the provider).
+ # (the `first` refers to when the block is called, not the provider).
def self.newvalue(name, options = {}, &block)
value = value_collection.newvalue(name, options, &block)
@@ -181,10 +181,10 @@ class Puppet::Property < Puppet::Parameter
def log(msg)
Puppet::Util::Log.create(
-
+
:level => resource[:loglevel],
:message => msg,
-
+
:source => self
)
end
diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb
index 8f993dbc1..4456feb4e 100644
--- a/lib/puppet/provider.rb
+++ b/lib/puppet/provider.rb
@@ -12,7 +12,7 @@ class Puppet::Provider
Puppet::Util.logmethods(self, true)
class << self
- # Include the util module so we have access to things like 'binary'
+ # Include the util module so we have access to things like 'which'
include Puppet::Util, Puppet::Util::Docs
include Puppet::Util::Logging
attr_accessor :name
@@ -43,7 +43,7 @@ class Puppet::Provider
raise Puppet::DevError, "No command #{name} defined for provider #{self.name}"
end
- binary(command)
+ which(command)
end
# Define commands that are not optional.
@@ -205,7 +205,7 @@ class Puppet::Provider
dochook(:defaults) do
if @defaults.length > 0
return " Default for " + @defaults.collect do |f, v|
- "``#{f}`` == ``#{v}``"
+ "`#{f}` == `#{v}`"
end.join(" and ") + "."
end
end
@@ -213,7 +213,7 @@ class Puppet::Provider
dochook(:commands) do
if @commands.length > 0
return " Required binaries: " + @commands.collect do |n, c|
- "``#{c}``"
+ "`#{c}`"
end.join(", ") + "."
end
end
@@ -221,7 +221,7 @@ class Puppet::Provider
dochook(:features) do
if features.length > 0
return " Supported features: " + features.collect do |f|
- "``#{f}``"
+ "`#{f}`"
end.join(", ") + "."
end
end
diff --git a/lib/puppet/provider/confine/exists.rb b/lib/puppet/provider/confine/exists.rb
index 085118b2a..09f94dfd9 100644
--- a/lib/puppet/provider/confine/exists.rb
+++ b/lib/puppet/provider/confine/exists.rb
@@ -6,10 +6,7 @@ class Puppet::Provider::Confine::Exists < Puppet::Provider::Confine
end
def pass?(value)
- if for_binary?
- return false unless value = binary(value)
- end
- value and FileTest.exist?(value)
+ value && (for_binary? ? which(value) : FileTest.exist?(value))
end
def message(value)
diff --git a/lib/puppet/provider/group/groupadd.rb b/lib/puppet/provider/group/groupadd.rb
index e661ddd7f..82ed4c0c7 100644
--- a/lib/puppet/provider/group/groupadd.rb
+++ b/lib/puppet/provider/group/groupadd.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "Group management via ``groupadd`` and its ilk.
+ desc "Group management via `groupadd` and its ilk.
The default for most platforms
diff --git a/lib/puppet/provider/group/ldap.rb b/lib/puppet/provider/group/ldap.rb
index 2737feea6..86c72a5d3 100644
--- a/lib/puppet/provider/group/ldap.rb
+++ b/lib/puppet/provider/group/ldap.rb
@@ -1,11 +1,11 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:group).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "Group management via ``ldap``.
+ desc "Group management via `ldap`.
This provider requires that you have valid values for all of the
- ldap-related settings, including ``ldapbase``. You will also almost
- definitely need settings for ``ldapuser`` and ``ldappassword``, so that
+ ldap-related settings, including `ldapbase`. You will also almost
+ definitely need settings for `ldapuser` and `ldappassword`, so that
your clients can write to ldap.
Note that this provider will automatically generate a GID for you if you do
diff --git a/lib/puppet/provider/group/pw.rb b/lib/puppet/provider/group/pw.rb
index e3dd714ee..a054d1ff1 100644
--- a/lib/puppet/provider/group/pw.rb
+++ b/lib/puppet/provider/group/pw.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:group).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "Group management via ``pw``.
+ desc "Group management via `pw`.
Only works on FreeBSD.
diff --git a/lib/puppet/provider/host/parsed.rb b/lib/puppet/provider/host/parsed.rb
index 4f15eff3f..a303c4bcf 100644
--- a/lib/puppet/provider/host/parsed.rb
+++ b/lib/puppet/provider/host/parsed.rb
@@ -8,66 +8,36 @@ else
end
- Puppet::Type.type(:host).provide(
- :parsed,
- :parent => Puppet::Provider::ParsedFile,
- :default_target => hosts,
-
- :filetype => :flat
-) do
+Puppet::Type.type(:host).provide(:parsed,:parent => Puppet::Provider::ParsedFile,
+ :default_target => hosts,:filetype => :flat) do
confine :exists => hosts
text_line :comment, :match => /^#/
text_line :blank, :match => /^\s*$/
- record_line :parsed, :fields => %w{ip name host_aliases},
- :optional => %w{host_aliases},
- :rts => true do |line|
- hash = {}
- if line.sub!(/^(\S+)\s+(\S+)\s*/, '')
- hash[:ip] = $1
- hash[:name] = $2
-
- if line.empty?
- hash[:host_aliases] = []
+ record_line :parsed, :fields => %w{ip name host_aliases comment},
+ :optional => %w{host_aliases comment},
+ :match => /^(\S+)\s+(\S+)\s*(.*?)?(?:\s*#\s*(.*))?$/,
+ :post_parse => proc { |hash|
+ # An absent comment should match "comment => ''"
+ hash[:comment] = '' if hash[:comment].nil? or hash[:comment] == :absent
+ unless hash[:host_aliases].nil? or hash[:host_aliases] == :absent
+ hash[:host_aliases] = hash[:host_aliases].split(/\s+/)
else
- line.sub!(/\s*/, '')
- line.sub!(/^([^#]+)\s*/) do |value|
- aliases = $1
- unless aliases =~ /^\s*$/
- hash[:host_aliases] = aliases.split(/\s+/)
- end
-
- ""
- end
+ hash[:host_aliases] = []
end
- else
- raise Puppet::Error, "Could not match '#{line}'"
- end
-
- hash[:host_aliases] = [] if hash[:host_aliases] == ""
-
- return hash
- end
-
- # Convert the current object into a host-style string.
- def self.to_line(hash)
- return super unless hash[:record_type] == :parsed
- [:ip, :name].each do |n|
- raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
- end
-
- str = "#{hash[:ip]}\t#{hash[:name]}"
-
- if hash.include? :host_aliases and !hash[:host_aliases].empty?
- if hash[:host_aliases].is_a? Array
+ },
+ :to_line => proc { |hash|
+ [:ip, :name].each do |n|
+ raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent
+ end
+ str = "#{hash[:ip]}\t#{hash[:name]}"
+ if hash.include? :host_aliases and !hash[:host_aliases].empty?
str += "\t#{hash[:host_aliases].join("\t")}"
- else
- raise ArgumentError, "Host aliases must be specified as an array"
end
- end
-
- str
- end
+ if hash.include? :comment and !hash[:comment].empty?
+ str += "\t# #{hash[:comment]}"
+ end
+ str
+ }
end
-
diff --git a/lib/puppet/provider/maillist/mailman.rb b/lib/puppet/provider/maillist/mailman.rb
index 4fdc20a69..633642af7 100755
--- a/lib/puppet/provider/maillist/mailman.rb
+++ b/lib/puppet/provider/maillist/mailman.rb
@@ -2,11 +2,11 @@ require 'puppet/provider/parsedfile'
Puppet::Type.type(:maillist).provide(:mailman) do
if [ "CentOS", "RedHat", "Fedora" ].any? { |os| Facter.value(:operatingsystem) == os }
- commands :list_lists => "/usr/lib/mailman/bin/list_lists", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
+ commands :list_lists => "/usr/lib/mailman/bin/list_lists --bare", :rmlist => "/usr/lib/mailman/bin/rmlist", :newlist => "/usr/lib/mailman/bin/newlist"
commands :mailman => "/usr/lib/mailman/mail/mailman"
else
# This probably won't work for non-Debian installs, but this path is sure not to be in the PATH.
- commands :list_lists => "list_lists", :rmlist => "rmlist", :newlist => "newlist"
+ commands :list_lists => "list_lists --bare", :rmlist => "rmlist", :newlist => "newlist"
commands :mailman => "/var/lib/mailman/mail/mailman"
end
@@ -14,10 +14,9 @@ Puppet::Type.type(:maillist).provide(:mailman) do
# Return a list of existing mailman instances.
def self.instances
- list_lists.split("\n").reject { |line| line.include?("matching mailing lists") }.collect do |line|
- name, description = line.sub(/^\s+/, '').sub(/\s+$/, '').split(/\s+-\s+/)
- description = :absent if description.include?("no description available")
- new(:ensure => :present, :name => name, :description => description)
+ list_lists.split("\n").collect do |line|
+ name = line.strip
+ new(:ensure => :present, :name => name)
end
end
diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb
index cb5adc698..3ad437b53 100644
--- a/lib/puppet/provider/mcx/mcxcontent.rb
+++ b/lib/puppet/provider/mcx/mcxcontent.rb
@@ -53,39 +53,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
confine :operatingsystem => :darwin
defaultfor :operatingsystem => :darwin
- # self.instances is all important.
- # This is the only class method, it returns
- # an array of instances of this class.
def self.instances
mcx_list = []
- for ds_type in TypeMap.keys
+ TypeMap.keys.each do |ds_type|
ds_path = "/Local/Default/#{TypeMap[ds_type]}"
output = dscl 'localhost', '-list', ds_path
member_list = output.split
- for ds_name in member_list
+ member_list.each do |ds_name|
content = mcxexport(ds_type, ds_name)
if content.empty?
Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data."
else
# This node has MCX data.
- rsrc = self.new(
- :name => "/#{TypeMap[ds_type]}/#{ds_name}",
- :ds_type => ds_type,
- :ds_name => ds_name,
-
- :content => content)
- mcx_list << rsrc
+ mcx_list << self.new(
+ :name => "/#{TypeMap[ds_type]}/#{ds_name}",
+ :ds_type => ds_type,
+ :ds_name => ds_name,
+ :content => content
+ )
end
end
end
mcx_list
end
- private
-
- # mcxexport is used by instances, and therefore
- # a class method.
def self.mcxexport(ds_type, ds_name)
ds_t = TypeMap[ds_type]
ds_n = ds_name.to_s
@@ -93,9 +85,49 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
dscl 'localhost', '-mcxexport', ds_path
end
+
+ def create
+ self.content=(resource[:content])
+ end
+
+ def destroy
+ ds_parms = get_dsparams
+ ds_t = TypeMap[ds_parms[:ds_type]]
+ ds_n = ds_parms[:ds_name].to_s
+ ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
+
+ dscl 'localhost', '-mcxdelete', ds_path
+ end
+
+ def exists?
+ begin
+ has_mcx?
+ rescue Puppet::ExecutionFailure => e
+ return false
+ end
+ end
+
+ def content
+ ds_parms = get_dsparams
+
+ self.class.mcxexport(ds_parms[:ds_type], ds_parms[:ds_name])
+ end
+
+ def content=(value)
+ # dscl localhost -mcximport
+ ds_parms = get_dsparams
+
+ mcximport(ds_parms[:ds_type], ds_parms[:ds_name], resource[:content])
+ end
+
+ private
+
+ def has_mcx?
+ !content.empty?
+ end
+
def mcximport(ds_type, ds_name, val)
ds_t = TypeMap[ds_type]
- ds_n = ds_name.to_s
ds_path = "/Local/Default/#{ds_t}/#{ds_name}"
tmp = Tempfile.new('puppet_mcx')
@@ -111,33 +143,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
# Given the resource name string, parse ds_type out.
def parse_type(name)
- tmp = name.split('/')[1]
- if ! tmp.is_a? String
+ ds_type = name.split('/')[1]
+ unless ds_type
raise MCXContentProviderException,
"Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
# De-pluralize and downcase.
- tmp = tmp.chop.downcase.to_sym
- if not TypeMap.keys.member? tmp
+ ds_type = ds_type.chop.downcase.to_sym
+ unless TypeMap.key? ds_type
raise MCXContentProviderException,
"Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter."
end
- tmp
+ ds_type
end
# Given the resource name string, parse ds_name out.
def parse_name(name)
ds_name = name.split('/')[2]
- if ! ds_name.is_a? String
+ unless ds_name
raise MCXContentProviderException,
"Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter."
end
ds_name
end
- # Gather ds_type and ds_name from resource or
- # parse it out of the name.
- # This is a private instance method, not a class method.
+ # Gather ds_type and ds_name from resource or parse it out of the name.
def get_dsparams
ds_type = resource[:ds_type]
ds_type ||= parse_type(resource[:name])
@@ -146,60 +176,10 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do
ds_name = resource[:ds_name]
ds_name ||= parse_name(resource[:name])
- rval = {
+ {
:ds_type => ds_type.to_sym,
:ds_name => ds_name,
}
-
- return rval
-
- end
-
- public
-
- def create
- self.content=(resource[:content])
- end
-
- def destroy
- ds_parms = get_dsparams
- ds_t = TypeMap[ds_parms[:ds_type]]
- ds_n = ds_parms[:ds_name].to_s
- ds_path = "/Local/Default/#{ds_t}/#{ds_n}"
-
- dscl 'localhost', '-mcxdelete', ds_path
- end
-
- def exists?
- # JJM Just re-use the content method and see if it's empty.
- begin
- mcx = content
- rescue Puppet::ExecutionFailure => e
- return false
- end
- has_mcx = ! mcx.empty?
- end
-
- def content
- ds_parms = get_dsparams
-
- mcx = self.class.mcxexport(
- ds_parms[:ds_type],
-
- ds_parms[:ds_name])
- mcx
- end
-
- def content=(value)
- # dscl localhost -mcximport
- ds_parms = get_dsparams
-
- mcx = mcximport(
- ds_parms[:ds_type],
- ds_parms[:ds_name],
-
- resource[:content])
- mcx
end
end
diff --git a/lib/puppet/provider/mount.rb b/lib/puppet/provider/mount.rb
index 393ae56c9..8c7b24bd4 100644
--- a/lib/puppet/provider/mount.rb
+++ b/lib/puppet/provider/mount.rb
@@ -41,7 +41,7 @@ module Puppet::Provider::Mount
case platform
when "Darwin"
line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris"
+ when "Solaris", "HP-UX"
line =~ /^#{name} on /
else
line =~ / on #{name} /
diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb
index 7339b646e..d57052bd9 100644
--- a/lib/puppet/provider/nameservice.rb
+++ b/lib/puppet/provider/nameservice.rb
@@ -165,6 +165,9 @@ class Puppet::Provider::NameService < Puppet::Provider
begin
execute(self.addcmd)
+ if feature?(:manages_password_age) && (cmd = passcmd)
+ execute(cmd)
+ end
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}"
end
diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb
index 965a2aa60..106d99eb3 100644
--- a/lib/puppet/provider/nameservice/directoryservice.rb
+++ b/lib/puppet/provider/nameservice/directoryservice.rb
@@ -321,6 +321,31 @@ class DirectoryService < Puppet::Provider::NameService
password_hash
end
+ # Unlike most other *nixes, OS X doesn't provide built in functionality
+ # for automatically assigning uids and gids to accounts, so we set up these
+ # methods for consumption by functionality like --mkusers
+ # By default we restrict to a reasonably sane range for system accounts
+ def self.next_system_id(id_type, min_id=20)
+ dscl_args = ['.', '-list']
+ if id_type == 'uid'
+ dscl_args << '/Users' << 'uid'
+ elsif id_type == 'gid'
+ dscl_args << '/Groups' << 'gid'
+ else
+ fail("Invalid id_type #{id_type}. Only 'uid' and 'gid' supported")
+ end
+ dscl_out = dscl(dscl_args)
+ # We're ok with throwing away negative uids here.
+ ids = dscl_out.split.compact.collect { |l| l.to_i if l.match(/^\d+$/) }
+ ids.compact!.sort! { |a,b| a.to_f <=> b.to_f }
+ # We're just looking for an unused id in our sorted array.
+ ids.each_index do |i|
+ next_id = ids[i] + 1
+ return next_id if ids[i+1] != next_id and next_id >= min_id
+ end
+ end
+
+
def ensure=(ensure_value)
super
# We need to loop over all valid properties for the type we're
@@ -422,7 +447,14 @@ class DirectoryService < Puppet::Provider::NameService
# Now we create all the standard properties
Puppet::Type.type(@resource.class.name).validproperties.each do |property|
next if property == :ensure
- if value = @resource.should(property) and value != ""
+ value = @resource.should(property)
+ if property == :gid and value.nil?
+ value = self.class.next_system_id(id_type='gid')
+ end
+ if property == :uid and value.nil?
+ value = self.class.next_system_id(id_type='uid')
+ end
+ if value != "" and not value.nil?
if property == :members
add_members(nil, value)
else
diff --git a/lib/puppet/provider/nameservice/objectadd.rb b/lib/puppet/provider/nameservice/objectadd.rb
index 80c142982..dbb9f306f 100644
--- a/lib/puppet/provider/nameservice/objectadd.rb
+++ b/lib/puppet/provider/nameservice/objectadd.rb
@@ -13,7 +13,8 @@ class ObjectAdd < Puppet::Provider::NameService
end
def modifycmd(param, value)
- cmd = [command(:modify), flag(param), value]
+ cmd = [command(param.to_s =~ /password_.+_age/ ? :password : :modify)]
+ cmd << flag(param) << value
if @resource.allowdupe? && ((param == :uid) || (param == :gid and self.class.name == :groupadd))
cmd << "-o"
end
diff --git a/lib/puppet/provider/package/apple.rb b/lib/puppet/provider/package/apple.rb
index 0946de47f..b5bb9102f 100755
--- a/lib/puppet/provider/package/apple.rb
+++ b/lib/puppet/provider/package/apple.rb
@@ -5,7 +5,7 @@ Puppet::Type.type(:package).provide :apple, :parent => Puppet::Provider::Package
desc "Package management based on OS X's builtin packaging system. This is
essentially the simplest and least functional package system in existence --
it only supports installation; no deletion or upgrades. The provider will
- automatically add the ``.pkg`` extension, so leave that off when specifying
+ automatically add the `.pkg` extension, so leave that off when specifying
the package name."
confine :operatingsystem => :darwin
diff --git a/lib/puppet/provider/package/apt.rb b/lib/puppet/provider/package/apt.rb
index d055e7552..2fc787419 100755
--- a/lib/puppet/provider/package/apt.rb
+++ b/lib/puppet/provider/package/apt.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``apt-get``."
+ desc "Package management via `apt-get`."
has_feature :versionable
@@ -14,6 +14,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
ENV['DEBIAN_FRONTEND'] = "noninteractive"
+ # disable common apt helpers to allow non-interactive package installs
+ ENV['APT_LISTBUGS_FRONTEND'] = "none"
+ ENV['APT_LISTCHANGES_FRONTEND'] = "none"
+
# A derivative of DPKG; this is how most people actually manage
# Debian boxes, and the only thing that differs is that it can
# install packages from remote sites.
diff --git a/lib/puppet/provider/package/aptitude.rb b/lib/puppet/provider/package/aptitude.rb
index 557e657a4..8bdf984e6 100755
--- a/lib/puppet/provider/package/aptitude.rb
+++ b/lib/puppet/provider/package/aptitude.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg do
- desc "Package management via ``aptitude``."
+ desc "Package management via `aptitude`."
has_feature :versionable
diff --git a/lib/puppet/provider/package/aptrpm.rb b/lib/puppet/provider/package/aptrpm.rb
index d7842089f..2eb33c72b 100644
--- a/lib/puppet/provider/package/aptrpm.rb
+++ b/lib/puppet/provider/package/aptrpm.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :aptrpm, :parent => :rpm, :source => :rpm do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``apt-get`` ported to ``rpm``."
+ desc "Package management via `apt-get` ported to `rpm`."
has_feature :versionable
diff --git a/lib/puppet/provider/package/blastwave.rb b/lib/puppet/provider/package/blastwave.rb
index 9f1f1ec19..e9c84845f 100755
--- a/lib/puppet/provider/package/blastwave.rb
+++ b/lib/puppet/provider/package/blastwave.rb
@@ -1,6 +1,6 @@
# Packaging using Blastwave's pkg-get program.
Puppet::Type.type(:package).provide :blastwave, :parent => :sun, :source => :sun do
- desc "Package management using Blastwave.org's ``pkg-get`` command on Solaris."
+ desc "Package management using Blastwave.org's `pkg-get` command on Solaris."
pkgget = "pkg-get"
pkgget = "/opt/csw/bin/pkg-get" if FileTest.executable?("/opt/csw/bin/pkg-get")
diff --git a/lib/puppet/provider/package/dpkg.rb b/lib/puppet/provider/package/dpkg.rb
index bee63bfba..7b34b09af 100755
--- a/lib/puppet/provider/package/dpkg.rb
+++ b/lib/puppet/provider/package/dpkg.rb
@@ -1,8 +1,8 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package do
- desc "Package management via ``dpkg``. Because this only uses ``dpkg``
- and not ``apt``, you must specify the source of any packages you want
+ desc "Package management via `dpkg`. Because this only uses `dpkg`
+ and not `apt`, you must specify the source of any packages you want
to manage."
has_feature :holdable
diff --git a/lib/puppet/provider/package/fink.rb b/lib/puppet/provider/package/fink.rb
index 5cf47860e..db991397a 100755
--- a/lib/puppet/provider/package/fink.rb
+++ b/lib/puppet/provider/package/fink.rb
@@ -2,7 +2,7 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
# Provide sorting functionality
include Puppet::Util::Package
- desc "Package management via ``fink``."
+ desc "Package management via `fink`."
commands :fink => "/sw/bin/fink"
commands :aptget => "/sw/bin/apt-get"
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index 8d70b756f..19414cec4 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -3,7 +3,7 @@ require 'uri'
# Ruby gems support.
Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package do
- desc "Ruby Gem support. If a URL is passed via ``source``, then that URL is used as the
+ desc "Ruby Gem support. If a URL is passed via `source`, then that URL is used as the
remote gem repository; if a source is present but is not a valid URL, it will be
interpreted as the path to a local gem file. If source is not present at all,
the gem will be installed from the default gem repositories."
diff --git a/lib/puppet/provider/package/openbsd.rb b/lib/puppet/provider/package/openbsd.rb
index ca477e56a..bb07d894a 100755
--- a/lib/puppet/provider/package/openbsd.rb
+++ b/lib/puppet/provider/package/openbsd.rb
@@ -2,8 +2,7 @@ require 'puppet/provider/package'
# Packaging on OpenBSD. Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
- include Puppet::Util::Execution
- desc "OpenBSD's form of ``pkg_add`` support."
+ desc "OpenBSD's form of `pkg_add` support."
commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
@@ -61,18 +60,15 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
"You must specify a package source for BSD packages"
end
- old_ensure = @resource[:ensure]
-
- if @resource[:source] =~ /\/$/
- withenv :PKG_PATH => @resource[:source] do
- @resource[:ensure] = old_ensure if (@resource[:ensure] = get_version) == nil
- full_name = [ @resource[:name], @resource[:ensure], @resource[:flavor] ]
- pkgadd full_name.join('-').chomp('-')
- end
+ if @resource[:source][-1,1] == ::File::PATH_SEPARATOR
+ e_vars = { :PKG_PATH => @resource[:source] }
+ full_name = [ @resource[:name], get_version || @resource[:ensure], @resource[:flavor] ].join('-').chomp('-')
else
- pkgadd @resource[:source]
+ e_vars = {}
+ full_name = @resource[:source]
end
+ Puppet::Util::Execution::withenv(e_vars) { pkgadd full_name }
end
def get_version
diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb
index d33a4f2f3..72dc260a4 100755
--- a/lib/puppet/provider/package/rpm.rb
+++ b/lib/puppet/provider/package/rpm.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/package'
# RPM packaging. Should work anywhere that has rpm installed.
Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do
- desc "RPM packaging support; should work anywhere with a working ``rpm``
+ desc "RPM packaging support; should work anywhere with a working `rpm`
binary."
has_feature :versionable
diff --git a/lib/puppet/provider/package/rug.rb b/lib/puppet/provider/package/rug.rb
index 7028cc9e5..28729952d 100644
--- a/lib/puppet/provider/package/rug.rb
+++ b/lib/puppet/provider/package/rug.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :rug, :parent => :rpm do
- desc "Support for suse ``rug`` package manager."
+ desc "Support for suse `rug` package manager."
has_feature :versionable
diff --git a/lib/puppet/provider/package/sunfreeware.rb b/lib/puppet/provider/package/sunfreeware.rb
index 53f03ed6e..4745ea1eb 100755
--- a/lib/puppet/provider/package/sunfreeware.rb
+++ b/lib/puppet/provider/package/sunfreeware.rb
@@ -1,7 +1,7 @@
# At this point, it's an exact copy of the Blastwave stuff.
Puppet::Type.type(:package).provide :sunfreeware, :parent => :blastwave, :source => :sun do
- desc "Package management using sunfreeware.com's ``pkg-get`` command on Solaris.
- At this point, support is exactly the same as ``blastwave`` support and
+ desc "Package management using sunfreeware.com's `pkg-get` command on Solaris.
+ At this point, support is exactly the same as `blastwave` support and
has not actually been tested."
commands :pkgget => "pkg-get"
diff --git a/lib/puppet/provider/package/up2date.rb b/lib/puppet/provider/package/up2date.rb
index 5ff32bedc..243bc6c6b 100644
--- a/lib/puppet/provider/package/up2date.rb
+++ b/lib/puppet/provider/package/up2date.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :up2date, :parent => :rpm, :source => :rpm do
- desc "Support for Red Hat's proprietary ``up2date`` package update
+ desc "Support for Red Hat's proprietary `up2date` package update
mechanism."
commands :up2date => "/usr/sbin/up2date-nox"
diff --git a/lib/puppet/provider/package/urpmi.rb b/lib/puppet/provider/package/urpmi.rb
index 88a17ccb4..425d77849 100644
--- a/lib/puppet/provider/package/urpmi.rb
+++ b/lib/puppet/provider/package/urpmi.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :urpmi, :parent => :rpm, :source => :rpm do
- desc "Support via ``urpmi``."
+ desc "Support via `urpmi`."
commands :urpmi => "urpmi", :urpmq => "urpmq", :rpm => "rpm"
if command('rpm')
diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb
index 07f68ddb1..6ed966fbd 100755
--- a/lib/puppet/provider/package/yum.rb
+++ b/lib/puppet/provider/package/yum.rb
@@ -1,5 +1,6 @@
+require 'puppet/util/package'
Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
- desc "Support via ``yum``."
+ desc "Support via `yum`."
has_feature :versionable
@@ -52,6 +53,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
should = @resource.should(:ensure)
self.debug "Ensuring => #{should}"
wanted = @resource[:name]
+ operation = :install
# XXX: We don't actually deal with epochs here.
case should
@@ -61,9 +63,14 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
else
# Add the package version
wanted += "-#{should}"
+ is = self.query
+ if is && Puppet::Util::Package.versioncmp(should, is[:ensure]) < 0
+ self.debug "Downgrading package #{@resource[:name]} from version #{is[:ensure]} to #{should}"
+ operation = :downgrade
+ end
end
- output = yum "-d", "0", "-e", "0", "-y", :install, wanted
+ output = yum "-d", "0", "-e", "0", "-y", operation, wanted
is = self.query
raise Puppet::Error, "Could not find package #{self.name}" unless is
diff --git a/lib/puppet/provider/package/zypper.rb b/lib/puppet/provider/package/zypper.rb
index d56c72549..f129ef6e6 100644
--- a/lib/puppet/provider/package/zypper.rb
+++ b/lib/puppet/provider/package/zypper.rb
@@ -1,5 +1,5 @@
Puppet::Type.type(:package).provide :zypper, :parent => :rpm do
- desc "Support for SuSE ``zypper`` package manager. Found in SLES10sp2+ and SLES11"
+ desc "Support for SuSE `zypper` package manager. Found in SLES10sp2+ and SLES11"
has_feature :versionable
diff --git a/lib/puppet/provider/service/base.rb b/lib/puppet/provider/service/base.rb
index 70d764187..211e7f964 100755
--- a/lib/puppet/provider/service/base.rb
+++ b/lib/puppet/provider/service/base.rb
@@ -5,7 +5,7 @@ Puppet::Type.type(:service).provide :base do
minimum you can specify is a binary for starting the process, and this
same binary will be searched for in the process table to stop the
service. It is preferable to specify start, stop, and status commands,
- akin to how you would do so using ``init``.
+ akin to how you would do so using `init`.
"
diff --git a/lib/puppet/provider/service/bsd.rb b/lib/puppet/provider/service/bsd.rb
index 2e00c33f1..e2a0e35f7 100644
--- a/lib/puppet/provider/service/bsd.rb
+++ b/lib/puppet/provider/service/bsd.rb
@@ -1,8 +1,8 @@
# Manage FreeBSD services.
Puppet::Type.type(:service).provide :bsd, :parent => :init do
- desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
+ desc "FreeBSD's (and probably NetBSD?) form of `init`-style service management.
- Uses ``rc.conf.d`` for service enabling and disabling.
+ Uses `rc.conf.d` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 4379f1b59..3d09e2849 100755
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -1,10 +1,10 @@
# Manage debian services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :debian, :parent => :init do
- desc "Debian's form of ``init``-style management.
+ desc "Debian's form of `init`-style management.
The only difference is that this supports service enabling and disabling
- via ``update-rc.d`` and determines enabled status via ``invoke-rc.d``.
+ via `update-rc.d` and determines enabled status via `invoke-rc.d`.
"
diff --git a/lib/puppet/provider/service/freebsd.rb b/lib/puppet/provider/service/freebsd.rb
index 10970e4da..f8c7134f0 100644
--- a/lib/puppet/provider/service/freebsd.rb
+++ b/lib/puppet/provider/service/freebsd.rb
@@ -18,6 +18,9 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
def rcvar
rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
rcvar = rcvar.split("\n")
+ rcvar.delete_if {|str| str =~ /^#\s*$/}
+ rcvar[1] = rcvar[1].gsub(/^\$/, '')
+ rcvar
end
# Extract service name
@@ -44,7 +47,7 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
def rcvar_value
value = self.rcvar[1]
self.error("No rcvar value found in rcvar") if value.nil?
- value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
+ value = value.gsub!(/(.*)_enable="?(\w+)"?/, '\2')
self.error("rcvar value is empty") if value.nil?
self.debug("rcvar value is #{value}")
value
@@ -78,7 +81,7 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
# Add a new setting to the rc files
def rc_add(service, rcvar, yesno)
- append = "\n\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\""
+ append = "\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\"\n"
# First, try the one-file-per-service style
if File.exists?(@@rcconf_dir)
File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) {
diff --git a/lib/puppet/provider/service/gentoo.rb b/lib/puppet/provider/service/gentoo.rb
index 08250a06a..382c74267 100644
--- a/lib/puppet/provider/service/gentoo.rb
+++ b/lib/puppet/provider/service/gentoo.rb
@@ -1,9 +1,9 @@
# Manage gentoo services. Start/stop is the same as InitSvc, but enable/disable
# is special.
Puppet::Type.type(:service).provide :gentoo, :parent => :init do
- desc "Gentoo's form of ``init``-style service management.
+ desc "Gentoo's form of `init`-style service management.
- Uses ``rc-update`` for service enabling and disabling.
+ Uses `rc-update` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/init.rb b/lib/puppet/provider/service/init.rb
index 6abff12db..447c01aa5 100755
--- a/lib/puppet/provider/service/init.rb
+++ b/lib/puppet/provider/service/init.rb
@@ -3,9 +3,9 @@
Puppet::Type.type(:service).provide :init, :parent => :base do
desc "Standard init service management.
- This provider assumes that the init script has no ``status`` command,
+ This provider assumes that the init script has no `status` command,
because so few scripts do, so you need to either provide a status
- command or specify via ``hasstatus`` that one already exists in the
+ command or specify via `hasstatus` that one already exists in the
init script.
"
diff --git a/lib/puppet/provider/service/launchd.rb b/lib/puppet/provider/service/launchd.rb
index 970359539..1632edabf 100644
--- a/lib/puppet/provider/service/launchd.rb
+++ b/lib/puppet/provider/service/launchd.rb
@@ -38,6 +38,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
commands :launchctl => "/bin/launchctl"
commands :sw_vers => "/usr/bin/sw_vers"
+ commands :plutil => "/usr/bin/plutil"
defaultfor :operatingsystem => :darwin
confine :operatingsystem => :darwin
@@ -52,6 +53,12 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
Launchd_Overrides = "/var/db/launchd.db/com.apple.launchd/overrides.plist"
+ # Read a plist, whether its format is XML or in Apple's "binary1"
+ # format.
+ def self.read_plist(path)
+ Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', path))
+ end
+
# returns a label => path map for either all jobs, or just a single
# job if the label is specified
def self.jobsearch(label=nil)
@@ -62,8 +69,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
next if f =~ /^\..*$/
next if FileTest.directory?(f)
fullpath = File.join(path, f)
- job = Plist::parse_xml(fullpath)
- if job and job.has_key?("Label")
+ if FileTest.file?(fullpath) and job = read_plist(fullpath) and job.has_key?("Label")
if job["Label"] == label
return { label => fullpath }
else
@@ -118,8 +124,11 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
def plist_from_label(label)
job = self.class.jobsearch(label)
job_path = job[label]
- job_plist = Plist::parse_xml(job_path)
- raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") if not job_plist
+ if FileTest.file?(job_path)
+ job_plist = self.class.read_plist(job_path)
+ else
+ raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}")
+ end
[job_path, job_plist]
end
@@ -200,9 +209,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled")
if self.class.get_macosx_version_major == "10.6":
- overrides = Plist::parse_xml(Launchd_Overrides)
-
- unless overrides.nil?
+ if FileTest.file?(Launchd_Overrides) and overrides = self.class.read_plist(Launchd_Overrides)
if overrides.has_key?(resource[:name])
overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled")
end
@@ -227,7 +234,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
# versions this is stored in the job plist itself.
def enable
if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides = self.class.read_plist(Launchd_Overrides)
overrides[resource[:name]] = { "Disabled" => false }
Plist::Emit.save_plist(overrides, Launchd_Overrides)
else
@@ -242,7 +249,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
def disable
if self.class.get_macosx_version_major == "10.6"
- overrides = Plist::parse_xml(Launchd_Overrides)
+ overrides = self.class.read_plist(Launchd_Overrides)
overrides[resource[:name]] = { "Disabled" => true }
Plist::Emit.save_plist(overrides, Launchd_Overrides)
else
diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb
index 3ca67d66f..e851a488d 100755
--- a/lib/puppet/provider/service/redhat.rb
+++ b/lib/puppet/provider/service/redhat.rb
@@ -1,9 +1,9 @@
# Manage Red Hat services. Start/stop uses /sbin/service and enable/disable uses chkconfig
Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init do
- desc "Red Hat's (and probably many others) form of ``init``-style service management:
+ desc "Red Hat's (and probably many others) form of `init`-style service management:
- Uses ``chkconfig`` for service enabling and disabling.
+ Uses `chkconfig` for service enabling and disabling.
"
diff --git a/lib/puppet/provider/service/upstart.rb b/lib/puppet/provider/service/upstart.rb
new file mode 100755
index 000000000..54971eeac
--- /dev/null
+++ b/lib/puppet/provider/service/upstart.rb
@@ -0,0 +1,73 @@
+Puppet::Type.type(:service).provide :upstart, :parent => :init do
+ desc "Ubuntu service manager upstart.
+
+ This provider manages upstart jobs which have replaced initd.
+
+ See:
+ * http://upstart.ubuntu.com/
+ "
+ # confine to :ubuntu for now because I haven't tested on other platforms
+ confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian]
+
+ commands :start => "/sbin/start",
+ :stop => "/sbin/stop",
+ :restart => "/sbin/restart",
+ :status_exec => "/sbin/status",
+ :initctl => "/sbin/initctl"
+
+ # upstart developer haven't implemented initctl enable/disable yet:
+ # http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/
+ # has_feature :enableable
+
+ def self.instances
+ instances = []
+ execpipe("#{command(:initctl)} list") { |process|
+ process.each { |line|
+ # needs special handling of services such as network-interface:
+ # initctl list:
+ # network-interface (lo) start/running
+ # network-interface (eth0) start/running
+ # network-interface-security start/running
+ name = \
+ if matcher = line.match(/^(network-interface)\s\(([^\)]+)\)/)
+ "#{matcher[1]} INTERFACE=#{matcher[2]}"
+ else
+ line.split.first
+ end
+ instances << new(:name => name)
+ }
+ }
+ instances
+ end
+
+ def startcmd
+ [command(:start), @resource[:name]]
+ end
+
+ def stopcmd
+ [command(:stop), @resource[:name]]
+ end
+
+ def restartcmd
+ (@resource[:hasrestart] == :true) && [command(:restart), @resource[:name]]
+ end
+
+ def status
+ # allows user override of status command
+ if @resource[:status]
+ ucommand(:status, false)
+ if $?.exitstatus == 0
+ return :running
+ else
+ return :stopped
+ end
+ else
+ output = status_exec(@resource[:name].split)
+ if (! $?.nil?) && (output =~ /start\//)
+ return :running
+ else
+ return :stopped
+ end
+ end
+ end
+end
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb
index 82f6b8881..6a3855c0e 100644
--- a/lib/puppet/provider/ssh_authorized_key/parsed.rb
+++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb
@@ -61,6 +61,13 @@ require 'puppet/provider/parsedfile'
Dir.mkdir(dir, dir_perm)
File.chown(uid, nil, dir)
end
+
+ # ParsedFile usually calls backup_target much later in the flush process,
+ # but our SUID makes that fail to open filebucket files for writing.
+ # Fortunately, there's already logic to make sure it only ever happens once,
+ # so calling it here supresses the later attempt by our superclass's flush method.
+ self.class.backup_target(target)
+
Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super }
File.chown(uid, nil, target)
File.chmod(file_perm, target)
diff --git a/lib/puppet/provider/user/hpux.rb b/lib/puppet/provider/user/hpux.rb
index 50506c4cd..983970935 100644
--- a/lib/puppet/provider/user/hpux.rb
+++ b/lib/puppet/provider/user/hpux.rb
@@ -26,5 +26,4 @@ Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do
def modifycmd(param,value)
super.insert(1,"-F")
end
-
end
diff --git a/lib/puppet/provider/user/ldap.rb b/lib/puppet/provider/user/ldap.rb
index df082c569..75a9667b3 100644
--- a/lib/puppet/provider/user/ldap.rb
+++ b/lib/puppet/provider/user/ldap.rb
@@ -1,10 +1,10 @@
require 'puppet/provider/ldap'
Puppet::Type.type(:user).provide :ldap, :parent => Puppet::Provider::Ldap do
- desc "User management via ``ldap``. This provider requires that you
+ desc "User management via `ldap`. This provider requires that you
have valid values for all of the ldap-related settings,
- including ``ldapbase``. You will also almost definitely need settings
- for ``ldapuser`` and ``ldappassword``, so that your clients can write
+ including `ldapbase`. You will also almost definitely need settings
+ for `ldapuser` and `ldappassword`, so that your clients can write
to ldap.
Note that this provider will automatically generate a UID for you if
diff --git a/lib/puppet/provider/user/pw.rb b/lib/puppet/provider/user/pw.rb
index 345d924bf..a5988cad1 100644
--- a/lib/puppet/provider/user/pw.rb
+++ b/lib/puppet/provider/user/pw.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/pw'
Puppet::Type.type(:user).provide :pw, :parent => Puppet::Provider::NameService::PW do
- desc "User management via ``pw`` on FreeBSD."
+ desc "User management via `pw` on FreeBSD."
commands :pw => "pw"
has_features :manages_homedir, :allows_duplicates
diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb
index ea1b01b3b..2377f9e65 100644
--- a/lib/puppet/provider/user/user_role_add.rb
+++ b/lib/puppet/provider/user/user_role_add.rb
@@ -2,17 +2,19 @@ require 'puppet/util/user_attr'
Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => :useradd do
- desc "User management inherits ``useradd`` and adds logic to manage roles on Solaris using roleadd."
+ desc "User management inherits `useradd` and adds logic to manage roles on Solaris using roleadd."
defaultfor :operatingsystem => :solaris
- commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "passwd", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
options :home, :flag => "-d", :method => :dir
options :comment, :method => :gecos
options :groups, :flag => "-G"
options :roles, :flag => "-R"
options :auths, :flag => "-A"
options :profiles, :flag => "-P"
+ options :password_min_age, :flag => "-n"
+ options :password_max_age, :flag => "-x"
verify :gid, "GID must be an integer" do |value|
value.is_a? Integer
@@ -22,14 +24,14 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
value !~ /\s/
end
- has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords
+ has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords, :manages_password_age
#must override this to hand the keyvalue pairs
def add_properties
cmd = []
Puppet::Type.type(:user).validproperties.each do |property|
#skip the password because we can't create it with the solaris useradd
- next if [:ensure, :password].include?(property)
+ next if [:ensure, :password, :password_min_age, :password_max_age].include?(property)
# 1680 Now you can set the hashed passwords on solaris:lib/puppet/provider/user/user_role_add.rb
# the value needs to be quoted, mostly because -c might
# have spaces in it
@@ -79,6 +81,9 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
run(transition("normal"), "transition role to")
else
run(addcmd, "create")
+ if cmd = passcmd
+ run(cmd, "change password policy for")
+ end
end
# added to handle case when password is specified
self.password = @resource[:password] if @resource[:password]
@@ -140,14 +145,23 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs")
end
- #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return the hashed pw (the second entry)
+ #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return it
#No abstraction, all esoteric knowledge of file formats, yay
+ def shadow_entry
+ return @shadow_entry if defined? @shadow_entry
+ @shadow_entry = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/ }.collect { |l| l.chomp.split(':') }.find { |user, _| user == @resource[:name] }
+ end
+
def password
- #got perl?
- if ary = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/}.collect { |l| l.split(':')[0..1] }.find { |user, passwd| user == @resource[:name] }
- pass = ary[1]
- end
- pass
+ shadow_entry[1] if shadow_entry
+ end
+
+ def password_min_age
+ shadow_entry ? shadow_entry[3] : :absent
+ end
+
+ def password_max_age
+ shadow_entry ? shadow_entry[4] : :absent
end
#Read in /etc/shadow, find the line for our used and rewrite it with the new pw
diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb
index ec87694d7..ba406cc63 100644
--- a/lib/puppet/provider/user/useradd.rb
+++ b/lib/puppet/provider/user/useradd.rb
@@ -1,13 +1,15 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "User management via ``useradd`` and its ilk. Note that you will need to install the ``Shadow Password`` Ruby library often known as ruby-libshadow to manage user passwords."
+ desc "User management via `useradd` and its ilk. Note that you will need to install the `Shadow Password` Ruby library often known as ruby-libshadow to manage user passwords."
- commands :add => "useradd", :delete => "userdel", :modify => "usermod"
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage"
options :home, :flag => "-d", :method => :dir
options :comment, :method => :gecos
options :groups, :flag => "-G"
+ options :password_min_age, :flag => "-m"
+ options :password_max_age, :flag => "-M"
verify :gid, "GID must be an integer" do |value|
value.is_a? Integer
@@ -17,9 +19,9 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
value !~ /\s/
end
- has_features :manages_homedir, :allows_duplicates
+ has_features :manages_homedir, :allows_duplicates, :manages_expiry
- has_feature :manages_passwords if Puppet.features.libshadow?
+ has_features :manages_passwords, :manages_password_age if Puppet.features.libshadow?
def check_allow_dup
@resource.allowdupe? ? ["-o"] : []
@@ -35,10 +37,20 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
cmd
end
+ def check_manage_expiry
+ cmd = []
+ if @resource[:expiry]
+ cmd << "-e #{@resource[:expiry]}"
+ end
+
+ cmd
+ end
+
def add_properties
cmd = []
Puppet::Type.type(:user).validproperties.each do |property|
next if property == :ensure
+ next if property.to_s =~ /password_.+_age/
# the value needs to be quoted, mostly because -c might
# have spaces in it
if value = @resource.should(property) and value != ""
@@ -53,9 +65,37 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
cmd += add_properties
cmd += check_allow_dup
cmd += check_manage_home
+ cmd += check_manage_expiry
cmd << @resource[:name]
end
+ def passcmd
+ age_limits = [:password_min_age, :password_max_age].select { |property| @resource.should(property) }
+ if age_limits.empty?
+ nil
+ else
+ [command(:password),age_limits.collect { |property| [flag(property), @resource.should(property)]}, @resource[:name]].flatten
+ end
+ end
+
+ def password_min_age
+ if Puppet.features.libshadow?
+ if ent = Shadow::Passwd.getspnam(@resource.name)
+ return ent.sp_min
+ end
+ end
+ :absent
+ end
+
+ def password_max_age
+ if Puppet.features.libshadow?
+ if ent = Shadow::Passwd.getspnam(@resource.name)
+ return ent.sp_max
+ end
+ end
+ :absent
+ end
+
# Retrieve the password using the Shadow Password library
def password
if Puppet.features.libshadow?
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index 414b1bc18..74805bb6f 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -2,6 +2,7 @@
require 'facter'
require 'puppet'
+require 'logger'
module Puppet::Rails
TIME_DEBUG = true
@@ -22,9 +23,8 @@ module Puppet::Rails
ActiveRecord::Base.logger.level = Logger::DEBUG
end
- if (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1)
- ActiveRecord::Base.allow_concurrency = true
- end
+ # As of ActiveRecord 2.2 allow_concurrency has been deprecated and no longer has any effect.
+ ActiveRecord::Base.allow_concurrency = true if Puppet::Util.activerecord_version < 2.2
ActiveRecord::Base.verify_active_connections!
@@ -52,21 +52,17 @@ module Puppet::Rails
args[:port] = Puppet[:dbport] unless Puppet[:dbport].to_s.empty?
args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
+ args[:pool] = Puppet[:dbconnections].to_i unless Puppet[:dbconnections].to_i <= 0
args[:database] = Puppet[:dbname]
args[:reconnect]= true
socket = Puppet[:dbsocket]
args[:socket] = socket unless socket.to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
when "oracle_enhanced":
args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty?
args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty?
args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty?
-
- connections = Puppet[:dbconnections].to_i
- args[:pool] = connections if connections > 0
+ args[:pool] = Puppet[:dbconnections].to_i unless Puppet[:dbconnections].to_i <= 0
else
raise ArgumentError, "Invalid db adapter #{adapter}"
end
diff --git a/lib/puppet/rails/host.rb b/lib/puppet/rails/host.rb
index 986cebd0a..b9dea2a3d 100644
--- a/lib/puppet/rails/host.rb
+++ b/lib/puppet/rails/host.rb
@@ -16,16 +16,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
belongs_to :source_file
has_many :resources, :dependent => :destroy, :class_name => "Puppet::Rails::Resource"
- # If the host already exists, get rid of its objects
- def self.clean(host)
- if obj = self.find_by_name(host)
- obj.rails_objects.clear
- return obj
- else
- return nil
- end
- end
-
def self.from_puppet(node)
host = find_by_name(node.name) || new(:name => node.name)
@@ -38,63 +28,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
host
end
- # Store our host in the database.
- def self.store(node, resources)
- args = {}
-
- host = nil
- railsmark "Stored node" do
- transaction do
- #unless host = find_by_name(name)
-
- debug_benchmark("Searched for host")do
- unless host = find_by_name(node.name)
- host = new(:name => node.name)
- end
- end
- if ip = node.parameters["ipaddress"]
- host.ip = ip
- end
-
- if env = node.environment
- host.environment = env
- end
-
- # Store the facts into the database.
- host.merge_facts(node.parameters)
-
- debug_benchmark("Handled resources") {
- host.merge_resources(resources)
- }
-
- host.last_compile = Time.now
-
- debug_benchmark("Saved host") {
- host.save
- }
- end
-
- end
-
- # This only runs if time debugging is enabled.
- write_benchmarks
-
- host
- end
-
- # Return the value of a fact.
- def fact(name)
-
- if fv = self.fact_values.find(
- :all, :include => :fact_name,
-
- :conditions => "fact_names.name = '#{name}'")
- return fv
- else
- return nil
- end
- end
-
# returns a hash of fact_names.name => [ fact_values ] for this host.
# Note that 'fact_values' is actually a list of the value instances, not
# just actual values.
@@ -305,11 +238,6 @@ class Puppet::Rails::Host < ActiveRecord::Base
end
end
- def update_connect_time
- self.last_connect = Time.now
- save
- end
-
def to_puppet
node = Puppet::Node.new(self.name)
{"ip" => "ipaddress", "environment" => "environment"}.each do |myparam, itsparam|
diff --git a/lib/puppet/reference/configuration.rb b/lib/puppet/reference/configuration.rb
index bfa2cb802..e6a8dc20f 100644
--- a/lib/puppet/reference/configuration.rb
+++ b/lib/puppet/reference/configuration.rb
@@ -33,7 +33,7 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
# Leave out the section information; it was apparently confusing people.
#str += "- **Section**: #{object.section}\n"
unless val == ""
- str += "- **Default**: #{val}\n"
+ str += "- *Default*: #{val}\n"
end
str += "\n"
end
@@ -42,12 +42,11 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
end
config.header = "
-Specifying Configuration Parameters
------------------------------------
+## Specifying Configuration Parameters
-On The Command-Line
-+++++++++++++++++++
-Every Puppet executable (with the exception of ``puppetdoc``) accepts all of
+### On The Command-Line
+
+Every Puppet executable (with the exception of `puppetdoc`) accepts all of
the parameters below, but not all of the arguments make sense for every executable.
I have tried to be as thorough as possible in the descriptions of the
@@ -55,60 +54,59 @@ arguments, so it should be obvious whether an argument is appropriate or not.
These parameters can be supplied to the executables either as command-line
options or in the configuration file. For instance, the command-line
-invocation below would set the configuration directory to ``/private/puppet``::
+invocation below would set the configuration directory to `/private/puppet`:
- $ puppet agent --confdir=/private/puppet
+ $ puppet agent --confdir=/private/puppet
Note that boolean options are turned on and off with a slightly different
-syntax on the command line::
+syntax on the command line:
- $ puppet agent --storeconfigs
+ $ puppet agent --storeconfigs
- $ puppet agent --no-storeconfigs
+ $ puppet agent --no-storeconfigs
The invocations above will enable and disable, respectively, the storage of
the client configuration.
-Configuration Files
-+++++++++++++++++++
+### Configuration Files
+
As mentioned above, the configuration parameters can also be stored in a
configuration file, located in the configuration directory. As root, the
-default configuration directory is ``/etc/puppet``, and as a regular user, the
-default configuration directory is ``~user/.puppet``. As of 0.23.0, all
-executables look for ``puppet.conf`` in their configuration directory
+default configuration directory is `/etc/puppet`, and as a regular user, the
+default configuration directory is `~user/.puppet`. As of 0.23.0, all
+executables look for `puppet.conf` in their configuration directory
(although they previously looked for separate files). For example,
-``puppet.conf`` is located at ``/etc/puppet/puppet.conf`` as root and
-``~user/.puppet/puppet.conf`` as a regular user by default.
+`puppet.conf` is located at `/etc/puppet/puppet.conf` as `root` and
+`~user/.puppet/puppet.conf` as a regular user by default.
+
+All executables will set any parameters set within the `[main]` section,
+and each executable will also use one of the `[master]`, `[agent]`.
-All executables will set any parameters set within the ``main`` section,
-and each executable will also use one of the ``master``, ``agent``, or
-``user`` sections.
+#### File Format
-File Format
-'''''''''''
The file follows INI-style formatting. Here is an example of a very simple
-``puppet.conf`` file::
+`puppet.conf` file:
- [main]
- confdir = /private/puppet
- storeconfigs = true
+ [main]
+ confdir = /private/puppet
+ storeconfigs = true
Note that boolean parameters must be explicitly specified as `true` or
`false` as seen above.
If you need to change file parameters (e.g., reset the mode or owner), do
-so within curly braces on the same line::
+so within curly braces on the same line:
- [main]
- myfile = /tmp/whatever {owner = root, mode = 644}
+ [main]
+ myfile = /tmp/whatever {owner = root, mode = 644}
If you're starting out with a fresh configuration, you may wish to let
the executable generate a template configuration file for you by invoking
the executable in question with the `--genconfig` command. The executable
will print a template configuration to standard output, which can be
-redirected to a file like so::
+redirected to a file like so:
- $ puppet agent --genconfig > /etc/puppet/puppet.conf
+ $ puppet agent --genconfig > /etc/puppet/puppet.conf
Note that this invocation will replace the contents of any pre-existing
`puppet.conf` file, so make a backup of your present config if it contains
@@ -117,28 +115,28 @@ valuable information.
Like the `--genconfig` argument, the executables also accept a `--genmanifest`
argument, which will generate a manifest that can be used to manage all of
Puppet's directories and files and prints it to standard output. This can
-likewise be redirected to a file::
+likewise be redirected to a file:
- $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
+ $ puppet agent --genmanifest > /etc/puppet/manifests/site.pp
Puppet can also create user and group accounts for itself (one `puppet` group
-and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument::
+and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument:
- $ puppet agent --mkusers
+ $ puppet agent --mkusers
-Signals
--------
-The ``puppet agent`` and ``puppet master`` executables catch some signals for special
-handling. Both daemons catch (``SIGHUP``), which forces the server to restart
-tself. Predictably, interrupt and terminate (``SIGINT`` and ``SIGTERM``) will shut
-down the server, whether it be an instance of ``puppet agent`` or ``puppet master``.
+## Signals
-Sending the ``SIGUSR1`` signal to an instance of ``puppet agent`` will cause it to
+The `puppet agent` and `puppet master` executables catch some signals for special
+handling. Both daemons catch (`SIGHUP`), which forces the server to restart
+tself. Predictably, interrupt and terminate (`SIGINT` and `SIGTERM`) will shut
+down the server, whether it be an instance of `puppet agent` or `puppet master`.
+
+Sending the `SIGUSR1` signal to an instance of `puppet agent` will cause it to
immediately begin a new configuration transaction with the server. This
-signal has no effect on ``puppet master``.
+signal has no effect on `puppet master`.
+
+## Configuration Parameter Reference
-Configuration Parameter Reference
----------------------------------
Below is a list of all documented parameters. Not all of them are valid with all
Puppet executables, but the executables will ignore any inappropriate values.
diff --git a/lib/puppet/reference/indirection.rb b/lib/puppet/reference/indirection.rb
index d14510c16..e5b076508 100644
--- a/lib/puppet/reference/indirection.rb
+++ b/lib/puppet/reference/indirection.rb
@@ -8,12 +8,12 @@ reference = Puppet::Util::Reference.newreference :indirection, :doc => "Indirect
Puppet::Indirector::Indirection.instances.sort { |a,b| a.to_s <=> b.to_s }.each do |indirection|
ind = Puppet::Indirector::Indirection.instance(indirection)
name = indirection.to_s.capitalize
- text += indirection.to_s + "\n" + ("-" * name.length) + "\n\n"
+ text += "## " + indirection.to_s + "\n\n"
text += ind.doc + "\n\n"
Puppet::Indirector::Terminus.terminus_classes(ind.name).sort { |a,b| a.to_s <=> b.to_s }.each do |terminus|
- text += terminus.to_s + "\n" + ("+" * terminus.to_s.length) + "\n\n"
+ text += "### " + terminus.to_s + "\n\n"
term_class = Puppet::Indirector::Terminus.terminus_class(ind.name, terminus)
@@ -26,9 +26,8 @@ end
reference.header = "This is the list of all indirections, their associated terminus classes, and how you select between them.
-In general, the appropriate terminus class is selected by the application for you (e.g., ``puppet agent`` would always use the ``rest``
-terminus for most of its indirected classes), but some classes are tunable via normal settings. These will have ``terminus setting``
-documentation listed with them.
+In general, the appropriate terminus class is selected by the application for you (e.g., `puppet agent` would always use the `rest`
+terminus for most of its indirected classes), but some classes are tunable via normal settings. These will have `terminus setting` documentation listed with them.
"
diff --git a/lib/puppet/reference/metaparameter.rb b/lib/puppet/reference/metaparameter.rb
index 6a319f1c2..c16a1d33a 100644
--- a/lib/puppet/reference/metaparameter.rb
+++ b/lib/puppet/reference/metaparameter.rb
@@ -9,16 +9,17 @@ metaparameter = Puppet::Util::Reference.newreference :metaparameter, :doc => "Al
}
str = %{
- Metaparameters
- --------------
- Metaparameters are parameters that work with any resource type; they are part of the
- Puppet framework itself rather than being part of the implementation of any
- given instance. Thus, any defined metaparameter can be used with any instance
- in your manifest, including defined components.
- Available Metaparameters
- ++++++++++++++++++++++++
- }
+# Metaparameters
+
+Metaparameters are parameters that work with any resource type; they are part of the
+Puppet framework itself rather than being part of the implementation of any
+given instance. Thus, any defined metaparameter can be used with any instance
+in your manifest, including defined components.
+
+## Available Metaparameters
+
+}
begin
params = []
Puppet::Type.eachmetaparam { |param|
@@ -29,14 +30,6 @@ metaparameter = Puppet::Util::Reference.newreference :metaparameter, :doc => "Al
a.to_s <=> b.to_s
}.each { |param|
str += paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param)), :level => 4)
- #puts "<dt>#{param}</dt>"
- #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ')
- #puts "<dd>"
- #puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab)
- #puts scrub(Puppet::Type.metaparamdoc(param))
- #puts "</dd>"
-
- #puts ""
}
rescue => detail
puts detail.backtrace
diff --git a/lib/puppet/reference/network.rb b/lib/puppet/reference/network.rb
index 15e4f6769..fda7931fb 100644
--- a/lib/puppet/reference/network.rb
+++ b/lib/puppet/reference/network.rb
@@ -29,11 +29,11 @@ on the server, and the client knows how to call the handler's methods
appropriately.
Most handlers are meant to be started on the server, usually within
-``puppet master``, and the clients are mostly started on the client,
-usually within ``puppet agent``.
+`puppet master`, and the clients are mostly started on the client,
+usually within `puppet agent`.
You can find the server-side handler for each interface at
-``puppet/network/handler/<name>.rb`` and the client class at
-``puppet/network/client/<name>.rb``.
+`puppet/network/handler/<name>.rb` and the client class at
+`puppet/network/client/<name>.rb`.
"
diff --git a/lib/puppet/reference/providers.rb b/lib/puppet/reference/providers.rb
index ef33a559b..c85ad23ab 100644
--- a/lib/puppet/reference/providers.rb
+++ b/lib/puppet/reference/providers.rb
@@ -47,7 +47,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
# Add the suitability note
if missing = provider.suitable?(false) and missing.empty?
- data << "**X**"
+ data << "*X*"
suit = true
functional = true
else
@@ -86,7 +86,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
# Add a note for every feature
features.each do |feature|
if provider.features.include?(feature)
- data << "**X**"
+ data << "*X*"
else
data << ""
end
@@ -95,7 +95,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
ret += h(type.name.to_s + "_", 2)
- ret += ".. _#{type.name}: #{"http://docs.puppetlabs.com/references/stable/type.html##{type.name}"}\n\n"
+ ret += "[#{type.name}](#{"http://docs.puppetlabs.com/references/stable/type.html##{type.name}"})\n\n"
ret += option("Default provider", default)
ret += doctable(headers, table_data)
@@ -111,7 +111,7 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
ret
end
providers.header = "
-Puppet resource types are usually backed by multiple implementations called ``providers``,
+Puppet resource types are usually backed by multiple implementations called `providers`,
which handle variance between platforms and tools.
Different providers are suitable or unsuitable on different platforms based on things
diff --git a/lib/puppet/reference/report.rb b/lib/puppet/reference/report.rb
index 481ca2dc1..47fc779ab 100644
--- a/lib/puppet/reference/report.rb
+++ b/lib/puppet/reference/report.rb
@@ -7,16 +7,15 @@ end
report.header = "
Puppet clients can report back to the server after each transaction. This
transaction report is sent as a YAML dump of the
-``Puppet::Transaction::Report`` class and includes every log message that was
+`Puppet::Transaction::Report` class and includes every log message that was
generated during the transaction along with as many metrics as Puppet knows how
-to collect. See `ReportsAndReporting Reports and Reporting`:trac:
-for more information on how to use reports.
+to collect. See [Reports and Reporting](http://projects.puppetlabs.com/projects/puppet/wiki/Reports_And_Reporting) for more information on how to use reports.
Currently, clients default to not sending in reports; you can enable reporting
-by setting the ``report`` parameter to true.
+by setting the `report` parameter to true.
-To use a report, set the ``reports`` parameter on the server; multiple
-reports must be comma-separated. You can also specify ``none`` to disable
+To use a report, set the `reports` parameter on the server; multiple
+reports must be comma-separated. You can also specify `none` to disable
reports entirely.
Puppet provides multiple report handlers that will process client reports:
diff --git a/lib/puppet/reference/type.rb b/lib/puppet/reference/type.rb
index be8742edc..b423387e9 100644
--- a/lib/puppet/reference/type.rb
+++ b/lib/puppet/reference/type.rb
@@ -5,34 +5,34 @@ type = Puppet::Util::Reference.newreference :type, :doc => "All Puppet resource
Puppet::Type.eachtype { |type|
next if type.name == :puppet
next if type.name == :component
+ next if type.name == :whit
types[type.name] = type
}
str = %{
- Resource Types
- --------------
+## Resource Types
- - The *namevar* is the parameter used to uniquely identify a type instance.
+- The *namevar* is the parameter used to uniquely identify a type instance.
This is the parameter that gets assigned when a string is provided before
the colon in a type declaration. In general, only developers will need to
- worry about which parameter is the ``namevar``.
+ worry about which parameter is the `namevar`.
- In the following code::
+ In the following code:
- file { "/etc/passwd":
- owner => root,
- group => root,
- mode => 644
- }
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
- ``/etc/passwd`` is considered the title of the file object (used for things like
- dependency handling), and because ``path`` is the namevar for ``file``, that
- string is assigned to the ``path`` parameter.
+ `/etc/passwd` is considered the title of the file object (used for things like
+ dependency handling), and because `path` is the namevar for `file`, that
+ string is assigned to the `path` parameter.
- *Parameters* determine the specific configuration of the instance. They either
directly modify the system (internally, these are called properties) or they affect
- how the instance behaves (e.g., adding a search path for ``exec`` instances or determining recursion on ``file`` instances).
+ how the instance behaves (e.g., adding a search path for `exec` instances or determining recursion on `file` instances).
- *Providers* provide low-level functionality for a given resource type. This is
usually in the form of calling out to external commands.
diff --git a/lib/puppet/reports/http.rb b/lib/puppet/reports/http.rb
index f1a74195d..7ac54dfbd 100644
--- a/lib/puppet/reports/http.rb
+++ b/lib/puppet/reports/http.rb
@@ -5,7 +5,7 @@ require 'uri'
Puppet::Reports.register_report(:http) do
desc <<-DESC
- Send report information via HTTP to the ``reporturl``. Each host sends
+ Send report information via HTTP to the `reporturl`. Each host sends
its report as a YAML dump and this sends this YAML to a client via HTTP POST.
The YAML is the `report` parameter of the request."
DESC
diff --git a/lib/puppet/reports/rrdgraph.rb b/lib/puppet/reports/rrdgraph.rb
index 9fbeb60e8..517fa8f03 100644
--- a/lib/puppet/reports/rrdgraph.rb
+++ b/lib/puppet/reports/rrdgraph.rb
@@ -1,12 +1,11 @@
Puppet::Reports.register_report(:rrdgraph) do
desc "Graph all available data about hosts using the RRD library. You
must have the Ruby RRDtool library installed to use this report, which
- you can get from `the RubyRRDTool RubyForge page`_. This package may also
- be available as ``ruby-rrd`` or ``rrdtool-ruby`` in your distribution's package
- management system. The library and/or package will both require the binary
- ``rrdtool`` package from your distribution to be installed.
-
- .. _the RubyRRDTool RubyForge page: http://rubyforge.org/projects/rubyrrdtool/
+ you can get from
+ [the RubyRRDTool RubyForge page](http://rubyforge.org/projects/rubyrrdtool/).
+ This package may also be available as `ruby-rrd` or `rrdtool-ruby` in your
+ distribution's package management system. The library and/or package will both
+ require the binary `rrdtool` package from your distribution to be installed.
This report will create, manage, and graph RRD database files for each
of the metrics generated during transactions, and it will create a
@@ -14,12 +13,12 @@ Puppet::Reports.register_report(:rrdgraph) do
point, it will not create a common index file to display links to
all hosts.
- All RRD files and graphs get created in the ``rrddir`` directory. If
+ All RRD files and graphs get created in the `rrddir` directory. If
you want to serve these publicly, you should be able to just alias that
directory in a web server.
- If you really know what you're doing, you can tune the ``rrdinterval``,
- which defaults to the ``runinterval``."
+ If you really know what you're doing, you can tune the `rrdinterval`,
+ which defaults to the `runinterval`."
def hostdir
@hostdir ||= File.join(Puppet[:rrddir], self.host)
@@ -123,7 +122,7 @@ Puppet::Reports.register_report(:rrdgraph) do
# that means we record the total time, the config time, and that's about
# it. We should probably send each type's time as a separate metric.
def timeclean(metric)
- metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) }
+ metric.values = metric.values.find_all { |name, label, value| ['total', 'config_retrieval'].include?(name.to_s) }
end
end
diff --git a/lib/puppet/reports/store.rb b/lib/puppet/reports/store.rb
index 65159fc07..30f24591c 100644
--- a/lib/puppet/reports/store.rb
+++ b/lib/puppet/reports/store.rb
@@ -2,7 +2,7 @@ require 'puppet'
Puppet::Reports.register_report(:store) do
desc "Store the yaml report on disk. Each host sends its report as a YAML dump
- and this just stores the file on disk, in the ``reportdir`` directory.
+ and this just stores the file on disk, in the `reportdir` directory.
These files collect quickly -- one every half hour -- so it is a good idea
to perform some maintenance on them if you use this report (it's the only
@@ -19,7 +19,7 @@ Puppet::Reports.register_report(:store) do
:owner => 'service',
:group => 'service'
},
-
+
:noop => [false, "Used by settings internally."]
)
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index 652104096..e17143e2f 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -6,12 +6,12 @@ require 'time'
Puppet::Reports.register_report(:tagmail) do
desc "This report sends specific log messages to specific email addresses
- based on the tags in the log messages. See the
- `UsingTags tag documentation`:trac: for more information
- on tags.
+ based on the tags in the log messages.
- To use this report, you must create a ``tagmail.conf`` (in the location
- specified by ``tagmap``). This is a simple file that maps tags to
+ See the [UsingTags tag documentation](http://projects.puppetlabs.com/projects/puppet/wiki/Using_Tags) for more information on tags.
+
+ To use this report, you must create a `tagmail.conf` (in the location
+ specified by `tagmap`). This is a simple file that maps tags to
email addresses: Any log messages in the report that match the specified
tags will be sent to the specified email addresses.
@@ -20,21 +20,20 @@ Puppet::Reports.register_report(:tagmail) do
the email addresses by a colon, and the email addresses should also
be comma-separated.
- Lastly, there is an ``all`` tag that will always match all log messages.
+ Lastly, there is an `all` tag that will always match all log messages.
- Here is an example tagmail.conf::
+ Here is an example `tagmail.conf`:
- all: me@domain.com
- webserver, !mailserver: httpadmins@domain.com
+ 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``.
+ This will send all messages to `me@domain.com`, and all messages from
+ webservers that are not also from mailservers to `httpadmins@domain.com`.
If you are using anti-spam controls, such as grey-listing, on your mail
- server you should whitelist the sending email (controlled by ``reportform`` configuration option) to ensure your email is not discarded as spam.
+ server you should whitelist the sending email (controlled by `reportform` configuration option) to ensure your email is not discarded as spam.
"
-
# Find all matching messages.
def match(taglists)
matching_logs = []
@@ -85,7 +84,7 @@ Puppet::Reports.register_report(:tagmail) do
pos = []
neg = []
taglist.sub(/\s+$/,'').split(/\s*,\s*/).each do |tag|
- unless tag =~ /^!?[-\w]+$/
+ unless tag =~ /^!?[-\w\.]+$/
raise ArgumentError, "Invalid tag #{tag.inspect}"
end
case tag
diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb
index 96d22e414..4f0d50750 100644
--- a/lib/puppet/resource.rb
+++ b/lib/puppet/resource.rb
@@ -13,7 +13,7 @@ class Puppet::Resource
extend Puppet::Util::Pson
include Enumerable
attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters, :strict
- attr_reader :namespaces
+ attr_reader :type, :title
require 'puppet/indirector'
extend Puppet::Indirector
@@ -80,6 +80,18 @@ class Puppet::Resource
end
end
+ def yaml_property_munge(x)
+ case x
+ when Hash
+ x.inject({}) { |h,kv|
+ k,v = kv
+ h[k] = self.class.value_to_pson_data(v)
+ h
+ }
+ else self.class.value_to_pson_data(x)
+ end
+ end
+
def to_pson(*args)
to_pson_data_hash.to_pson(*args)
end
@@ -154,33 +166,42 @@ class Puppet::Resource
end
end
+ # This stub class is only needed for serialization compatibility with 0.25.x
+ class Reference
+ attr_accessor :type,:title
+ def initialize(type,title)
+ @type,@title = type,title
+ end
+ end
+
# Create our resource.
def initialize(type, title = nil, attributes = {})
@parameters = {}
- @namespaces = [""]
- # Set things like namespaces and strictness first.
+ # Set things like strictness first.
attributes.each do |attr, value|
next if attr == :parameters
send(attr.to_s + "=", value)
end
- # We do namespaces first, and use tmp variables, so our title
- # canonicalization works (i.e., namespaces are set and resource
- # types can be looked up)
- tmp_type, tmp_title = extract_type_and_title(type, title)
- self.type = tmp_type
- self.title = tmp_title
+ @type, @title = extract_type_and_title(type, title)
+
+ @type = munge_type_name(@type)
+
+ if @type == "Class"
+ @title = :main if @title == ""
+ @title = munge_type_name(@title)
+ end
if params = attributes[:parameters]
extract_parameters(params)
end
- resolve_type_and_title
-
tag(self.type)
tag(self.title) if valid_tag?(self.title)
+ @reference = Reference.new(@type,@title) # for serialization compatibility with 0.25.x
+
raise ArgumentError, "Invalid resource type #{type}" if strict? and ! resource_type
end
@@ -193,17 +214,12 @@ class Puppet::Resource
return(catalog ? catalog.resource(to_s) : nil)
end
- def title=(value)
- @unresolved_title = value
- @title = nil
- end
-
def resource_type
- @resource_type ||= case type
- when "Class"; find_hostclass(title)
- when "Node"; find_node(title)
+ case type
+ when "Class"; known_resource_types.hostclass(title == :main ? "" : title)
+ when "Node"; known_resource_types.node(title)
else
- find_resource_type(type)
+ Puppet::Type.type(type.to_s.downcase.to_sym) || known_resource_types.definition(type)
end
end
@@ -314,28 +330,6 @@ class Puppet::Resource
self
end
- # We have to lazy-evaluate this.
- def title=(value)
- @title = nil
- @unresolved_title = value
- end
-
- # We have to lazy-evaluate this.
- def type=(value)
- @type = nil
- @unresolved_type = value || "Class"
- end
-
- def title
- resolve_type_and_title unless @title
- @title
- end
-
- def type
- resolve_type_and_title unless @type
- @type
- end
-
def valid_parameter?(name)
resource_type.valid_parameter?(name)
end
@@ -346,29 +340,6 @@ class Puppet::Resource
private
- def find_node(name)
- known_resource_types.node(name)
- end
-
- def find_hostclass(title)
- name = title == :main ? "" : title
- known_resource_types.find_hostclass(namespaces, name)
- end
-
- def find_resource_type(type)
- # It still works fine without the type == 'class' short-cut, but it is a lot slower.
- return nil if ["class", "node"].include? type.to_s.downcase
- find_builtin_resource_type(type) || find_defined_resource_type(type)
- end
-
- def find_builtin_resource_type(type)
- Puppet::Type.type(type.to_s.downcase.to_sym)
- end
-
- def find_defined_resource_type(type)
- known_resource_types.find_definition(namespaces, type.to_s.downcase)
- end
-
# Produce a canonical method name.
def parameter_name(param)
param = param.to_s.downcase.to_sym
@@ -378,10 +349,6 @@ class Puppet::Resource
param
end
- def namespaces=(ns)
- @namespaces = Array(ns)
- end
-
# The namevar for our resource type. If the type doesn't exist,
# always use :name.
def namevar
@@ -428,54 +395,9 @@ class Puppet::Resource
value.to_s.split("::").collect { |s| s.capitalize }.join("::")
end
- # This is an annoyingly complicated method for resolving qualified
- # types as necessary, and putting them in type or title attributes.
- def resolve_type_and_title
- if @unresolved_type
- @type = resolve_type
- @unresolved_type = nil
- end
- if @unresolved_title
- @title = resolve_title
- @unresolved_title = nil
- end
- end
-
- def resolve_type
- case type = munge_type_name(@unresolved_type)
- when "Class", "Node";
- type
- else
- # Otherwise, some kind of builtin or defined resource type
- munge_type_name( (r = find_resource_type(type)) ? r.name : type)
- end
- end
-
- # This method only works if resolve_type was called first
- def resolve_title
- case @type
- when "Node"; return @unresolved_title
- when "Class";
- resolve_title_for_class(@unresolved_title)
- else
- @unresolved_title
- end
- end
-
- def resolve_title_for_class(title)
- if title == "" or title == :main
- return :main
- end
-
- if klass = find_hostclass(title)
- result = klass.name
- end
- munge_type_name(result || title)
- end
-
def parse_title
h = {}
- type = find_resource_type(@type)
+ type = resource_type
if type.respond_to? :title_patterns
type.title_patterns.each { |regexp, symbols_and_lambdas|
if captures = regexp.match(title.to_s)
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 4b4342d11..a8668d844 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -57,7 +57,7 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
end
def title_key_for_ref( ref )
- ref =~ /^([\w:]+)\[(.*)\]$/m
+ ref =~ /^([-\w:]+)\[(.*)\]$/m
[$1, $2]
end
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index 85c0979c1..77824845d 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -13,8 +13,8 @@ class Puppet::Resource::Type
RESOURCE_SUPERTYPES = [:hostclass, :node, :definition]
- attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection, :module_name
- attr_reader :type, :namespace, :arguments, :behaves_like
+ attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection
+ attr_reader :type, :namespace, :arguments, :behaves_like, :module_name
RESOURCE_SUPERTYPES.each do |t|
define_method("#{t}?") { self.type == t }
@@ -69,6 +69,7 @@ class Puppet::Resource::Type
end
scope = subscope(scope, resource) unless resource.title == :main
+ scope.compiler.add_class(name) unless definition?
set_resource_parameters(resource, scope)
@@ -91,6 +92,8 @@ class Puppet::Resource::Type
end
set_arguments(options[:arguments])
+
+ @module_name = options[:module_name]
end
# This is only used for node names, and really only when the node name
@@ -137,21 +140,15 @@ class Puppet::Resource::Type
end
end
- # Make an instance of our resource type. This is only possible
- # for those classes and nodes that don't have any arguments, and is
- # only useful for things like the 'include' function.
- def mk_plain_resource(scope)
+ # Make an instance of the resource type, and place it in the catalog
+ # if it isn't in the catalog already. This is only possible for
+ # classes and nodes. No parameters are be supplied--if this is a
+ # parameterized class, then all parameters take on their default
+ # values.
+ def ensure_in_catalog(scope)
type == :definition and raise ArgumentError, "Cannot create resources for defined resource types"
resource_type = type == :hostclass ? :class : :node
- # Make sure our parent class has been evaluated, if we have one.
- if parent
- parent_resource = scope.catalog.resource(resource_type, parent)
- unless parent_resource
- parent_type(scope).mk_plain_resource(scope)
- end
- end
-
# Do nothing if the resource already exists; this makes sure we don't
# get multiple copies of the class resource, which helps provide the
# singleton nature of classes.
@@ -160,11 +157,22 @@ class Puppet::Resource::Type
end
resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
+ instantiate_resource(scope, resource)
scope.compiler.add_resource(scope, resource)
- scope.catalog.tag(*resource.tags)
resource
end
+ def instantiate_resource(scope, resource)
+ # Make sure our parent class has been evaluated, if we have one.
+ if parent && !scope.catalog.resource(resource.type, parent)
+ parent_type(scope).ensure_in_catalog(scope)
+ end
+
+ if ['Class', 'Node'].include? resource.type
+ scope.catalog.tag(*resource.tags)
+ end
+ end
+
def name
return @name unless @name.is_a?(Regexp)
@name.source.downcase.gsub(/[^-\w:.]/,'').sub(/^\.+/,'')
@@ -174,12 +182,29 @@ class Puppet::Resource::Type
@name.is_a?(Regexp)
end
+ # MQR TODO:
+ #
+ # The change(s) introduced by the fix for #4270 are mostly silly & should be
+ # removed, though we didn't realize it at the time. If it can be established/
+ # ensured that nodes never call parent_type and that resource_types are always
+ # (as they should be) members of exactly one resource_type_collection the
+ # following method could / should be replaced with:
+ #
+ # def parent_type
+ # @parent_type ||= parent && (
+ # resource_type_collection.find_or_load([name],parent,type.to_sym) ||
+ # fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type} in #{resource_type_collection.environment}"
+ # )
+ # end
+ #
+ # ...and then the rest of the changes around passing in scope reverted.
+ #
def parent_type(scope = nil)
return nil unless parent
unless @parent_type
raise "Must pass scope to parent_type when called first time" unless scope
- unless @parent_type = scope.environment.known_resource_types.send("find_#{type}", scope.namespaces, parent)
+ unless @parent_type = scope.environment.known_resource_types.send("find_#{type}", [name], parent)
fail Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type} in #{scope.environment}"
end
end
@@ -215,8 +240,13 @@ class Puppet::Resource::Type
resource[param] = value
end
- scope.setvar("title", resource.title) unless set.include? :title
- scope.setvar("name", resource.name) unless set.include? :name
+ if @type == :hostclass
+ scope.setvar("title", resource.title.to_s.downcase) unless set.include? :title
+ scope.setvar("name", resource.name.to_s.downcase ) unless set.include? :name
+ else
+ scope.setvar("title", resource.title ) unless set.include? :title
+ scope.setvar("name", resource.name ) unless set.include? :name
+ end
scope.setvar("module_name", module_name) if module_name and ! set.include? :module_name
if caller_name = scope.parent_module_name and ! set.include?(:caller_module_name)
diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb
index 6a933362f..a96927613 100644
--- a/lib/puppet/resource/type_collection.rb
+++ b/lib/puppet/resource/type_collection.rb
@@ -19,6 +19,12 @@ class Puppet::Resource::TypeCollection
@watched_files = {}
end
+ def import_ast(ast, modname)
+ ast.instantiate(modname).each do |instance|
+ add(instance)
+ end
+ end
+
def <<(thing)
add(thing)
self
@@ -92,50 +98,8 @@ class Puppet::Resource::TypeCollection
@definitions[munge_name(name)]
end
- def find(namespaces, name, type)
- #Array("") == [] for some reason
- namespaces = [namespaces] unless namespaces.is_a?(Array)
-
- if r = find_fully_qualified(name, type)
- return r
- end
-
- namespaces.each do |namespace|
- ary = namespace.split("::")
-
- while ary.length > 0
- tmp_namespace = ary.join("::")
- if r = find_partially_qualified(tmp_namespace, name, type)
- return r
- end
-
- # Delete the second to last object, which reduces our namespace by one.
- ary.pop
- end
-
- if result = send(type, name)
- return result
- end
- end
- nil
- end
-
- def find_or_load(namespaces, name, type)
- name = name.downcase
- namespaces = [namespaces] unless namespaces.is_a?(Array)
- namespaces = namespaces.collect { |ns| ns.downcase }
-
- # This could be done in the load_until, but the knowledge seems to
- # belong here.
- if r = find(namespaces, name, type)
- return r
- end
-
- loader.load_until(namespaces, name) { find(namespaces, name, type) }
- end
-
def find_node(namespaces, name)
- find("", name, :node)
+ @nodes[munge_name(name)]
end
def find_hostclass(namespaces, name)
@@ -152,23 +116,6 @@ class Puppet::Resource::TypeCollection
end
end
- def perform_initial_import
- parser = Puppet::Parser::Parser.new(environment)
- if code = Puppet.settings.uninterpolated_value(:code, environment.to_s) and code != ""
- parser.string = code
- else
- file = Puppet.settings.value(:manifest, environment.to_s)
- return unless File.exist?(file)
- parser.file = file
- end
- parser.parse
- rescue => detail
- msg = "Could not parse for environment #{environment}: #{detail}"
- error = Puppet::Error.new(msg)
- error.set_backtrace(detail.backtrace)
- raise error
- end
-
def stale?
@watched_files.values.detect { |file| file.changed? }
end
@@ -197,12 +144,52 @@ class Puppet::Resource::TypeCollection
private
- def find_fully_qualified(name, type)
- send(type, name.sub(/^::/, ''))
+ # Return a list of all possible fully-qualified names that might be
+ # meant by the given name, in the context of namespaces.
+ def resolve_namespaces(namespaces, name)
+ name = name.downcase
+ if name =~ /^::/
+ # name is explicitly fully qualified, so just return it, sans
+ # initial "::".
+ return [name.sub(/^::/, '')]
+ end
+ if name == ""
+ # The name "" has special meaning--it always refers to a "main"
+ # hostclass which contains all toplevel resources.
+ return [""]
+ end
+
+ namespaces = [namespaces] unless namespaces.is_a?(Array)
+ namespaces = namespaces.collect { |ns| ns.downcase }
+
+ result = []
+ namespaces.each do |namespace|
+ ary = namespace.split("::")
+
+ # Search each namespace nesting in innermost-to-outermost order.
+ while ary.length > 0
+ result << "#{ary.join("::")}::#{name}"
+ ary.pop
+ end
+
+ # Finally, search the toplevel namespace.
+ result << name
+ end
+
+ return result.uniq
end
- def find_partially_qualified(namespace, name, type)
- send(type, [namespace, name].join("::"))
+ # Resolve namespaces and find the given object. Autoload it if
+ # necessary.
+ def find_or_load(namespaces, name, type)
+ resolve_namespaces(namespaces, name).each do |fqname|
+ if result = send(type, fqname) || loader.try_load_fqname(type, fqname)
+ return result
+ end
+ end
+
+ # Nothing found.
+ return nil
end
def munge_name(name)
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 945b1beb3..6d153b46d 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -7,123 +7,45 @@ require 'set'
# A hopefully-faster graph class to replace the use of GRATR.
class Puppet::SimpleGraph
- # An internal class for handling a vertex's edges.
- class VertexWrapper
- attr_accessor :in, :out, :vertex
-
- # Remove all references to everything.
- def clear
- @adjacencies[:in].clear
- @adjacencies[:out].clear
- @vertex = nil
- end
-
- def initialize(vertex)
- @vertex = vertex
- @adjacencies = {:in => {}, :out => {}}
- end
-
- # Find adjacent vertices or edges.
- def adjacent(options)
- direction = options[:direction] || :out
- options[:type] ||= :vertices
-
- return send(direction.to_s + "_edges") if options[:type] == :edges
-
- @adjacencies[direction].keys.reject { |vertex| @adjacencies[direction][vertex].empty? }
- end
-
- # Add an edge to our list.
- def add_edge(direction, edge)
- opposite_adjacencies(direction, edge) << edge
- end
-
- # Return all known edges.
- def edges
- in_edges + out_edges
- end
-
- # Test whether we share an edge with a given vertex.
- def has_edge?(direction, vertex)
- return(vertex_adjacencies(direction, vertex).length > 0 ? true : false)
- end
-
- # Create methods for returning the degree and edges.
- [:in, :out].each do |direction|
- # LAK:NOTE If you decide to create methods for directly
- # testing the degree, you'll have to get the values and flatten
- # the results -- you might have duplicate edges, which can give
- # a false impression of what the degree is. That's just
- # as expensive as just getting the edge list, so I've decided
- # to only add this method.
- define_method("#{direction}_edges") do
- @adjacencies[direction].values.inject([]) { |total, adjacent| total += adjacent.to_a; total }
- end
- end
-
- # The other vertex in the edge.
- def other_vertex(direction, edge)
- case direction
- when :in; edge.source
- else
- edge.target
- end
- end
-
- # Remove an edge from our list. Assumes that we've already checked
- # that the edge is valid.
- def remove_edge(direction, edge)
- opposite_adjacencies(direction, edge).delete(edge)
- end
-
- def to_s
- vertex.to_s
- end
-
- private
-
- # These methods exist so we don't need a Hash with a default proc.
-
- # Look up the adjacencies for a vertex at the other end of an
- # edge.
- def opposite_adjacencies(direction, edge)
- opposite_vertex = other_vertex(direction, edge)
- vertex_adjacencies(direction, opposite_vertex)
- end
-
- # Look up the adjacencies for a given vertex.
- def vertex_adjacencies(direction, vertex)
- @adjacencies[direction][vertex] ||= Set.new
- @adjacencies[direction][vertex]
- end
- end
-
+ #
+ # All public methods of this class must maintain (assume ^ ensure) the following invariants, where "=~=" means
+ # equiv. up to order:
+ #
+ # @in_to.keys =~= @out_to.keys =~= all vertices
+ # @in_to.values.collect { |x| x.values }.flatten =~= @out_from.values.collect { |x| x.values }.flatten =~= all edges
+ # @in_to[v1][v2] =~= @out_from[v2][v1] =~= all edges from v1 to v2
+ # @in_to [v].keys =~= vertices with edges leading to v
+ # @out_from[v].keys =~= vertices with edges leading from v
+ # no operation may shed reference loops (for gc)
+ # recursive operation must scale with the depth of the spanning trees, or better (e.g. no recursion over the set
+ # of all vertices, etc.)
+ #
+ # This class is intended to be used with DAGs. However, if the
+ # graph has a cycle, it will not cause non-termination of any of the
+ # algorithms. The topsort method detects and reports cycles.
+ #
def initialize
- @vertices = {}
- @edges = []
+ @in_to = {}
+ @out_from = {}
+ @upstream_from = {}
+ @downstream_from = {}
end
# Clear our graph.
def clear
- @vertices.each { |vertex, wrapper| wrapper.clear }
- @vertices.clear
- @edges.clear
- end
-
- # Which resources a given resource depends upon.
- def dependents(resource)
- tree_from_vertex(resource).keys
+ @in_to.clear
+ @out_from.clear
+ @upstream_from.clear
+ @downstream_from.clear
end
# Which resources depend upon the given resource.
def dependencies(resource)
- # Cache the reversal graph, because it's somewhat expensive
- # to create.
- @reversal ||= reversal
- # Strangely, it's significantly faster to search a reversed
- # tree in the :out direction than to search a normal tree
- # in the :in direction.
- @reversal.tree_from_vertex(resource, :out).keys
+ vertex?(resource) ? upstream_from_vertex(resource).keys : []
+ end
+
+ def dependents(resource)
+ vertex?(resource) ? downstream_from_vertex(resource).keys : []
end
# Whether our graph is directed. Always true. Used to produce dot files.
@@ -133,8 +55,7 @@ class Puppet::SimpleGraph
# Determine all of the leaf nodes below a given vertex.
def leaves(vertex, direction = :out)
- tree = tree_from_vertex(vertex, direction)
- l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? }
+ tree_from_vertex(vertex, direction).keys.find_all { |c| adjacent(c, :direction => direction).empty? }
end
# Collect all of the edges that the passed events match. Returns
@@ -149,9 +70,7 @@ class Puppet::SimpleGraph
# Get all of the edges that this vertex should forward events
# to, which is the same thing as saying all edges directly below
# This vertex in the graph.
- adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
- edge.match?(event.name)
- end
+ @out_from[source].values.flatten.find_all { |edge| edge.match?(event.name) }
end
# Return a reversed version of this graph.
@@ -159,20 +78,50 @@ class Puppet::SimpleGraph
result = self.class.new
vertices.each { |vertex| result.add_vertex(vertex) }
edges.each do |edge|
- newedge = edge.class.new(edge.target, edge.source, edge.label)
- result.add_edge(newedge)
+ result.add_edge edge.class.new(edge.target, edge.source, edge.label)
end
result
end
# Return the size of the graph.
def size
- @vertices.length
+ vertices.size
end
- # Return the graph as an array.
def to_a
- @vertices.keys
+ vertices
+ end
+
+ # Provide a topological sort with cycle reporting
+ def topsort_with_cycles
+ degree = {}
+ zeros = []
+ result = []
+
+ # Collect each of our vertices, with the number of in-edges each has.
+ vertices.each do |v|
+ edges = @in_to[v].dup
+ zeros << v if edges.empty?
+ degree[v] = edges
+ end
+
+ # Iterate over each 0-degree vertex, decrementing the degree of
+ # each of its out-edges.
+ while v = zeros.pop
+ result << v
+ @out_from[v].each { |v2,es|
+ degree[v2].delete(v)
+ zeros << v2 if degree[v2].empty?
+ }
+ end
+
+ # If we have any vertices left with non-zero in-degrees, then we've found a cycle.
+ if cycles = degree.values.reject { |ns| ns.empty? } and cycles.length > 0
+ message = cycles.collect { |edges| '('+edges.collect { |e| e.to_s }.join(", ")+')' }.join(", ")
+ raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
+ end
+
+ result
end
# Provide a topological sort.
@@ -182,26 +131,24 @@ class Puppet::SimpleGraph
result = []
# Collect each of our vertices, with the number of in-edges each has.
- @vertices.each do |name, wrapper|
- edges = wrapper.in_edges
- zeros << wrapper if edges.length == 0
- degree[wrapper.vertex] = edges
+ vertices.each do |v|
+ edges = @in_to[v]
+ zeros << v if edges.empty?
+ degree[v] = edges.length
end
# Iterate over each 0-degree vertex, decrementing the degree of
# each of its out-edges.
- while wrapper = zeros.pop
- result << wrapper.vertex
- wrapper.out_edges.each do |edge|
- degree[edge.target].delete(edge)
- zeros << @vertices[edge.target] if degree[edge.target].length == 0
- end
+ while v = zeros.pop
+ result << v
+ @out_from[v].each { |v2,es|
+ zeros << v2 if (degree[v2] -= 1) == 0
+ }
end
# If we have any vertices left with non-zero in-degrees, then we've found a cycle.
- if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0
- message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ")
- raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
+ if cycles = degree.values.reject { |ns| ns == 0 } and cycles.length > 0
+ topsort_with_cycles
end
result
@@ -209,103 +156,80 @@ class Puppet::SimpleGraph
# Add a new vertex to the graph.
def add_vertex(vertex)
- @reversal = nil
- return false if vertex?(vertex)
- setup_vertex(vertex)
- true # don't return the VertexWrapper instance.
+ @in_to[vertex] ||= {}
+ @out_from[vertex] ||= {}
end
# Remove a vertex from the graph.
- def remove_vertex!(vertex)
- return nil unless vertex?(vertex)
- @vertices[vertex].edges.each { |edge| remove_edge!(edge) }
- @edges -= @vertices[vertex].edges
- @vertices[vertex].clear
- @vertices.delete(vertex)
+ def remove_vertex!(v)
+ return unless vertex?(v)
+ @upstream_from.clear
+ @downstream_from.clear
+ (@in_to[v].values+@out_from[v].values).flatten.each { |e| remove_edge!(e) }
+ @in_to.delete(v)
+ @out_from.delete(v)
end
# Test whether a given vertex is in the graph.
- def vertex?(vertex)
- @vertices.include?(vertex)
+ def vertex?(v)
+ @in_to.include?(v)
end
# Return a list of all vertices.
def vertices
- @vertices.keys
+ @in_to.keys
end
# Add a new edge. The graph user has to create the edge instance,
# since they have to specify what kind of edge it is.
- def add_edge(source, target = nil, label = nil)
- @reversal = nil
- if target
- edge = Puppet::Relationship.new(source, target, label)
- else
- edge = source
- end
- [edge.source, edge.target].each { |vertex| setup_vertex(vertex) unless vertex?(vertex) }
- @vertices[edge.source].add_edge :out, edge
- @vertices[edge.target].add_edge :in, edge
- @edges << edge
- true
+ def add_edge(e,*a)
+ return add_relationship(e,*a) unless a.empty?
+ @upstream_from.clear
+ @downstream_from.clear
+ add_vertex(e.source)
+ add_vertex(e.target)
+ @in_to[ e.target][e.source] ||= []; @in_to[ e.target][e.source] |= [e]
+ @out_from[e.source][e.target] ||= []; @out_from[e.source][e.target] |= [e]
end
- # Find a matching edge. Note that this only finds the first edge,
- # not all of them or whatever.
- def edge(source, target)
- @edges.each_with_index { |test_edge, index| return test_edge if test_edge.source == source and test_edge.target == target }
+ def add_relationship(source, target, label = nil)
+ add_edge Puppet::Relationship.new(source, target, label)
end
- def edge_label(source, target)
- return nil unless edge = edge(source, target)
- edge.label
+ # Find all matching edges.
+ def edges_between(source, target)
+ (@out_from[source] || {})[target] || []
end
# Is there an edge between the two vertices?
def edge?(source, target)
- return false unless vertex?(source) and vertex?(target)
-
- @vertices[source].has_edge?(:out, target)
+ vertex?(source) and vertex?(target) and @out_from[source][target]
end
def edges
- @edges.dup
+ @in_to.values.collect { |x| x.values }.flatten
end
- # Remove an edge from our graph.
- def remove_edge!(edge)
- @vertices[edge.source].remove_edge(:out, edge)
- @vertices[edge.target].remove_edge(:in, edge)
-
- @edges.delete(edge)
- nil
+ def each_edge
+ @in_to.each { |t,ns| ns.each { |s,es| es.each { |e| yield e }}}
end
- # Find adjacent edges.
- def adjacent(vertex, options = {})
- return [] unless wrapper = @vertices[vertex]
- wrapper.adjacent(options)
+ # Remove an edge from our graph.
+ def remove_edge!(e)
+ if edge?(e.source,e.target)
+ @upstream_from.clear
+ @downstream_from.clear
+ @in_to [e.target].delete e.source if (@in_to [e.target][e.source] -= [e]).empty?
+ @out_from[e.source].delete e.target if (@out_from[e.source][e.target] -= [e]).empty?
+ end
end
- private
-
- # An internal method that skips the validation, so we don't have
- # duplicate validation calls.
- def setup_vertex(vertex)
- @vertices[vertex] = VertexWrapper.new(vertex)
+ # Find adjacent edges.
+ def adjacent(v, options = {})
+ return [] unless ns = (options[:direction] == :in) ? @in_to[v] : @out_from[v]
+ (options[:type] == :edges) ? ns.values.flatten : ns.keys
end
-
- public
-
-# # For some reason, unconnected vertices do not show up in
-# # this graph.
-# def to_jpg(path, name)
-# gv = vertices
-# Dir.chdir(path) do
-# induced_subgraph(gv).write_to_graphic_file('jpg', name)
-# end
-# end
-
+
# Take container information from another graph and use it
# to replace any container vertices with their respective leaves.
# This creates direct relationships where there were previously
@@ -318,16 +242,15 @@ class Puppet::SimpleGraph
# to container leaves, but that would result in many more
# relationships.
stage_class = Puppet::Type.type(:stage)
+ whit_class = Puppet::Type.type(:whit)
containers = other.topsort.find_all { |v| (v.is_a?(type) or v.is_a?(stage_class)) and vertex?(v) }
containers.each do |container|
# Get the list of children from the other graph.
children = other.adjacent(container, :direction => :out)
- # Just remove the container if it's empty.
- if children.empty?
- remove_vertex!(container)
- next
- end
+ # MQR TODO: Luke suggests that it should be possible to refactor the system so that
+ # container nodes are retained, thus obviating the need for the whit.
+ children = [whit_class.new(:name => container.name, :catalog => other)] if children.empty?
# First create new edges for each of the :in edges
[:in, :out].each do |dir|
@@ -382,6 +305,26 @@ class Puppet::SimpleGraph
predecessor
end
+ def downstream_from_vertex(v)
+ return @downstream_from[v] if @downstream_from[v]
+ result = @downstream_from[v] = {}
+ @out_from[v].keys.each do |node|
+ result[node] = 1
+ result.update(downstream_from_vertex(node))
+ end
+ result
+ end
+
+ def upstream_from_vertex(v)
+ return @upstream_from[v] if @upstream_from[v]
+ result = @upstream_from[v] = {}
+ @in_to[v].keys.each do |node|
+ result[node] = 1
+ result.update(upstream_from_vertex(node))
+ end
+ result
+ end
+
# LAK:FIXME This is just a paste of the GRATR code with slight modifications.
# Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an
@@ -423,18 +366,6 @@ class Puppet::SimpleGraph
system('dotty', dotfile)
end
- # Use +dot+ to create a graphical representation of the graph. Returns the
- # filename of the graphics file.
- def write_to_graphic_file (fmt='png', dotfile='graph')
- src = dotfile + '.dot'
- dot = dotfile + '.' + fmt
-
- File.open(src, 'w') {|f| f << self.to_dot << "\n"}
-
- system( "dot -T#{fmt} #{src} -o #{dot}" )
- dot
- end
-
# Produce the graph files if requested.
def write_graph(name)
return unless Puppet[:graph]
@@ -446,4 +377,73 @@ class Puppet::SimpleGraph
f.puts to_dot("name" => name.to_s.capitalize)
}
end
+
+ # This flag may be set to true to use the new YAML serialzation
+ # format (where @vertices is a simple list of vertices rather than a
+ # list of VertexWrapper objects). Deserialization supports both
+ # formats regardless of the setting of this flag.
+ class << self
+ attr_accessor :use_new_yaml_format
+ end
+ self.use_new_yaml_format = false
+
+ # Stub class to allow graphs to be represented in YAML using the old
+ # (version 2.6) format.
+ class VertexWrapper
+ attr_reader :vertex, :adjacencies
+ def initialize(vertex, adjacencies)
+ @vertex = vertex
+ @adjacencies = adjacencies
+ end
+ end
+
+ # instance_variable_get is used by Object.to_zaml to get instance
+ # variables. Override it so that we can simulate the presence of
+ # instance variables @edges and @vertices for serialization.
+ def instance_variable_get(v)
+ case v.to_s
+ when '@edges' then
+ edges
+ when '@vertices' then
+ if self.class.use_new_yaml_format
+ vertices
+ else
+ result = {}
+ vertices.each do |vertex|
+ adjacencies = {}
+ [:in, :out].each do |direction|
+ adjacencies[direction] = {}
+ adjacent(vertex, :direction => direction, :type => :edges).each do |edge|
+ other_vertex = direction == :in ? edge.source : edge.target
+ (adjacencies[direction][other_vertex] ||= Set.new).add(edge)
+ end
+ end
+ result[vertex] = Puppet::SimpleGraph::VertexWrapper.new(vertex, adjacencies)
+ end
+ result
+ end
+ else
+ super(v)
+ end
+ end
+
+ def to_yaml_properties
+ other_vars = instance_variables.reject { |v| %w{@in_to @out_from @upstream_from @downstream_from}.include?(v) }
+ (other_vars + %w{@vertices @edges}).sort.uniq
+ end
+
+ def yaml_initialize(tag, var)
+ initialize()
+ vertices = var.delete('vertices')
+ edges = var.delete('edges')
+ if vertices.is_a?(Hash)
+ # Support old (2.6) format
+ vertices = vertices.keys
+ end
+ vertices.each { |v| add_vertex(v) }
+ edges.each { |e| add_edge(e) }
+ var.each do |varname, value|
+ instance_variable_set("@#{varname}", value)
+ end
+ end
end
diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb
index e4d06a039..2f6cae3f5 100644
--- a/lib/puppet/ssl/certificate_request.rb
+++ b/lib/puppet/ssl/certificate_request.rb
@@ -29,7 +29,7 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base
# Support either an actual SSL key, or a Puppet key.
key = key.content if key.is_a?(Puppet::SSL::Key)
- # If we're a CSR for the CA, then use the real certname, rather than the
+ # If we're a CSR for the CA, then use the real ca_name, rather than the
# fake 'ca' name. This is mostly for backward compatibility with 0.24.x,
# but it's also just a good idea.
common_name = name == Puppet::SSL::CA_NAME ? Puppet.settings[:ca_name] : name
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 63e6b922a..f3321bd29 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -147,21 +147,19 @@ class Puppet::SSLCertificates::CA
# Create the root certificate.
def mkrootcert
- # Make the root cert's name the FQDN of the host running the CA.
- name = Facter["hostname"].value
+ # Make the root cert's name "Puppet CA: " plus the FQDN of the host running the CA.
+ name = "Puppet CA: #{Facter["hostname"].value}"
if domain = Facter["domain"].value
name += ".#{domain}"
end
- cert = Certificate.new(
-
+ cert = Certificate.new(
:name => name,
:cert => @config[:cacert],
:encrypt => @config[:capass],
:key => @config[:cakey],
:selfsign => true,
:ttl => ttl,
-
:type => :ca
)
@@ -241,19 +239,15 @@ class Puppet::SSLCertificates::CA
f << "%04X" % (serial + 1)
}
-
- newcert = Puppet::SSLCertificates.mkcert(
-
+ newcert = Puppet::SSLCertificates.mkcert(
:type => :server,
:name => csr.subject,
:ttl => ttl,
:issuer => @cert,
:serial => serial,
-
:publickey => csr.public_key
)
-
sign_with_key(newcert)
self.storeclientcert(newcert)
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index e6d1e0528..1d3091428 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -62,30 +62,49 @@ class Puppet::Transaction::Report
host
end
- # Provide a summary of this report.
+ # Provide a human readable textual summary of this report.
def summary
+ report = raw_summary
+
ret = ""
+ report.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |key|
+ ret += "#{Puppet::Util::Metric.labelize(key)}:\n"
- @metrics.sort { |a,b| a[1].label <=> b[1].label }.each do |name, metric|
- ret += "#{metric.label}:\n"
- metric.values.sort { |a,b|
+ report[key].keys.sort { |a,b|
# sort by label
- if a[0] == :total
+ if a == :total
1
- elsif b[0] == :total
+ elsif b == :total
-1
else
- a[1] <=> b[1]
+ report[key][a].to_s <=> report[key][b].to_s
end
- }.each do |name, label, value|
+ }.each do |label|
+ value = report[key][label]
next if value == 0
value = "%0.2f" % value if value.is_a?(Float)
- ret += " %15s %s\n" % [label + ":", value]
+ ret += " %15s %s\n" % [Puppet::Util::Metric.labelize(label) + ":", value]
end
end
ret
end
+ # Provide a raw hash summary of this report.
+ def raw_summary
+ report = {}
+
+ @metrics.each do |name, metric|
+ key = metric.name.to_s
+ report[key] = {}
+ metric.values.each do |name, label, value|
+ report[key][name.to_s] = value
+ end
+ report[key]["total"] = 0 unless key == "time" or report[key].include?("total")
+ end
+ (report["time"] ||= {})["last_run"] = Time.now.tv_sec
+ report
+ end
+
# Based on the contents of this report's metrics, compute a single number
# that represents the report. The resulting number is a bitmask where
# individual bits represent the presence of different metrics.
@@ -103,7 +122,6 @@ class Puppet::Transaction::Report
resource_statuses.each do |name, status|
metrics[:total] += status.change_count if status.change_count
end
-
add_metric(:changes, metrics)
end
@@ -124,7 +142,6 @@ class Puppet::Transaction::Report
metrics[:total] = resource_statuses.length
resource_statuses.each do |name, status|
-
Puppet::Resource::Status::STATES.each do |state|
metrics[state] += 1 if status.send(state)
end
diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb
index aace6a38a..29ec9a539 100644
--- a/lib/puppet/transaction/resource_harness.rb
+++ b/lib/puppet/transaction/resource_harness.rb
@@ -72,7 +72,7 @@ class Puppet::Transaction::ResourceHarness
resource[param] = value
audited << param
else
- resource.info "Storing newly-audited value #{current[param]} for #{param}"
+ resource.debug "Storing newly-audited value #{current[param]} for #{param}"
cache(resource, param, current[param])
end
end
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index c3855a400..1b6e7dcd7 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -410,13 +410,15 @@ class Type
property = self.newattr(name)
- begin
- # make sure the parameter doesn't have any errors
- property.value = value
- rescue => detail
- error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
- error.set_backtrace(detail.backtrace)
- raise error
+ if property
+ begin
+ # make sure the parameter doesn't have any errors
+ property.value = value
+ rescue => detail
+ error = Puppet::Error.new("Parameter #{name} failed: #{detail}")
+ error.set_backtrace(detail.backtrace)
+ raise error
+ end
end
nil
@@ -472,6 +474,12 @@ class Type
raise Puppet::Error, "Resource type #{self.class.name} does not support parameter #{name}"
end
+ if provider and ! provider.class.supports_parameter?(klass)
+ missing = klass.required_features.find_all { |f| ! provider.class.feature?(f) }
+ info "Provider %s does not support features %s; not managing attribute %s" % [provider.class.name, missing.join(", "), name]
+ return nil
+ end
+
return @parameters[name] if @parameters.include?(name)
@parameters[name] = klass.new(:resource => self)
@@ -933,16 +941,16 @@ class Type
newmetaparam(:schedule) do
desc "On what schedule the object should be managed. You must create a
schedule object, and then reference the name of that object to use
- that for your schedule::
+ that for your schedule:
- schedule { daily:
- period => daily,
- range => \"2-4\"
- }
+ schedule { daily:
+ period => daily,
+ range => \"2-4\"
+ }
- exec { \"/usr/bin/apt-get update\":
- schedule => daily
- }
+ exec { \"/usr/bin/apt-get update\":
+ schedule => daily
+ }
The creation of the schedule object does not need to appear in the
configuration before objects that use it."
@@ -957,7 +965,7 @@ class Type
the value, and any changes already get logged."
validate do |list|
- list = Array(list)
+ list = Array(list).collect {|p| p.to_sym}
unless list == [:all]
list.each do |param|
next if @resource.class.validattr?(param)
@@ -982,8 +990,8 @@ class Type
end
def properties_to_audit(list)
- if list == :all
- list = all_properties if list == :all
+ if !list.kind_of?(Array) && list.to_sym == :all
+ list = all_properties
else
list = Array(list).collect { |p| p.to_sym }
end
@@ -1020,40 +1028,40 @@ class Type
newmetaparam(:alias) do
desc "Creates an alias for the object. Puppet uses this internally when you
- provide a symbolic name::
-
- file { sshdconfig:
- path => $operatingsystem ? {
- solaris => \"/usr/local/etc/ssh/sshd_config\",
- default => \"/etc/ssh/sshd_config\"
- },
- source => \"...\"
- }
+ provide a symbolic name:
+
+ file { sshdconfig:
+ path => $operatingsystem ? {
+ solaris => \"/usr/local/etc/ssh/sshd_config\",
+ default => \"/etc/ssh/sshd_config\"
+ },
+ source => \"...\"
+ }
- service { sshd:
- subscribe => file[sshdconfig]
- }
+ service { sshd:
+ subscribe => File[sshdconfig]
+ }
- When you use this feature, the parser sets ``sshdconfig`` as the name,
+ When you use this feature, the parser sets `sshdconfig` as the name,
and the library sets that as an alias for the file so the dependency
- lookup for ``sshd`` works. You can use this parameter yourself,
+ lookup for `sshd` works. You can use this parameter yourself,
but note that only the library can use these aliases; for instance,
- the following code will not work::
+ the following code will not work:
- file { \"/etc/ssh/sshd_config\":
- owner => root,
- group => root,
- alias => sshdconfig
- }
+ file { \"/etc/ssh/sshd_config\":
+ owner => root,
+ group => root,
+ alias => sshdconfig
+ }
- file { sshdconfig:
- mode => 644
- }
+ file { sshdconfig:
+ mode => 644
+ }
There's no way here for the Puppet parser to know that these two stanzas
should be affecting the same file.
- See the `LanguageTutorial language tutorial`:trac: for more information.
+ See the [Language Tutorial](http://docs.puppetlabs.com/guides/language_tutorial.html) for more information.
"
@@ -1083,9 +1091,9 @@ class Type
be useful to add your own tags to a given resource.
Tags are currently useful for things like applying a subset of a
- host's configuration::
+ host's configuration:
- puppet agent --test --tags mytag
+ puppet agent --test --tags mytag
This way, when you're testing a configuration you can run just the
portion you're testing."
@@ -1189,23 +1197,23 @@ class Type
newmetaparam(:require, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :NONE}) do
desc "One or more objects that this object depends on.
This is used purely for guaranteeing that changes to required objects
- happen before the dependent object. For instance::
+ happen before the dependent object. For instance:
- # Create the destination directory before you copy things down
- file { \"/usr/local/scripts\":
- ensure => directory
- }
+ # Create the destination directory before you copy things down
+ file { \"/usr/local/scripts\":
+ ensure => directory
+ }
- file { \"/usr/local/scripts/myscript\":
- source => \"puppet://server/module/myscript\",
- mode => 755,
- require => File[\"/usr/local/scripts\"]
- }
+ file { \"/usr/local/scripts/myscript\":
+ source => \"puppet://server/module/myscript\",
+ mode => 755,
+ require => File[\"/usr/local/scripts\"]
+ }
Multiple dependencies can be specified by providing a comma-seperated list
- of resources, enclosed in square brackets::
+ of resources, enclosed in square brackets:
- require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
+ require => [ File[\"/usr/local\"], File[\"/usr/local/scripts\"] ]
Note that Puppet will autorequire everything that it can, and
there are hooks in place so that it's easy for resources to add new
@@ -1219,10 +1227,10 @@ class Type
Currently, exec resources will autorequire their CWD (if it is
specified) plus any fully qualified paths that appear in the
- command. For instance, if you had an ``exec`` command that ran
- the ``myscript`` mentioned above, the above code that pulls the
+ command. For instance, if you had an `exec` command that ran
+ the `myscript` mentioned above, the above code that pulls the
file down would be automatically listed as a requirement to the
- ``exec`` code, so that you would always be running againts the
+ `exec` code, so that you would always be running againts the
most recent version.
"
end
@@ -1230,20 +1238,20 @@ class Type
newmetaparam(:subscribe, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :ALL_EVENTS, :callback => :refresh}) do
desc "One or more objects that this object depends on. Changes in the
subscribed to objects result in the dependent objects being
- refreshed (e.g., a service will get restarted). For instance::
-
- class nagios {
- file { \"/etc/nagios/nagios.conf\":
- source => \"puppet://server/module/nagios.conf\",
- alias => nagconf # just to make things easier for me
- }
- service { nagios:
- ensure => running,
- subscribe => File[nagconf]
+ refreshed (e.g., a service will get restarted). For instance:
+
+ class nagios {
+ file { \"/etc/nagios/nagios.conf\":
+ source => \"puppet://server/module/nagios.conf\",
+ alias => nagconf # just to make things easier for me
+ }
+ service { nagios:
+ ensure => running,
+ subscribe => File[nagconf]
+ }
}
- }
- Currently the ``exec``, ``mount`` and ``service`` type support
+ Currently the `exec`, `mount` and `service` type support
refreshing.
"
end
@@ -1251,18 +1259,18 @@ class Type
newmetaparam(:before, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :NONE}) do
desc %{This parameter is the opposite of **require** -- it guarantees
that the specified object is applied later than the specifying
- object::
+ object:
- file { "/var/nagios/configuration":
- source => "...",
- recurse => true,
- before => Exec["nagios-rebuid"]
- }
+ file { "/var/nagios/configuration":
+ source => "...",
+ recurse => true,
+ before => Exec["nagios-rebuid"]
+ }
- exec { "nagios-rebuild":
- command => "/usr/bin/make",
- cwd => "/var/nagios/configuration"
- }
+ exec { "nagios-rebuild":
+ command => "/usr/bin/make",
+ cwd => "/var/nagios/configuration"
+ }
This will make sure all of the files are up to date before the
make command is run.}
@@ -1270,16 +1278,16 @@ class Type
newmetaparam(:notify, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :ALL_EVENTS, :callback => :refresh}) do
desc %{This parameter is the opposite of **subscribe** -- it sends events
- to the specified object::
+ to the specified object:
- file { "/etc/sshd_config":
- source => "....",
- notify => Service[sshd]
- }
+ file { "/etc/sshd_config":
+ source => "....",
+ notify => Service[sshd]
+ }
- service { sshd:
- ensure => running
- }
+ service { sshd:
+ ensure => running
+ }
This will restart the sshd service if the sshd config file changes.}
end
@@ -1293,24 +1301,24 @@ class Type
By default, all classes get directly added to the
'main' stage. You can create new stages as resources:
- stage { [pre, post]: }
+ stage { [pre, post]: }
To order stages, use standard relationships:
- stage { pre: before => Stage[main] }
+ stage { pre: before => Stage[main] }
Or use the new relationship syntax:
- Stage[pre] -> Stage[main] -> Stage[post]
+ Stage[pre] -> Stage[main] -> Stage[post]
Then use the new class parameters to specify a stage:
- class { foo: stage => pre }
+ class { foo: stage => pre }
Stages can only be set on classes, not individual resources. This will
- fail::
+ fail:
- file { '/foo': stage => pre, ensure => file }
+ file { '/foo': stage => pre, ensure => file }
}
end
diff --git a/lib/puppet/type/augeas.rb b/lib/puppet/type/augeas.rb
index 7fcfdd7a3..d29bda648 100644
--- a/lib/puppet/type/augeas.rb
+++ b/lib/puppet/type/augeas.rb
@@ -28,27 +28,28 @@ Puppet::Type.newtype(:augeas) do
via the augeas tool.
Requires:
- - augeas to be installed (http://www.augeas.net)
- - ruby-augeas bindings
- Sample usage with a string::
+ - augeas to be installed (http://www.augeas.net)
+ - ruby-augeas bindings
- augeas{\"test1\" :
- context => \"/files/etc/sysconfig/firstboot\",
- changes => \"set RUN_FIRSTBOOT YES\",
- onlyif => \"match other_value size > 0\",
- }
+ Sample usage with a string:
- Sample usage with an array and custom lenses::
+ augeas{\"test1\" :
+ context => \"/files/etc/sysconfig/firstboot\",
+ changes => \"set RUN_FIRSTBOOT YES\",
+ onlyif => \"match other_value size > 0\",
+ }
- augeas{\"jboss_conf\":
- context => \"/files\",
- changes => [
- \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
- \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
- ],
- load_path => \"$/usr/share/jbossas/lenses\",
- }
+ Sample usage with an array and custom lenses:
+
+ augeas{\"jboss_conf\":
+ context => \"/files\",
+ changes => [
+ \"set /etc/jbossas/jbossas.conf/JBOSS_IP $ipaddress\",
+ \"set /etc/jbossas/jbossas.conf/JAVA_HOME /usr\"
+ ],
+ load_path => \"$/usr/share/jbossas/lenses\",
+ }
"
@@ -71,23 +72,23 @@ Puppet::Type.newtype(:augeas) do
newparam (:onlyif) do
desc "Optional augeas command and comparisons to control the execution of this type.
- Supported onlyif syntax::
-
- get [AUGEAS_PATH] [COMPARATOR] [STRING]
- match [MATCH_PATH] size [COMPARATOR] [INT]
- match [MATCH_PATH] include [STRING]
- match [MATCH_PATH] not_include [STRING]
- match [MATCH_PATH] == [AN_ARRAY]
- match [MATCH_PATH] != [AN_ARRAY]
-
- where::
-
- AUGEAS_PATH is a valid path scoped by the context
- MATCH_PATH is a valid match synatx scoped by the context
- COMPARATOR is in the set [> >= != == <= <]
- STRING is a string
- INT is a number
- AN_ARRAY is in the form ['a string', 'another']"
+ Supported onlyif syntax:
+
+ get [AUGEAS_PATH] [COMPARATOR] [STRING]
+ match [MATCH_PATH] size [COMPARATOR] [INT]
+ match [MATCH_PATH] include [STRING]
+ match [MATCH_PATH] not_include [STRING]
+ match [MATCH_PATH] == [AN_ARRAY]
+ match [MATCH_PATH] != [AN_ARRAY]
+
+ where:
+
+ AUGEAS_PATH is a valid path scoped by the context
+ MATCH_PATH is a valid match synatx scoped by the context
+ COMPARATOR is in the set [> >= != == <= <]
+ STRING is a string
+ INT is a number
+ AN_ARRAY is in the form ['a string', 'another']"
defaultto ""
end
@@ -95,16 +96,14 @@ Puppet::Type.newtype(:augeas) do
newparam(:changes) do
desc "The changes which should be applied to the filesystem. This
can be either a string which contains a command or an array of commands.
- Commands supported are::
+ Commands supported are:
- set [PATH] [VALUE] Sets the value VALUE at loction PATH
- rm [PATH] Removes the node at location PATH
- remove [PATH] Synonym for rm
- clear [PATH] Keeps the node at PATH, but removes the value.
- ins [LABEL] [WHERE] [PATH]
- Inserts an empty node LABEL either [WHERE={before|after}] PATH.
- insert [LABEL] [WHERE] [PATH]
- Synonym for ins
+ set [PATH] [VALUE] Sets the value VALUE at loction PATH
+ rm [PATH] Removes the node at location PATH
+ remove [PATH] Synonym for rm
+ clear [PATH] Keeps the node at PATH, but removes the value.
+ ins [LABEL] [WHERE] [PATH] Inserts an empty node LABEL either [WHERE={before|after}] PATH.
+ insert [LABEL] [WHERE] [PATH] Synonym for ins
If the parameter 'context' is set that value is prepended to PATH"
end
@@ -136,11 +135,11 @@ Puppet::Type.newtype(:augeas) do
end
newparam(:lens) do
- desc "Use a specific lens, e.g. 'Hosts.lns'. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
+ desc "Use a specific lens, e.g. `Hosts.lns`. When this parameter is set, you must also set the incl parameter to indicate which file to load. Only that file will be loaded, which greatly speeds up execution of the type"
end
newparam(:incl) do
- desc "Load only a specific file, e.g. '/etc/hosts'. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
+ desc "Load only a specific file, e.g. `/etc/hosts`. When this parameter is set, you must also set the lens parameter to indicate which lens to use."
end
validate do
diff --git a/lib/puppet/type/computer.rb b/lib/puppet/type/computer.rb
index 86a30be27..89a0692bf 100644
--- a/lib/puppet/type/computer.rb
+++ b/lib/puppet/type/computer.rb
@@ -10,7 +10,7 @@ Puppet::Type.newtype(:computer) do
This provider only manages Computer objects in the local directory service
domain, not in remote directories.
- If you wish to manage /etc/hosts on Mac OS X, then simply use the host
+ If you wish to manage `/etc/hosts` file on Mac OS X, then simply use the host
type as per other platforms.
This type primarily exists to create localhost Computer objects that MCX
@@ -31,7 +31,7 @@ Puppet::Type.newtype(:computer) do
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
desc "Control the existences of this computer record. Set this attribute to
- ``present`` to ensure the computer record exists. Set it to ``absent``
+ `present` to ensure the computer record exists. Set it to `absent`
to delete any computer records with this name"
newvalue(:present) do
provider.create
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index b3f5e608d..76399d693 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -15,32 +15,32 @@ Puppet::Type.newtype(:cron) do
association is made and synced to disk, you can then manage the job
normally (e.g., change the schedule of the job).
- Example::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => 2,
- minute => 0
- }
-
- Note that all cron values can be specified as an array of values::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => [2, 4]
- }
-
- Or using ranges, or the step syntax ``*/2`` (although there's no guarantee that
- your ``cron`` daemon supports it)::
-
- cron { logrotate:
- command => \"/usr/sbin/logrotate\",
- user => root,
- hour => ['2-4'],
- minute => '*/10'
- }
+ Example:
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => 2,
+ minute => 0
+ }
+
+ Note that all cron values can be specified as an array of values:
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => [2, 4]
+ }
+
+ Or using ranges, or the step syntax `*/2` (although there's no guarantee that
+ your `cron` daemon supports it):
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => ['2-4'],
+ minute => '*/10'
+ }
"
ensurable
@@ -169,7 +169,7 @@ Puppet::Type.newtype(:cron) do
end
if value == "*"
- return value
+ return :absent
end
return value unless self.class.boundaries
@@ -206,7 +206,7 @@ Puppet::Type.newtype(:cron) do
profile is not sourced when the command is run, so if the
user's environment is desired it should be sourced manually.
- All cron parameters support ``absent`` as a value; this will
+ All cron parameters support `absent` as a value; this will
remove any existing values for that field."
def retrieve
@@ -230,7 +230,7 @@ Puppet::Type.newtype(:cron) do
end
newproperty(:special) do
- desc "Special schedules only supported on FreeBSD."
+ desc "Special schedules"
def specials
%w{reboot yearly annually monthly weekly daily midnight hourly}
@@ -293,7 +293,7 @@ Puppet::Type.newtype(:cron) do
but will not associate them with a specific job.
Settings should be specified exactly as they should appear in
- the crontab, e.g., ``PATH=/bin:/usr/bin:/usr/sbin``."
+ the crontab, e.g., `PATH=/bin:/usr/bin:/usr/sbin`."
validate do |value|
unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent"
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index bfeaaad34..606888c75 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -6,51 +6,51 @@ module Puppet
@doc = "Executes external commands. It is critical that all commands
executed using this mechanism can be run multiple times without
harm, i.e., they are *idempotent*. One useful way to create idempotent
- commands is to use the checks like ``creates`` to avoid running the
+ commands is to use the checks like `creates` to avoid running the
command unless some condition is met.
- Note also that you can restrict an ``exec`` to only run when it receives
- events by using the ``refreshonly`` parameter; this is a useful way to
+ Note also that you can restrict an `exec` to only run when it receives
+ events by using the `refreshonly` parameter; this is a useful way to
have your configuration respond to events with arbitrary commands.
- It is worth noting that ``exec`` is special, in that it is not
- currently considered an error to have multiple ``exec`` instances
+ It is worth noting that `exec` is special, in that it is not
+ currently considered an error to have multiple `exec` instances
with the same name. This was done purely because it had to be this
way in order to get certain functionality, but it complicates things.
- In particular, you will not be able to use ``exec`` instances that
+ In particular, you will not be able to use `exec` instances that
share their commands with other instances as a dependency, since
Puppet has no way of knowing which instance you mean.
- For example::
+ For example:
- # defined in the production class
- exec { \"make\":
- cwd => \"/prod/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
+ # defined in the production class
+ exec { \"make\":
+ cwd => \"/prod/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
- . etc. .
+ . etc. .
- # defined in the test class
- exec { \"make\":
- cwd => \"/test/build/dir\",
- path => \"/usr/bin:/usr/sbin:/bin\"
- }
+ # defined in the test class
+ exec { \"make\":
+ cwd => \"/test/build/dir\",
+ path => \"/usr/bin:/usr/sbin:/bin\"
+ }
Any other type would throw an error, complaining that you had
the same instance being managed in multiple places, but these are
- obviously different images, so ``exec`` had to be treated specially.
+ obviously different images, so `exec` had to be treated specially.
It is recommended to avoid duplicate names whenever possible.
- Note that if an ``exec`` receives an event from another resource,
- it will get executed again (or execute the command specified in ``refresh``, if there is one).
+ Note that if an `exec` receives an event from another resource,
+ it will get executed again (or execute the command specified in `refresh`, if there is one).
- There is a strong tendency to use ``exec`` to do whatever work Puppet
+ There is a strong tendency to use `exec` to do whatever work Puppet
can't already do; while this is obviously acceptable (and unavoidable)
- in the short term, it is highly recommended to migrate work from ``exec``
+ in the short term, it is highly recommended to migrate work from `exec`
to native Puppet types as quickly as possible. If you find that
- you are doing a lot of work with ``exec``, please at least notify
+ you are doing a lot of work with `exec`, please at least notify
us at Puppet Labs what you are doing, and hopefully we can work with
you to get a native resource type for the work you are doing."
@@ -159,9 +159,9 @@ module Puppet
desc "The actual command to execute. Must either be fully qualified
or a search path for the command must be provided. If the command
succeeds, any output produced will be logged at the instance's
- normal log level (usually ``notice``), but if the command fails
+ normal log level (usually `notice`), but if the command fails
(meaning its return code does not match the specified code) then
- any output is logged at the ``err`` log level."
+ any output is logged at the `err` log level."
end
newparam(:path) do
@@ -223,7 +223,7 @@ module Puppet
newparam(:logoutput) do
desc "Whether to log output. Defaults to logging output at the
- loglevel for the ``exec`` resource. Use *on_failure* to only
+ loglevel for the `exec` resource. Use *on_failure* to only
log the output when the command reports an error. Values are
**true**, *false*, *on_failure*, and any legal log level."
@@ -253,7 +253,7 @@ module Puppet
newparam(:environment) do
desc "Any additional environment variables you want to set for a
command. Note that if you use this to set PATH, it will override
- the ``path`` attribute. Multiple environment variables should be
+ the `path` attribute. Multiple environment variables should be
specified as an array."
validate do |values|
@@ -330,22 +330,22 @@ module Puppet
desc "The command should only be run as a
refresh mechanism for when a dependent object is changed. It only
makes sense to use this option when this command depends on some
- other object; it is useful for triggering an action::
-
- # Pull down the main aliases file
- file { \"/etc/aliases\":
- source => \"puppet://server/module/aliases\"
- }
-
- # Rebuild the database, but only when the file changes
- exec { newaliases:
- path => [\"/usr/bin\", \"/usr/sbin\"],
- subscribe => File[\"/etc/aliases\"],
- refreshonly => true
- }
+ other object; it is useful for triggering an action:
+
+ # Pull down the main aliases file
+ file { \"/etc/aliases\":
+ source => \"puppet://server/module/aliases\"
+ }
+
+ # Rebuild the database, but only when the file changes
+ exec { newaliases:
+ path => [\"/usr/bin\", \"/usr/sbin\"],
+ subscribe => File[\"/etc/aliases\"],
+ refreshonly => true
+ }
- Note that only ``subscribe`` and ``notify`` can trigger actions, not ``require``,
- so it only makes sense to use ``refreshonly`` with ``subscribe`` or ``notify``."
+ Note that only `subscribe` and `notify` can trigger actions, not `require`,
+ so it only makes sense to use `refreshonly` with `subscribe` or `notify`."
newvalues(:true, :false)
@@ -364,13 +364,13 @@ module Puppet
newcheck(:creates) do
desc "A file that this command creates. If this
parameter is provided, then the command will only be run
- if the specified file does not exist::
+ if the specified file does not exist:
- exec { \"tar xf /my/tar/file.tar\":
- cwd => \"/var/tmp\",
- creates => \"/var/tmp/myfile\",
- path => [\"/usr/bin\", \"/usr/sbin\"]
- }
+ exec { \"tar xf /my/tar/file.tar\":
+ cwd => \"/var/tmp\",
+ creates => \"/var/tmp/myfile\",
+ path => [\"/usr/bin\", \"/usr/sbin\"]
+ }
"
@@ -396,16 +396,16 @@ module Puppet
end
newcheck(:unless) do
- desc "If this parameter is set, then this ``exec`` will run unless
- the command returns 0. For example::
+ desc "If this parameter is set, then this `exec` will run unless
+ the command returns 0. For example:
- exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
- }
+ exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\"
+ }
- This would add ``root`` to the cron.allow file (on Solaris) unless
- ``grep`` determines it's already there.
+ This would add `root` to the cron.allow file (on Solaris) unless
+ `grep` determines it's already there.
Note that this command follows the same rules as the main command,
which is to say that it must be fully qualified if the path is not set.
@@ -433,22 +433,22 @@ module Puppet
end
newcheck(:onlyif) do
- desc "If this parameter is set, then this ``exec`` will only run if
- the command returns 0. For example::
+ desc "If this parameter is set, then this `exec` will only run if
+ the command returns 0. For example:
- exec { \"logrotate\":
- path => \"/usr/bin:/usr/sbin:/bin\",
- onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
- }
+ exec { \"logrotate\":
+ path => \"/usr/bin:/usr/sbin:/bin\",
+ onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\"
+ }
- This would run ``logrotate`` only if that test returned true.
+ This would run `logrotate` only if that test returned true.
Note that this command follows the same rules as the main command,
which is to say that it must be fully qualified if the path is not set.
- Also note that onlyif can take an array as its value, eg::
+ Also note that onlyif can take an array as its value, e.g.:
- onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
+ onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
This will only run the exec if /all/ conditions in the array return true.
"
@@ -553,13 +553,7 @@ module Puppet
if self[:path]
if Puppet.features.posix? and !File.exists?(exe)
withenv :PATH => self[:path].join(File::PATH_SEPARATOR) do
- path = %x{which #{exe}}.chomp
- if path == ""
- raise ArgumentError,
- "Could not find command '#{exe}'"
- else
- exe = path
- end
+ exe = which(exe) || raise(ArgumentError,"Could not find command '#{exe}'")
end
elsif Puppet.features.microsoft_windows? and !File.exists?(exe)
self[:path].each do |path|
@@ -683,4 +677,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 71f2756bc..f35a26408 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -16,7 +16,7 @@ Puppet::Type.newtype(:file) do
@doc = "Manages local files, including setting ownership and
permissions, creation of both files and directories, and
retrieving entire files from remote servers. As Puppet matures, it
- expected that the ``file`` resource will be used less and less to
+ expected that the `file` resource will be used less and less to
manage content, and instead native resources will be used to do so.
If you find that you are often copying files in from a central
@@ -61,33 +61,33 @@ Puppet::Type.newtype(:file) do
newparam(:backup) do
desc "Whether files should be backed up before
being replaced. The preferred method of backing files up is via
- a ``filebucket``, which stores files by their MD5 sums and allows
+ a `filebucket`, which stores files by their MD5 sums and allows
easy retrieval without littering directories with backups. You
can specify a local filebucket or a network-accessible
- server-based filebucket by setting ``backup => bucket-name``.
- Alternatively, if you specify any value that begins with a ``.``
- (e.g., ``.puppet-bak``), then Puppet will use copy the file in
+ server-based filebucket by setting `backup => bucket-name`.
+ Alternatively, if you specify any value that begins with a `.`
+ (e.g., `.puppet-bak`), then Puppet will use copy the file in
the same directory with that value as the extension of the
- backup. Setting ``backup => false`` disables all backups of the
+ backup. Setting `backup => false` disables all backups of the
file in question.
- Puppet automatically creates a local filebucket named ``puppet`` and
+ Puppet automatically creates a local filebucket named `puppet` and
defaults to backing up there. To use a server-based filebucket,
- you must specify one in your configuration::
+ you must specify one in your configuration
- filebucket { main:
- server => puppet
- }
+ filebucket { main:
+ server => puppet
+ }
- The ``puppet master`` daemon creates a filebucket by default,
+ The `puppet master` daemon creates a filebucket by default,
so you can usually back up to your main server with this
configuration. Once you've described the bucket in your
- configuration, you can use it in any file::
+ configuration, you can use it in any file
- file { \"/my/file\":
- source => \"/path/in/nfs/or/something\",
- backup => main
- }
+ file { \"/my/file\":
+ source => \"/path/in/nfs/or/something\",
+ backup => main
+ }
This will back the file up to the central server.
@@ -192,9 +192,9 @@ Puppet::Type.newtype(:file) do
newparam(:ignore) do
desc "A parameter which omits action on files matching
specified patterns during recursion. Uses Ruby's builtin globbing
- engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``.
+ engine, so shell metacharacters are fully supported, e.g. `[a-z]*`.
Matches that would descend into the directory structure are ignored,
- e.g., ``*/*``."
+ e.g., `*/*`."
validate do |value|
unless value.is_a?(Array) or value.is_a?(String) or value == false
@@ -205,10 +205,10 @@ Puppet::Type.newtype(:file) do
newparam(:links) do
desc "How to handle links during file actions. During file copying,
- ``follow`` will copy the target file instead of the link, ``manage``
- will copy the link itself, and ``ignore`` will just pass it by.
- When not copying, ``manage`` and ``ignore`` behave equivalently
- (because you cannot really ignore links entirely during local recursion), and ``follow`` will manage the file to which the
+ `follow` will copy the target file instead of the link, `manage`
+ will copy the link itself, and `ignore` will just pass it by.
+ When not copying, `manage` and `ignore` behave equivalently
+ (because you cannot really ignore links entirely during local recursion), and `follow` will manage the file to which the
link points."
newvalues(:follow, :manage)
@@ -223,7 +223,7 @@ Puppet::Type.newtype(:file) do
files unless you really know what you are doing. This option only
makes sense when recursively managing directories.
- Note that when using ``purge`` with ``source``, Puppet will purge any files
+ Note that when using `purge` with `source`, Puppet will purge any files
that are not on the remote system."
defaultto :false
@@ -234,7 +234,7 @@ Puppet::Type.newtype(:file) do
newparam(:sourceselect) do
desc "Whether to copy all valid sources, or just the first one. This parameter
is only used in recursive copies; by default, the first valid source is the
- only one used as a recursive source, but if this parameter is set to ``all``,
+ only one used as a recursive source, but if this parameter is set to `all`,
then all valid sources will have all of their contents copied to the local host,
and for sources that have the same file, the source earlier in the list will
be used."
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index 74b380f55..b8f30a9c7 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -161,11 +161,17 @@ module Puppet
}
end
+ def self.standalone?
+ Puppet.settings[:name] == "apply"
+ end
+
def each_chunk_from(source_or_content)
if source_or_content.is_a?(String)
yield source_or_content
elsif source_or_content.nil?
yield read_file_from_filebucket
+ elsif self.class.standalone?
+ yield source_or_content.content
elsif source_or_content.local?
chunk_file_from_disk(source_or_content) { |chunk| yield chunk }
else
@@ -184,7 +190,7 @@ module Puppet
end
def chunk_file_from_source(source_or_content)
- request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path)
+ request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path.sub(/^\//,''))
connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
connection.request_get(indirection2uri(request), add_accept_encoding({"Accept" => "raw"})) do |response|
case response.code
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index c74a1d47a..967e06aee 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -3,27 +3,27 @@ module Puppet
require 'etc'
desc "Whether to create files that don't currently exist.
Possible values are *absent*, *present*, *file*, and *directory*.
- Specifying ``present`` will match any form of file existence, and
+ Specifying `present` will match any form of file existence, and
if the file is missing will create an empty file. Specifying
- ``absent`` will delete the file (and directory if recurse => true).
+ `absent` will delete the file (and directory if recurse => true).
Anything other than those values will be considered to be a symlink.
- For instance, the following text creates a link::
+ For instance, the following text creates a link:
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"/etc/inet/inetd.conf\"
- }
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"/etc/inet/inetd.conf\"
+ }
- You can make relative links::
+ You can make relative links:
- # Useful on solaris
- file { \"/etc/inetd.conf\":
- ensure => \"inet/inetd.conf\"
- }
+ # Useful on solaris
+ file { \"/etc/inetd.conf\":
+ ensure => \"inet/inetd.conf\"
+ }
If you need to make a relative link to a file named the same
- as one of the valid values, you must prefix it with ``./`` or
+ as one of the valid values, you must prefix it with `./` or
something similar.
You can also make recursive symlinks, which will create a
diff --git a/lib/puppet/type/file/mode.rb b/lib/puppet/type/file/mode.rb
index 9abf56d26..1ce56c843 100755
--- a/lib/puppet/type/file/mode.rb
+++ b/lib/puppet/type/file/mode.rb
@@ -13,14 +13,14 @@ module Puppet
entries in a directory, and search/traverse allows you to access
(read/write/execute) those entries.) Because of this feature, you
can recursively make a directory and all of the files in it
- world-readable by setting e.g.::
+ world-readable by setting e.g.:
- file { '/some/dir':
- mode => 644,
- recurse => true,
- }
+ file { '/some/dir':
+ mode => 644,
+ recurse => true,
+ }
- In this case all of the files underneath ``/some/dir`` will have
+ In this case all of the files underneath `/some/dir` will have
mode 644, and all of the directories will have mode 755."
@event = :file_changed
diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb
index edcfb83b2..a33c6a000 100644
--- a/lib/puppet/type/file/selcontext.rb
+++ b/lib/puppet/type/file/selcontext.rb
@@ -56,7 +56,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
desc "What the SELinux user component of the context of the file should be.
- Any valid SELinux user component is accepted. For example ``user_u``.
+ Any valid SELinux user component is accepted. For example `user_u`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -67,7 +67,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
desc "What the SELinux role component of the context of the file should be.
- Any valid SELinux role component is accepted. For example ``role_r``.
+ Any valid SELinux role component is accepted. For example `role_r`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -78,7 +78,7 @@ module Puppet
Puppet::Type.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
desc "What the SELinux type component of the context of the file should be.
- Any valid SELinux type component is accepted. For example ``tmp_t``.
+ Any valid SELinux type component is accepted. For example `tmp_t`.
If not specified it defaults to the value returned by matchpathcon for
the file, if any exists. Only valid on systems with SELinux support
enabled."
@@ -89,8 +89,8 @@ module Puppet
Puppet::Type.type(:file).newproperty(:selrange, :parent => Puppet::SELFileContext) do
desc "What the SELinux range component of the context of the file should be.
- Any valid SELinux range component is accepted. For example ``s0`` or
- ``SystemHigh``. If not specified it defaults to the value returned by
+ Any valid SELinux range component is accepted. For example `s0` or
+ `SystemHigh`. If not specified it defaults to the value returned by
matchpathcon for the file, if any exists. Only valid on systems with
SELinux support enabled and that have support for MCS (Multi-Category
Security)."
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 2eaf4a33f..7d03de2b0 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -12,7 +12,7 @@ module Puppet
include Puppet::Util::Diff
attr_accessor :source, :local
- desc "Copy a file over the current file. Uses ``checksum`` to
+ desc "Copy a file over the current file. Uses `checksum` to
determine when a file should be copied. Valid values are either
fully qualified paths to files, or URIs. Currently supported URI
types are *puppet* and *file*.
@@ -20,47 +20,47 @@ module Puppet
This is one of the primary mechanisms for getting content into
applications that Puppet does not directly support and is very
useful for those configuration files that don't change much across
- sytems. For instance::
+ sytems. For instance:
- class sendmail {
- file { \"/etc/mail/sendmail.cf\":
- source => \"puppet://server/modules/module_name/sendmail.cf\"
+ class sendmail {
+ file { \"/etc/mail/sendmail.cf\":
+ source => \"puppet://server/modules/module_name/sendmail.cf\"
+ }
}
- }
- You can also leave out the server name, in which case ``puppet agent``
- will fill in the name of its configuration server and ``puppet apply``
+ You can also leave out the server name, in which case `puppet agent`
+ will fill in the name of its configuration server and `puppet apply`
will use the local filesystem. This makes it easy to use the same
configuration in both local and centralized forms.
- Currently, only the ``puppet`` scheme is supported for source
+ Currently, only the `puppet` scheme is supported for source
URL's. Puppet will connect to the file server running on
- ``server`` to retrieve the contents of the file. If the
- ``server`` part is empty, the behavior of the command-line
- interpreter (``puppet apply``) and the client demon (``puppet agent``) differs
- slightly: ``apply`` will look such a file up on the module path
- on the local host, whereas ``agent`` will connect to the
+ `server` to retrieve the contents of the file. If the
+ `server` part is empty, the behavior of the command-line
+ interpreter (`puppet apply`) and the client demon (`puppet agent`) differs
+ slightly: `apply` will look such a file up on the module path
+ on the local host, whereas `agent` will connect to the
puppet server that it received the manifest from.
- See the `FileServingConfiguration fileserver configuration documentation`:trac: for information on how to configure
+ See the [fileserver configuration documentation](http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration) for information on how to configure
and use file services within Puppet.
If you specify multiple file sources for a file, then the first
source that exists will be used. This allows you to specify
- what amount to search paths for files::
-
- file { \"/path/to/my/file\":
- source => [
- \"/modules/nfs/files/file.$host\",
- \"/modules/nfs/files/file.$operatingsystem\",
- \"/modules/nfs/files/file\"
- ]
- }
+ what amount to search paths for files:
+
+ file { \"/path/to/my/file\":
+ source => [
+ \"/modules/nfs/files/file.$host\",
+ \"/modules/nfs/files/file.$operatingsystem\",
+ \"/modules/nfs/files/file\"
+ ]
+ }
This will use the first found file as the source.
- You cannot currently copy links using this mechanism; set ``links``
- to ``follow`` if any remote sources are links.
+ You cannot currently copy links using this mechanism; set `links`
+ to `follow` if any remote sources are links.
"
validate do |sources|
@@ -94,6 +94,16 @@ module Puppet
metadata && metadata.checksum
end
+ # Look up (if necessary) and return remote content.
+ cached_attr(:content) do
+ raise Puppet::DevError, "No source for content was stored with the metadata" unless metadata.source
+
+ unless tmp = Puppet::FileServing::Content.find(metadata.source)
+ fail "Could not find any content at %s" % metadata.source
+ end
+ tmp.content
+ end
+
# Copy the values from the source to the resource. Yay.
def copy_source_values
devfail "Somehow got asked to copy source values without any metadata" unless metadata
diff --git a/lib/puppet/type/filebucket.rb b/lib/puppet/type/filebucket.rb
index 65ff88411..7fd2ef46b 100755
--- a/lib/puppet/type/filebucket.rb
+++ b/lib/puppet/type/filebucket.rb
@@ -16,13 +16,13 @@ module Puppet
undo transactions.
You will normally want to define a single filebucket for your
- whole network and then use that as the default backup location::
+ whole network and then use that as the default backup location:
- # Define the bucket
- filebucket { main: server => puppet }
+ # Define the bucket
+ filebucket { main: server => puppet }
- # Specify it as the default target
- File { backup => main }
+ # Specify it as the default target
+ File { backup => main }
Puppetmaster servers create a filebucket by default, so this will
work in a default configuration."
@@ -92,4 +92,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb
index 9f26d2243..cde1cfd65 100755
--- a/lib/puppet/type/group.rb
+++ b/lib/puppet/type/group.rb
@@ -89,7 +89,7 @@ module Puppet
newparam(:allowdupe, :boolean => true) do
desc "Whether to allow duplicate GIDs. This option does not work on
- FreeBSD (contract to the ``pw`` man page)."
+ FreeBSD (contract to the `pw` man page)."
newvalues(:true, :false)
@@ -97,4 +97,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb
index 929542d7c..1af74d886 100755
--- a/lib/puppet/type/host.rb
+++ b/lib/puppet/type/host.rb
@@ -5,19 +5,17 @@ module Puppet
newproperty(:ip) do
desc "The host's IP address, IPv4 or IPv6."
- validate do |value|
- unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/
- raise Puppet::Error, "Invalid IP address"
+ validate do |value|
+ unless value =~ /^((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})$/
+ raise Puppet::Error, "Invalid IP address"
+ end
end
- end
end
newproperty(:host_aliases) do
- desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
+ desc "Any aliases the host might have. Multiple values must be
+ specified as an array."
def insync?(is)
is == @should
@@ -28,21 +26,6 @@ module Puppet
currentvalue.join(" ")
end
- def retrieve
- is = super
- case is
- when String
- is = is.split(/\s*,\s*/)
- when Symbol
- is = [is]
- when Array
- # nothing
- else
- raise Puppet::DevError, "Invalid @is type #{is.class}"
- end
- is
- end
-
# We actually want to return the whole array here, not just the first
# value.
def should
@@ -63,9 +46,14 @@ module Puppet
validate do |value|
raise Puppet::Error, "Host aliases cannot include whitespace" if value =~ /\s/
+ raise Puppet::Error, "Host alias cannot be an empty string. Use an empty array to delete all host_aliases " if value =~ /^\s*$/
end
end
+ newproperty(:comment) do
+ desc "A comment that will be attached to the line with a # character"
+ end
+
newproperty(:target) do
desc "The file in which to store service information. Only used by
those providers that write to disk."
@@ -94,8 +82,7 @@ module Puppet
end
@doc = "Installs and manages host entries. For most systems, these
- entries will just be in ``/etc/hosts``, but some systems (notably OS X)
+ entries will just be in `/etc/hosts`, but some systems (notably OS X)
will have different solutions."
end
end
-
diff --git a/lib/puppet/type/k5login.rb b/lib/puppet/type/k5login.rb
index 850e37733..a343e9e5c 100644
--- a/lib/puppet/type/k5login.rb
+++ b/lib/puppet/type/k5login.rb
@@ -3,15 +3,15 @@
# Plug-in type for handling k5login files
Puppet::Type.newtype(:k5login) do
- @doc = "Manage the .k5login file for a user. Specify the full path to
- the .k5login file as the name and an array of principals as the
+ @doc = "Manage the `.k5login` file for a user. Specify the full path to
+ the `.k5login` file as the name and an array of principals as the
property principals."
ensurable
# Principals that should exist in the file
newproperty(:principals, :array_matching => :all) do
- desc "The principals present in the .k5login file."
+ desc "The principals present in the `.k5login` file."
end
# The path/name of the k5login file
diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb
index 9b17c279d..ef6fbb6c1 100644
--- a/lib/puppet/type/macauthorization.rb
+++ b/lib/puppet/type/macauthorization.rb
@@ -1,8 +1,7 @@
Puppet::Type.newtype(:macauthorization) do
@doc = "Manage the Mac OS X authorization database.
- See:
- http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html for more information."
+ See the [Apple developer site](http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html) for more information."
ensurable
diff --git a/lib/puppet/type/mailalias.rb b/lib/puppet/type/mailalias.rb
index 5534fdf25..ce7ca790b 100755
--- a/lib/puppet/type/mailalias.rb
+++ b/lib/puppet/type/mailalias.rb
@@ -46,4 +46,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/maillist.rb b/lib/puppet/type/maillist.rb
index 7ac0e4e4f..732fbf09f 100755
--- a/lib/puppet/type/maillist.rb
+++ b/lib/puppet/type/maillist.rb
@@ -60,4 +60,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/mcx.rb b/lib/puppet/type/mcx.rb
index e56b11938..4f0a6c3c5 100644
--- a/lib/puppet/type/mcx.rb
+++ b/lib/puppet/type/mcx.rb
@@ -21,8 +21,6 @@ Puppet::Type.newtype(:mcx) do
@doc = "MCX object management using DirectoryService on OS X.
-Original Author: Jeff McCune <mccune.jeff@gmail.com>
-
The default provider of this type merely manages the XML plist as
reported by the dscl -mcxexport command. This is similar to the
content property of the file type in Puppet.
@@ -51,13 +49,13 @@ to other machines.
newparam(:name) do
desc "The name of the resource being managed.
- The default naming convention follows Directory Service paths::
+ The default naming convention follows Directory Service paths:
- /Computers/localhost
- /Groups/admin
- /Users/localadmin
+ /Computers/localhost
+ /Groups/admin
+ /Users/localadmin
- The ds_type and ds_name type parameters are not necessary if the
+ The `ds_type` and `ds_name` type parameters are not necessary if the
default naming convention is followed."
isnamevar
end
@@ -80,8 +78,10 @@ to other machines.
newproperty(:content, :required_features => :manages_content) do
desc "The XML Plist. The value of MCXSettings in DirectoryService.
This is the standard output from the system command:
- dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
- Note that ds_type is capitalized and plural in the dscl command."
+
+ dscl localhost -mcxexport /Local/Default/<ds_type>/ds_name
+
+ Note that `ds_type` is capitalized and plural in the dscl command."
end
# JJM Yes, this is not DRY at all. Because of the code blocks
diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index 6ee5dd174..e8c6b3290 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -5,8 +5,8 @@ module Puppet
information into the mount table. The actual behavior depends
on the value of the 'ensure' parameter.
- Note that if a ``mount`` receives an event from another resource,
- it will try to remount the filesystems if ``ensure`` is set to ``mounted``."
+ Note that if a `mount` receives an event from another resource,
+ it will try to remount the filesystems if `ensure` is set to `mounted`."
feature :refreshable, "The provider can remount the filesystem.",
:methods => [:remount]
@@ -15,10 +15,10 @@ module Puppet
# call code when sync is called.
newproperty(:ensure) do
desc "Control what to do with this mount. Set this attribute to
- ``umounted`` to make sure the filesystem is in the filesystem table
- but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to ``absent`` to unmount (if necessary) and remove
- the filesystem from the fstab. Set to ``mounted`` to add it to the
- fstab and mount it. Set to ``present`` to add to fstab but not change
+ `umounted` to make sure the filesystem is in the filesystem table
+ but not mounted (if the filesystem is currently mounted, it will be unmounted). Set it to `absent` to unmount (if necessary) and remove
+ the filesystem from the fstab. Set to `mounted` to add it to the
+ fstab and mount it. Set to `present` to add to fstab but not change
mount/unmount status"
newvalue(:defined) do
@@ -149,7 +149,7 @@ module Puppet
newproperty(:dump) do
desc "Whether to dump the mount. Not all platform support this.
- Valid values are ``1`` or ``0``. or ``2`` on FreeBSD, Default is ``0``."
+ Valid values are `1` or `0`. or `2` on FreeBSD, Default is `0`."
if Facter["operatingsystem"].value == "FreeBSD"
newvalue(%r{(0|1|2)})
@@ -183,7 +183,7 @@ module Puppet
end
newparam(:path) do
- desc "The deprecated name for the mount point. Please use ``name`` now."
+ desc "The deprecated name for the mount point. Please use `name` now."
def value=(value)
warning "'path' is deprecated for mounts. Please use 'name'."
@@ -193,7 +193,7 @@ module Puppet
end
newparam(:remounts) do
- desc "Whether the mount can be remounted ``mount -o remount``. If
+ desc "Whether the mount can be remounted `mount -o remount`. If
this is false, then the filesystem will be unmounted and remounted
manually, which is prone to failure."
@@ -210,7 +210,7 @@ module Puppet
def refresh
# Only remount if we're supposed to be mounted.
- provider.remount if self.should(:fstype) != "swap" and provider.mounted?
+ provider.remount if self.should(:fstype) != "swap" and self.should(:ensure) == :mounted
end
def value(name)
@@ -222,4 +222,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/notify.rb b/lib/puppet/type/notify.rb
index 97935e270..a6ec1dc8b 100644
--- a/lib/puppet/type/notify.rb
+++ b/lib/puppet/type/notify.rb
@@ -42,4 +42,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index f25464db5..51a866332 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -8,12 +8,12 @@ module Puppet
@doc = "Manage packages. There is a basic dichotomy in package
support right now: Some package types (e.g., yum and apt) can
retrieve their own package files, while others (e.g., rpm and sun) cannot. For those package formats that cannot retrieve
- their own files, you can use the ``source`` parameter to point to
+ their own files, you can use the `source` parameter to point to
the correct file.
Puppet will automatically guess the packaging format that you are
using based on the platform you are on, but you can override it
- using the ``provider`` parameter; each provider defines what it
+ using the `provider` parameter; each provider defines what it
requires in order to function, and you must meet those requirements
to use a given provider."
@@ -22,7 +22,7 @@ module Puppet
feature :uninstallable, "The provider can uninstall packages.",
:methods => [:uninstall]
feature :upgradeable, "The provider can upgrade to the latest version of a
- package. This feature is used by specifying ``latest`` as the
+ package. This feature is used by specifying `latest` as the
desired value for the package.",
:methods => [:update, :latest]
feature :purgeable, "The provider can purge packages. This generally means
@@ -104,7 +104,6 @@ module Puppet
end
end
-
defaultto :installed
# Override the parent method, because we've got all kinds of
@@ -181,35 +180,35 @@ module Puppet
system uses internally, which is sometimes (especially on Solaris)
a name that is basically useless to humans. If you want to
abstract package installation, then you can use aliases to provide
- a common name to packages::
-
- # In the 'openssl' class
- $ssl = $operatingsystem ? {
- solaris => SMCossl,
- default => openssl
- }
-
- # It is not an error to set an alias to the same value as the
- # object name.
- package { $ssl:
- ensure => installed,
- alias => openssl
- }
-
- . etc. .
-
- $ssh = $operatingsystem ? {
- solaris => SMCossh,
- default => openssh
- }
-
- # Use the alias to specify a dependency, rather than
- # having another selector to figure it out again.
- package { $ssh:
- ensure => installed,
- alias => openssh,
- require => Package[openssl]
- }
+ a common name to packages:
+
+ # In the 'openssl' class
+ $ssl = $operatingsystem ? {
+ solaris => SMCossl,
+ default => openssl
+ }
+
+ # It is not an error to set an alias to the same value as the
+ # object name.
+ package { $ssl:
+ ensure => installed,
+ alias => openssl
+ }
+
+ . etc. .
+
+ $ssh = $operatingsystem ? {
+ solaris => SMCossh,
+ default => openssh
+ }
+
+ # Use the alias to specify a dependency, rather than
+ # having another selector to figure it out again.
+ package { $ssh:
+ ensure => installed,
+ alias => openssh,
+ require => Package[openssl]
+ }
"
isnamevar
@@ -228,7 +227,7 @@ module Puppet
end
newparam(:type) do
- desc "Deprecated form of ``provider``."
+ desc "Deprecated form of `provider`."
munge do |value|
warning "'type' is deprecated; use 'provider' instead"
@@ -243,7 +242,7 @@ module Puppet
This is currently only used on Solaris. The value will be
validated according to system rules, which in the case of
Solaris means that it should either be a fully qualified path
- or it should be in /var/sadm/install/admin."
+ or it should be in `/var/sadm/install/admin`."
end
newparam(:responsefile) do
@@ -320,4 +319,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/resources.rb b/lib/puppet/type/resources.rb
index 34382e067..ae41b883b 100644
--- a/lib/puppet/type/resources.rb
+++ b/lib/puppet/type/resources.rb
@@ -1,12 +1,9 @@
-# Created by Luke Kanies on 2006-12-12.
-# Copyright (c) 2006. All rights reserved.
-
require 'puppet'
Puppet::Type.newtype(:resources) do
@doc = "This is a metatype that can manage other resource types. Any
metaparams specified here will be passed on to any generated resources,
- so you can purge umanaged resources but set ``noop`` to true so the
+ so you can purge umanaged resources but set `noop` to true so the
purging is only logged and does not actually happen."
@@ -132,4 +129,3 @@ Puppet::Type.newtype(:resources) do
%w{root nobody bin noaccess daemon sys}
end
end
-
diff --git a/lib/puppet/type/schedule.rb b/lib/puppet/type/schedule.rb
index bedf1e536..82f17e533 100755
--- a/lib/puppet/type/schedule.rb
+++ b/lib/puppet/type/schedule.rb
@@ -16,7 +16,7 @@ module Puppet
Thus, it behooves you to use wider scheduling (e.g., over a couple of
hours) combined with periods and repetitions. For instance, if you
wanted to restrict certain resources to only running once, between
- the hours of two and 4 AM, then you would use this schedule::
+ the hours of two and 4 AM, then you would use this schedule:
schedule { maint:
range => \"2 - 4\",
@@ -33,7 +33,7 @@ module Puppet
Puppet automatically creates a schedule for each valid period with the
same name as that period (e.g., hourly and daily). Additionally,
a schedule named *puppet* is created and used as the default,
- with the following attributes::
+ with the following attributes:
schedule { puppet:
period => hourly,
@@ -45,11 +45,11 @@ module Puppet
newparam(:name) do
desc "The name of the schedule. This name is used to retrieve the
- schedule when assigning it to an object::
+ schedule when assigning it to an object:
schedule { daily:
period => daily,
- range => [2, 4]
+ range => \"2 - 4\",
}
exec { \"/usr/bin/apt-get update\":
@@ -65,7 +65,7 @@ module Puppet
is always a range within a 24 hour period, and hours must be
specified in numbers between 0 and 23, inclusive. Minutes and
seconds can be provided, using the normal colon as a separator.
- For instance::
+ For instance:
schedule { maintenance:
range => \"1:30 - 4:30\"
@@ -196,17 +196,17 @@ module Puppet
Note that the period defines how often a given resource will get
applied but not when; if you would like to restrict the hours
that a given resource can be applied (e.g., only at night during
- a maintenance window) then use the ``range`` attribute.
+ a maintenance window) then use the `range` attribute.
If the provided periods are not sufficient, you can provide a
value to the *repeat* attribute, which will cause Puppet to
schedule the affected resources evenly in the period the
- specified number of times. Take this schedule::
+ specified number of times. Take this schedule:
- schedule { veryoften:
- period => hourly,
- repeat => 6
- }
+ schedule { veryoften:
+ period => hourly,
+ repeat => 6
+ }
This can cause Puppet to apply that resource up to every 10 minutes.
@@ -215,7 +215,7 @@ module Puppet
internal factors might prevent it from actually running that
often (e.g., long-running Puppet runs will squash conflictingly scheduled runs).
- See the ``periodmatch`` attribute for tuning whether to match
+ See the `periodmatch` attribute for tuning whether to match
times by their distance apart or by their specific value."
newvalues(:hourly, :daily, :weekly, :monthly, :never)
@@ -307,10 +307,10 @@ module Puppet
Puppet.debug "Creating default schedules"
result << self.new(
-
+
:name => "puppet",
:period => :hourly,
-
+
:repeat => "2"
)
@@ -318,9 +318,7 @@ module Puppet
@parameters.find { |p| p.name == :period }.value_collection.values.each { |value|
result << self.new(
-
:name => value.to_s,
-
:period => value
)
}
@@ -349,4 +347,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb
index cf873e987..204b89056 100644
--- a/lib/puppet/type/selboolean.rb
+++ b/lib/puppet/type/selboolean.rb
@@ -1,11 +1,7 @@
-#
-# Simple module for manageing SELinux booleans
-#
-
module Puppet
newtype(:selboolean) do
@doc = "Manages SELinux booleans on systems with SELinux support. The supported booleans
- are any of the ones found in /selinux/booleans/."
+ are any of the ones found in `/selinux/booleans/`."
newparam(:name) do
desc "The name of the SELinux boolean to be managed."
@@ -20,7 +16,7 @@ module Puppet
newparam(:persistent) do
desc "If set true, SELinux booleans will be written to disk and persist accross reboots.
- The default is ``false``."
+ The default is `false`."
defaultto :false
newvalues(:true, :false)
@@ -28,4 +24,3 @@ module Puppet
end
end
-
diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb
index 240d6e6d1..60be8a855 100644
--- a/lib/puppet/type/selmodule.rb
+++ b/lib/puppet/type/selmodule.rb
@@ -18,7 +18,7 @@ Puppet::Type.newtype(:selmodule) do
newparam(:selmoduledir) do
desc "The directory to look for the compiled pp module file in.
- Currently defaults to /usr/share/selinux/targeted. If selmodulepath
+ Currently defaults to `/usr/share/selinux/targeted`. If selmodulepath
is not specified the module will be looked for in this directory in a
in a file called NAME.pp, where NAME is the value of the name parameter."
@@ -34,9 +34,9 @@ Puppet::Type.newtype(:selmodule) do
newproperty(:syncversion) do
- desc "If set to ``true``, the policy will be reloaded if the
+ desc "If set to `true`, the policy will be reloaded if the
version found in the on-disk file differs from the loaded
- version. If set to ``false`` (the default) the the only check
+ version. If set to `false` (the default) the the only check
that will be made is if the policy is loaded at all or not."
newvalue(:true)
@@ -51,4 +51,3 @@ Puppet::Type.newtype(:selmodule) do
end
end
end
-
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index 8f5c6ee37..786a50448 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -17,10 +17,10 @@ module Puppet
can provide the better behaviour you will get. Or, you can just
use a platform that has very good service support.
- Note that if a ``service`` receives an event from another resource,
+ Note that if a `service` receives an event from another resource,
the service will get restarted. The actual command to restart the
service depends on the platform. You can provide a special command
- for restarting with the ``restart`` attribute."
+ for restarting with the `restart` attribute."
feature :refreshable, "The provider can restart the service.",
:methods => [:restart]
@@ -83,7 +83,7 @@ module Puppet
newparam(:binary) do
desc "The path to the daemon. This is only used for
systems that do not support init scripts. This binary will be
- used to start the service if no ``start`` parameter is
+ used to start the service if no `start` parameter is
provided."
end
@@ -94,12 +94,14 @@ module Puppet
not support any kind of status command; thus, you must specify
manually whether the service you are running has such a
command (or you can specify a specific command using the
- ``status`` parameter).
+ `status` parameter).
If you do not specify anything, then the service name will be
looked for in the process table."
newvalues(:true, :false)
+
+ defaultto :true
end
newparam(:name) do
desc "The name of the service to run. This name is used to find
@@ -140,7 +142,7 @@ module Puppet
end
newparam(:start) do
desc "Specify a *start* command manually. Most service subsystems
- support a ``start`` command, so this will not need to be
+ support a `start` command, so this will not need to be
specified."
end
newparam(:status) do
@@ -156,14 +158,14 @@ module Puppet
newparam(:control) do
desc "The control variable used to manage services (originally for HP-UX).
- Defaults to the upcased service name plus ``START`` replacing dots with
- underscores, for those providers that support the ``controllable`` feature."
+ Defaults to the upcased service name plus `START` replacing dots with
+ underscores, for those providers that support the `controllable` feature."
defaultto { resource.name.gsub(".","_").upcase + "_START" if resource.provider.controllable? }
end
newparam :hasrestart do
- desc "Specify that an init script has a ``restart`` option. Otherwise,
- the init script's ``stop`` and ``start`` methods are used."
+ desc "Specify that an init script has a `restart` option. Otherwise,
+ the init script's `stop` and `start` methods are used."
newvalues(:true, :false)
end
diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb
index 2bfa87b0f..e3320140e 100644
--- a/lib/puppet/type/ssh_authorized_key.rb
+++ b/lib/puppet/type/ssh_authorized_key.rb
@@ -34,8 +34,8 @@ module Puppet
newproperty(:target) do
desc "The absolute filename in which to store the SSH key. This
property is optional and should only be used in cases where keys
- are stored in a non-standard location (ie not in
- ~user/.ssh/authorized_keys)."
+ are stored in a non-standard location (i.e.` not in
+ `~user/.ssh/authorized_keys`)."
defaultto :absent
@@ -96,4 +96,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/sshkey.rb b/lib/puppet/type/sshkey.rb
index e1adc7173..b7a1b8a8d 100755
--- a/lib/puppet/type/sshkey.rb
+++ b/lib/puppet/type/sshkey.rb
@@ -1,8 +1,8 @@
module Puppet
newtype(:sshkey) do
@doc = "Installs and manages ssh host keys. At this point, this type
- only knows how to install keys into /etc/ssh/ssh_known_hosts, and
- it cannot manage user authorized keys yet."
+ only knows how to install keys into `/etc/ssh/ssh_known_hosts`. See
+ the `ssh_authorized_key` type to manage authorized keys."
ensurable
@@ -23,9 +23,7 @@ module Puppet
# to see if we can automatically glean any aliases.
newproperty(:host_aliases) do
desc 'Any aliases the host might have. Multiple values must be
- specified as an array. Note that this property is not the same as
- the "alias" metaparam; use this property to add aliases to a host
- on disk, and "alias" to aliases for use in your Puppet scripts.'
+ specified as an array.'
attr_accessor :meta
@@ -56,7 +54,7 @@ module Puppet
newproperty(:target) do
desc "The file in which to store the ssh key. Only used by
- the ``parsed`` provider."
+ the `parsed` provider."
defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
@resource.class.defaultprovider.default_target
@@ -67,4 +65,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/stage.rb b/lib/puppet/type/stage.rb
index d22cd7b70..0736dc4b9 100644
--- a/lib/puppet/type/stage.rb
+++ b/lib/puppet/type/stage.rb
@@ -1,11 +1,12 @@
Puppet::Type.newtype(:stage) do
desc "A resource type for specifying run stages. The actual stage should
- be specified on resources::
- class { foo: stage => pre }
+ be specified on resources:
+
+ class { foo: stage => pre }
- And you must manually control stage order::
+ And you must manually control stage order:
- stage { pre: before => Stage[main] }
+ stage { pre: before => Stage[main] }
You automatically get a 'main' stage created, and by default all resources
get inserted into that stage.
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index a6605211e..93a7e96cf 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -1,11 +1,12 @@
Puppet::Type.newtype(:tidy) do
require 'puppet/file_serving/fileset'
+ require 'puppet/file_bucket/dipper'
@doc = "Remove unwanted files based on specific criteria. Multiple
criteria are OR'd together, so a file that is too large but is not
old enough will still get tidied.
- If you don't specify either 'age' or 'size', then all files will
+ If you don't specify either `age` or `size`, then all files will
be removed.
This resource type works by generating a file resource for every file
@@ -47,7 +48,7 @@ Puppet::Type.newtype(:tidy) do
at least one of the patterns specified. Multiple patterns can
be specified using an array.
- Example::
+ Example:
tidy { \"/tmp\":
age => \"1w\",
@@ -55,7 +56,7 @@ Puppet::Type.newtype(:tidy) do
matches => [ \"[0-9]pub*.tmp\", \"*.temp\", \"tmpfile?\" ]
}
- This removes files from \/tmp if they are one week old or older,
+ This removes files from `/tmp` if they are one week old or older,
are not in a subdirectory and match one of the shell globs given.
Note that the patterns are matched against the basename of each
@@ -140,15 +141,17 @@ Puppet::Type.newtype(:tidy) do
newparam(:size) do
desc "Tidy files whose size is equal to or greater than
the specified size. Unqualified values are in kilobytes, but
- *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*,
- and *megabytes*, respectively. Only the first character is
- significant, so the full word can also be used."
+ *b*, *k*, *m*, *g*, and *t* can be appended to specify *bytes*,
+ *kilobytes*, *megabytes*, *gigabytes*, and *terabytes*, respectively.
+ Only the first character is significant, so the full word can also
+ be used."
@@sizeconvertors = {
:b => 0,
:k => 1,
:m => 2,
- :g => 3
+ :g => 3,
+ :t => 4
}
def convert(unit, multi)
diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb
index c7ac796a3..c8110bb69 100755
--- a/lib/puppet/type/user.rb
+++ b/lib/puppet/type/user.rb
@@ -12,7 +12,7 @@ module Puppet
This resource type uses the prescribed native tools for creating
groups and generally uses POSIX APIs for retrieving information
- about them. It does not directly modify /etc/passwd or anything."
+ about them. It does not directly modify `/etc/passwd` or anything."
feature :allows_duplicates,
"The provider supports duplicate users with the same UID."
@@ -24,9 +24,16 @@ module Puppet
"The provider can modify user passwords, by accepting a password
hash."
+ feature :manages_password_age,
+ "The provider can set age requirements and restrictions for
+ passwords."
+
feature :manages_solaris_rbac,
"The provider can manage roles and normal users"
+ feature :manages_expiry,
+ "The provider can manage the expiry date for a user."
+
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
newvalue(:present, :event => :user_created) do
provider.create
@@ -157,6 +164,43 @@ module Puppet
end
end
+ newproperty(:password_min_age, :required_features => :manages_password_age) do
+ desc "The minimum amount of time in days a password must be used before it may be changed"
+
+ munge do |value|
+ case value
+ when String
+ Integer(value)
+ else
+ value
+ end
+ end
+
+ validate do |value|
+ if value.to_s !~ /^\d+$/
+ raise ArgumentError, "Password minimum age must be provided as a number"
+ end
+ end
+ end
+
+ newproperty(:password_max_age, :required_features => :manages_password_age) do
+ desc "The maximum amount of time in days a password may be used before it must be changed"
+
+ munge do |value|
+ case value
+ when String
+ Integer(value)
+ else
+ value
+ end
+ end
+
+ validate do |value|
+ if value.to_s !~ /^\d+$/
+ raise ArgumentError, "Password maximum age must be provided as a number"
+ end
+ end
+ end
newproperty(:groups, :parent => Puppet::Property::List) do
desc "The groups of which the user is a member. The primary
@@ -210,6 +254,17 @@ module Puppet
end
end
+ newproperty(:expiry, :required_features => :manages_expiry) do
+ desc "The expiry date for this user. Must be provided in
+ a zero padded YYYY-MM-DD format - e.g 2010-02-19."
+
+ validate do |value|
+ if value !~ /^\d{4}-\d{2}-\d{2}$/
+ raise ArgumentError, "Expiry dates must be YYYY-MM-DD"
+ end
+ end
+ end
+
# Autorequire the group, if it's around
autorequire(:group) do
autos = []
@@ -381,4 +436,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/whit.rb b/lib/puppet/type/whit.rb
new file mode 100644
index 000000000..55bfcfb46
--- /dev/null
+++ b/lib/puppet/type/whit.rb
@@ -0,0 +1,11 @@
+Puppet::Type.newtype(:whit) do
+ desc "The smallest possible resource type, for when you need a resource and naught else."
+
+ newparam :name do
+ desc "The name of the whit, because it must have one."
+ end
+
+ def to_s
+ "Class[#{name}]"
+ end
+end
diff --git a/lib/puppet/type/yumrepo.rb b/lib/puppet/type/yumrepo.rb
index e0ed3ad37..160b2164d 100644
--- a/lib/puppet/type/yumrepo.rb
+++ b/lib/puppet/type/yumrepo.rb
@@ -52,8 +52,9 @@ module Puppet
newtype(:yumrepo) do
@doc = "The client-side description of a yum repository. Repository
- configurations are found by parsing /etc/yum.conf and
- the files indicated by reposdir in that file (see yum.conf(5) for details)
+ configurations are found by parsing `/etc/yum.conf` and
+ the files indicated by the `reposdir` option in that file
+ (see yum.conf(5) for details)
Most parameters are identical to the ones documented
in yum.conf(5)
@@ -85,7 +86,7 @@ module Puppet
clear
inifile.each_section do |s|
next if s.name == "main"
- obj = create(:name => s.name, :audit => check)
+ obj = new(:name => s.name, :audit => check)
current_values = obj.retrieve
obj.eachproperty do |property|
if current_values[property].nil?
@@ -294,6 +295,12 @@ module Puppet
newvalue(%r{(0|1)}) { }
end
+ newproperty(:http_caching, :parent => Puppet::IniProperty) do
+ desc "Either 'packages' or 'all' or 'none'.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r(packages|all|none)) { }
+ end
+
newproperty(:timeout, :parent => Puppet::IniProperty) do
desc "Number of seconds to wait for a connection before timing
out.\n#{ABSENT_DOC}"
@@ -324,6 +331,12 @@ module Puppet
newvalue(%r{[1-9][0-9]?}) { }
end
+ newproperty(:cost, :parent => Puppet::IniProperty) do
+ desc "Cost of this repository.\n#{ABSENT_DOC}"
+ newvalue(:absent) { self.should = :absent }
+ newvalue(%r{\d+}) { }
+ end
+
newproperty(:proxy, :parent => Puppet::IniProperty) do
desc "URL to the proxy server for this repository.\n#{ABSENT_DOC}"
newvalue(:absent) { self.should = :absent }
diff --git a/lib/puppet/type/zfs.rb b/lib/puppet/type/zfs.rb
index e1a972ddf..1757931f8 100755
--- a/lib/puppet/type/zfs.rb
+++ b/lib/puppet/type/zfs.rb
@@ -33,7 +33,7 @@ module Puppet
end
newproperty(:snapdir) do
- desc "The sharenfs property."
+ desc "The snapdir property."
end
autorequire(:zpool) do
@@ -48,4 +48,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb
index d523c469a..408d6f5dd 100644
--- a/lib/puppet/type/zone.rb
+++ b/lib/puppet/type/zone.rb
@@ -69,9 +69,9 @@ Puppet::Type.newtype(:zone) do
ensurable do
desc "The running state of the zone. The valid states directly reflect
- the states that ``zoneadm`` provides. The states are linear,
- in that a zone must be ``configured`` then ``installed``, and
- only then can be ``running``. Note also that ``halt`` is currently
+ the states that `zoneadm` provides. The states are linear,
+ in that a zone must be `configured` then `installed`, and
+ only then can be `running`. Note also that `halt` is currently
used to stop zones."
@states = {}
@@ -313,31 +313,31 @@ Puppet::Type.newtype(:zone) do
# only used to boot the zone the very first time.
newparam(:sysidcfg) do
desc %{The text to go into the sysidcfg file when the zone is first
- booted. The best way is to use a template::
-
- # $templatedir/sysidcfg
- system_locale=en_US
- timezone=GMT
- terminal=xterms
- security_policy=NONE
- root_password=&lt;%= password %>
- timeserver=localhost
- name_service=DNS {domain_name=&lt;%= domain %> name_server=&lt;%= nameserver %>}
- network_interface=primary {hostname=&lt;%= realhostname %>
- ip_address=&lt;%= ip %>
- netmask=&lt;%= netmask %>
- protocol_ipv6=no
- default_route=&lt;%= defaultroute %>}
- nfs4_domain=dynamic
-
- And then call that::
-
- zone { myzone:
- ip => "bge0:192.168.0.23",
- sysidcfg => template(sysidcfg),
- path => "/opt/zones/myzone",
- realhostname => "fully.qualified.domain.name"
- }
+ booted. The best way is to use a template:
+
+ # $templatedir/sysidcfg
+ system_locale=en_US
+ timezone=GMT
+ terminal=xterms
+ security_policy=NONE
+ root_password=<%= password %>
+ timeserver=localhost
+ name_service=DNS {domain_name=<%= domain %> name_server=<%= nameserver %>}
+ network_interface=primary {hostname=<%= realhostname %>
+ ip_address=<%= ip %>
+ netmask=<%= netmask %>
+ protocol_ipv6=no
+ default_route=<%= defaultroute %>}
+ nfs4_domain=dynamic
+
+ And then call that:
+
+ zone { myzone:
+ ip => "bge0:192.168.0.23",
+ sysidcfg => template(sysidcfg),
+ path => "/opt/zones/myzone",
+ realhostname => "fully.qualified.domain.name"
+ }
The sysidcfg only matters on the first booting of the zone,
so Puppet only checks for it at that time.}
diff --git a/lib/puppet/type/zpool.rb b/lib/puppet/type/zpool.rb
index 80e635504..49cce552a 100755
--- a/lib/puppet/type/zpool.rb
+++ b/lib/puppet/type/zpool.rb
@@ -44,8 +44,11 @@ module Puppet
end
newproperty(:mirror, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string.
- mirror => [\"disk1 disk2\", \"disk3 disk4\"]"
+ desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string:
+
+ mirror => [\"disk1 disk2\", \"disk3 disk4\"]
+
+ "
validate do |value|
raise ArgumentError, "mirror names must be provided as string separated, not a comma-separated list" if value.include?(",")
@@ -53,8 +56,11 @@ module Puppet
end
newproperty(:raidz, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
- desc "List of all the devices to raid for this pool. Should be an array of space separated strings.
- raidz => [\"disk1 disk2\", \"disk3 disk4\"]"
+ desc "List of all the devices to raid for this pool. Should be an array of space separated strings:
+
+ raidz => [\"disk1 disk2\", \"disk3 disk4\"]
+
+ "
validate do |value|
raise ArgumentError, "raid names must be provided as string separated, not a comma-separated list" if value.include?(",")
@@ -84,4 +90,3 @@ module Puppet
end
end
end
-
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index bb4127089..850d147e2 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -3,6 +3,7 @@
require 'puppet/util/monkey_patches'
require 'sync'
require 'puppet/external/lock'
+require 'monitor'
module Puppet
# A command failed to execute.
@@ -17,13 +18,29 @@ module Util
require 'puppet/util/posix'
extend Puppet::Util::POSIX
- # Create a hash to store the different sync objects.
- @@syncresources = {}
+ @@sync_objects = {}.extend MonitorMixin
- # Return the sync object associated with a given resource.
- def self.sync(resource)
- @@syncresources[resource] ||= Sync.new
- @@syncresources[resource]
+ def self.activerecord_version
+ if (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR))
+ ([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f)
+ else
+ 0
+ end
+ end
+
+
+ def self.synchronize_on(x,type)
+ sync_object,users = 0,1
+ begin
+ @@sync_objects.synchronize {
+ (@@sync_objects[x] ||= [Sync.new,0])[users] += 1
+ }
+ @@sync_objects[x][sync_object].synchronize(type) { yield }
+ ensure
+ @@sync_objects.synchronize {
+ @@sync_objects.delete(x) unless (@@sync_objects[x][users] -= 1) > 0
+ }
+ end
end
# Change the process to a different user
@@ -181,7 +198,7 @@ module Util
end
end
- def binary(bin)
+ def which(bin)
if bin =~ /^\//
return bin if FileTest.file? bin and FileTest.executable? bin
else
@@ -192,7 +209,7 @@ module Util
end
nil
end
- module_function :binary
+ module_function :which
# Execute the provided command in a pipe, yielding the pipe object.
def execpipe(command, failonfail = true)
@@ -351,9 +368,7 @@ module Util
# Create an exclusive lock.
def threadlock(resource, type = Sync::EX)
- Puppet::Util.sync(resource).synchronize(type) do
- yield
- end
+ Puppet::Util.synchronize_on(resource,type) { yield }
end
# Because some modules provide their own version of this method.
@@ -363,15 +378,10 @@ module Util
def memory
unless defined?(@pmap)
- pmap = %x{which pmap 2>/dev/null}.chomp
- if $CHILD_STATUS != 0 or pmap =~ /^no/
- @pmap = nil
- else
- @pmap = pmap
- end
+ @pmap = which('pmap')
end
if @pmap
- return %x{pmap #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
+ %x{#{@pmap} #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i
else
0
end
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