summaryrefslogtreecommitdiffstats
path: root/lib/puppet/application/puppet.rb
blob: c8ca81975538e38f0bde1fa478cc02e220fe218a (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
require 'puppet'
require 'puppet/application'
require 'puppet/network/handler'
require 'puppet/network/client'

Puppet::Application.new(:puppet) do

    should_parse_config

    option("--debug","-d")
    option("--execute EXECUTE","-e")
    option("--loadclasses","-L")
    option("--verbose","-v")
    option("--use-nodes")
    option("--detailed-exitcodes")

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

    option("--version",  "-V") do |arg|
        puts "%s" % Puppet.version
        exit
    end

    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
        # Collect our facts.
        facts = Puppet::Node::Facts.find(Puppet[:certname])

        # 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

            # And apply it
            transaction = catalog.apply

            status = 0
            if not Puppet[:noop] and options[:detailed_exits] then
                transaction.generate_report
                status |= 2 if transaction.report.metrics["changes"][:total] > 0
                status |= 4 if transaction.report.metrics["resources"][:failed] > 0
            end
            exit(status)
        rescue => detail
            if Puppet[:trace]
                puts detail.backtrace
            end
            if detail.is_a?(XMLRPC::FaultException)
                $stderr.puts detail.message
            else
                $stderr.puts detail
            end
            exit(1)
        end
    end

    setup do
        # Now parse the config
        if Puppet[:config] and File.exists? Puppet[:config]
            Puppet.settings.parse(Puppet[:config])
        end

        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

        # 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
    end
end