Ok.  The code looks ready to go, but I haven't had a chance to test it  
yet.  Has anyone else been able to test it?

On May 1, 2009, at 10:56 PM, Christian Hofstaedtler wrote:

>
> * Luke Kanies <[email protected]> [090501 15:47]:
>>
>> +1, with a comment or two below
>
> Thanks; I've now fixed everything I found, rebased onto current
> master (and fixed a bug that came up because of this), and now
> tested against rack 1.0.0, which was recently released.
>
>> On Apr 28, 2009, at 3:41 PM, Christian Hofstaedtler wrote:
>>
>>>
>>> From: Christian Hofstaedtler <[email protected]>
>>>
>>>
>>> Signed-off-by: Christian Hofstaedtler <[email protected]>
>>> ---
>>> ext/rack/README                         |   76 ++++++++++++++++++++ 
>>> ++
>>> +++++++++
>>> ext/rack/apache2.conf                   |   24 ++++++++++
>>> ext/rack/config.ru                      |   16 +++++++
>>> lib/puppet/application/puppetmasterd.rb |   22 +++++++--
>>> spec/unit/application/puppetmasterd.rb  |   41 +++++++++++++++++
>>> 5 files changed, 174 insertions(+), 5 deletions(-)
>>> create mode 100644 ext/rack/README
>>> create mode 100644 ext/rack/apache2.conf
>>> create mode 100644 ext/rack/config.ru
>>>
>>> diff --git a/ext/rack/README b/ext/rack/README
>>> new file mode 100644
>>> index 0000000..dc15158
>>> --- /dev/null
>>> +++ b/ext/rack/README
>>> @@ -0,0 +1,76 @@
>>> +
>>> +PUPPETMASTER AS A RACK APPLICATION
>>> +==================================
>>> +
>>> +puppetmaster can now be hosted as a standard Rack application. A
>>> proper
>>> +config.ru is provided for this.
>>> +
>>> +For more details about rack, see http://rack.rubyforge.org/ .
>>> +
>>> +Getting started
>>> +===============
>>> +
>>> +You'll need rack installed. Puppetmaster has only been tested with
>>> version
>>> +0.9.1.
>>> +
>>> +
>>> +WEBrick
>>> +-------
>>> +
>>> +WEBrick is currently not supported as a Rack host. You'll be better
>>> off
>>> +just running puppetmasterd directly.
>>> +
>>> +
>>> +Mongrel
>>> +-------
>>> +
>>> +If you like Mongrel, and want to replicate wiki:UsingMongrel, you
>>> could
>>> +probably start your backend mongrels this way:
>>> +
>>> +cd ext/rack
>>> +for port in `seq 18140 18150`; do
>>> +  rackup --server mongrel --port $port &
>>> +done
>>> +
>>> +rackup is part of the rack gem. Make sure it's in your path.
>>> +
>>> +
>>> +
>>> +Apache with Passenger (aka mod_rails)
>>> +-------------------------------------
>>> +
>>> +Make sure puppetmasterd ran at least once, so the SSL certificates
>>> +got set up.
>>
>> Is this still true?  I expect things to work better now, and if not,
>> it's quite easy (using Puppet::SSL::Host) to generate the certs.
>
> Well, Apache won't start if the certificate files don't exist yet.
>
>>> +Install Rack:
>>> +  gem install -v 0.9.1 rack
>>> +
>>> +Install Apache and Passenger:
>>> +  apt-get install apache2
>>> +  gem install passenger
>>> +  passenger-install-apache2-module
>>> +  (See the Passenger installation instructions [1] 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 [2]:
>>> +  chown puppet ext/rack/config.ru
>>> +
>>> +Go:
>>> +/etc/init.d/apache2 restart
>>
>> This could almost be a puppet manifest. :)
>
> True. I've now put most of this into a manifest.
>
>>>
>>> +[1] http://www.modrails.com/install.html
>>> +
>>> +[2] 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/rack/apache2.conf b/ext/rack/apache2.conf
>>> new file mode 100644
>>> index 0000000..0711316
>>> --- /dev/null
>>> +++ b/ext/rack/apache2.conf
>>> @@ -0,0 +1,24 @@
>>> +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
>>> +
>>> +   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/rack/config.ru b/ext/rack/config.ru
>>> new file mode 100644
>>> index 0000000..171b07e
>>> --- /dev/null
>>> +++ b/ext/rack/config.ru
>>> @@ -0,0 +1,16 @@
>>> +# 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:
>>> +$:.push('/home/ch/puppet-cleanrack/lib')
>>> +
>>> +require 'puppet'
>>> +Puppet.settings[:name] = "puppetmasterd"
>>> +
>>> +ARGV << "--debug"
>>> +ARGV << "--rack"
>>> +require 'puppet/application/puppetmasterd'
>>> +# we're usually running inside a Rack::Builder.new {} block,
>>> +# therefore we need to call run *here*.
>>> +run Puppet::Application[:puppetmasterd].run
>>> +
>>> diff --git a/lib/puppet/application/puppetmasterd.rb b/lib/puppet/
>>> application/puppetmasterd.rb
>>> index fe92bca..85dc58f 100644
>>> --- a/lib/puppet/application/puppetmasterd.rb
>>> +++ b/lib/puppet/application/puppetmasterd.rb
>>> @@ -2,6 +2,7 @@ require 'puppet'
>>> require 'puppet/application'
>>> require 'puppet/daemon'
>>> require 'puppet/network/server'
>>> +require 'puppet/network/http/rack' if Puppet.features.rack?
>>>
>>> Puppet::Application.new(:puppetmasterd) do
>>>
>>> @@ -10,6 +11,9 @@ Puppet::Application.new(:puppetmasterd) do
>>>    option("--debug", "-d")
>>>    option("--verbose", "-v")
>>>
>>> +    # internal option, only to be used by ext/rack/config.ru
>>> +    option("--rack")
>>> +
>>>    option("--logdest",  "-l") do |arg|
>>>        begin
>>>            Puppet::Util::Log.newdestination(arg)
>>> @@ -59,8 +63,6 @@ Puppet::Application.new(:puppetmasterd) do
>>>            xmlrpc_handlers << :CA
>>>        end
>>>
>>> -        @daemon.server =
>>> Puppet::Network::Server.new(:xmlrpc_handlers => xmlrpc_handlers)
>>> -
>>>        # Make sure we've got a localhost ssl cert
>>>        Puppet::SSL::Host.localhost
>>>
>>> @@ -80,11 +82,21 @@ Puppet::Application.new(:puppetmasterd) do
>>>            end
>>>        end
>>>
>>> -        @daemon.daemonize if Puppet[:daemonize]
>>> +        if not options[:rack]
>>
>> As with Brice, I prefer 'unless options[:rack]'.
>
> Fixed.
>
>>>
>>> +            @daemon.server =
>>> Puppet::Network::Server.new(:xmlrpc_handlers => xmlrpc_handlers)
>>> +            @daemon.daemonize if Puppet[:daemonize]
>>> +        else
>>> +            require 'puppet/network/http/rack'
>>> +            @app = Puppet::Network::HTTP::Rack.new(:xmlrpc_handlers
>>> => xmlrpc_handlers, :protocols => [:rest, :xmlrpc])
>>> +        end
>>
>> I'd think that you could still do Network::Server.new, because it
>> basically just passes through to the Rack instance, right?
>
> Well, with --rack specified, it is assumed that there is no daemon
> puppetmaster can control, therefore 90% of P::Network::Server would
> be useless/would need to be if'd out.
>
>>>
>>>        Puppet.notice "Starting Puppet server version %s" %
>>> [Puppet.version]
>>>
>>> -        @daemon.start
>>> +        if not options[:rack]
>>> +            @daemon.start
>>> +        else
>>> +            return @app
>>> +        end
>>
>> And for these, they could almost just be noops in the Rack app, but I
>> suppose that would be more confusing.  Certainly 'start' could
>> reasonable be a noop, anyway.
>>
>> Both of these are small points, btw.
>>
>>>
>>>    end
>>>
>>>    setup do
>>> @@ -96,7 +108,7 @@ Puppet::Application.new(:puppetmasterd) do
>>>                Puppet::Util::Log.level = :info
>>>            end
>>>
>>> -            unless Puppet[:daemonize]
>>> +            unless Puppet[:daemonize] or options[:rack]
>>>                Puppet::Util::Log.newdestination(:console)
>>>                options[:setdest] = true
>>>            end
>>> diff --git a/spec/unit/application/puppetmasterd.rb b/spec/unit/
>>> application/puppetmasterd.rb
>>> index 5b193eb..df6f878 100644
>>> --- a/spec/unit/application/puppetmasterd.rb
>>> +++ b/spec/unit/application/puppetmasterd.rb
>>> @@ -131,6 +131,14 @@ describe "PuppetMaster" do
>>>            @puppetmasterd.run_setup
>>>        end
>>>
>>> +        it "should set syslog as the log destination if --rack" do
>>> +            @puppetmasterd.options.stubs(:
>>> []).with(:rack).returns(:true)
>>> +
>>> +            Puppet::Log.expects(:newdestination).with(:syslog)
>>> +
>>> +            @puppetmasterd.run_setup
>>> +        end
>>> +
>>>        it "should print puppet config if asked to in Puppet config"
>>> do
>>>            @puppetmasterd.stubs(:exit)
>>>            Puppet.settings.stubs(:print_configs?).returns(true)
>>> @@ -255,6 +263,8 @@ describe "PuppetMaster" do
>>>                @puppetmasterd.run_preinit
>>>                @server = stub_everything 'server'
>>>                Puppet::Network::Server.stubs(:new).returns(@server)
>>> +                @app = stub_everything 'app'
>>> +                 
>>> Puppet::Network::HTTP::Rack.stubs(:new).returns(@app)
>>>                Puppet::SSL::Host.stubs(:localhost)
>>>                Puppet::SSL::CertificateAuthority.stubs(:ca?)
>>>                Process.stubs(:uid).returns(1000)
>>> @@ -325,6 +335,37 @@ describe "PuppetMaster" do
>>>                @puppetmasterd.main
>>>            end
>>>
>>> +            describe "with --rack" do
>>> +                confine "Rack is not available" =>
>>> Puppet.features.rack?
>>> +
>>> +                it "it should create the app with REST and XMLRPC
>>> support" do
>>> +                    @puppetmasterd.options.stubs(:
>>> []).with(:rack).returns(:true)
>>> +
>>> +                    Puppet::Network::HTTP::Rack.expects(:new).with
>>> { |args|
>>> +                        args[:xmlrpc_handlers] ==
>>> [:Status, :FileServer, :Master, :Report, :Filebucket] and
>>> +                        args[:protocols] == [:rest, :xmlrpc]
>>> +                    }
>>> +
>>> +                    @puppetmasterd.main
>>> +                end
>>> +
>>> +                it "it should not start a daemon" do
>>> +                    @puppetmasterd.options.stubs(:
>>> []).with(:rack).returns(:true)
>>> +
>>> +                    @daemon.expects(:start).never
>>> +
>>> +                    @puppetmasterd.main
>>> +                end
>>> +
>>> +                it "it should return the app" do
>>> +                    @puppetmasterd.options.stubs(:
>>> []).with(:rack).returns(:true)
>>> +
>>> +                    app = @puppetmasterd.main
>>> +                    app.should equal(@app)
>>> +                end
>>> +
>>> +            end
>>> +
>>>        end
>>>    end
>>> end
>>> -- 
>>> 1.5.6.5
>>>
>>>
>>>>
>
> -- 
> christian hofstaedtler
>
> >


-- 
Life isn't fair. It's just fairer than death, that's all.
     -- William Goldman
---------------------------------------------------------------------
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