summaryrefslogtreecommitdiffstats
path: root/lib/puppet/application/master.rb
blob: a8ed27c42f02358784b9907ab1f49c18d3005cd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
require 'puppet/application'

class Puppet::Application::Master < Puppet::Application

    should_parse_config
    run_mode :master

    option("--debug", "-d")
    option("--verbose", "-v")

    # internal option, only to be used by ext/rack/config.ru
    option("--rack")

    option("--compile host",  "-c host") do |arg|
        options[:node] = arg
    end

    option("--logdest DEST",  "-l DEST") 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

    def preinit
        trap(:INT) do
            $stderr.puts "Cancelling startup"
            exit(0)
        end

        # Create this first-off, so we have ARGV
        require 'puppet/daemon'
        @daemon = Puppet::Daemon.new
        @daemon.argv = ARGV.dup
    end

    def run_command
        if options[:node]
            compile
        elsif Puppet[:parseonly]
            parseonly
        else
            main
        end
    end

    def compile
        Puppet::Util::Log.newdestination :console
        raise ArgumentError, "Cannot render compiled catalogs without pson support" unless Puppet.features.pson?
        begin
            unless catalog = Puppet::Resource::Catalog.find(options[:node])
                raise "Could not compile catalog for %s" % options[:node]
            end

            jj catalog.to_resource
        rescue => detail
            $stderr.puts detail
            exit(30)
        end
        exit(0)
    end

    def parseonly
        begin
            Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
        rescue => detail
            Puppet.err detail
            exit 1
        end
        exit(0)
    end

    def main
        require 'etc'
        require 'puppet/file_serving/content'
        require 'puppet/file_serving/metadata'

        xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]

        if Puppet[:ca]
            xmlrpc_handlers << :CA
        end

        # 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 Puppet.features.root?
            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

        unless options[:rack]
            require 'puppet/network/server'
            @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

        Puppet.notice "Starting Puppet master version %s" % [Puppet.version]

        unless options[:rack]
            @daemon.start
        else
            return @app
        end
    end

    def setup
        # 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] or options[:rack]
                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, :master, :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
end