diff --git a/templates/server/config.ru.erb b/templates/server/config.ru.erb index dcc6020..03ef006 100644 --- a/templates/server/config.ru.erb +++ b/templates/server/config.ru.erb @@ -1,120 +1,119 @@ ### Next part of the file is managed by a different template ### ## Module: '<%= scope.to_hash['module_name'] %>' # a config.ru, for use with every rack-compatible webserver. # SSL needs to be handled outside this, though. # if puppet is not in your RUBYLIB: # $LOAD_PATH.unshift('/opt/puppet/lib') $0 = "master" # if you want debugging: # ARGV << "--debug" ARGV << "--rack" # Rack applications typically don't start as root. Set --confdir and --vardir # to prevent reading configuration from ~puppet/.puppet/puppet.conf and writing # to ~puppet/.puppet ARGV << "--confdir" << "<%= @confdir %>" ARGV << "--vardir" << "<%= @vardir %>" <% (@rack_arguments || []).each do |server_rack_argument| -%> ARGV << "<%= server_rack_argument %>" <% end -%> <% if @puppetversion.to_f >= 4.0 -%> # always_cache_features is a performance improvement and safe for a master to # apply. This is intended to allow agents to recognize new features that may be # delivered during catalog compilation. ARGV << "--always_cache_features" # Rack middleware for Puppet 3 compatibility # See Debian bug #832536 class Puppet3Compat attr_reader :master @@puppet4_endpoints = ['puppet', 'puppet-ca'] @@v1_res_endpoints = ['catalog', 'file_bucket_file', 'file_content', 'file_metadata', 'file_metadatas', 'report', 'facts', 'node', 'resource_type', 'resource_types', 'status'] @@v1_ca_endpoints = ['certificate', 'certificate_request', 'certificate_status', 'certificate_statuses', 'certificate_revocation_list'] @@v2_endpoints = ['environments'] def initialize(app) @master = app end def call(env) components = env["PATH_INFO"].to_s.split("/") components.shift if components.first.empty? if components.length < 2 return master.call(env) end environment = components.shift @api = components.first # Short-circuit Puppet 4 requests if @@puppet4_endpoints.include?(environment) return master.call(env) end @req = Rack::Request.new(env) # Rewrite Puppet 3 requests if @@v1_ca_endpoints.include?(@api) @req.path_info = "/puppet-ca/v1/#{components.join("/")}" elsif @@v1_res_endpoints.include?(@api) || @@v2_endpoints.include?(@api) @req.path_info = "/puppet/v3/#{components.join("/")}" end if environment != "v2.0" @req.update_param("environment", environment) # Re-create the query string env['QUERY_STRING'] = Rack::Utils.build_query(@req.params) end - if @api =~ /^file_(content|bucket_file)/ && @req.get? - env["HTTP_ACCEPT"] = "binary" - elsif @api == "file_bucket_file" && (@req.post? || @req.put?) + env["HTTP_ACCEPT"] = env["HTTP_ACCEPT"].split(/\s*,\s*/).map { |a| a.sub(/^raw|s$/, 'binary') }.uniq.join(', ') + if @api == "file_bucket_file" && (@req.post? || @req.put?) env["CONTENT_TYPE"] = "application/octet-stream" end master.call(env).tap do |res| if @api =~ /^file_(content|bucket_file)/ && @req.get? # Always respond with text/plain to Puppet 3 clients. res[1]["Content-Type"] = "text/plain" end end end end use Puppet3Compat <% end -%> # NOTE: it's unfortunate that we have to use the "CommandLine" class # here to launch the app, but it contains some initialization logic # (such as triggering the parsing of the config file) that is very # important. We should do something less nasty here when we've # gotten our API and settings initialization logic cleaned up. # # Also note that the "$0 = master" line up near the top here is # the magic that allows the CommandLine class to know that it's # supposed to be running master. # # --cprice 2012-05-22 # #Ensure UTF-8 is our default (sadly Ruby 1.9 sets to US-ASCII) Encoding.default_external = Encoding::UTF_8 if defined? Encoding require 'puppet/util/command_line' # we're usually running inside a Rack::Builder.new {} block, # therefore we need to call run *here*. run Puppet::Util::CommandLine.new.execute