summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@reductivelabs.com>2009-12-21 16:23:44 -0800
committerLuke Kanies <luke@reductivelabs.com>2009-12-21 16:23:44 -0800
commit740fd6b301af89ab3aad89bca183ad1fcdc24ac4 (patch)
treef34617a229509c373d28d67abb453e7ae2136c39 /lib
parent8971d8beae2c409f9052f27c3f80ad3bdfff4de2 (diff)
parent4a06379f8770c164e42bcc410d874076c6e95f24 (diff)
downloadpuppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.tar.gz
puppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.tar.xz
puppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.zip
Merge branch '0.25.x'
Conflicts: lib/puppet/agent.rb lib/puppet/application/puppetd.rb lib/puppet/parser/ast/leaf.rb lib/puppet/util/rdoc/parser.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/agent.rb4
-rw-r--r--lib/puppet/application/puppetd.rb9
-rw-r--r--lib/puppet/application/puppetdoc.rb7
-rw-r--r--lib/puppet/configurer.rb10
-rw-r--r--lib/puppet/configurer/fact_handler.rb9
-rw-r--r--lib/puppet/defaults.rb12
-rw-r--r--lib/puppet/external/pson/common.rb2
-rw-r--r--lib/puppet/external/pson/pure.rb4
-rw-r--r--lib/puppet/file_serving/base.rb17
-rw-r--r--lib/puppet/file_serving/configuration.rb4
-rw-r--r--lib/puppet/file_serving/metadata.rb45
-rw-r--r--lib/puppet/indirector/catalog/active_record.rb5
-rw-r--r--lib/puppet/indirector/facts/facter.rb2
-rw-r--r--lib/puppet/indirector/ldap.rb2
-rw-r--r--lib/puppet/indirector/node/ldap.rb2
-rwxr-xr-xlib/puppet/network/authstore.rb5
-rw-r--r--lib/puppet/network/format_handler.rb2
-rw-r--r--lib/puppet/network/formats.rb50
-rw-r--r--lib/puppet/network/http/rack/httphandler.rb18
-rw-r--r--lib/puppet/network/http/rack/rest.rb8
-rw-r--r--lib/puppet/network/http/rack/xmlrpc.rb8
-rw-r--r--lib/puppet/network/http_server/webrick.rb5
-rw-r--r--lib/puppet/node/environment.rb29
-rw-r--r--lib/puppet/parameter.rb18
-rw-r--r--lib/puppet/parser/ast/boolean_operator.rb4
-rw-r--r--lib/puppet/parser/collector.rb22
-rw-r--r--lib/puppet/parser/functions/generate.rb4
-rw-r--r--lib/puppet/parser/functions/require.rb5
-rw-r--r--lib/puppet/parser/functions/versioncmp.rb2
-rw-r--r--lib/puppet/parser/resource.rb6
-rwxr-xr-xlib/puppet/provider/package/dpkg.rb2
-rw-r--r--lib/puppet/provider/package/portage.rb50
-rw-r--r--lib/puppet/provider/package/rug.rb2
-rw-r--r--lib/puppet/provider/package/up2date.rb2
-rw-r--r--lib/puppet/provider/package/urpmi.rb2
-rw-r--r--lib/puppet/provider/service/daemontools.rb2
-rwxr-xr-xlib/puppet/provider/service/debian.rb2
-rw-r--r--lib/puppet/provider/service/runit.rb2
-rw-r--r--lib/puppet/provider/ssh_authorized_key/parsed.rb3
-rw-r--r--lib/puppet/provider/zone/solaris.rb17
-rw-r--r--lib/puppet/rails.rb4
-rw-r--r--lib/puppet/rails/resource.rb2
-rw-r--r--lib/puppet/resource/catalog.rb6
-rw-r--r--lib/puppet/resource/reference.rb34
-rw-r--r--lib/puppet/ssl/certificate_revocation_list.rb2
-rw-r--r--lib/puppet/ssl/host.rb5
-rw-r--r--lib/puppet/sslcertificates/ca.rb9
-rw-r--r--lib/puppet/transaction.rb27
-rw-r--r--lib/puppet/type.rb17
-rwxr-xr-xlib/puppet/type/cron.rb2
-rw-r--r--lib/puppet/type/file.rb52
-rwxr-xr-xlib/puppet/type/file/content.rb10
-rwxr-xr-xlib/puppet/type/file/mode.rb19
-rwxr-xr-xlib/puppet/type/file/owner.rb11
-rw-r--r--lib/puppet/type/k5login.rb2
-rwxr-xr-xlib/puppet/type/maillist.rb11
-rw-r--r--lib/puppet/type/resources.rb24
-rwxr-xr-xlib/puppet/type/tidy.rb11
-rw-r--r--lib/puppet/util.rb5
-rw-r--r--lib/puppet/util/log.rb4
-rw-r--r--lib/puppet/util/methodhelper.rb7
-rw-r--r--lib/puppet/util/monkey_patches.rb8
-rw-r--r--lib/puppet/util/rdoc/parser.rb17
-rw-r--r--lib/puppet/util/selinux.rb23
-rw-r--r--lib/puppet/util/subclass_loader.rb2
-rw-r--r--lib/puppet/util/suidmanager.rb12
-rw-r--r--lib/puppet/util/tagging.rb26
67 files changed, 488 insertions, 268 deletions
diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb
index 7bd97415f..09607372f 100644
--- a/lib/puppet/agent.rb
+++ b/lib/puppet/agent.rb
@@ -52,7 +52,7 @@ class Puppet::Agent
with_client do |client|
begin
sync.synchronize { lock { result = client.run(*args) } }
- rescue => detail
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not run %s: %s" % [client_class, detail]
end
@@ -124,7 +124,7 @@ class Puppet::Agent
def with_client
begin
@client = client_class.new
- rescue => detail
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not create instance of %s: %s" % [client_class, detail]
return
diff --git a/lib/puppet/application/puppetd.rb b/lib/puppet/application/puppetd.rb
index c1f733183..9302cf105 100644
--- a/lib/puppet/application/puppetd.rb
+++ b/lib/puppet/application/puppetd.rb
@@ -137,7 +137,7 @@ Puppet::Application.new(:puppetd) do
options[:verbose] = true
options[:onetime] = true
options[:detailed_exitcodes] = true
- options[:waitforcert] = 0
+ options[:waitforcert] = 0 unless @explicit_waitforcert
end
# Handle the logging settings.
@@ -172,13 +172,6 @@ Puppet::Application.new(:puppetd) do
exit(14)
end
- # FIXME: we should really figure out how to distribute the CRL
- # to clients. In the meantime, we just disable CRL checking if
- # the CRL file doesn't exist
- unless File::exist?(Puppet[:cacrl])
- Puppet[:cacrl] = 'false'
- end
-
handlers = nil
if options[:serve].empty?
diff --git a/lib/puppet/application/puppetdoc.rb b/lib/puppet/application/puppetdoc.rb
index a5496ccee..0a4e0c3c3 100644
--- a/lib/puppet/application/puppetdoc.rb
+++ b/lib/puppet/application/puppetdoc.rb
@@ -66,8 +66,9 @@ Puppet::Application.new(:puppetdoc) do
exit_code = 0
files = []
unless @manifest
- files += Puppet[:modulepath].split(':').collect { |p| File.expand_path(p) }
- files += Puppet[:manifestdir].split(':').collect { |p| File.expand_path(p) }
+ env = Puppet::Node::Environment.new
+ files += env.modulepath
+ files += env.manifestdir
end
files += ARGV
Puppet.info "scanning: %s" % files.inspect
@@ -191,7 +192,7 @@ Puppet::Application.new(:puppetdoc) do
end
end
- def setup_rdoc
+ def setup_rdoc(dummy_argument=:work_arround_for_ruby_GC_bug)
# consume the unknown options
# and feed them as settings
if @unknown_args.size > 0
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index b63df0754..72aef91c0 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -93,7 +93,7 @@ class Puppet::Configurer
duration = thinmark do
result = catalog_class.find(name, fact_options.merge(:ignore_cache => true))
end
- rescue => detail
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not retrieve catalog from remote server: %s" % detail
end
@@ -123,6 +123,7 @@ class Puppet::Configurer
# Convert a plain resource catalog into our full host catalog.
def convert_catalog(result, duration)
catalog = result.to_ral
+ catalog.finalize
catalog.retrieval_duration = duration
catalog.host_config = true
catalog.write_class_file
@@ -133,7 +134,12 @@ class Puppet::Configurer
# This just passes any options on to the catalog,
# which accepts :tags and :ignoreschedules.
def run(options = {})
- prepare()
+ begin
+ prepare()
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Failed to prepare catalog: %s" % detail
+ end
if catalog = options[:catalog]
options.delete(:catalog)
diff --git a/lib/puppet/configurer/fact_handler.rb b/lib/puppet/configurer/fact_handler.rb
index 43e9f35f4..cbb627680 100644
--- a/lib/puppet/configurer/fact_handler.rb
+++ b/lib/puppet/configurer/fact_handler.rb
@@ -11,14 +11,13 @@ module Puppet::Configurer::FactHandler
end
def find_facts
- reload_facter()
-
# This works because puppetd configures Facts to use 'facter' for
# finding facts and the 'rest' terminus for caching them. Thus, we'll
# compile them and then "cache" them on the server.
begin
+ reload_facter()
Puppet::Node::Facts.find(Puppet[:certname])
- rescue => detail
+ rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
raise Puppet::Error, "Could not retrieve local facts: %s" % detail
end
@@ -29,11 +28,11 @@ module Puppet::Configurer::FactHandler
#format = facts.class.default_format
# Hard-code yaml, because I couldn't get marshal to work.
- format = :yaml
+ format = :b64_zlib_yaml
text = facts.render(format)
- return {:facts_format => format, :facts => CGI.escape(text)}
+ return {:facts_format => :b64_zlib_yaml, :facts => CGI.escape(text)}
end
# Retrieve facts from the central server.
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 590de83fd..050fcaa7e 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -527,6 +527,18 @@ module Puppet
authority requests. It's a separate server because it cannot
and does not need to horizontally scale."],
:ca_port => ["$masterport", "The port to use for the certificate authority."],
+ :catalog_format => {
+ :default => "",
+ :desc => "(Deprecated for 'preferred_serialization_format') What format to
+ use to dump the catalog. Only supports 'marshal' and 'yaml'. Only
+ matters on the client, since it asks the server for a specific format.",
+ :hook => proc { |value|
+ if value
+ Puppet.warning "Setting 'catalog_format' is deprecated; use 'preferred_serialization_format' instead."
+ Puppet.settings[:preferred_serialization_format] = value
+ end
+ }
+ },
:preferred_serialization_format => ["pson", "The preferred means of serializing
ruby instances for passing over the wire. This won't guarantee that all
instances will be serialized using this method, since not all classes
diff --git a/lib/puppet/external/pson/common.rb b/lib/puppet/external/pson/common.rb
index 71b85ce54..87bce988b 100644
--- a/lib/puppet/external/pson/common.rb
+++ b/lib/puppet/external/pson/common.rb
@@ -48,7 +48,7 @@ module PSON
case
when c.empty? then p
when p.const_defined?(c) then p.const_get(c)
- else raise ArgumentError, "can't find const #{path}"
+ else raise ArgumentError, "can't find const for unregistered document type #{path}"
end
end
end
diff --git a/lib/puppet/external/pson/pure.rb b/lib/puppet/external/pson/pure.rb
index 43f39b2a6..7bb18aa70 100644
--- a/lib/puppet/external/pson/pure.rb
+++ b/lib/puppet/external/pson/pure.rb
@@ -11,8 +11,8 @@ module PSON
UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
UTF8toUTF16.iconv('no bom')
rescue LoadError
- raise MissingUnicodeSupport,
- "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
+ # We actually don't care
+ Puppet.warning "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
rescue Errno::EINVAL, Iconv::InvalidEncoding
# Iconv doesn't support big endian utf-16. Let's try to hack this manually
# into the converters.
diff --git a/lib/puppet/file_serving/base.rb b/lib/puppet/file_serving/base.rb
index c82bb1992..a7ab9b66e 100644
--- a/lib/puppet/file_serving/base.rb
+++ b/lib/puppet/file_serving/base.rb
@@ -22,7 +22,7 @@ class Puppet::FileServing::Base
end
# Return the full path to our file. Fails if there's no path set.
- def full_path
+ def full_path(dummy_argument=:work_arround_for_ruby_GC_bug)
(if relative_path.nil? or relative_path == "" or relative_path == "."
path
else
@@ -74,4 +74,19 @@ class Puppet::FileServing::Base
end
File.send(@stat_method, full_path())
end
+
+ def to_pson_data_hash
+ {
+ # No 'document_type' since we don't send these bare
+ 'data' => {
+ 'path' => @path,
+ 'relative_path' => @relative_path,
+ 'links' => @links
+ },
+ 'metadata' => {
+ 'api_version' => 1
+ }
+ }
+ end
+
end
diff --git a/lib/puppet/file_serving/configuration.rb b/lib/puppet/file_serving/configuration.rb
index ac54a7a8a..9034caed1 100644
--- a/lib/puppet/file_serving/configuration.rb
+++ b/lib/puppet/file_serving/configuration.rb
@@ -96,9 +96,9 @@ class Puppet::FileServing::Configuration
def mk_default_mounts
@mounts["modules"] ||= Mount::Modules.new("modules")
- @mounts["modules"].allow('*')
+ @mounts["modules"].allow('*') if @mounts["modules"].empty?
@mounts["plugins"] ||= Mount::Plugins.new("plugins")
- @mounts["plugins"].allow('*')
+ @mounts["plugins"].allow('*') if @mounts["plugins"].empty?
end
# Read the configuration file.
diff --git a/lib/puppet/file_serving/metadata.rb b/lib/puppet/file_serving/metadata.rb
index 335dad497..275a090eb 100644
--- a/lib/puppet/file_serving/metadata.rb
+++ b/lib/puppet/file_serving/metadata.rb
@@ -71,8 +71,47 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
end
end
- def initialize(*args)
- @checksum_type = "md5"
- super
+ def initialize(path,data={})
+ @owner = data.delete('owner')
+ @group = data.delete('group')
+ @mode = data.delete('mode')
+ if checksum = data.delete('checksum')
+ @checksum_type = checksum['type']
+ @checksum = checksum['value']
+ end
+ @checksum_type ||= "md5"
+ @ftype = data.delete('type')
+ @destination = data.delete('destination')
+ super(path,data)
+ end
+
+ PSON.register_document_type('FileMetadata',self)
+ def to_pson_data_hash
+ {
+ 'document_type' => 'FileMetadata',
+ 'data' => super['data'].update({
+ 'owner' => owner,
+ 'group' => group,
+ 'mode' => mode,
+ 'checksum' => {
+ 'type' => checksum_type,
+ 'value' => checksum
+ },
+ 'type' => ftype,
+ 'destination' => destination,
+ }),
+ 'metadata' => {
+ 'api_version' => 1
+ }
+ }
+ end
+
+ def to_pson(*args)
+ to_pson_data_hash.to_pson(*args)
+ end
+
+ def self.from_pson(data)
+ new(data.delete('path'), data)
end
+
end
diff --git a/lib/puppet/indirector/catalog/active_record.rb b/lib/puppet/indirector/catalog/active_record.rb
index e3b56ece6..575ce72fb 100644
--- a/lib/puppet/indirector/catalog/active_record.rb
+++ b/lib/puppet/indirector/catalog/active_record.rb
@@ -30,6 +30,11 @@ class Puppet::Resource::Catalog::ActiveRecord < Puppet::Indirector::ActiveRecord
host.merge_resources(catalog.vertices)
host.last_compile = Time.now
+ if node = Puppet::Node.find(catalog.name)
+ host.ip = node.parameters["ipaddress"]
+ host.environment = node.environment
+ end
+
host.save
end
end
diff --git a/lib/puppet/indirector/facts/facter.rb b/lib/puppet/indirector/facts/facter.rb
index 9df71fcac..6c6cbc6be 100644
--- a/lib/puppet/indirector/facts/facter.rb
+++ b/lib/puppet/indirector/facts/facter.rb
@@ -29,7 +29,7 @@ class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
Timeout::timeout(self.timeout) do
load file
end
- rescue => detail
+ rescue Exception => detail
Puppet.warning "Could not load fact file %s: %s" % [fqfile, detail]
end
end
diff --git a/lib/puppet/indirector/ldap.rb b/lib/puppet/indirector/ldap.rb
index 7485bd932..51bab0e6e 100644
--- a/lib/puppet/indirector/ldap.rb
+++ b/lib/puppet/indirector/ldap.rb
@@ -40,7 +40,7 @@ class Puppet::Indirector::Ldap < Puppet::Indirector::Terminus
found = true
yield entry
end
- rescue => detail
+ rescue Exception => detail
if count == 0
# Try reconnecting to ldap if we get an exception and we haven't yet retried.
count += 1
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index 4600a0dd5..dd8cebfac 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -73,7 +73,7 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# The attributes that Puppet will stack as array over the full
# hierarchy.
- def stacked_attributes
+ def stacked_attributes(dummy_argument=:work_arround_for_ruby_GC_bug)
Puppet[:ldapstackedattrs].split(/\s*,\s*/)
end
diff --git a/lib/puppet/network/authstore.rb b/lib/puppet/network/authstore.rb
index ab31faec8..fb3d0145b 100755
--- a/lib/puppet/network/authstore.rb
+++ b/lib/puppet/network/authstore.rb
@@ -63,6 +63,11 @@ module Puppet
@globalallow
end
+ # does this auth store has any rules?
+ def empty?
+ @globalallow.nil? && @declarations.size == 0
+ end
+
def initialize
@globalallow = nil
@declarations = []
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index 2ffbcef3d..e508a0283 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -129,6 +129,8 @@ module Puppet::Network::FormatHandler
if list.include?(preferred_format)
list.delete(preferred_format)
list.unshift(preferred_format)
+ else
+ Puppet.warning "Value of 'preferred_serialization_format' ('#{preferred_format}') is invalid, using default ('#{list.first}')"
end
list
end
diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index df6ef399c..010c23521 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -39,6 +39,56 @@ Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
end
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
+ require 'base64'
+ require 'zlib'
+
+ def intern(klass, text)
+ decode(text)
+ end
+
+ def intern_multiple(klass, text)
+ decode(text)
+ end
+
+ def render(instance)
+ yaml = instance.to_yaml
+
+ yaml = encode(fixup(yaml)) unless yaml.nil?
+ yaml
+ end
+
+ def render_multiple(instances)
+ yaml = instances.to_yaml
+
+ yaml = encode(fixup(yaml)) unless yaml.nil?
+ yaml
+ end
+
+ # Because of yaml issue in ruby 1.8.1...
+ def supported?(klass)
+ RUBY_VERSION != '1.8.1'
+ end
+
+ # fixup invalid yaml as per:
+ # http://redmine.ruby-lang.org/issues/show/1331
+ def fixup(yaml)
+ yaml.gsub!(/((?:&id\d+\s+)?!ruby\/object:.*?)\s*\?/) { "? #{$1}" }
+ yaml
+ end
+
+ def encode(text)
+ Base64.encode64(Zlib::Deflate.deflate(text, Zlib::BEST_COMPRESSION))
+ end
+
+ def decode(yaml)
+ YAML.load(Zlib::Inflate.inflate(Base64.decode64(yaml)))
+ end
+end
+
Puppet::Network::FormatHandler.create(:marshal, :mime => "text/marshal") do
# Marshal doesn't need the class name; it's serialized.
diff --git a/lib/puppet/network/http/rack/httphandler.rb b/lib/puppet/network/http/rack/httphandler.rb
index 31aa8371e..e14206850 100644
--- a/lib/puppet/network/http/rack/httphandler.rb
+++ b/lib/puppet/network/http/rack/httphandler.rb
@@ -12,23 +12,5 @@ class Puppet::Network::HTTP::RackHttpHandler
raise NotImplementedError, "Your RackHttpHandler subclass is supposed to override service(request)"
end
- def ssl_client_header(request)
- env_or_request_env(Puppet[:ssl_client_header], request)
- end
-
- def ssl_client_verify_header(request)
- env_or_request_env(Puppet[:ssl_client_verify_header], request)
- end
-
- # Older Passenger versions passed all Environment vars in app(env),
- # but since 2.2.3 they (some?) are really in ENV.
- # Mongrel, etc. may also still use request.env.
- def env_or_request_env(var, request)
- if ENV.include?(var)
- ENV[var]
- else
- request.env[var]
- end
- end
end
diff --git a/lib/puppet/network/http/rack/rest.rb b/lib/puppet/network/http/rack/rest.rb
index bdca651d1..104751271 100644
--- a/lib/puppet/network/http/rack/rest.rb
+++ b/lib/puppet/network/http/rack/rest.rb
@@ -63,11 +63,11 @@ class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
result[:ip] = request.ip
# if we find SSL info in the headers, use them to get a hostname.
- # try this with :ssl_client_header.
- # For Apache you need special configuration, see ext/rack/README.
- if dn = ssl_client_header(request) and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ # try this with :ssl_client_header, which defaults should work for
+ # Apache with StdEnvVars.
+ if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
result[:node] = dn_matchdata[1].to_str
- result[:authenticated] = (ssl_client_verify_header(request) == 'SUCCESS')
+ result[:authenticated] = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
else
result[:node] = resolve_node(result)
result[:authenticated] = false
diff --git a/lib/puppet/network/http/rack/xmlrpc.rb b/lib/puppet/network/http/rack/xmlrpc.rb
index 9d0f486bc..4fc9e82fc 100644
--- a/lib/puppet/network/http/rack/xmlrpc.rb
+++ b/lib/puppet/network/http/rack/xmlrpc.rb
@@ -43,11 +43,11 @@ class Puppet::Network::HTTP::RackXMLRPC < Puppet::Network::HTTP::RackHttpHandler
ip = request.ip
# if we find SSL info in the headers, use them to get a hostname.
- # try this with :ssl_client_header.
- # For Apache you need special configuration, see ext/rack/README.
- if dn = ssl_client_header(request) and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ # try this with :ssl_client_header, which defaults should work for
+ # Apache with StdEnvVars.
+ if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
node = dn_matchdata[1].to_str
- authenticated = (ssl_client_verify_header(request) == 'SUCCESS')
+ authenticated = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
else
begin
node = Resolv.getname(ip)
diff --git a/lib/puppet/network/http_server/webrick.rb b/lib/puppet/network/http_server/webrick.rb
index a863d3a20..2dae9ccd8 100644
--- a/lib/puppet/network/http_server/webrick.rb
+++ b/lib/puppet/network/http_server/webrick.rb
@@ -21,13 +21,10 @@ module Puppet
# with them, with flags appropriate for checking client
# certificates for revocation
def x509store
- if Puppet[:cacrl] == 'false'
+ unless File.exist?(Puppet[:cacrl])
# No CRL, no store needed
return nil
end
- unless File.exist?(Puppet[:cacrl])
- raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'false' to disable CRL usage"
- end
crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
store = OpenSSL::X509::Store.new
store.purpose = OpenSSL::X509::PURPOSE_ANY
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index 133f22c77..94f899200 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -55,15 +55,7 @@ class Puppet::Node::Environment
if ENV["PUPPETLIB"]
dirs = ENV["PUPPETLIB"].split(File::PATH_SEPARATOR) + dirs
end
- dirs.collect do |dir|
- if dir !~ /^#{File::SEPARATOR}/
- File.join(Dir.getwd, dir)
- else
- dir
- end
- end.find_all do |p|
- p =~ /^#{File::SEPARATOR}/ && FileTest.directory?(p)
- end
+ validate_dirs(dirs)
end
# Return all modules from this environment.
@@ -73,7 +65,26 @@ class Puppet::Node::Environment
module_names.collect { |path| Puppet::Module.new(path, self) rescue nil }.compact
end
+ # Cache the manifestdir, so that we aren't searching through
+ # all known directories all the time.
+ cached_attr(:manifestdir, :ttl => Puppet[:filetimeout]) do
+ validate_dirs(self[:manifestdir].split(File::PATH_SEPARATOR))
+ end
+
def to_s
name.to_s
end
+
+ def validate_dirs(dirs)
+ dirs.collect do |dir|
+ if dir !~ /^#{File::SEPARATOR}/
+ File.join(Dir.getwd, dir)
+ else
+ dir
+ end
+ end.find_all do |p|
+ p =~ /^#{File::SEPARATOR}/ && FileTest.directory?(p)
+ end
+ end
+
end
diff --git a/lib/puppet/parameter.rb b/lib/puppet/parameter.rb
index f4086671d..58a91477a 100644
--- a/lib/puppet/parameter.rb
+++ b/lib/puppet/parameter.rb
@@ -293,6 +293,13 @@ class Puppet::Parameter
define_method(:unmunge, &block)
end
+ # Optionaly convert the value to a canonical form so that it will
+ # be found in hashes, etc. Mostly useful for namevars.
+ def to_canonicalize(&block)
+ metaclass = (class << self; self; end)
+ metaclass.send(:define_method,:canonicalize,&block)
+ end
+
# Mark whether we're the namevar.
def isnamevar
@isnamevar = true
@@ -464,10 +471,19 @@ class Puppet::Parameter
value
end
+ # Assume the value is already in canonical form by default
+ def self.canonicalize(value)
+ value
+ end
+
+ def canonicalize(value)
+ self.class.canonicalize(value)
+ end
+
# A wrapper around our munging that makes sure we raise useful exceptions.
def munge(value)
begin
- ret = unsafe_munge(value)
+ ret = unsafe_munge(canonicalize(value))
rescue Puppet::Error => detail
Puppet.debug "Reraising %s" % detail
raise
diff --git a/lib/puppet/parser/ast/boolean_operator.rb b/lib/puppet/parser/ast/boolean_operator.rb
index 160e0e69e..89725d73b 100644
--- a/lib/puppet/parser/ast/boolean_operator.rb
+++ b/lib/puppet/parser/ast/boolean_operator.rb
@@ -20,14 +20,14 @@ class Puppet::Parser::AST
# return result
# lazy evaluate right operand
case @operator
- when "and";
+ when "and"
if Puppet::Parser::Scope.true?(lval)
rval = @rval.safeevaluate(scope)
Puppet::Parser::Scope.true?(rval)
else # false and false == false
false
end
- when "or";
+ when "or"
if Puppet::Parser::Scope.true?(lval)
true
else
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index a7f81b4e7..a6763c419 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -102,18 +102,24 @@ class Puppet::Parser::Collector
raise Puppet::DevError, "Cannot collect resources for a nil host" unless @scope.host
host = Puppet::Rails::Host.find_by_name(@scope.host)
- query = {:include => {:param_values => :param_name}}
-
search = "(exported=? AND restype=?)"
values = [true, @type]
search += " AND (%s)" % @equery if @equery
- # this is a small performance optimisation
- # the tag mechanism involves 3 more joins, which are
- # needed only if we query on tags.
- if search =~ /puppet_tags/
- query[:include][:puppet_tags] = :resource_tags
+ # note:
+ # we're not eagerly including any relations here because
+ # it can creates so much objects we'll throw out later.
+ # We used to eagerly include param_names/values but the way
+ # the search filter is built ruined those efforts and we
+ # were eagerly loading only the searched parameter and not
+ # the other ones.
+ query = {}
+ case search
+ when /puppet_tags/
+ query = {:joins => {:resource_tags => :puppet_tag}}
+ when /param_name/
+ query = {:joins => {:param_values => :param_name}}
end
# We're going to collect objects from rails, but we don't want any
@@ -139,7 +145,7 @@ class Puppet::Parser::Collector
# and such, we'll need to vary the conditions, but this works with no
# attributes, anyway.
time = Puppet::Util.thinmark do
- Puppet::Rails::Resource.find(:all, @type, true, query).each do |obj|
+ Puppet::Rails::Resource.find(:all, query).each do |obj|
if resource = exported_resource(obj)
count += 1
resources << resource
diff --git a/lib/puppet/parser/functions/generate.rb b/lib/puppet/parser/functions/generate.rb
index 1be9016ed..18fe883b4 100644
--- a/lib/puppet/parser/functions/generate.rb
+++ b/lib/puppet/parser/functions/generate.rb
@@ -1,7 +1,7 @@
# Runs an external command and returns the results
Puppet::Parser::Functions::newfunction(:generate, :type => :rvalue,
- :doc => "Calls an external command and returns the results of the
- command. Any arguments are passed to the external command as
+ :doc => "Calls an external command on the Puppet master and returns
+ the results of the command. Any arguments are passed to the external command as
arguments. If the generator does not exit with return code of 0,
the generator is considered to have failed and a parse error is
thrown. Generators can only have file separators, alphanumerics, dashes,
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
index 3a2032d7f..d72169af5 100644
--- a/lib/puppet/parser/functions/require.rb
+++ b/lib/puppet/parser/functions/require.rb
@@ -27,7 +27,10 @@ Note that this function only works with clients 0.25 and later, and it will
fail if used with earlier clients.
") do |vals|
- send(:function_include, vals)
+ # Verify that the 'include' function is loaded
+ method = Puppet::Parser::Functions.function(:include)
+
+ send(method, vals)
if resource.metaparam_compatibility_mode?
warning "The 'require' function is only compatible with clients at 0.25 and above; including class but not adding dependency"
else
diff --git a/lib/puppet/parser/functions/versioncmp.rb b/lib/puppet/parser/functions/versioncmp.rb
index bdf539127..9435655a7 100644
--- a/lib/puppet/parser/functions/versioncmp.rb
+++ b/lib/puppet/parser/functions/versioncmp.rb
@@ -18,7 +18,7 @@ This functions returns a number::
Example::
if versioncmp('2.6-1', '2.4.5') > 0 {
- notify('2.6-1 is > than 2.4.5')
+ notice('2.6-1 is > than 2.4.5')
}
") do |args|
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index b8aaf2715..651ed4224 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -139,6 +139,12 @@ class Puppet::Parser::Resource
if params = options[:params]
options.delete(:params)
params.each do |param|
+ # Don't set the same parameter twice
+ if @params[param.name]
+ self.fail Puppet::ParseError, "Duplicate parameter '%s' for on %s" %
+ [param.name, self.to_s]
+ end
+
set_parameter(param)
end
end
diff --git a/lib/puppet/provider/package/dpkg.rb b/lib/puppet/provider/package/dpkg.rb
index a4c398282..d6ec56ad4 100755
--- a/lib/puppet/provider/package/dpkg.rb
+++ b/lib/puppet/provider/package/dpkg.rb
@@ -83,7 +83,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
def latest
output = dpkg_deb "--show", @resource[:source]
matches = /^(\S+)\t(\S+)$/.match(output).captures
- unless matches[0].match(@resource[:name])
+ unless matches[0].match( Regexp.escape(@resource[:name]) )
warning "source doesn't contain named package, but %s" % matches[0]
end
matches[1]
diff --git a/lib/puppet/provider/package/portage.rb b/lib/puppet/provider/package/portage.rb
index e92058040..bd03aad2e 100644
--- a/lib/puppet/provider/package/portage.rb
+++ b/lib/puppet/provider/package/portage.rb
@@ -1,7 +1,6 @@
require 'puppet/provider/package'
Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Package do
- include Puppet::Util::Execution
desc "Provides packaging support for Gentoo's portage system."
has_feature :versionable
@@ -13,33 +12,32 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
defaultfor :operatingsystem => :gentoo
def self.instances
- result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(\S+)\] \[(\S+)\] (\S+) (.*)/
+ result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
- version_format = "<version>{!last} {}"
- search_format = "<category> <name> [<installedversions:SPLITVERSIONS>] [<bestversion:SPLITVERSIONS>] <homepage> <description>"
+ version_format = "{last}<version>{}"
+ search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
begin
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
update_eix
end
+
search_output = nil
- withenv :SPLITVERSIONS => version_format do
- search_output = eix "--nocolor", "--pure-packages", "--installed", "--format", search_format
+ Puppet::Util::Execution.withenv :LASTVERSION => version_format do
+ search_output = eix "--nocolor", "--pure-packages", "--stable", "--installed", "--format", search_format
end
packages = []
search_output.each do |search_result|
- match = result_format.match( search_result )
+ match = result_format.match(search_result)
if match
package = {}
- result_fields.zip(match.captures) { |field, value|
+ result_fields.zip(match.captures) do |field, value|
package[field] = value unless !value or value.empty?
- }
+ end
package[:provider] = :portage
- package[:ensure] = package[:ensure].split.last
-
packages << new(package)
end
end
@@ -74,36 +72,35 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
end
def query
- result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(\S*)\] \[(\S+)\] (\S+) (.*)/
+ result_fields = [:category, :name, :ensure, :version_available, :vendor, :description]
+
+ version_format = "{last}<version>{}"
+ search_format = "<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n"
search_field = package_name.count('/') > 0 ? "--category-name" : "--name"
search_value = package_name
- version_format = "<version>{!last} {}"
- search_format = "<category> <name> [<installedversions:FORMAT_PVERSION>] [<bestversion:FORMAT_PVERSION>] <homepage> <description>"
-
begin
if !FileUtils.uptodate?("/var/cache/eix", %w(/usr/bin/eix /usr/portage/metadata/timestamp))
update_eix
end
+
search_output = nil
- withenv :SPLITVERSIONS => version_format do
- search_output = eix "--nocolor", "--pure-packages", "--format", search_format, "--exact", search_field, search_value
+ Puppet::Util::Execution.withenv :LASTVERSION => version_format do
+ search_output = eix "--nocolor", "--pure-packages", "--stable", "--format", search_format, "--exact", search_field, search_value
end
packages = []
search_output.each do |search_result|
- match = result_format.match( search_result )
+ match = result_format.match(search_result)
- if( match )
+ if match
package = {}
- result_fields.zip( match.captures ) { |field, value| package[field] = value unless !value or value.empty? }
- if package[:ensure]
- package[:ensure] = package[:ensure].split.last
- else
- package[:ensure] = :absent
+ result_fields.zip(match.captures) do |field, value|
+ package[field] = value unless !value or value.empty?
end
+ package[:ensure] = package[:ensure] ? package[:ensure] : :absent
packages << package
end
end
@@ -126,4 +123,3 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
return self.query[:version_available]
end
end
-
diff --git a/lib/puppet/provider/package/rug.rb b/lib/puppet/provider/package/rug.rb
index b68ec30c5..ca27cbbd3 100644
--- a/lib/puppet/provider/package/rug.rb
+++ b/lib/puppet/provider/package/rug.rb
@@ -36,7 +36,7 @@ Puppet::Type.type(:package).provide :rug, :parent => :rpm do
#rug can only get a list of *all* available packages?
output = rug "list-updates"
- if output =~ /#{@resource[:name]}\s*\|\s*([0-9\.\-]+)/
+ if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([0-9\.\-]+)/
return $1
else
# rug didn't find updates, pretend the current
diff --git a/lib/puppet/provider/package/up2date.rb b/lib/puppet/provider/package/up2date.rb
index d8a12652f..284bbaf42 100644
--- a/lib/puppet/provider/package/up2date.rb
+++ b/lib/puppet/provider/package/up2date.rb
@@ -25,7 +25,7 @@ Puppet::Type.type(:package).provide :up2date, :parent => :rpm, :source => :rpm d
#up2date can only get a list of *all* available packages?
output = up2date "--showall"
- if output =~ /^#{@resource[:name]}-(\d+.*)\.\w+/
+ if output =~ /^#{Regexp.escape @resource[:name]}-(\d+.*)\.\w+/
return $1
else
# up2date didn't find updates, pretend the current
diff --git a/lib/puppet/provider/package/urpmi.rb b/lib/puppet/provider/package/urpmi.rb
index a95835284..a79e96227 100644
--- a/lib/puppet/provider/package/urpmi.rb
+++ b/lib/puppet/provider/package/urpmi.rb
@@ -43,7 +43,7 @@ Puppet::Type.type(:package).provide :urpmi, :parent => :rpm, :source => :rpm do
def latest
output = urpmq "-S", @resource[:name]
- if output =~ /^#{@resource[:name]}\s+:\s+.*\(\s+(\S+)\s+\)/
+ if output =~ /^#{Regexp.escape @resource[:name]}\s+:\s+.*\(\s+(\S+)\s+\)/
return $1
else
# urpmi didn't find updates, pretend the current
diff --git a/lib/puppet/provider/service/daemontools.rb b/lib/puppet/provider/service/daemontools.rb
index 2c6c6dbc7..3749f9c2c 100644
--- a/lib/puppet/provider/service/daemontools.rb
+++ b/lib/puppet/provider/service/daemontools.rb
@@ -45,7 +45,7 @@ Puppet::Type.type(:service).provide :daemontools, :parent => :base do
attr_writer :defpath
# Determine the daemon path.
- def defpath
+ def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
unless defined?(@defpath) and @defpath
["/var/lib/service", "/etc"].each do |path|
if FileTest.exist?(path)
diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 7ddbd288b..51fb7a22b 100755
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -29,7 +29,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
def enabled?
# TODO: Replace system() call when Puppet::Util.execute gives us a way
# to determine exit status. http://projects.reductivelabs.com/issues/2538
- system("/usr/sbin/invoke-rc.d", "--query", @resource[:name], "start")
+ system("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start")
# 104 is the exit status when you query start an enabled service.
# 106 is the exit status when the policy layer supplies a fallback action
diff --git a/lib/puppet/provider/service/runit.rb b/lib/puppet/provider/service/runit.rb
index b313fc79c..b8b444e34 100644
--- a/lib/puppet/provider/service/runit.rb
+++ b/lib/puppet/provider/service/runit.rb
@@ -38,7 +38,7 @@ Puppet::Type.type(:service).provide :runit, :parent => :daemontools do
class << self
# this is necessary to autodetect a valid resource
# default path, since there is no standard for such directory.
- def defpath
+ def defpath(dummy_argument=:work_arround_for_ruby_GC_bug)
unless defined?(@defpath) and @defpath
["/etc/sv", "/var/lib/service"].each do |path|
if FileTest.exist?(path)
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb
index 69eec9fde..b435c513c 100644
--- a/lib/puppet/provider/ssh_authorized_key/parsed.rb
+++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb
@@ -14,8 +14,9 @@ Puppet::Type.type(:ssh_authorized_key).provide(:parsed,
:fields => %w{options type key name},
:optional => %w{options},
:rts => /^\s+/,
- :match => /^(?:(.+) )?(ssh-dss|ssh-rsa) ([^ ]+)(?: (.+))?$/,
+ :match => /^(?:(.+) )?(ssh-dss|ssh-rsa) ([^ ]+) ?(.*)$/,
:post_parse => proc { |h|
+ h[:name] = "" if h[:name] == :absent
h[:options] ||= [:absent]
h[:options] = Puppet::Type::Ssh_authorized_key::ProviderParsed.parse_options(h[:options]) if h[:options].is_a? String
},
diff --git a/lib/puppet/provider/zone/solaris.rb b/lib/puppet/provider/zone/solaris.rb
index 778b9e0a1..b047f6984 100644
--- a/lib/puppet/provider/zone/solaris.rb
+++ b/lib/puppet/provider/zone/solaris.rb
@@ -64,7 +64,7 @@ Puppet::Type.type(:zone).provide(:solaris) do
@property_hash.clear
end
- def install
+ def install(dummy_argument=:work_arround_for_ruby_GC_bug)
if @resource[:install_args]
zoneadm :install, @resource[:install_args].split(" ")
else
@@ -156,11 +156,16 @@ Puppet::Type.type(:zone).provide(:solaris) do
def start
# Check the sysidcfg stuff
if cfg = @resource[:sysidcfg]
- path = File.join(@resource[:path], "root", "etc", "sysidcfg")
+ zoneetc = File.join(@resource[:path], "root", "etc")
+ sysidcfg = File.join(zoneetc, "sysidcfg")
- unless File.exists?(path)
+ # if the zone root isn't present "ready" the zone
+ # which makes zoneadmd mount the zone root
+ zoneadm :ready unless File.directory?(zoneetc)
+
+ unless File.exists?(sysidcfg)
begin
- File.open(path, "w", 0600) do |f|
+ File.open(sysidcfg, "w", 0600) do |f|
f.puts cfg
end
rescue => detail
@@ -193,6 +198,10 @@ Puppet::Type.type(:zone).provide(:solaris) do
main
end
+ def ready
+ zoneadm :ready
+ end
+
def stop
zoneadm :halt
end
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index c941d8f3d..34ca58c5a 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -22,6 +22,10 @@ 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
+
ActiveRecord::Base.verify_active_connections!
begin
diff --git a/lib/puppet/rails/resource.rb b/lib/puppet/rails/resource.rb
index 12d321143..984bdc05a 100644
--- a/lib/puppet/rails/resource.rb
+++ b/lib/puppet/rails/resource.rb
@@ -199,7 +199,7 @@ class Puppet::Rails::Resource < ActiveRecord::Base
result
end
- def ref
+ def ref(dummy_argument=:work_arround_for_ruby_GC_bug)
"%s[%s]" % [self[:restype].split("::").collect { |s| s.capitalize }.join("::"), self.title.to_s]
end
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 5bf9a8368..f21c820a0 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -78,7 +78,7 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
@resource_table[ref] = resource
# If the name and title differ, set up an alias
- #self.alias(resource, resource.name) if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.name != resource.title
+
if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.name != resource.title
self.alias(resource, resource.name) if resource.isomorphic?
end
@@ -430,12 +430,12 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
# the class.
edge = Puppet::Relationship.from_pson(edge) if edge.is_a?(Hash)
unless source = result.resource(edge.source)
- raise ArgumentError, "Could not convert from pson: Could not find relationship source '%s'" % source
+ raise ArgumentError, "Could not convert from pson: Could not find relationship source #{edge.source.inspect}"
end
edge.source = source
unless target = result.resource(edge.target)
- raise ArgumentError, "Could not convert from pson: Could not find relationship target '%s'" % target
+ raise ArgumentError, "Could not convert from pson: Could not find relationship target #{edge.target.inspect}"
end
edge.target = target
diff --git a/lib/puppet/resource/reference.rb b/lib/puppet/resource/reference.rb
index c205f1038..dce4449de 100644
--- a/lib/puppet/resource/reference.rb
+++ b/lib/puppet/resource/reference.rb
@@ -20,24 +20,12 @@ class Puppet::Resource::Reference
end
def initialize(argtype, argtitle = nil)
- if argtitle.nil?
- if argtype.is_a?(Puppet::Type)
- self.title = argtype.title
- self.type = argtype.class.name
- else
- self.title = argtype
- if self.title == argtype
- raise ArgumentError, "No title provided and title '%s' is not a valid resource reference" % argtype.inspect
- end
- end
- else
- # This will set @type if it looks like a resource reference.
- self.title = argtitle
-
- # Don't override whatever was done by setting the title.
- self.type ||= argtype
- end
-
+ self.type,self.title =
+ if (argtitle || argtype) =~ /^([^\[\]]+)\[(.+)\]$/m then [ $1, $2 ]
+ elsif argtitle then [ argtype, argtitle ]
+ elsif argtype.is_a?(Puppet::Type) then [ argtype.class.name, argtype.title ]
+ else raise ArgumentError, "No title provided and #{argtype.inspect} is not a valid resource reference"
+ end
@builtin_type = nil
end
@@ -47,15 +35,11 @@ class Puppet::Resource::Reference
return nil
end
- # If the title has square brackets, treat it like a reference and
- # set things appropriately; else, just set it.
def title=(value)
- if value =~ /^([^\[\]]+)\[(.+)\]$/
- self.type = $1
- @title = $2
- else
- @title = value
+ if @type and klass = Puppet::Type.type(@type.to_s.downcase)
+ value = klass.canonicalize_ref(value)
end
+ @title = value
end
# Canonize the type so we know it's always consistent.
diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb
index f3c1a348a..c725bde48 100644
--- a/lib/puppet/ssl/certificate_revocation_list.rb
+++ b/lib/puppet/ssl/certificate_revocation_list.rb
@@ -46,8 +46,6 @@ class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base
# The name doesn't actually matter; there's only one CRL.
# We just need the name so our Indirector stuff all works more easily.
def initialize(fakename)
- raise Puppet::Error, "Cannot manage the CRL when :cacrl is set to false" if [false, "false"].include?(Puppet[:cacrl])
-
@name = "crl"
end
diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb
index d7993e70e..98061c5e2 100644
--- a/lib/puppet/ssl/host.rb
+++ b/lib/puppet/ssl/host.rb
@@ -235,12 +235,11 @@ class Puppet::SSL::Host
# Attempt to retrieve a cert, if we don't already have one.
def wait_for_cert(time)
- return if certificate
begin
+ return if certificate
generate
-
return if certificate
- rescue StandardError => detail
+ rescue Exception => detail
Puppet.err "Could not request certificate: %s" % detail.to_s
if time < 1
puts "Exiting; failed to retrieve certificate and watiforcert is disabled"
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index b0bcdb612..f6bcbc1f7 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -134,7 +134,7 @@ class Puppet::SSLCertificates::CA
# List certificates waiting to be signed. This returns a list of hostnames, not actual
# files -- the names can be converted to full paths with host2csrfile.
- def list
+ def list(dummy_argument=:work_arround_for_ruby_GC_bug)
return Dir.entries(Puppet[:csrdir]).find_all { |file|
file =~ /\.pem$/
}.collect { |file|
@@ -144,7 +144,7 @@ class Puppet::SSLCertificates::CA
# List signed certificates. This returns a list of hostnames, not actual
# files -- the names can be converted to full paths with host2csrfile.
- def list_signed
+ def list_signed(dummy_argument=:work_arround_for_ruby_GC_bug)
return Dir.entries(Puppet[:signeddir]).find_all { |file|
file =~ /\.pem$/
}.collect { |file|
@@ -194,9 +194,6 @@ class Puppet::SSLCertificates::CA
# Revoke the certificate with serial number SERIAL issued by this
# CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- if @config[:cacrl] == 'false'
- raise Puppet::Error, "Revocation requires a CRL, but ca_crl is set to 'false'"
- end
time = Time.now
revoked = OpenSSL::X509::Revoked.new
revoked.serial = serial
@@ -344,8 +341,6 @@ class Puppet::SSLCertificates::CA
@crl = OpenSSL::X509::CRL.new(
File.read(@config[:cacrl])
)
- elsif @config[:cacrl] == 'false'
- @crl = nil
else
# Create new CRL
@crl = OpenSSL::X509::CRL.new
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index d04856d39..e132b7238 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -2,6 +2,7 @@
# and performs them
require 'puppet'
+require 'puppet/util/tagging'
module Puppet
class Transaction
@@ -18,6 +19,7 @@ class Transaction
attr_reader :events
include Puppet::Util
+ include Puppet::Util::Tagging
# Add some additional times for reporting
def addtimes(hash)
@@ -353,6 +355,7 @@ class Transaction
made = [made] unless made.is_a?(Array)
made.uniq.find_all do |res|
begin
+ res.tag(*resource.tags)
@catalog.add_resource(res) do |r|
r.finish
make_parent_child_relationship(resource, [r])
@@ -601,26 +604,26 @@ class Transaction
# The tags we should be checking.
def tags
unless defined? @tags
- tags = Puppet[:tags]
- if tags.nil? or tags == ""
- @tags = []
- else
- @tags = tags.split(/\s*,\s*/)
- end
+ self.tags = Puppet[:tags]
end
- @tags
+ super
end
- def tags=(tags)
- tags = [tags] unless tags.is_a?(Array)
- @tags = tags
+ def handle_qualified_tags( qualified )
+ # The default behavior of Puppet::Util::Tagging is
+ # to split qualified tags into parts. That would cause
+ # qualified tags to match too broadly here.
+ return
end
# Is this resource tagged appropriately?
def missing_tags?(resource)
- return false if self.ignore_tags? or tags.empty?
- return true unless resource.tagged?(tags)
+ not appropriately_tagged?(resource)
+ end
+
+ def appropriately_tagged?(resource)
+ self.ignore_tags? or tags.empty? or resource.tagged?(*tags)
end
# Are there any edges that target this resource?
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index ee87c2680..2f7b57afc 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -210,8 +210,8 @@ class Type
end
# Find the namevar
- def self.namevar
- unless defined? @namevar
+ def self.namevar_parameter
+ @namevar_parameter ||= (
params = @parameters.find_all { |param|
param.isnamevar? or param.name == :name
}
@@ -219,12 +219,19 @@ class Type
if params.length > 1
raise Puppet::DevError, "Found multiple namevars for %s" % self.name
elsif params.length == 1
- @namevar = params[0].name
+ params.first
else
raise Puppet::DevError, "No namevar for %s" % self.name
end
- end
- @namevar
+ )
+ end
+
+ def self.namevar
+ @namevar ||= namevar_parameter.name
+ end
+
+ def self.canonicalize_ref(s)
+ namevar_parameter.canonicalize(s)
end
# Create a new parameter. Requires a block and a name, stores it in the
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index 1269f3872..1cdd56184 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -312,7 +312,7 @@ Puppet::Type.newtype(:cron) do
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"
+ unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent"
raise ArgumentError, "Invalid environment setting %s" %
value.inspect
end
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 34dc4454e..a4666a95f 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -46,6 +46,12 @@ module Puppet
unmunge do |value|
File.join( Puppet::FileCollection.collection.path(value[:index]), value[:name] )
end
+
+ to_canonicalize do |s|
+ # Get rid of any duplicate slashes, and remove any trailing slashes unless
+ # the title is just a slash, in which case leave it.
+ s.gsub(/\/+/, "/").sub(/(.)\/$/,'\1')
+ end
end
newparam(:backup) do
@@ -120,10 +126,10 @@ module Puppet
munge do |value|
newval = super(value)
case newval
- when :true, :inf: true
- when :false: false
- when :remote: :remote
- when Integer, Fixnum, Bignum:
+ when :true, :inf; true
+ when :false; false
+ when :remote; :remote
+ when Integer, Fixnum, Bignum
self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
# recurse == 0 means no recursion
@@ -131,7 +137,7 @@ module Puppet
resource[:recurselimit] = value
true
- when /^\d+$/:
+ when /^\d+$/
self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit"
value = Integer(value)
@@ -154,8 +160,8 @@ module Puppet
munge do |value|
newval = super(value)
case newval
- when Integer, Fixnum, Bignum: value
- when /^\d+$/: Integer(value)
+ when Integer, Fixnum, Bignum; value
+ when /^\d+$/; Integer(value)
else
raise ArgumentError, "Invalid recurselimit value %s" % value.inspect
end
@@ -399,11 +405,7 @@ module Puppet
super
- # Get rid of any duplicate slashes, and remove any trailing slashes.
- @title = @title.gsub(/\/+/, "/")
-
- @title.sub!(/\/$/, "") unless @title == "/"
-
+ @title = self.class.canonicalize_ref(@title)
@stat = nil
end
@@ -494,26 +496,18 @@ module Puppet
# not likely to have many actual conflicts, which is good, because
# this is a pretty inefficient implementation.
def remove_less_specific_files(files)
- # We sort the paths so we can short-circuit some tests.
- mypath = self[:path]
- other_paths = catalog.vertices.find_all do |r|
- r.is_a?(self.class) and r[:path][0..(mypath.length - 1)] == mypath
- end.collect { |r| r[:path] }.sort { |a, b| a.length <=> b.length } - [self[:path]]
+ mypath = self[:path].split(File::Separator)
+ other_paths = catalog.vertices.
+ select { |r| r.is_a?(self.class) and r[:path] != self[:path] }.
+ collect { |r| r[:path].split(File::Separator) }.
+ select { |p| p[0,mypath.length] == mypath }
return files if other_paths.empty?
- remove = []
- files.each do |file|
- path = file[:path]
- other_paths.each do |p|
- if path[0..(p.length - 1)] == p
- remove << file
- break
- end
- end
- end
-
- files - remove
+ files.reject { |file|
+ path = file[:path].split(File::Separator)
+ other_paths.any? { |p| path[0,p.length] == p }
+ }
end
# A simple method for determining whether we should be recursing.
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index ff71a55ce..36e6c4172 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -96,7 +96,7 @@ module Puppet
return true if ! @resource.replace?
if self.should
- return super
+ result = super
elsif source = resource.parameter(:source)
fail "Got a remote source with no checksum" unless source.checksum
result = (is == source.checksum)
@@ -114,14 +114,14 @@ module Puppet
def retrieve
return :absent unless stat = @resource.stat
-
+ ftype = stat.ftype
# Don't even try to manage the content on directories or links
- return nil if stat.ftype == "directory"
+ return nil if ["directory","link"].include? ftype
begin
- return "{#{checksum_type}}" + send(checksum_type.to_s + "_file", resource[:path]).to_s
+ "{#{checksum_type}}" + send(checksum_type.to_s + "_file", resource[:path]).to_s
rescue => detail
- raise Puppet::Error, "Could not read %s: %s" % [@resource.title, detail]
+ raise Puppet::Error, "Could not read #{ftype} #{@resource.title}: #{detail}"
end
end
diff --git a/lib/puppet/type/file/mode.rb b/lib/puppet/type/file/mode.rb
index fd9c27ae6..83034cbd9 100755
--- a/lib/puppet/type/file/mode.rb
+++ b/lib/puppet/type/file/mode.rb
@@ -5,7 +5,24 @@ module Puppet
Puppet::Type.type(:file).newproperty(:mode) do
require 'etc'
desc "Mode the file should be. Currently relatively limited:
- you must specify the exact mode the file should be."
+ you must specify the exact mode the file should be.
+
+ Note that when you set the mode of a directory, Puppet always
+ sets the search/traverse (1) bit anywhere the read (4) bit is set.
+ This is almost always what you want: read allows you to list the
+ 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.::
+
+ file { '/some/dir':
+ mode => 644,
+ recurse => true,
+ }
+
+ 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
# Our modes are octal, so make sure they print correctly. Other
diff --git a/lib/puppet/type/file/owner.rb b/lib/puppet/type/file/owner.rb
index 1dff59cb3..e5ca06a86 100755
--- a/lib/puppet/type/file/owner.rb
+++ b/lib/puppet/type/file/owner.rb
@@ -28,10 +28,7 @@ module Puppet
end
def insync?(current)
- unless Puppet::Util::SUIDManager.uid == 0
- warning "Cannot manage ownership unless running as root"
- return true
- end
+ return true unless should
@should.each do |value|
if value =~ /^\d+$/
@@ -44,6 +41,12 @@ module Puppet
return true if uid == current
end
+
+ unless Puppet::Util::SUIDManager.uid == 0
+ warnonce "Cannot manage ownership unless running as root"
+ return true
+ end
+
return false
end
diff --git a/lib/puppet/type/k5login.rb b/lib/puppet/type/k5login.rb
index 20c03241f..5526fda21 100644
--- a/lib/puppet/type/k5login.rb
+++ b/lib/puppet/type/k5login.rb
@@ -56,7 +56,7 @@ Puppet::Type.newtype(:k5login) do
end
# Return the principals
- def principals
+ def principals(dummy_argument=:work_arround_for_ruby_GC_bug)
if File.exists?(@resource[:name])
File.readlines(@resource[:name]).collect { |line| line.chomp }
else
diff --git a/lib/puppet/type/maillist.rb b/lib/puppet/type/maillist.rb
index e2430aa13..4ab9be252 100755
--- a/lib/puppet/type/maillist.rb
+++ b/lib/puppet/type/maillist.rb
@@ -42,13 +42,10 @@ module Puppet
should = :absent
end
atype = Puppet::Type.type(:mailalias)
- return provider.aliases.collect do |name, recipient|
- if atype[name]
- nil
- else
- malias = Puppet::Type.type(:mailalias).new(:name => name, :recipient => recipient, :ensure => should)
- end
- end.compact
+
+ provider.aliases.
+ reject { |name,recipient| catalog.resource(:mailalias, name) }.
+ collect { |name,recipient| atype.new(:name => name, :recipient => recipient, :ensure => should) }
end
end
end
diff --git a/lib/puppet/type/resources.rb b/lib/puppet/type/resources.rb
index 87bde972b..e1de55711 100644
--- a/lib/puppet/type/resources.rb
+++ b/lib/puppet/type/resources.rb
@@ -99,18 +99,18 @@ Puppet::Type.newtype(:resources) do
def generate
return [] unless self.purge?
resource_type.instances.
- reject { |r| managed? }.
- reject { |r| catalog.resources.include? r.ref }.
- select { |r| check(r) }.
- select { |r| able_to_ensure_absent?(r) }.
- each { |resource|
- @parameters.each do |name, param|
- resource[name] = param.value if param.metaparam?
- end
-
- # Mark that we're purging, so transactions can handle relationships
- # correctly
- resource.purging
+ reject { |r| catalog.resources.include? r.ref }.
+ select { |r| check(r) }.
+ select { |r| r.class.validproperty?(:ensure) }.
+ select { |r| able_to_ensure_absent?(r) }.
+ each { |resource|
+ @parameters.each do |name, param|
+ resource[name] = param.value if param.metaparam?
+ end
+
+ # Mark that we're purging, so transactions can handle relationships
+ # correctly
+ resource.purging
}
end
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index f45171d90..b5ccb3fb1 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -247,8 +247,15 @@ Puppet::Type.newtype(:tidy) do
def generate
return [] unless stat(self[:path])
- if self[:recurse]
- files = Puppet::FileServing::Fileset.new(self[:path], :recurse => self[:recurse]).files.collect do |f|
+ case self[:recurse]
+ when Integer, Fixnum, Bignum, /^\d+$/
+ parameter = { :recurse => true, :recurselimit => self[:recurse] }
+ when true, :true, :inf
+ parameter = { :recurse => true }
+ end
+
+ if parameter
+ files = Puppet::FileServing::Fileset.new(self[:path], parameter).files.collect do |f|
f == "." ? self[:path] : File.join(self[:path], f)
end
else
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index 6f83c7ac5..21573d1da 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -55,10 +55,11 @@ module Util
end
unless Puppet::Util::SUIDManager.uid == user
begin
+ Puppet::Util::SUIDManager.initgroups(user)
Puppet::Util::SUIDManager.uid = user
Puppet::Util::SUIDManager.euid = user
- rescue
- $stderr.puts "could not change to user %s" % user
+ rescue => detail
+ $stderr.puts "Could not change to user %s: %s" % [user, detail]
exit(74)
end
end
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index 25c4677fb..4cdad700c 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -282,9 +282,9 @@ class Puppet::Util::Log
def colorize(level, str)
case Puppet[:color]
- when false; str
- when true, :ansi, "ansi"; console_color(level, str)
+ when true, :ansi, "ansi", :yes, "yes"; console_color(level, str)
when :html, "html"; html_color(level, str)
+ else str
end
end
diff --git a/lib/puppet/util/methodhelper.rb b/lib/puppet/util/methodhelper.rb
index 32fca1877..ecc9d537f 100644
--- a/lib/puppet/util/methodhelper.rb
+++ b/lib/puppet/util/methodhelper.rb
@@ -12,11 +12,10 @@ module Puppet::Util::MethodHelper
def set_options(options)
options.each do |param,value|
method = param.to_s + "="
- begin
+ if respond_to? method
self.send(method, value)
- rescue NoMethodError
- raise ArgumentError, "Invalid parameter %s to object class %s" %
- [param,self.class.to_s]
+ else
+ raise ArgumentError, "Invalid parameter #{param} to object class #{self.class}"
end
end
end
diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb
index e69de29bb..6e438bc73 100644
--- a/lib/puppet/util/monkey_patches.rb
+++ b/lib/puppet/util/monkey_patches.rb
@@ -0,0 +1,8 @@
+module RDoc
+ def self.caller(skip=nil)
+ in_gem_wrapper = false
+ Kernel.caller.reject { |call|
+ in_gem_wrapper ||= call =~ /#{Regexp.escape $0}:\d+:in `load'/
+ }
+ end
+end
diff --git a/lib/puppet/util/rdoc/parser.rb b/lib/puppet/util/rdoc/parser.rb
index 3f04fbf52..4d0ac484f 100644
--- a/lib/puppet/util/rdoc/parser.rb
+++ b/lib/puppet/util/rdoc/parser.rb
@@ -200,9 +200,20 @@ class Parser
if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil?
begin
- ref = resource_stmt_to_ref(stmt)
- Puppet.debug "rdoc: found resource: %s[%s]" % [ref.type, ref.title]
- container.add_resource(ref)
+ 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: %s[%s]" % [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 << res
+ end
+
+ container.add_resource(PuppetResource.new(type, title, stmt.doc, param))
rescue => detail
raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}"
end
diff --git a/lib/puppet/util/selinux.rb b/lib/puppet/util/selinux.rb
index bdf44152b..3eff03996 100644
--- a/lib/puppet/util/selinux.rb
+++ b/lib/puppet/util/selinux.rb
@@ -13,6 +13,8 @@ rescue LoadError
# Nothing
end
+require 'pathname'
+
module Puppet::Util::SELinux
def selinux_support?
@@ -91,7 +93,7 @@ module Puppet::Util::SELinux
# I believe that the OS should always provide at least a fall-through context
# though on any well-running system.
def set_selinux_context(file, value, component = false)
- unless selinux_support?
+ unless selinux_support? && selinux_label_support?(file)
return nil
end
@@ -185,9 +187,19 @@ module Puppet::Util::SELinux
return mntpoint
end
+ def realpath(path)
+ path, rest = Pathname.new(path), []
+ path, rest = path.dirname, [path.basename] + rest while ! path.exist?
+ File.join( path.realpath, *rest )
+ end
+
+ def parent_directory(path)
+ Pathname.new(path).dirname.to_s
+ end
+
# Internal helper function to return which type of filesystem a
# given file path resides on
- def find_fs(file)
+ def find_fs(path)
unless mnts = read_mounts()
return nil
end
@@ -198,13 +210,12 @@ module Puppet::Util::SELinux
# Just in case: return something if you're down to "/" or ""
# Remove the last slash and everything after it,
# and repeat with that as the file for the next loop through.
- ary = file.split('/')
- while not ary.empty? do
- path = ary.join('/')
+ path = realpath(path)
+ while not path.empty? do
if mnts.has_key?(path)
return mnts[path]
end
- ary.pop
+ path = parent_directory(path)
end
return mnts['/']
end
diff --git a/lib/puppet/util/subclass_loader.rb b/lib/puppet/util/subclass_loader.rb
index 8776e855c..b71ec7293 100644
--- a/lib/puppet/util/subclass_loader.rb
+++ b/lib/puppet/util/subclass_loader.rb
@@ -72,7 +72,7 @@ module Puppet::Util::SubclassLoader
end
# Retrieve or calculate a name.
- def name
+ def name(dummy_argument=:work_arround_for_ruby_GC_bug)
unless defined? @name
@name = self.to_s.sub(/.+::/, '').intern
end
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index c5df0d198..a0a9178bb 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -7,7 +7,7 @@ module Puppet::Util::SUIDManager
extend Forwardable
to_delegate_to_process = [ :euid=, :euid, :egid=, :egid,
- :uid=, :uid, :gid=, :gid ]
+ :uid=, :uid, :gid=, :gid, :groups=, :groups ]
to_delegate_to_process.each do |method|
def_delegator Process, method
@@ -26,13 +26,16 @@ module Puppet::Util::SUIDManager
# We set both because some programs like to drop privs, i.e. bash.
old_uid, old_gid = self.uid, self.gid
old_euid, old_egid = self.euid, self.egid
+ old_groups = self.groups
begin
self.egid = convert_xid :gid, new_gid if new_gid
+ self.initgroups(convert_xid(:uid, new_uid)) if new_uid
self.euid = convert_xid :uid, new_uid if new_uid
yield
ensure
self.euid, self.egid = old_euid, old_egid
+ self.groups = old_groups
end
end
module_function :asuser
@@ -49,6 +52,13 @@ module Puppet::Util::SUIDManager
end
module_function :convert_xid
+ # Initialize supplementary groups
+ def initgroups(user)
+ require 'etc'
+ Process.initgroups(Etc.getpwuid(user).name, Process.gid)
+ end
+
+ 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)
diff --git a/lib/puppet/util/tagging.rb b/lib/puppet/util/tagging.rb
index f421d18d8..9ee90799f 100644
--- a/lib/puppet/util/tagging.rb
+++ b/lib/puppet/util/tagging.rb
@@ -16,13 +16,12 @@ module Puppet::Util::Tagging
@tags << tag unless @tags.include?(tag)
end
- # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
- qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) }
+ handle_qualified_tags( qualified )
end
# Are we tagged with the provided tag?
- def tagged?(tag)
- defined?(@tags) and @tags.include?(tag.to_s)
+ def tagged?(*tags)
+ not ( self.tags & tags.flatten.collect { |t| t.to_s } ).empty?
end
# Return a copy of the tag list, so someone can't ask for our tags
@@ -32,8 +31,27 @@ module Puppet::Util::Tagging
@tags.dup
end
+ def tags=(tags)
+ @tags = []
+
+ return if tags.nil? or tags == ""
+
+ if tags.is_a?(String)
+ tags = tags.strip.split(/\s*,\s*/)
+ end
+
+ tags.each do |t|
+ tag(t)
+ end
+ end
+
private
+ def handle_qualified_tags( qualified )
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) }
+ end
+
def valid_tag?(tag)
tag =~ /^\w[-\w:.]*$/
end