Signed-off-by: Brice Figureau <brice-pup...@daysofwonder.com>
---
 bin/puppetmasterd                       |  168 +----------------
 lib/puppet/application/puppetmasterd.rb |  143 ++++++++++++++
 spec/unit/application/puppetmasterd.rb  |  323 +++++++++++++++++++++++++++++++
 3 files changed, 468 insertions(+), 166 deletions(-)
 create mode 100644 lib/puppet/application/puppetmasterd.rb
 create mode 100644 spec/unit/application/puppetmasterd.rb

diff --git a/bin/puppetmasterd b/bin/puppetmasterd
index 3abdb77..9f12f67 100755
--- a/bin/puppetmasterd
+++ b/bin/puppetmasterd
@@ -62,169 +62,5 @@
 # Copyright (c) 2005 Reductive Labs, LLC
 # Licensed under the GNU Public License
 
-# Do an initial trap, so that cancels don't get a stack trace.
-trap(:INT) do
-    $stderr.puts "Cancelling startup"
-    exit(0)
-end
-
-require 'getoptlong'
-require 'puppet'
-require 'puppet/daemon'
-require 'puppet/network/server'
-
-# Create this first-off, so we have ARGV
-daemon = Puppet::Daemon.new
-daemon.argv = ARGV.dup
-
-options = [
-       [ "--debug",    "-d",                   GetoptLong::NO_ARGUMENT ],
-       [ "--help",             "-h",                   GetoptLong::NO_ARGUMENT 
],
-       [ "--logdest",  "-l",                   GetoptLong::REQUIRED_ARGUMENT ],
-       [ "--verbose",  "-v",                   GetoptLong::NO_ARGUMENT ],
-    [ "--version",  "-V",           GetoptLong::NO_ARGUMENT ]
-]
-
-# Add all of the config parameters as valid options.
-Puppet.settings.addargs(options)
-
-result = GetoptLong.new(*options)
-
-options = {
-    :setdest => false,
-    :verbose => false,
-    :debug => false
-}
-
-begin
-    result.each { |opt,arg|
-        case opt
-            # First check to see if the argument is a valid configuration 
parameter;
-            # if so, set it. NOTE: there is a catch-all at the bottom for 
defaults.rb
-            when "--debug"
-                options[:debug] = true
-            when "--help"
-                if Puppet.features.usage?
-                    RDoc::usage && exit
-                else
-                    puts "No help available unless you have RDoc::usage 
installed"
-                    exit
-                end
-            when "--logdest"
-                begin
-                    Puppet::Util::Log.newdestination(arg)
-                    options[:setdest] = true
-                rescue => detail
-                    if Puppet[:debug]
-                        puts detail.backtrace
-                    end
-                    $stderr.puts detail.to_s
-                end
-            when "--version"
-                puts "%s" % Puppet.version
-                exit
-            when "--verbose"
-                options[:verbose] = true
-            else
-                Puppet.settings.handlearg(opt, arg)
-        end
-    }
-rescue GetoptLong::InvalidOption => detail
-    $stderr.puts "Try '#{$0} --help'"
-    #$stderr.puts detail
-    exit(1)
-end
-
-# Now parse the config
-Puppet.parse_config
-
-# Handle the logging settings.
-if options[:debug] or options[:verbose]
-    if options[:debug]
-        Puppet::Util::Log.level = :debug
-    else
-        Puppet::Util::Log.level = :info
-    end
-
-    unless Puppet[:daemonize]
-        Puppet::Util::Log.newdestination(:console)
-        options[:setdest] = true
-    end
-end
-
-unless options[:setdest]
-    Puppet::Util::Log.newdestination(:syslog)
-end
-
-if Puppet.settings.print_configs?
-    exit(Puppet.settings.print_configs ? 0 : 1)
-end
-
-Puppet.settings.use :main, :puppetmasterd, :ssl
-
-# 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
-
-# Configure all of the SSL stuff.
-if Puppet::SSL::CertificateAuthority.ca?
-    Puppet::SSL::Host.ca_location = :local
-    Puppet.settings.use :ca
-    Puppet::SSL::CertificateAuthority.instance
-else
-    Puppet::SSL::Host.ca_location = :none
-end
-
-require 'etc'
-
-if Puppet[:parseonly]
-    begin
-        Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
-    rescue => detail
-        Puppet.err detail
-        exit 1
-    end
-    exit(0)
-end
-
-require 'puppet/file_serving/content'
-require 'puppet/file_serving/metadata'
-require 'puppet/checksum'
-
-xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
-
-# Just set up serving to all of the indirected classes.
-rest_handlers = Puppet::Indirector::Indirection.instances
-
-if Puppet[:ca]
-    xmlrpc_handlers << :CA
-end
-
-daemon.server = Puppet::Network::Server.new(:handlers => rest_handlers, 
:xmlrpc_handlers => xmlrpc_handlers)
-
-# Make sure we've got a localhost ssl cert
-Puppet::SSL::Host.localhost
-
-# And now configure our server to *only* hit the CA for data, because that's
-# all it will have write access to.
-if Puppet::SSL::CertificateAuthority.ca?
-    Puppet::SSL::Host.ca_location = :only
-end
-
-if Process.uid == 0
-    begin
-        Puppet::Util.chuser
-    rescue => detail
-        puts detail.backtrace if Puppet[:trace]
-        $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], 
detail]
-        exit(39)
-    end
-end
-
-daemon.daemonize if Puppet[:daemonize]
-
-Puppet.notice "Starting Puppet server version %s" % [Puppet.version]
-
-daemon.start
+require 'puppet/application/puppetmasterd'
+Puppet::Application[:puppetmasterd].run
diff --git a/lib/puppet/application/puppetmasterd.rb 
b/lib/puppet/application/puppetmasterd.rb
new file mode 100644
index 0000000..e9b2e7f
--- /dev/null
+++ b/lib/puppet/application/puppetmasterd.rb
@@ -0,0 +1,143 @@
+require 'puppet'
+require 'puppet/application'
+require 'puppet/daemon'
+require 'puppet/network/server'
+
+puppetmasterd_options = [
+    [ "--debug",    "-d",   GetoptLong::NO_ARGUMENT ],
+    [ "--help",     "-h",   GetoptLong::NO_ARGUMENT ],
+    [ "--logdest",  "-l",   GetoptLong::REQUIRED_ARGUMENT ],
+    [ "--verbose",  "-v",   GetoptLong::NO_ARGUMENT ],
+    [ "--version",  "-V",   GetoptLong::NO_ARGUMENT ]
+]
+
+Puppet::Application.new(:puppetmasterd, puppetmasterd_options) do
+
+    should_parse_config
+
+    dispatch do
+        return Puppet[:parseonly] ? :parseonly : :main
+    end
+
+    command(:parseonly) do
+        begin
+            Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
+        rescue => detail
+            Puppet.err detail
+            exit 1
+        end
+        exit(0)
+    end
+
+    command(:main) do
+        require 'etc'
+        require 'puppet/file_serving/content'
+        require 'puppet/file_serving/metadata'
+        require 'puppet/checksum'
+
+        xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
+
+        # Just set up serving to all of the indirected classes.
+        rest_handlers = Puppet::Indirector::Indirection.instances
+
+        if Puppet[:ca]
+            xmlrpc_handlers << :CA
+        end
+
+        @daemon.server = Puppet::Network::Server.new(:handlers => 
rest_handlers, :xmlrpc_handlers => xmlrpc_handlers)
+
+        # Make sure we've got a localhost ssl cert
+        Puppet::SSL::Host.localhost
+
+        # And now configure our server to *only* hit the CA for data, because 
that's
+        # all it will have write access to.
+        if Puppet::SSL::CertificateAuthority.ca?
+            Puppet::SSL::Host.ca_location = :only
+        end
+
+        if Process.uid == 0
+            begin
+                Puppet::Util.chuser
+            rescue => detail
+                puts detail.backtrace if Puppet[:trace]
+                $stderr.puts "Could not change user to %s: %s" % 
[Puppet[:user], detail]
+                exit(39)
+            end
+        end
+
+        @daemon.daemonize if Puppet[:daemonize]
+
+        Puppet.notice "Starting Puppet server version %s" % [Puppet.version]
+
+        @daemon.start
+    end
+
+    setup do
+        # Handle the logging settings.
+        if options[:debug] or options[:verbose]
+            if options[:debug]
+                Puppet::Util::Log.level = :debug
+            else
+                Puppet::Util::Log.level = :info
+            end
+
+            unless Puppet[:daemonize]
+                Puppet::Util::Log.newdestination(:console)
+                options[:setdest] = true
+            end
+        end
+
+        unless options[:setdest]
+            Puppet::Util::Log.newdestination(:syslog)
+        end
+
+        if Puppet.settings.print_configs?
+            exit(Puppet.settings.print_configs ? 0 : 1)
+        end
+
+        Puppet.settings.use :main, :puppetmasterd, :ssl
+
+        # 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
+
+        # Configure all of the SSL stuff.
+        if Puppet::SSL::CertificateAuthority.ca?
+            Puppet::SSL::Host.ca_location = :local
+            Puppet.settings.use :ca
+            Puppet::SSL::CertificateAuthority.instance
+        else
+            Puppet::SSL::Host.ca_location = :none
+        end
+    end
+
+    preinit do
+        trap(:INT) do
+            $stderr.puts "Cancelling startup"
+            exit(0)
+        end
+
+        # Create this first-off, so we have ARGV
+        @daemon = Puppet::Daemon.new
+        @daemon.argv = ARGV.dup
+    end
+
+    option(:logdest) do |arg|
+        begin
+            Puppet::Util::Log.newdestination(arg)
+            options[:setdest] = true
+        rescue => detail
+            if Puppet[:debug]
+                puts detail.backtrace
+            end
+            $stderr.puts detail.to_s
+        end
+    end
+
+    option(:version) do |arg|
+        puts "%s" % Puppet.version
+        exit
+    end
+end
\ No newline at end of file
diff --git a/spec/unit/application/puppetmasterd.rb 
b/spec/unit/application/puppetmasterd.rb
new file mode 100644
index 0000000..f66ec8c
--- /dev/null
+++ b/spec/unit/application/puppetmasterd.rb
@@ -0,0 +1,323 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/application/puppetmasterd'
+
+describe "PuppetMaster" do
+    before :each do
+        @puppetmasterd = Puppet::Application[:puppetmasterd]
+        @daemon = stub_everything 'daemon'
+        Puppet::Daemon.stubs(:new).returns(@daemon)
+    end
+
+    it "should ask Puppet::Application to parse Puppet configuration file" do
+        @puppetmasterd.should_parse_config?.should be_true
+    end
+
+    it "should declare a main command" do
+        @puppetmasterd.should respond_to(:main)
+    end
+
+    it "should declare a parseonly command" do
+        @puppetmasterd.should respond_to(:parseonly)
+    end
+
+    it "should declare a preinit block" do
+        @puppetmasterd.should respond_to(:run_preinit)
+    end
+
+    describe "during preinit" do
+        before :each do
+            @puppetmasterd.stubs(:trap)
+        end
+
+        it "should catch INT" do
+            @puppetmasterd.stubs(:trap).with { |arg,block| arg == :INT }
+
+            @puppetmasterd.run_preinit
+        end
+
+        it "should create a Puppet Daemon" do
+            Puppet::Daemon.expects(:new).returns(@daemon)
+
+            @puppetmasterd.run_preinit
+        end
+
+        it "should give ARGV to the Daemon" do
+            argv = stub 'argv'
+            ARGV.stubs(:dup).returns(argv)
+            @daemon.expects(:argv=).with(argv)
+
+            @puppetmasterd.run_preinit
+        end
+
+    end
+
+    describe "when applying options" do
+        it "should exit after printing the version" do
+            @puppetmasterd.stubs(:puts)
+
+            lambda { @puppetmasterd.handle_version(nil) }.should 
raise_error(SystemExit)
+        end
+
+        it "should set the log destination with --logdest" do
+            Puppet::Log.expects(:newdestination).with("console")
+
+            @puppetmasterd.handle_logdest("console")
+        end
+
+        it "should put the setdest options to true" do
+            @puppetmasterd.options.expects(:[]=).with(:setdest,true)
+
+            @puppetmasterd.handle_logdest("console")
+        end
+    end
+
+    describe "during setup" do
+
+        before :each do
+            Puppet::Log.stubs(:newdestination)
+            Puppet.stubs(:settraps)
+            Puppet::Log.stubs(:level=)
+            Puppet::SSL::CertificateAuthority.stubs(:instance)
+            Puppet::SSL::CertificateAuthority.stubs(:ca?)
+            Puppet.settings.stubs(:use)
+
+            @puppetmasterd.options.stubs(:[]).with(any_parameters)
+        end
+
+        it "should set log level to debug if --debug was passed" do
+            @puppetmasterd.options.stubs(:[]).with(:debug).returns(true)
+
+            Puppet::Log.expects(:level=).with(:debug)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should set log level to info if --verbose was passed" do
+            @puppetmasterd.options.stubs(:[]).with(:verbose).returns(true)
+
+            Puppet::Log.expects(:level=).with(:info)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should set console as the log destination if no --logdest and 
--daemonize" do
+            @puppetmasterd.stubs(:[]).with(:daemonize).returns(:false)
+
+            Puppet::Log.expects(:newdestination).with(:syslog)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should set syslog as the log destination if no --logdest and not 
--daemonize" do
+            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)
+
+            Puppet.settings.expects(:print_configs)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should exit after printing puppet config if asked to in Puppet 
config" do
+            Puppet.settings.stubs(:print_configs?).returns(true)
+
+            lambda { @puppetmasterd.run_setup }.should raise_error(SystemExit)
+        end
+
+        it "should tell Puppet.settings to use :main,:ssl and :puppetmasterd 
category" do
+            Puppet.settings.expects(:use).with(:main,:puppetmasterd,:ssl)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should set node facst terminus to yaml" do
+            Puppet::Node::Facts.expects(:terminus_class=).with(:yaml)
+
+            @puppetmasterd.run_setup
+        end
+
+        it "should cache class in yaml" do
+            Puppet::Node.expects(:cache_class=).with(:yaml)
+
+            @puppetmasterd.run_setup
+        end
+
+        describe "with no ca" do
+
+            it "should set the ca_location to none" do
+                Puppet::SSL::Host.expects(:ca_location=).with(:none)
+
+                @puppetmasterd.run_setup
+            end
+
+        end
+
+        describe "with a ca configured" do
+
+            before :each do
+                Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
+            end
+
+            it "should set the ca_location to local" do
+                Puppet::SSL::Host.expects(:ca_location=).with(:local)
+
+                @puppetmasterd.run_setup
+            end
+
+            it "should tell Puppet.settings to use :ca category" do
+                Puppet.settings.expects(:use).with(:ca)
+
+                @puppetmasterd.run_setup
+            end
+
+            it "should instantiate the CertificateAuthority singleton" do
+                Puppet::SSL::CertificateAuthority.expects(:instance)
+
+                @puppetmasterd.run_setup
+            end
+
+
+        end
+
+    end
+
+    describe "when running" do
+
+        it "should dispatch to parseonly if parseonly is set" do
+            Puppet.stubs(:[]).with(:parseonly).returns(true)
+
+            @puppetmasterd.get_command.should == :parseonly
+        end
+
+        it "should dispatch to main if parseonly is not set" do
+            Puppet.stubs(:[]).with(:parseonly).returns(false)
+
+            @puppetmasterd.get_command.should == :main
+        end
+
+        describe "the parseonly command" do
+            before :each do
+                Puppet.stubs(:[]).with(:environment)
+                Puppet.stubs(:[]).with(:manifest).returns("site.pp")
+                @interpreter = stub_everything
+                Puppet.stubs(:err)
+                @puppetmasterd.stubs(:exit)
+                Puppet::Parser::Interpreter.stubs(:new).returns(@interpreter)
+            end
+
+            it "should delegate to the Puppet Parser" do
+
+                @interpreter.expects(:parser)
+
+                @puppetmasterd.parseonly
+            end
+
+            it "should exit with exit code 0 if no error" do
+                @puppetmasterd.expects(:exit).with(0)
+
+                @puppetmasterd.parseonly
+            end
+
+            it "should exit with exit code 1 if error" do
+                @interpreter.stubs(:parser).raises(Puppet::ParseError)
+
+                @puppetmasterd.expects(:exit).with(1)
+
+                @puppetmasterd.parseonly
+            end
+
+        end
+
+        describe "the main command" do
+            before :each do
+                @puppetmasterd.run_preinit
+                @server = stub_everything 'server'
+                Puppet::Network::Server.stubs(:new).returns(@server)
+                Puppet::SSL::Host.stubs(:localhost)
+                Puppet::SSL::CertificateAuthority.stubs(:ca?)
+                Process.stubs(:uid).returns(1000)
+                Puppet.stubs(:service)
+                Puppet.stubs(:[])
+                Puppet.stubs(:notice)
+                Puppet.stubs(:start)
+            end
+
+            it "should create a Server" do
+                Puppet::Network::Server.expects(:new)
+
+                @puppetmasterd.main
+            end
+
+            it "should give the server to the daemon" do
+                @daemon.expects(:server=).with(@server)
+
+                @puppetmasterd.main
+            end
+
+            it "should create the server with the right XMLRPC handlers" do
+                Puppet::Network::Server.expects(:new).with { |args| 
args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket]}
+
+                @puppetmasterd.main
+            end
+
+            it "should create the server with a :ca xmlrpc handler if needed" 
do
+                Puppet.stubs(:[]).with(:ca).returns(true)
+                Puppet::Network::Server.expects(:new).with { |args| 
args[:xmlrpc_handlers].include?(:CA) }
+
+                @puppetmasterd.main
+            end
+
+            it "should create the server with the right REST handlers" do
+                
Puppet::Indirector::Indirection.stubs(:instances).returns("handlers")
+                Puppet::Network::Server.expects(:new).with { |args| 
args[:handlers] == "handlers"}
+
+                @puppetmasterd.main
+            end
+
+            it "should generate a SSL cert for localhost" do
+                Puppet::SSL::Host.expects(:localhost)
+
+                @puppetmasterd.main
+            end
+
+            it "should make sure to *only* hit the CA for data" do
+                Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
+
+                Puppet::SSL::Host.expects(:ca_location=).with(:only)
+
+                @puppetmasterd.main
+            end
+
+            it "should drop privileges if running as root" do
+                Process.stubs(:uid).returns(0)
+
+                Puppet::Util.expects(:chuser)
+
+                @puppetmasterd.main
+            end
+
+            it "should daemonize if needed" do
+                Puppet.stubs(:[]).with(:daemonize).returns(true)
+
+                @daemon.expects(:daemonize)
+
+                @puppetmasterd.main
+            end
+
+            it "should start the service" do
+                @daemon.expects(:start)
+
+                @puppetmasterd.main
+            end
+
+        end
+    end
+end
\ No newline at end of file
-- 
1.6.0.2


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

Reply via email to