diff options
| author | Jacob Helwig <jacob@puppetlabs.com> | 2011-06-28 18:05:49 -0700 |
|---|---|---|
| committer | Jacob Helwig <jacob@puppetlabs.com> | 2011-06-28 18:05:49 -0700 |
| commit | 8772bb7659a8586402802ce80d43fa249a4d6171 (patch) | |
| tree | ff0133bdcee37fde5dfeccaeb4a479f1449a3027 /lib | |
| parent | cf93404e53aa32ac4a919ddd57d09ed78abfc1b5 (diff) | |
| parent | 8432684e25cc82beb1f5d977dd509fd7bab3901b (diff) | |
| download | puppet-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.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/application/apply.rb | 8 | ||||
| -rw-r--r-- | lib/puppet/application/doc.rb | 35 | ||||
| -rw-r--r-- | lib/puppet/configurer.rb | 107 | ||||
| -rw-r--r-- | lib/puppet/indirector/rest.rb | 47 | ||||
| -rw-r--r-- | lib/puppet/interface/option.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/metatype/manager.rb | 27 | ||||
| -rw-r--r-- | lib/puppet/resource/catalog.rb | 12 | ||||
| -rw-r--r-- | lib/puppet/ssl/certificate.rb | 6 | ||||
| -rw-r--r-- | lib/puppet/transaction.rb | 26 | ||||
| -rw-r--r-- | lib/puppet/transaction/report.rb | 4 | ||||
| -rw-r--r-- | lib/puppet/type.rb | 37 |
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 |
