summaryrefslogtreecommitdiffstats
path: root/lib/puppet/application/main.rb
blob: 2952ef4ae87307e450affaf85afe1005fae21427 (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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
require 'puppet'
require 'puppet/application'
require 'puppet/configurer'
require 'puppet/network/handler'
require 'puppet/network/client'

Puppet::Application.new(:main) do

    should_parse_config

    option("--debug","-d")
    option("--execute EXECUTE","-e") do |arg|
        options[:code] = arg
    end
    option("--loadclasses","-L")
    option("--verbose","-v")
    option("--use-nodes")
    option("--detailed-exitcodes")

    option("--apply catalog",  "-a catalog") do |arg|
        options[:catalog] = arg
    end

    option("--logdest LOGDEST", "-l") do |arg|
        begin
            Puppet::Util::Log.newdestination(arg)
            options[:logset] = true
        rescue => detail
            $stderr.puts detail.to_s
        end
    end

    dispatch do
        if options[:catalog]
            :apply
        elsif Puppet[:parseonly]
            :parseonly
        else
            :main
        end
    end

    command(:apply) do
        require 'puppet/configurer'

        if options[:catalog] == "-"
            text = $stdin.read
        else
            text = File.read(options[:catalog])
        end

        begin
            catalog = Puppet::Resource::Catalog.convert_from(Puppet::Resource::Catalog.default_format,text)
            unless catalog.is_a?(Puppet::Resource::Catalog)
                catalog = Puppet::Resource::Catalog.pson_create(catalog)
            end
        rescue => detail
            raise Puppet::Error, "Could not deserialize catalog from pson: %s" % detail
        end

        catalog = catalog.to_ral

        configurer = Puppet::Configurer.new
        configurer.run :catalog => catalog
    end

    command(:parseonly) do
        # Set our code or file to use.
        if options[:code] or ARGV.length == 0
            Puppet[:code] = options[:code] || STDIN.read
        else
            Puppet[:manifest] = ARGV.shift
        end
        begin
            Puppet::Resource::TypeCollection.new(Puppet[:environment]).perform_initial_import
        rescue => detail
            Puppet.err detail
            exit 1
        end
        exit 0
    end

    command(:main) do
        # Set our code or file to use.
        if options[:code] or ARGV.length == 0
            Puppet[:code] = options[:code] || STDIN.read
        else
            Puppet[:manifest] = ARGV.shift
        end

        # Collect our facts.
        unless facts = Puppet::Node::Facts.find(Puppet[:certname])
            raise "Could not find facts for %s" % Puppet[:certname]
        end

        # Find our Node
        unless node = Puppet::Node.find(Puppet[:certname])
            raise "Could not find node %s" % Puppet[:certname]
        end

        # Merge in the facts.
        node.merge(facts.values)

        # Allow users to load the classes that puppetd creates.
        if options[:loadclasses]
            file = Puppet[:classfile]
            if FileTest.exists?(file)
                unless FileTest.readable?(file)
                    $stderr.puts "%s is not readable" % file
                    exit(63)
                end
                node.classes = File.read(file).split(/[\s\n]+/)
            end
        end

        begin
            # Compile our catalog
            starttime = Time.now
            catalog = Puppet::Resource::Catalog.find(node.name, :use_node => node)

            # Translate it to a RAL catalog
            catalog = catalog.to_ral

            catalog.host_config = true if Puppet[:graph] or Puppet[:report]

            catalog.finalize

            catalog.retrieval_duration = Time.now - starttime

            configurer = Puppet::Configurer.new
            configurer.execute_prerun_command

            # And apply it
            transaction = catalog.apply

            configurer.execute_postrun_command

            status = 0
            if not Puppet[:noop] and options[:detailed_exitcodes] then
                transaction.generate_report
                exit(transaction.report.exit_status)
            else
                exit(0)
            end
        rescue => detail
            puts detail.backtrace if Puppet[:trace]
            if detail.is_a?(XMLRPC::FaultException)
                $stderr.puts detail.message
            else
                $stderr.puts detail
            end
            exit(1)
        end
    end

    setup do
        if Puppet.settings.print_configs?
            exit(Puppet.settings.print_configs ? 0 : 1)
        end

        # If noop is set, then also enable diffs
        if Puppet[:noop]
            Puppet[:show_diff] = true
        end

        unless options[:logset]
            Puppet::Util::Log.newdestination(:console)
        end
        client = nil
        server = nil

        trap(:INT) do
            $stderr.puts "Exiting"
            exit(1)
        end

        if options[:debug]
            Puppet::Util::Log.level = :debug
        elsif options[:verbose]
            Puppet::Util::Log.level = :info
        end
    end
end