summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJacob Helwig <jacob@puppetlabs.com>2011-06-28 18:05:49 -0700
committerJacob Helwig <jacob@puppetlabs.com>2011-06-28 18:05:49 -0700
commit8772bb7659a8586402802ce80d43fa249a4d6171 (patch)
treeff0133bdcee37fde5dfeccaeb4a479f1449a3027 /lib
parentcf93404e53aa32ac4a919ddd57d09ed78abfc1b5 (diff)
parent8432684e25cc82beb1f5d977dd509fd7bab3901b (diff)
downloadpuppet-8772bb7659a8586402802ce80d43fa249a4d6171.tar.gz
puppet-8772bb7659a8586402802ce80d43fa249a4d6171.tar.xz
puppet-8772bb7659a8586402802ce80d43fa249a4d6171.zip
Merge branch '2.7.x'
* 2.7.x: (23 commits) Clean up indentation, whitespace, and commented out code Remove order dependency from functions integration spec (#7956) Porting cron tests (#7956) Port resource acceptance tests (#8048) Gem install puppet no longer fails if rdoc enabled. Updating for 2.7.1 release. (#8048) Gem install puppet no longer fails if rdoc enabled. Readying for release of 2.6.9 Updating CHANGELOG for 2.7.0 (#6854) Update Red Hat spec file Bumping release in lib/puppet.rb and updating CHANGELOG. Bumping RPM spec file to 2.6.9rc1. (#7224) Reword 'hostname was not match' error message (#7224) Add a helper to Puppet::SSL::Certificate to retrieve alternate names (#7506) Organize READMEs; specify supported Ruby versions in README.md (#7506) Specify supported Ruby versions in README.md (#5641) Help text: document that puppet doc takes modulepath, manifestdir, and environment options (#6418) Make test 64118 more portable (#7127) Stop puppet if a prerun command fails Do not needlessly create multiple reports when creating a transaction ...
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet.rb2
-rw-r--r--lib/puppet/application/apply.rb8
-rw-r--r--lib/puppet/application/doc.rb35
-rw-r--r--lib/puppet/configurer.rb107
-rw-r--r--lib/puppet/indirector/rest.rb47
-rw-r--r--lib/puppet/interface/option.rb2
-rw-r--r--lib/puppet/metatype/manager.rb27
-rw-r--r--lib/puppet/resource/catalog.rb12
-rw-r--r--lib/puppet/ssl/certificate.rb6
-rw-r--r--lib/puppet/transaction.rb26
-rw-r--r--lib/puppet/transaction/report.rb4
-rw-r--r--lib/puppet/type.rb37
12 files changed, 173 insertions, 140 deletions
diff --git a/lib/puppet.rb b/lib/puppet.rb
index bcac94d45..c895da921 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.7.0'
+ PUPPETVERSION = '2.7.1'
def Puppet.version
PUPPETVERSION
diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb
index 3ba06d34a..5562a9b09 100644
--- a/lib/puppet/application/apply.rb
+++ b/lib/puppet/application/apply.rb
@@ -213,7 +213,13 @@ Copyright (c) 2011 Puppet Labs, LLC Licensed under the Apache 2.0 License
configurer = Puppet::Configurer.new
report = configurer.run(:skip_plugin_download => true, :catalog => catalog)
- exit( options[:detailed_exitcodes] ? report.exit_status : 0 )
+ if not report
+ exit(1)
+ elsif options[:detailed_exitcodes] then
+ exit(report.exit_status)
+ else
+ exit(0)
+ end
rescue => detail
puts detail.backtrace if Puppet[:trace]
$stderr.puts detail.message
diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb
index a88f27c78..65cd37da8 100644
--- a/lib/puppet/application/doc.rb
+++ b/lib/puppet/application/doc.rb
@@ -87,29 +87,40 @@ puppet doc will output a single manifest's documentation on stdout.
OPTIONS
-------
* --all:
- Output the docs for all of the reference types. In 'rdoc'
- modes, this also outputs documentation for all resources
+ Output the docs for all of the reference types. In 'rdoc' mode, this also
+ outputs documentation for all resources.
* --help:
Print this help message
* --outputdir:
- Specifies the directory where to output the rdoc
- documentation in 'rdoc' mode.
+ Used only in 'rdoc' mode. The directory to which the rdoc output should
+ be written.
* --mode:
- Determine the output mode. Valid modes are 'text', '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'
+ Determine the output mode. Valid modes are 'text', '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'.
+ Build a particular reference. Get a list of references by running
+ 'puppet doc --list'.
* --charset:
- Used only in 'rdoc' mode. It sets the charset used in the
- html files produced.
+ Used only in 'rdoc' mode. It sets the charset used in the html files produced.
+
+* --manifestdir:
+ Used only in 'rdoc' mode. The directory to scan for stand-alone manifests.
+ If not supplied, puppet doc will use the manifestdir from puppet.conf.
+
+* --modulepath:
+ Used only in 'rdoc' mode. The directory or directories to scan for modules.
+ If not supplied, puppet doc will use the modulepath from puppet.conf.
+
+* --environment:
+ Used only in 'rdoc' mode. The configuration environment from which
+ to read the modulepath and manifestdir settings, when reading said settings
+ from puppet.conf. Due to a known bug, this option is not currently effective.
EXAMPLE
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index 980da634e..3d6e8557c 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -5,8 +5,6 @@ require 'puppet/network/http_pool'
require 'puppet/util'
class Puppet::Configurer
- class CommandHookError < RuntimeError; end
-
require 'puppet/configurer/fact_handler'
require 'puppet/configurer/plugin_handler'
@@ -79,8 +77,6 @@ class Puppet::Configurer
download_plugins unless options[:skip_plugin_download]
download_fact_plugins unless options[:skip_plugin_download]
-
- execute_prerun_command
end
# Get the remote catalog, yo. Returns nil if no catalog can be found.
@@ -109,67 +105,73 @@ class Puppet::Configurer
catalog
end
- # The code that actually runs the catalog.
- # This just passes any options on to the catalog,
- # which accepts :tags and :ignoreschedules.
- def run(options = {})
- begin
- prepare(options)
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Failed to prepare catalog: #{detail}"
+ # Retrieve (optionally) and apply a catalog. If a catalog is passed in
+ # the options, then apply that one, otherwise retrieve it.
+ def retrieve_and_apply_catalog(options, fact_options)
+ unless catalog = (options.delete(:catalog) || retrieve_catalog(fact_options))
+ Puppet.err "Could not retrieve catalog; skipping run"
+ return
end
- if Puppet::Resource::Catalog.indirection.terminus_class == :rest
- # This is a bit complicated. We need the serialized and escaped facts,
- # and we need to know which format they're encoded in. Thus, we
- # get a hash with both of these pieces of information.
- fact_options = facts_for_uploading
+ report = options[:report]
+ report.configuration_version = catalog.version
+
+ benchmark(:notice, "Finished catalog run") do
+ catalog.apply(options)
end
+ report.finalize_report
+ report
+ end
+
+ # The code that actually runs the catalog.
+ # This just passes any options on to the catalog,
+ # which accepts :tags and :ignoreschedules.
+ def run(options = {})
options[:report] ||= Puppet::Transaction::Report.new("apply")
report = options[:report]
- Puppet::Util::Log.newdestination(report)
- if catalog = options[:catalog]
- options.delete(:catalog)
- elsif ! catalog = retrieve_catalog(fact_options)
- Puppet.err "Could not retrieve catalog; skipping run"
- return
- end
+ Puppet::Util::Log.newdestination(report)
+ begin
+ prepare(options)
- report.configuration_version = catalog.version
+ if Puppet::Resource::Catalog.indirection.terminus_class == :rest
+ # This is a bit complicated. We need the serialized and escaped facts,
+ # and we need to know which format they're encoded in. Thus, we
+ # get a hash with both of these pieces of information.
+ fact_options = facts_for_uploading
+ end
- transaction = nil
+ # set report host name now that we have the fact
+ report.host = Puppet[:node_name_value]
- begin
- benchmark(:notice, "Finished catalog run") do
- transaction = catalog.apply(options)
+ begin
+ execute_prerun_command or return nil
+ retrieve_and_apply_catalog(options, fact_options)
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Failed to apply catalog: #{detail}"
+ return nil
+ ensure
+ execute_postrun_command or return nil
end
- report
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Failed to apply catalog: #{detail}"
- return
+ 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
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)
+ send_report(report)
end
- def send_report(report, trans)
- report.finalize_report if trans
+ def send_report(report)
puts report.summary if Puppet[:summarize]
save_last_run_summary(report)
Puppet::Transaction::Report.indirection.save(report) if Puppet[:report]
@@ -207,12 +209,15 @@ class Puppet::Configurer
end
def execute_from_setting(setting)
- return if (command = Puppet[setting]) == ""
+ return true if (command = Puppet[setting]) == ""
begin
Puppet::Util.execute([command])
+ true
rescue => detail
- raise CommandHookError, "Could not run command from #{setting}: #{detail}"
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not run command from #{setting}: #{detail}"
+ false
end
end
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb
index 0d3997221..8018fe8e3 100644
--- a/lib/puppet/indirector/rest.rb
+++ b/lib/puppet/indirector/rest.rb
@@ -71,16 +71,49 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
Puppet::Network::HttpPool.http_instance(request.server || self.class.server, request.port || self.class.port)
end
+ [:get, :post, :head, :delete, :put].each do |method|
+ define_method "http_#{method}" do |request, *args|
+ http_request(method, request, *args)
+ end
+ end
+
+ def http_request(method, request, *args)
+ http_connection = network(request)
+ peer_certs = []
+
+ # We add the callback to collect the certificates for use in constructing
+ # the error message if the verification failed. This is necessary since we
+ # don't have direct access to the cert that we expected the connection to
+ # use otherwise.
+ #
+ http_connection.verify_callback = proc do |preverify_ok, ssl_context|
+ peer_certs << Puppet::SSL::Certificate.from_s(ssl_context.current_cert.to_pem)
+ preverify_ok
+ end
+
+ http_connection.send(method, *args)
+ rescue OpenSSL::SSL::SSLError => error
+ if error.message.include? "hostname was not match"
+ raise unless cert = peer_certs.find { |c| c.name !~ /^puppet ca/i }
+
+ valid_certnames = [cert.name, *cert.alternate_names].uniq
+ msg = valid_certnames.length > 1 ? "one of #{valid_certnames.join(', ')}" : valid_certnames.first
+
+ raise Puppet::Error, "Server hostname '#{http_connection.address}' did not match server certificate; expected #{msg}"
+ else
+ raise
+ end
+ end
+
def find(request)
uri, body = request_to_uri_and_body(request)
uri_with_query_string = "#{uri}?#{body}"
- http_connection = network(request)
# WEBrick in Ruby 1.9.1 only supports up to 1024 character lines in an HTTP request
# http://redmine.ruby-lang.org/issues/show/3991
response = if "GET #{uri_with_query_string} HTTP/1.1\r\n".length > 1024
- http_connection.post(uri, body, headers)
+ http_post(request, uri, body, headers)
else
- http_connection.get(uri_with_query_string, headers)
+ http_get(request, uri_with_query_string, headers)
end
result = deserialize response
result.name = request.key if result.respond_to?(:name=)
@@ -88,7 +121,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
end
def head(request)
- response = network(request).head(indirection2uri(request), headers)
+ response = http_head(request, indirection2uri(request), headers)
case response.code
when "404"
return false
@@ -101,7 +134,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
end
def search(request)
- unless result = deserialize(network(request).get(indirection2uri(request), headers), true)
+ unless result = deserialize(http_get(request, indirection2uri(request), headers), true)
return []
end
result
@@ -109,12 +142,12 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
def destroy(request)
raise ArgumentError, "DELETE does not accept options" unless request.options.empty?
- deserialize network(request).delete(indirection2uri(request), headers)
+ deserialize http_delete(request, indirection2uri(request), headers)
end
def save(request)
raise ArgumentError, "PUT does not accept options" unless request.options.empty?
- deserialize network(request).put(indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
+ deserialize http_put(request, indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
end
private
diff --git a/lib/puppet/interface/option.rb b/lib/puppet/interface/option.rb
index b68bdeb12..3cd930acf 100644
--- a/lib/puppet/interface/option.rb
+++ b/lib/puppet/interface/option.rb
@@ -2,8 +2,6 @@ require 'puppet/interface'
class Puppet::Interface::Option
include Puppet::Interface::TinyDocs
- # For compatibility, deprecated, and should go fairly soon...
- ['', '='].each { |x| alias :"desc#{x}" :"description#{x}" }
def initialize(parent, *declaration, &block)
@parent = parent
diff --git a/lib/puppet/metatype/manager.rb b/lib/puppet/metatype/manager.rb
index 12cbf645c..597a89f31 100644
--- a/lib/puppet/metatype/manager.rb
+++ b/lib/puppet/metatype/manager.rb
@@ -61,10 +61,9 @@ module Manager
# Then create the class.
- klass = genclass(
- name,
+ klass = genclass(
+ name,
:parent => (parent || Puppet::Type),
-
:overwrite => true,
:hash => @types,
:attributes => options,
@@ -87,14 +86,11 @@ module Manager
# Now set up autoload any providers that might exist for this type.
- klass.providerloader = Puppet::Util::Autoload.new(
- klass,
-
- "puppet/provider/#{klass.name.to_s}"
- )
+ klass.providerloader = Puppet::Util::Autoload.new(klass, "puppet/provider/#{klass.name.to_s}")
- # We have to load everything so that we can figure out the default type.
+ # We have to load everything so that we can figure out the default provider.
klass.providerloader.loadall
+ klass.providify unless klass.providers.empty?
klass
end
@@ -103,11 +99,7 @@ module Manager
def rmtype(name)
# Then create the class.
- klass = rmclass(
- name,
-
- :hash => @types
- )
+ klass = rmclass(name, :hash => @types)
singleton_class.send(:remove_method, "new#{name}") if respond_to?("new#{name}")
end
@@ -132,12 +124,7 @@ module Manager
# Create a loader for Puppet types.
def typeloader
unless defined?(@typeloader)
-
- @typeloader = Puppet::Util::Autoload.new(
- self,
-
- "puppet/type", :wrap => false
- )
+ @typeloader = Puppet::Util::Autoload.new(self, "puppet/type", :wrap => false)
end
@typeloader
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index b742d283f..8eb4266db 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -128,9 +128,10 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
expire
Puppet::Util::Storage.load if host_config?
- transaction = Puppet::Transaction.new(self)
- transaction.report = options[:report] if options[:report]
+ transaction = Puppet::Transaction.new(self, options[:report])
+ register_report = options[:report].nil?
+
transaction.tags = options[:tags] if options[:tags]
transaction.ignoreschedules = true if options[:ignoreschedules]
transaction.for_network_device = options[:network_device]
@@ -138,7 +139,12 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
transaction.add_times :config_retrieval => self.retrieval_duration || 0
begin
- transaction.evaluate
+ Puppet::Util::Log.newdestination(transaction.report) if register_report
+ begin
+ transaction.evaluate
+ ensure
+ Puppet::Util::Log.close(transaction.report) if register_report
+ end
rescue Puppet::Error => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not apply complete catalog: #{detail}"
diff --git a/lib/puppet/ssl/certificate.rb b/lib/puppet/ssl/certificate.rb
index a0e600291..d57ac1a06 100644
--- a/lib/puppet/ssl/certificate.rb
+++ b/lib/puppet/ssl/certificate.rb
@@ -27,6 +27,12 @@ class Puppet::SSL::Certificate < Puppet::SSL::Base
[:s]
end
+ def alternate_names
+ alts = content.extensions.find{|ext| ext.oid == "subjectAltName"}
+ return [] unless alts
+ alts.value.split(/,\s+/).map{|al| al.sub(/^DNS:/,'')}
+ end
+
def expiration
return nil unless content
content.not_after
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index 089f4d945..3152d768d 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -16,7 +16,7 @@ class Puppet::Transaction
attr_accessor :configurator
# The report, once generated.
- attr_accessor :report
+ attr_reader :report
# Routes and stores any events and subscriptions.
attr_reader :event_manager
@@ -92,25 +92,17 @@ class Puppet::Transaction
# collects all of the changes, executes them, and responds to any
# necessary events.
def evaluate
- # Start logging.
- Puppet::Util::Log.newdestination(@report)
-
prepare
Puppet.info "Applying configuration version '#{catalog.version}'" if catalog.version
- begin
- relationship_graph.traverse do |resource|
- if resource.is_a?(Puppet::Type::Component)
- Puppet.warning "Somehow left a component in the relationship graph"
- else
- seconds = thinmark { eval_resource(resource) }
- resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
- end
+ relationship_graph.traverse do |resource|
+ if resource.is_a?(Puppet::Type::Component)
+ Puppet.warning "Somehow left a component in the relationship graph"
+ else
+ seconds = thinmark { eval_resource(resource) }
+ resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
end
- ensure
- # And then close the transaction log.
- Puppet::Util::Log.close(@report)
end
Puppet.debug "Finishing transaction #{object_id}"
@@ -221,10 +213,10 @@ class Puppet::Transaction
# this should only be called by a Puppet::Type::Component resource now
# and it should only receive an array
- def initialize(catalog)
+ def initialize(catalog, report = nil)
@catalog = catalog
- @report = Puppet::Transaction::Report.new("apply")
+ @report = report || Puppet::Transaction::Report.new("apply", catalog.version)
@event_manager = Puppet::Transaction::EventManager.new(self)
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index 020a5efce..807163961 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -10,8 +10,8 @@ class Puppet::Transaction::Report
indirects :report, :terminus_class => :processor
- attr_accessor :configuration_version
- attr_reader :resource_statuses, :logs, :metrics, :host, :time, :kind, :status
+ attr_accessor :configuration_version, :host
+ attr_reader :resource_statuses, :logs, :metrics, :time, :kind, :status
# This is necessary since Marshall doesn't know how to
# dump hash with default proc (see below @records)
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 558491a7f..15f340f55 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -1442,9 +1442,8 @@ class Type
def self.provide(name, options = {}, &block)
name = Puppet::Util.symbolize(name)
- if obj = provider_hash[name]
+ if unprovide(name)
Puppet.debug "Reloading #{name} #{self.name} provider"
- unprovide(name)
end
parent = if pname = options[:parent]
@@ -1467,16 +1466,14 @@ class Type
self.providify
-
- provider = genclass(
- name,
- :parent => parent,
- :hash => provider_hash,
- :prefix => "Provider",
- :block => block,
- :include => feature_module,
- :extend => feature_module,
-
+ provider = genclass(
+ name,
+ :parent => parent,
+ :hash => provider_hash,
+ :prefix => "Provider",
+ :block => block,
+ :include => feature_module,
+ :extend => feature_module,
:attributes => options
)
@@ -1536,18 +1533,11 @@ class Type
end
def self.unprovide(name)
- if provider_hash.has_key? name
-
- rmclass(
- name,
- :hash => provider_hash,
-
- :prefix => "Provider"
- )
- if @defaultprovider and @defaultprovider.name == name
- @defaultprovider = nil
- end
+ if @defaultprovider and @defaultprovider.name == name
+ @defaultprovider = nil
end
+
+ rmclass(name, :hash => provider_hash, :prefix => "Provider")
end
# Return an array of all of the suitable providers.
@@ -1607,7 +1597,6 @@ class Type
# Collect the current prereqs
list.each { |dep|
- obj = nil
# Support them passing objects directly, to save some effort.
unless dep.is_a? Puppet::Type
# Skip autorequires that we aren't managing