diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/defaults.rb | 2 | ||||
-rw-r--r-- | lib/puppet/network/client.rb | 20 | ||||
-rw-r--r-- | lib/puppet/network/client/master.rb | 15 | ||||
-rw-r--r-- | lib/puppet/network/http_pool.rb | 92 | ||||
-rw-r--r-- | lib/puppet/network/http_server/webrick.rb | 4 | ||||
-rw-r--r-- | lib/puppet/network/xmlrpc/client.rb | 97 | ||||
-rw-r--r-- | lib/puppet/node/catalog.rb | 21 | ||||
-rw-r--r-- | lib/puppet/parser/resource/reference.rb | 8 | ||||
-rwxr-xr-x | lib/puppet/provider/package/rpm.rb | 18 | ||||
-rw-r--r-- | lib/puppet/sslcertificates/support.rb | 10 | ||||
-rw-r--r-- | lib/puppet/type/pfile.rb | 7 | ||||
-rwxr-xr-x | lib/puppet/type/pfilebucket.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/util/filetype.rb | 3 |
13 files changed, 166 insertions, 135 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 26afdb4f9..a767d2952 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -385,8 +385,6 @@ module Puppet may need to use a FQDN for the server hostname when using a proxy."], :http_proxy_port => [3128, "The HTTP proxy port to use for outgoing connections"], - :http_keepalive => [true, - "Whether to reuse http connections, thus enabling http-keepalive."], :http_enable_post_connection_check => [true, "Boolean; wheter or not puppetd should validate the server SSL certificate against the request hostname."], diff --git a/lib/puppet/network/client.rb b/lib/puppet/network/client.rb index 52431e227..283436e95 100644 --- a/lib/puppet/network/client.rb +++ b/lib/puppet/network/client.rb @@ -122,13 +122,8 @@ class Puppet::Network::Client end # Make sure we set the driver up when we read the cert in. - def read_cert - if super - @driver.recycle_connection(self) if @driver.respond_to?(:recycle_connection) - return true - else - return false - end + def recycle_connection + @driver.recycle_connection if @driver.respond_to?(:recycle_connection) end # A wrapper method to run and then store the last run time @@ -141,9 +136,7 @@ class Puppet::Network::Client self.run self.lastrun = Time.now.to_i rescue => detail - if Puppet[:trace] - puts detail.backtrace - end + puts detail.backtrace if Puppet[:trace] Puppet.err "Could not run %s: %s" % [self.class, detail] end end @@ -182,8 +175,11 @@ class Puppet::Network::Client :tolerance => 1, :start? => true ) do - if self.scheduled? - self.runnow + begin + self.runnow if self.scheduled? + rescue => detail + puts detail.backtrace if Puppet[:trace] + Puppet.err "Could not run client; got otherwise uncaught exception: %s" % detail end end diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb index 341192740..6d1a0235f 100644 --- a/lib/puppet/network/client/master.rb +++ b/lib/puppet/network/client/master.rb @@ -1,6 +1,7 @@ # The client for interacting with the puppetmaster config server. require 'sync' require 'timeout' +require 'puppet/network/http_pool' class Puppet::Network::Client::Master < Puppet::Network::Client unless defined? @@sync @@ -69,7 +70,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client def clear @catalog.clear(true) if @catalog Puppet::Type.allclear - mkdefault_objects @catalog = nil end @@ -204,17 +204,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client self.class.instance = self @running = false - - mkdefault_objects - end - - # Make the default objects necessary for function. - def mkdefault_objects - # First create the default scheduling objects - Puppet::Type.type(:schedule).mkdefaultschedules - - # And filebuckets - Puppet::Type.type(:filebucket).mkdefaultbucket end # Mark that we should restart. The Puppet module checks whether we're running, @@ -274,7 +263,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Now close all of our existing http connections, since there's no # reason to leave them lying open. - Puppet::Network::XMLRPCClient.clear_http_instances + Puppet::Network::HttpPool.clear_http_instances end lockfile.unlock diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb new file mode 100644 index 000000000..99f09a90c --- /dev/null +++ b/lib/puppet/network/http_pool.rb @@ -0,0 +1,92 @@ +require 'puppet/sslcertificates/support' +require 'net/https' + +# Manage Net::HTTP instances for keep-alive. +module Puppet::Network::HttpPool + # This handles reading in the key and such-like. + extend Puppet::SSLCertificates::Support + @http_cache = {} + + # Clear our http cache, closing all connections. + def self.clear_http_instances + @http_cache.each do |name, connection| + connection.finish if connection.started? + end + @http_cache.clear + @cert = nil + @key = nil + end + + # Make sure we set the driver up when we read the cert in. + def self.read_cert + if val = super # This calls read_cert from the Puppet::SSLCertificates::Support module. + # Clear out all of our connections, since they previously had no cert and now they + # should have them. + clear_http_instances + return val + else + return false + end + end + + # Use cert information from a Puppet client to set up the http object. + def self.cert_setup(http) + # Just no-op if we don't have certs. + return false unless (defined?(@cert) and @cert) or self.read_cert + + store = OpenSSL::X509::Store.new + store.add_file Puppet[:localcacert] + store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT + + http.cert_store = store + http.ca_file = Puppet[:localcacert] + http.cert = self.cert + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.key = self.key + end + + # Retrieve a cached http instance of caching is enabled, else return + # a new one. + def self.http_instance(host, port, reset = false) + # We overwrite the uninitialized @http here with a cached one. + key = "%s:%s" % [host, port] + + # Return our cached instance if we've got a cache, as long as we're not + # resetting the instance. + return @http_cache[key] if ! reset and @http_cache[key] + + # Clean up old connections if we have them. + if http = @http_cache[key] + @http_cache.delete(key) + http.finish if http.started? + end + + args = [host, port] + if Puppet[:http_proxy_host] == "none" + args << nil << nil + else + args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port] + end + http = Net::HTTP.new(*args) + + # Pop open the http client a little; older versions of Net::HTTP(s) didn't + # give us a reader for ca_file... Grr... + class << http; attr_accessor :ca_file; end + + http.use_ssl = true + http.read_timeout = 120 + http.open_timeout = 120 + # JJM Configurable fix for #896. + if Puppet[:http_enable_post_connection_check] + http.enable_post_connection_check = true + else + http.enable_post_connection_check = false + end + + cert_setup(http) + + @http_cache[key] = http + + return http + end +end diff --git a/lib/puppet/network/http_server/webrick.rb b/lib/puppet/network/http_server/webrick.rb index d2bb7b750..3c9f72e17 100644 --- a/lib/puppet/network/http_server/webrick.rb +++ b/lib/puppet/network/http_server/webrick.rb @@ -27,14 +27,14 @@ module Puppet return nil end unless File.exist?(Puppet[:cacrl]) - raise Puppet::Error, "Could not find CRL" + raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'none' 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 store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK unless self.ca_cert - raise Puppet::Error, "No CA certificate" + raise Puppet::Error, "Could not find CA certificate" end store.add_file(Puppet[:localcacert]) diff --git a/lib/puppet/network/xmlrpc/client.rb b/lib/puppet/network/xmlrpc/client.rb index 5048a040a..27bb3dc5e 100644 --- a/lib/puppet/network/xmlrpc/client.rb +++ b/lib/puppet/network/xmlrpc/client.rb @@ -1,4 +1,5 @@ require 'puppet/sslcertificates' +require 'puppet/network/http_pool' require 'openssl' require 'puppet/external/base64' @@ -10,66 +11,15 @@ module Puppet::Network class ClientError < Puppet::Error; end class XMLRPCClientError < Puppet::Error; end class XMLRPCClient < ::XMLRPC::Client + attr_accessor :puppet_server, :puppet_port @clients = {} - @@http_cache = {} class << self include Puppet::Util include Puppet::Util::ClassGen end - # Clear our http cache, closing all connections. - def self.clear_http_instances - @@http_cache.each do |name, connection| - connection.finish if connection.started? - end - @@http_cache.clear - end - - # Retrieve a cached http instance of caching is enabled, else return - # a new one. - def self.http_instance(host, port, reset = false) - # We overwrite the uninitialized @http here with a cached one. - key = "%s:%s" % [host, port] - - # Return our cached instance if keepalive is enabled and we've got - # a cache, as long as we're not resetting the instance. - return @@http_cache[key] if ! reset and Puppet[:http_keepalive] and @@http_cache[key] - - # Clean up old connections if we have them. - if http = @@http_cache[key] - @@http_cache.delete(key) - http.finish if http.started? - end - - args = [host, port] - if Puppet[:http_proxy_host] == "none" - args << nil << nil - else - args << Puppet[:http_proxy_host] << Puppet[:http_proxy_port] - end - http = Net::HTTP.new(*args) - - # Pop open the http client a little; older versions of Net::HTTP(s) didn't - # give us a reader for ca_file... Grr... - class << http; attr_accessor :ca_file; end - - http.use_ssl = true - http.read_timeout = 120 - http.open_timeout = 120 - # JJM Configurable fix for #896. - if Puppet[:http_enable_post_connection_check] - http.enable_post_connection_check = true - else - http.enable_post_connection_check = false - end - - @@http_cache[key] = http if Puppet[:http_keepalive] - - return http - end - # Create a netclient for each handler def self.mkclient(handler) interface = handler.interface @@ -81,8 +31,7 @@ module Puppet::Network # they want. constant = handler.name.to_s.capitalize name = namespace.downcase - newclient = genclass(name, :hash => @clients, - :constant => constant) + newclient = genclass(name, :hash => @clients, :constant => constant) interface.methods.each { |ary| method = ary[0] @@ -97,7 +46,7 @@ module Puppet::Network rescue OpenSSL::SSL::SSLError => detail if detail.message =~ /bad write retry/ Puppet.warning "Transient SSL write error; restarting connection and retrying" - self.recycle_connection(@cert_client) + self.recycle_connection retry end raise XMLRPCClientError, @@ -118,7 +67,7 @@ module Puppet::Network raise error rescue Errno::EPIPE, EOFError Puppet.warning "Other end went away; restarting connection and retrying" - self.recycle_connection(@cert_client) + self.recycle_connection retry rescue => detail if detail.message =~ /^Wrong size\. Was \d+, should be \d+$/ @@ -141,30 +90,6 @@ module Puppet::Network @clients[handler] || self.mkclient(handler) end - # Use cert information from a Puppet client to set up the http object. - def cert_setup(client) - # Cache it for next time - @cert_client = client - - unless FileTest.exist?(Puppet[:localcacert]) - raise Puppet::SSLCertificates::Support::MissingCertificate, - "Could not find ca certificate %s" % Puppet[:localcacert] - end - - # We can't overwrite certificates, @http will freeze itself - # once started. - unless @http.ca_file - @http.ca_file = Puppet[:localcacert] - store = OpenSSL::X509::Store.new - store.add_file Puppet[:localcacert] - store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT - @http.cert_store = store - @http.cert = client.cert - @http.verify_mode = OpenSSL::SSL::VERIFY_PEER - @http.key = client.key - end - end - def initialize(hash = {}) hash[:Path] ||= "/RPC2" hash[:Server] ||= Puppet[:server] @@ -188,13 +113,15 @@ module Puppet::Network true, # use_ssl 120 # a two minute timeout, instead of 30 seconds ) - @http = self.class.http_instance(@host, @port) + @http = Puppet::Network::HttpPool.http_instance(@host, @port) end - def recycle_connection(client) - @http = self.class.http_instance(@host, @port, true) # reset the instance - - cert_setup(client) + # Get rid of our existing connection, replacing it with a new one. + # This should only happen if we lose our connection somehow (e.g., an EPIPE) + # or we've just downloaded certs and we need to create new http instances + # with the certs added. + def recycle_connection + @http = Puppet::Network::HttpPool.http_instance(@host, @port, true) # reset the instance end def start diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb index a02d59ae9..c9de2019d 100644 --- a/lib/puppet/node/catalog.rb +++ b/lib/puppet/node/catalog.rb @@ -260,6 +260,8 @@ class Puppet::Node::Catalog < Puppet::PGraph # Make sure all of our resources are "finished". def finalize + make_default_resources + @resource_table.values.each { |resource| resource.finish } write_graph(:resources) @@ -287,6 +289,20 @@ class Puppet::Node::Catalog < Puppet::PGraph finalize() end end + + # Make the default objects necessary for function. + def make_default_resources + # We have to add the resources to the catalog, or else they won't get cleaned up after + # the transaction. + + # First create the default scheduling objects + Puppet::Type.type(:schedule).mkdefaultschedules.each { |res| add_resource(res) unless resource(res.ref) } + + # And filebuckets + if bucket = Puppet::Type.type(:filebucket).mkdefaultbucket + add_resource(bucket) + end + end # Create a graph of all of the relationships in our catalog. def relationship_graph @@ -367,6 +383,11 @@ class Puppet::Node::Catalog < Puppet::PGraph end end + # Return an array of all resources. + def resources + @resource_table.keys + end + # Add a tag. def tag(*names) names.each do |name| diff --git a/lib/puppet/parser/resource/reference.rb b/lib/puppet/parser/resource/reference.rb index 1dd816093..6e70d23b7 100644 --- a/lib/puppet/parser/resource/reference.rb +++ b/lib/puppet/parser/resource/reference.rb @@ -62,7 +62,13 @@ class Puppet::Parser::Resource::Reference < Puppet::ResourceReference end def to_ref - return [type.to_s,title.to_s] + # We have to return different cases to provide backward compatibility + # from 0.24.x to 0.23.x. + if builtin? + return [type.to_s.downcase, title.to_s] + else + return [type.to_s, title.to_s] + end end def typeclass diff --git a/lib/puppet/provider/package/rpm.rb b/lib/puppet/provider/package/rpm.rb index 4af299283..98ca1efa6 100755 --- a/lib/puppet/provider/package/rpm.rb +++ b/lib/puppet/provider/package/rpm.rb @@ -92,6 +92,19 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr end def uninstall + query unless get(:arch) + nvr = "#{get(:name)}-#{get(:version)}-#{get(:release)}" + arch = ".#{get(:arch)}" + # If they specified an arch in the manifest, erase that Otherwise, + # erase the arch we got back from the query. If multiple arches are + # installed and only the package name is specified (without the + # arch), this will uninstall all of them on successive runs of the + # client, one after the other + if @resource[:name][-arch.size, arch.size] == arch + nvr += arch + else + nvr += ".#{get(:arch)}" + end rpm "-e", nvr end @@ -99,11 +112,6 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr self.install end - def nvr - query unless @nvr - @nvr - end - def self.nevra_to_hash(line) line.chomp! hash = {} diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb index e63458b33..1d692c994 100644 --- a/lib/puppet/sslcertificates/support.rb +++ b/lib/puppet/sslcertificates/support.rb @@ -30,25 +30,23 @@ module Puppet::SSLCertificates::Support define_method(reader) do return nil unless FileTest.exists?(Puppet[param]) begin - instance_variable_set(var, - klass.new(File.read(Puppet[param]))) + instance_variable_set(var, klass.new(File.read(Puppet[param]))) rescue => detail - raise InvalidCertificate, "Could not read %s: %s" % - [param, detail] + raise InvalidCertificate, "Could not read %s: %s" % [param, detail] end end # Define the overall method, which just calls the reader and maker # as appropriate. define_method(name) do - unless instance_variable_get(var) + unless cert = instance_variable_get(var) unless cert = send(reader) cert = send(maker) Puppet.settings.write(param) { |f| f.puts cert.to_pem } end instance_variable_set(var, cert) end - instance_variable_get(var) + cert end end diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index bccdaa265..f86e1e273 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -72,12 +72,7 @@ module Puppet filebucketed files. " - defaultto do - # Make sure the default file bucket exists. - obj = Puppet::Type.type(:filebucket)["puppet"] || - Puppet::Type.type(:filebucket).create(:name => "puppet") - obj.bucket - end + defaultto { "puppet" } munge do |value| # I don't really know how this is happening. diff --git a/lib/puppet/type/pfilebucket.rb b/lib/puppet/type/pfilebucket.rb index cf4e5aac3..b268610e9 100755 --- a/lib/puppet/type/pfilebucket.rb +++ b/lib/puppet/type/pfilebucket.rb @@ -66,9 +66,9 @@ module Puppet # Create a default filebucket. def self.mkdefaultbucket unless default = self["puppet"] - default = self.create :name => "puppet", :path => Puppet[:clientbucketdir] + return self.create(:name => "puppet", :path => Puppet[:clientbucketdir]) end - default + return nil end def self.instances diff --git a/lib/puppet/util/filetype.rb b/lib/puppet/util/filetype.rb index 81d93a924..1c7734cc4 100755 --- a/lib/puppet/util/filetype.rb +++ b/lib/puppet/util/filetype.rb @@ -74,7 +74,8 @@ class Puppet::Util::FileType # Pick or create a filebucket to use. def bucket - Puppet::Type.type(:filebucket).mkdefaultbucket.bucket + filebucket = Puppet::Type.type(:filebucket) + (filebucket["puppet"] || filebucket.mkdefaultbucket).bucket end def initialize(path) |