Hmm, I could have sworn I had commentary on this patch, but I can't  
seem to find anything I disagree with.  I guess it'd be nice to see  
direct support in puppetmasterd for this.

It should be pretty straightforward to add support for it using the -- 
servertype switch, rather than using this config.ru file.

Otherwise, +1

On Sep 25, 2008, at 4:31 PM, Christian Hofstaedtler wrote:

>
> Tried mailing this 5 times or so but it didn't show up on the list,
> now trying with the Google Groups web interface...
>
> From 39cad0d23fe87baf3f8a591d7884e15b10004407 Mon Sep 17 00:00:00 2001
> From: Christian Hofstaedtler <[EMAIL PROTECTED]>
> Date: Wed, 24 Sep 2008 10:07:38 +0200
> Subject: [PATCH 1/1] Implement a Puppetmaster inside Passenger
>
> This consists of a new Puppet::Network::HTTPServer::Rack,
> plus configuration details for Passenger.
>
> Signed-off-by: Christian Hofstaedtler <[EMAIL PROTECTED]>
> ---
> ext/passenger/README                   |   63 ++++++++++++++
> ext/passenger/apache2.conf             |   29 ++++++
> ext/passenger/config.ru                |   40 +++++++++
> lib/puppet/network/http_server/rack.rb |  148 ++++++++++++++++++++++++
> ++++++++
> 4 files changed, 280 insertions(+), 0 deletions(-)
> create mode 100644 ext/passenger/README
> create mode 100644 ext/passenger/apache2.conf
> create mode 100644 ext/passenger/config.ru
> create mode 100644 lib/puppet/network/http_server/rack.rb
>
> diff --git a/ext/passenger/README b/ext/passenger/README
> new file mode 100644
> index 0000000..fcdcb91
> --- /dev/null
> +++ b/ext/passenger/README
> @@ -0,0 +1,63 @@
> +
> +PUPPETMASTER INSIDE APACHE & PASSENGER
> +======================================
> +
> +This is about running a puppetmaster inside Apache.
> +
> +Please also see the docs at 
> http://reductivelabs.com/trac/puppet/wiki/UsingPassenger
> +for further information.
> +
> +
> +WHAT IS IT?
> +===========
> +
> +Passenger [1] (AKA mod_rails or mod_rack) is an Apache 2.x Extension
> for
> +serving Rails or Rack applications.
> +
> +This extension allows running a puppetmasterd as a Rack application;
> +it has only been tested with Passenger.
> +
> +
> +SHORT INSTALLATION INSTRUCTIONS
> +===============================
> +
> +Make sure puppetmasterd ran at least once, so the SSL certificates
> +got set up.
> +
> +Install Rack:
> +  gem install -v 0.4.0 rack
> +
> +Install Apache and Passenger:
> +  apt-get install apache2
> +  gem install passenger
> +  passenger-install-apache2-module
> +  (See the Passenger installation instructions [2] for details.)
> +
> +Enable Apache modules:
> +  a2enmod ssl
> +  a2enmod headers
> +
> +Configure Apache:
> +  cp apache2.conf /etc/apache2/conf.d/puppetmasterd
> +  vim /etc/apache2/conf.d/puppetmasterd (replace the server
> hostnames)
> +
> +Install the rack application [3]:
> +  mkdir -p /usr/share/puppet/rack/puppetmasterd
> +  mkdir /usr/share/puppet/rack/puppetmasterd/public /usr/share/ 
> puppet/
> rack/puppetmasterd/tmp
> +  cp config.ru /usr/share/puppet/rack/puppetmasterd
> +  chown puppet /usr/share/puppet/rack/puppetmasterd/config.ru
> +
> +Go:
> +/etc/init.d/apache2 restart
> +
> +
> +
> +[1] http://www.modrails.com/
> +
> +[2] http://www.modrails.com/install.html
> +
> +[3] Passenger will not let applications run as root or the Apache
> user,
> +instead an implicit setuid will be done, to the user whom owns
> +config.ru. Therefore, config.ru shall be owned by the puppet user.
> +
> +
> diff --git a/ext/passenger/apache2.conf b/ext/passenger/apache2.conf
> new file mode 100644
> index 0000000..6a8a974
> --- /dev/null
> +++ b/ext/passenger/apache2.conf
> @@ -0,0 +1,29 @@
> +Listen 8140
> +<VirtualHost *:8140>
> +     SSLEngine on
> +     SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
> +     SSLCertificateFile      /var/lib/puppet/ssl/certs/puppet-
> server.inqnet.at.pem
> +     SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/puppet-
> server.inqnet.at.pem
> +     SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
> +     SSLCACertificateFile    /var/lib/puppet/ssl/ca/ca_crt.pem
> +     # If Apache complains about invalid signatures on the CRL, you can
> try disabling
> +     # CRL checking by commenting the next line.
> +     SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
> +     SSLVerifyClient optional
> +     SSLVerifyDepth  1
> +     SSLOptions +StdEnvVars
> +
> +     # The following client headers allow the same configuration to work
> with Pound.
> +     RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
> +     RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
> +     RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
> +
> +     RackAutoDetect On
> +     DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/
> +     <Directory /usr/share/puppet/rack/puppetmasterd/>
> +             Options None
> +             AllowOverride None
> +             Order allow,deny
> +             allow from all
> +     </Directory>
> +</VirtualHost>
> diff --git a/ext/passenger/config.ru b/ext/passenger/config.ru
> new file mode 100644
> index 0000000..8608292
> --- /dev/null
> +++ b/ext/passenger/config.ru
> @@ -0,0 +1,40 @@
> +# Author: Christian Hofstaedtler <[EMAIL PROTECTED]>
> +# Copyright (c) 2007 Luke Kanies, 2008 Christian Hofstaedtler
> +#
> +# This file is mostly based on puppetmasterd, which is part of
> +# the standard puppet distribution.
> +
> +require 'rack'
> +require 'puppet'
> +require 'puppet/network/http_server/rack'
> +
> +# startup code from bin/puppetmasterd
> +Puppet.parse_config
> +Puppet::Util::Log.level = :info
> +Puppet::Util::Log.newdestination(:syslog)
> +# A temporary solution, to at least make the master work for now.
> +Puppet::Node::Facts.terminus_class = :yaml
> +# Cache our nodes in yaml.  Currently not configurable.
> +Puppet::Node.cache_class = :yaml
> +
> +# The list of handlers running inside this puppetmaster
> +handlers = {
> +     :Status => {},
> +     :FileServer => {},
> +     :Master => {},
> +     :CA => {},
> +     :FileBucket => {},
> +     :Report => {}
> +}
> +
> +# Fire up the Rack-Server instance
> +server = Puppet::Network::HTTPServer::Rack.new(handlers)
> +
> +# prepare the rack app
> +app = proc do |env|
> +     server.process(env)
> +end
> +
> +# Go.
> +run app
> +
> diff --git a/lib/puppet/network/http_server/rack.rb b/lib/puppet/
> network/http_server/rack.rb
> new file mode 100644
> index 0000000..801c9d1
> --- /dev/null
> +++ b/lib/puppet/network/http_server/rack.rb
> @@ -0,0 +1,148 @@
> +# Author: Christian Hofstaedtler <[EMAIL PROTECTED]>
> +# Copyright (c) 2006 Manuel Holtgrewe, 2007 Luke Kanies,
> +#               2008 Christian Hofstaedtler
> +#
> +# This file is mostly based on the mongrel module, which is part of
> +# the standard puppet distribution.
> +#
> +# puppet/network/http_server/mongrel.rb has the following license,
> +# and is based heavily on a file retrieved from:
> +# http://ttt.ggnore.net/2006/11/15/xmlrpc-with-mongrel-and-ruby-off-rails/
> +#
> +# Permission is hereby granted, free of charge, to any person
> obtaining
> +# a copy of this software and associated documentation files (the
> +# "Software"), to deal in the Software without restriction, including
> +# without limitation the rights to use, copy, modify, merge, publish,
> +# distribute, sublicense, and/or sell copies of the Software, and to
> +# permit persons to whom the Software is furnished to do so, subject
> to
> +# the following conditions:
> +#
> +# The above copyright notice and this permission notice shall be
> +# included in all copies or substantial portions of the Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> +# SOFTWARE.
> +
> +
> +require 'puppet'
> +require 'puppet/network/handler'
> +require 'puppet/sslcertificates'
> +
> +require 'xmlrpc/server'
> +require 'puppet/network/xmlrpc/server'
> +require 'puppet/network/http_server'
> +require 'puppet/network/client_request'
> +require 'puppet/network/handler'
> +
> +require 'resolv'
> +require 'rack'
> +
> +# A handler for a Rack-style puppet(master)d. For the most part, it
> works
> +# exactly the same as HTTPServer::Mongrel:
> +# After checking whether the request itself is sane, the handler
> forwards
> +# it to an internal instance of XMLRPC::BasicServer to process it.
> +module Puppet::Network
> +     class HTTPServer::Rack
> +             attr_reader :xmlrpc_server
> +
> +             def initialize(handlers)
> +                     @debug = false
> +                     if Puppet[:debug]
> +                             @debug = true
> +                     end
> +
> +                     Puppet.info "Starting Rack server for puppet version 
> %s" %
> Puppet.version
> +                     if Puppet[:name] != "puppetmasterd" then
> +                             Puppet.warning 'Rack server is not named 
> "puppetmasterd", this
> may be not what you want. ($0 = %s)' % $0
> +                     end
> +
> +                     @xmlrpc_server = Puppet::Network::XMLRPCServer.new
> +                     handlers.each do |name, args|
> +                             unless handler = 
> Puppet::Network::Handler.handler(name)
> +                                     raise ArgumentError, "Invalid handler 
> %s" % name
> +                             end
> +                             h = handler.new(args)
> +                             @xmlrpc_server.add_handler(handler.interface, h)
> +                     end
> +                     Puppet.info "Rack server is waiting to serve requests."
> +             end
> +
> +             # Validate a rack-style request (in env), and run the requested
> XMLRPC
> +             # call.
> +             def process(env)
> +                     # time to serve a request
> +                     req = Rack::Request.new(env)
> +
> +                     if @debug then
> +                             Puppet.info "Handling request, details:"
> +                             env.each do |name, val|
> +                                     l = "  env: %s ->" % name
> +                                     l = l + ' %s' % val
> +                                     Puppet.info l
> +                             end
> +                     end
> +
> +                     if not req.post? then
> +                             return [405, { "Content-Type" => "text/html" }, 
> "Method Not
> Allowed"]
> +                     end
> +                     if req.media_type() != "text/xml" then
> +                             return [400, { "Content-Type" => "text/html" }, 
> "Bad Request"]
> +                     end
> +                     if req.content_length().to_i <= 0 then
> +                             return [411, { "Content-Type" => "text/html" }, 
> "Length
> Required"]
> +                     end
> +
> +                     body = ''
> +                     req.body().each { |line| body = body + line }
> +                     if @debug then
> +                             Puppet.info "Request Body: %s" % body
> +                     end
> +                     if body.size != req.content_length().to_i then
> +                             if @debug then
> +                                     Puppet.info "body length didnt match 
> %d" % body.size
> +                                     Puppet.info " vs. -> %d" % 
> req.content_length().to_i
> +                             end
> +                             return [400, { "Content-Type" => "text/html" }, 
> "Bad Request
> Length"]
> +                     end
> +                     info = client_info(env)
> +                     begin
> +                             data = @xmlrpc_server.process(body, info)
> +                             return [200, { "Content-Type" => "text/xml; 
> charset=utf-8" },
> data]
> +                     rescue => detail
> +                             Puppet.err "Rack: Internal Server Error: 
> XMLRPC_Server.process
> problem. Details follow: "
> +                             detail.backtrace.each { |line|  Puppet.err " 
> --> %s" % line }
> +                             return [500, { "Content-Type" => "text/html" }, 
> "Internal Server
> Error"]
> +                     end
> +             end
> +
> +             private
> +
> +             def client_info(request)
> +                     ip = request["REMOTE_ADDR"]
> +                     # JJM #906 The following dn.match regular expression is 
> forgiving
> +                     # enough to match the two Distinguished Name string 
> contents
> +                     # coming from Apache, Pound or other reverse SSL 
> proxies.
> +                     if dn = request[Puppet[:ssl_client_header]] and 
> dn_matchdata =
> dn.match(/^.*?CN\s*=\s*(.*)/)
> +                             client = dn_matchdata[1].to_str
> +                             valid = 
> (request[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
> +                     else
> +                             begin
> +                                     client = Resolv.getname(ip)
> +                             rescue => detail
> +                                     Puppet.err "Could not resolve %s: %s" % 
> [ip, detail]
> +                                     client = "unknown"
> +                             end
> +                             valid = false
> +                     end
> +                     info = Puppet::Network::ClientRequest.new(client, ip, 
> valid)
> +                     return info
> +             end
> +     end
> +end
> +
> --
> 1.5.4.3
>
>
> >


-- 
Should I say "I believe in physics", or "I know that physics is true"?
     -- Ludwig Wittgenstein, On Certainty, 602.
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to