summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xext/module:puppet195
-rw-r--r--lib/puppet/parser/interpreter.rb6
-rw-r--r--lib/puppet/parser/scope.rb10
-rw-r--r--lib/puppet/server/master.rb5
-rwxr-xr-xtest/executables/puppetbin.rb4
-rwxr-xr-xtest/executables/puppetmodule.rb60
6 files changed, 276 insertions, 4 deletions
diff --git a/ext/module:puppet b/ext/module:puppet
new file mode 100755
index 000000000..151fac4c9
--- /dev/null
+++ b/ext/module:puppet
@@ -0,0 +1,195 @@
+#!/usr/bin/ruby
+
+#
+# = Synopsis
+#
+# Run a +puppet+ script as a cfengine module.
+#
+# = Usage
+#
+# puppet [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose]
+# [-l|--logfile <file>] [-p|--parse-only] <file>
+# [-c|--confdir <configuration directory>] [--vardir <var directory>]
+#
+# = Description
+#
+# This is the standalone puppet execution script; use it to execute
+# individual scripts that you write. If you need to execute site-wide
+# scripts, use +puppetd+ and +puppetmasterd+.
+#
+# = Options
+#
+# confdir::
+# The configuration root directory, where +puppetmasterd+ defaults to looking
+# for all of its configuration files. Defaults to +/etc/puppet+.
+#
+# debug::
+# Enable full debugging.
+#
+# help::
+# Print this help message
+#
+# logfile::
+# Where to send messages. Choose between syslog, the console, and a log file.
+# Defaults to sending messages to the console.
+#
+# parse-only::
+# Just verify syntax, do not apply anything.
+#
+# vardir::
+# The variable-size directory, used for storing state. Defaults to
+# /var/puppet.
+#
+# verbose::
+# Print extra information.
+#
+# = Author
+#
+# Luke Kanies
+#
+# = Copyright
+#
+# Copyright (c) 2005 Reductive Labs, LLC
+# Licensed under the GNU Public License
+
+require 'puppet'
+require 'puppet/server'
+require 'puppet/client'
+require 'getoptlong'
+
+$haveusage = true
+
+begin
+ require 'rdoc/usage'
+rescue LoadError
+ $haveusage = false
+end
+
+result = GetoptLong.new(
+ [ "--confdir", "-c", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
+ [ "--help", "-h", GetoptLong::NO_ARGUMENT ],
+ [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
+ [ "--noop", "-n", GetoptLong::NO_ARGUMENT ],
+ [ "--use-nodes", GetoptLong::NO_ARGUMENT ],
+ [ "--parse-only", "-p", GetoptLong::NO_ARGUMENT ],
+ [ "--vardir", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--version", "-V", GetoptLong::NO_ARGUMENT ]
+)
+
+debug = false
+verbose = false
+noop = false
+logfile = false
+parseonly = false
+
+master = {
+ :Local => true
+}
+
+# We default to a non-console log destination, because we assume this is being
+# run non-interactively.
+#Puppet[:logdest] = :console
+
+begin
+ result.each { |opt,arg|
+ case opt
+ when "--confdir"
+ Puppet[:puppetconf] = arg
+ when "--version"
+ puts "%s" % Puppet.version
+ exit
+ when "--help"
+ if $haveusage
+ RDoc::usage && exit
+ else
+ puts "No help available unless you have RDoc::usage installed"
+ exit
+ end
+ when "--noop"
+ Puppet[:noop] = true
+ when "--use-nodes"
+ master[:UseNodes] = true
+ when "--verbose"
+ verbose = true
+ when "--parse-only"
+ parseonly = true
+ when "--debug"
+ debug = true
+ when "--logdest"
+ begin
+ Puppet[:logdest] = arg
+ rescue => detail
+ $stderr.puts detail.to_s
+ end
+ when "--vardir"
+ Puppet[:puppetvar] = arg
+ end
+ }
+rescue GetoptLong::InvalidOption => detail
+ $stderr.puts "Try '#{$0} --help'"
+ #if $haveusage
+ # RDoc::usage(1,'usage')
+ #end
+ exit(1)
+end
+
+if debug
+ Puppet[:loglevel] = :debug
+elsif verbose
+ Puppet[:loglevel] = :info
+end
+
+unless ARGV.length > 0
+ $stderr.puts "You must pass a script to parse"
+ exit(14)
+end
+
+master[:File] = ARGV.shift
+
+unless ENV.include?("CFALLCLASSES")
+ $stderr.puts "Cfengine classes must be passed to the module"
+ exit(15)
+end
+
+master[:UseNodes] = false
+
+classes = ENV["CFALLCLASSES"].split(":")
+
+if classes.empty?
+ $stderr.puts "Could not find any cfengine classes"
+ exit(16)
+end
+
+master[:Classes] = classes
+
+begin
+ server = Puppet::Server::Master.new(master)
+rescue => detail
+ $stderr.puts detail
+ exit(1)
+end
+
+begin
+ client = Puppet::Client::MasterClient.new(
+ :Master => server,
+ :Cache => false
+ )
+rescue => detail
+ $stderr.puts detail
+ exit(1)
+end
+
+
+if parseonly
+ exit(0)
+end
+
+begin
+ client.getconfig
+ client.apply
+rescue => detail
+ Puppet.err detail
+ exit(1)
+end
diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb
index 557af958b..6a8a333e8 100644
--- a/lib/puppet/parser/interpreter.rb
+++ b/lib/puppet/parser/interpreter.rb
@@ -28,6 +28,10 @@ module Puppet
@usenodes = true
end
+ # Set it to either the value or nil. This is currently only used
+ # by the cfengine module.
+ @classes = hash[:Classes] || []
+
# Create our parser object
parsefiles
@@ -64,7 +68,7 @@ module Puppet
@scope.interp = self
@scope.type = "puppet"
@scope.name = "top"
- return @scope.evaluate(@ast, facts)
+ return @scope.evaluate(@ast, facts, @classes)
end
#@ast.evaluate(@scope)
rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 93d97e396..c5ee0226a 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -233,13 +233,21 @@ module Puppet
# silly method, in that it just calls evaluate on the passed-in
# objects, and then calls to_trans on itself. It just conceals
# a paltry amount of info from whomever's using the scope object.
- def evaluate(objects, facts = {})
+ def evaluate(objects, facts = {}, classes = [])
facts.each { |var, value|
self.setvar(var, value)
}
objects.safeevaluate(self)
+ # These classes would be passed in manually, via something like
+ # a cfengine module
+ classes.each { |klass|
+ if code = self.lookuptype(klass)
+ code.safeevaluate(self, {}, klass, klass)
+ end
+ }
+
return self.to_trans
end
diff --git a/lib/puppet/server/master.rb b/lib/puppet/server/master.rb
index 261d93d97..e86663d0f 100644
--- a/lib/puppet/server/master.rb
+++ b/lib/puppet/server/master.rb
@@ -44,6 +44,11 @@ class Server
args[:UseNodes] = false
end
+ # This is only used by the cfengine module
+ if hash.include?(:Classes)
+ args[:Classes] = hash[:Classes]
+ end
+
begin
@interpreter = Puppet::Parser::Interpreter.new(args)
rescue => detail
diff --git a/test/executables/puppetbin.rb b/test/executables/puppetbin.rb
index 3f9ebda78..4c1d2a24c 100755
--- a/test/executables/puppetbin.rb
+++ b/test/executables/puppetbin.rb
@@ -4,8 +4,6 @@ if __FILE__ == $0
$puppetbase = "../.."
end
-# $ID: $
-
require 'puppet'
require 'puppet/server'
require 'puppet/sslcertificates'
@@ -51,3 +49,5 @@ class TestPuppetBin < Test::Unit::TestCase
assert(FileTest.exists?(@createdfile), "Failed to create config'ed file")
end
end
+
+# $Id: $
diff --git a/test/executables/puppetmodule.rb b/test/executables/puppetmodule.rb
new file mode 100755
index 000000000..ba356f6cc
--- /dev/null
+++ b/test/executables/puppetmodule.rb
@@ -0,0 +1,60 @@
+if __FILE__ == $0
+ $:.unshift '../../lib'
+ $:.unshift '..'
+ $puppetbase = "../.."
+end
+
+require 'puppet'
+require 'puppet/server'
+require 'puppet/sslcertificates'
+require 'test/unit'
+require 'puppettest.rb'
+
+# add the bin directory to our search path
+ENV["PATH"] += ":" + File.join($puppetbase, "bin")
+
+# and then the library directories
+libdirs = $:.find_all { |dir|
+ dir =~ /puppet/ or dir =~ /\.\./
+}
+ENV["RUBYLIB"] = libdirs.join(":")
+
+$module = File.join($puppetbase, "ext", "module:puppet")
+
+class TestPuppetModule < Test::Unit::TestCase
+ include ServerTest
+
+ def test_execution
+ file = tempfile()
+
+ createdfile = tempfile()
+
+ File.open(file, "w") { |f|
+ f.puts "class yaytest { file { \"#{createdfile}\": create => true } }"
+ }
+
+ output = nil
+ cmd = $module
+ cmd += " --verbose"
+ #cmd += " --fqdn %s" % fqdn
+ cmd += " --confdir %s" % Puppet[:puppetconf]
+ cmd += " --vardir %s" % Puppet[:puppetvar]
+ if Puppet[:debug]
+ cmd += " --logdest %s" % "console"
+ else
+ cmd += " --logdest %s" % "/dev/null"
+ end
+
+ ENV["CFALLCLASSES"] = "yaytest:all"
+
+ Puppet.err :mark
+ assert_nothing_raised {
+ system(cmd + " " + file)
+ }
+ assert($? == 0, "Puppet module exited with code %s" % $?.to_i)
+
+ assert(FileTest.exists?(createdfile), "Failed to create config'ed file")
+ end
+end
+
+# $Id$