~nvalcarcel/ubuntu/lucid/puppet/fix-546677

« back to all changes in this revision

Viewing changes to lib/puppet/application/puppetrun.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
begin
 
2
    require 'rubygems'
 
3
rescue LoadError
 
4
    # Nothing; we were just doing this just in case
 
5
end
 
6
 
 
7
begin
 
8
    require 'ldap'
 
9
rescue LoadError
 
10
    $stderr.puts "Failed to load ruby LDAP library. LDAP functionality will not be available"
 
11
end
 
12
 
 
13
require 'puppet'
 
14
require 'puppet/application'
 
15
 
 
16
Puppet::Application.new(:puppetrun) do
 
17
 
 
18
    should_not_parse_config
 
19
 
 
20
    attr_accessor :hosts, :tags, :classes
 
21
 
 
22
    option("--all","-a")
 
23
    option("--foreground","-f")
 
24
    option("--debug","-d")
 
25
    option("--ping","-P")
 
26
    option("--test")
 
27
 
 
28
    option("--host HOST") do |arg|
 
29
        @hosts << arg
 
30
    end
 
31
 
 
32
    option("--tag TAG", "-t") do |arg|
 
33
        @tags << arg
 
34
    end
 
35
 
 
36
    option("--class CLASS", "-c") do |arg|
 
37
        @classes << arg
 
38
    end
 
39
 
 
40
    option("--no-fqdn", "-n") do |arg|
 
41
        options[:fqdn] = false
 
42
    end
 
43
 
 
44
    option("--parallel PARALLEL", "-p") do |arg|
 
45
        begin
 
46
            options[:parallel] = Integer(arg)
 
47
        rescue
 
48
            $stderr.puts "Could not convert %s to an integer" % arg.inspect
 
49
            exit(23)
 
50
        end
 
51
    end
 
52
 
 
53
 
 
54
    dispatch do
 
55
        options[:test] ? :test : :main
 
56
    end
 
57
 
 
58
    command(:test) do
 
59
        puts "Skipping execution in test mode"
 
60
        exit(0)
 
61
    end
 
62
 
 
63
    command(:main) do
 
64
        require 'puppet/network/client'
 
65
        require 'puppet/util/ldap/connection'
 
66
 
 
67
        todo = @hosts.dup
 
68
 
 
69
        failures = []
 
70
 
 
71
        # Now do the actual work
 
72
        go = true
 
73
        while go
 
74
            # If we don't have enough children in process and we still have hosts left to
 
75
            # do, then do the next host.
 
76
            if @children.length < options[:parallel] and ! todo.empty?
 
77
                host = todo.shift
 
78
                pid = fork do
 
79
                    run_for_host(host)
 
80
                end
 
81
                @children[pid] = host
 
82
            else
 
83
                # Else, see if we can reap a process.
 
84
                begin
 
85
                    pid = Process.wait
 
86
 
 
87
                    if host = @children[pid]
 
88
                        # Remove our host from the list of children, so the parallelization
 
89
                        # continues working.
 
90
                        @children.delete(pid)
 
91
                        if $?.exitstatus != 0
 
92
                            failures << host
 
93
                        end
 
94
                        print "%s finished with exit code %s\n" % [host, $?.exitstatus]
 
95
                    else
 
96
                        $stderr.puts "Could not find host for PID %s with status %s" %
 
97
                            [pid, $?.exitstatus]
 
98
                    end
 
99
                rescue Errno::ECHILD
 
100
                    # There are no children left, so just exit unless there are still
 
101
                    # children left to do.
 
102
                    next unless todo.empty?
 
103
 
 
104
                    if failures.empty?
 
105
                        puts "Finished"
 
106
                        exit(0)
 
107
                    else
 
108
                        puts "Failed: %s" % failures.join(", ")
 
109
                        exit(3)
 
110
                    end
 
111
                end
 
112
            end
 
113
        end
 
114
    end
 
115
 
 
116
    def run_for_host(host)
 
117
        if options[:ping]
 
118
            out = %x{ping -c 1 #{host}}
 
119
            unless $? == 0
 
120
                $stderr.print "Could not contact %s\n" % host
 
121
                next
 
122
            end
 
123
        end
 
124
        client = Puppet::Network::Client.runner.new(
 
125
            :Server => host,
 
126
            :Port => Puppet[:puppetport]
 
127
        )
 
128
 
 
129
        print "Triggering %s\n" % host
 
130
        begin
 
131
            result = client.run(@tags, options[:ignoreschedules] || false, options[:foreground] || false)
 
132
        rescue => detail
 
133
            puts detail.backtrace if Puppet[:trace]
 
134
            $stderr.puts "Host %s failed: %s\n" % [host, detail]
 
135
            exit(2)
 
136
        end
 
137
 
 
138
        case result
 
139
        when "success"; exit(0)
 
140
        when "running"
 
141
            $stderr.puts "Host %s is already running" % host
 
142
            exit(3)
 
143
        else
 
144
            $stderr.puts "Host %s returned unknown answer '%s'" % [host, result]
 
145
            exit(12)
 
146
        end
 
147
    end
 
148
 
 
149
    preinit do
 
150
        [:INT, :TERM].each do |signal|
 
151
            trap(signal) do
 
152
                $stderr.puts "Cancelling"
 
153
                exit(1)
 
154
            end
 
155
        end
 
156
        options[:parallel] = 1
 
157
        options[:verbose] = true
 
158
        options[:fqdn] = true
 
159
        options[:ignoreschedules] = false
 
160
        options[:foreground] = false
 
161
 
 
162
        @hosts = []
 
163
        @classes = []
 
164
        @tags = []
 
165
    end
 
166
 
 
167
    setup do
 
168
        if options[:debug]
 
169
            Puppet::Util::Log.level = :debug
 
170
        else
 
171
            Puppet::Util::Log.level = :info
 
172
        end
 
173
 
 
174
        # Now parse the config
 
175
        Puppet.parse_config
 
176
 
 
177
        if Puppet[:node_terminus] == "ldap" and (options[:all] or @classes)
 
178
            if options[:all]
 
179
                @hosts = Puppet::Node.search("whatever").collect { |node| node.name }
 
180
                puts "all: %s" % @hosts.join(", ")
 
181
            else
 
182
                @hosts = []
 
183
                @classes.each do |klass|
 
184
                    list = Puppet::Node.search("whatever", :class => klass).collect { |node| node.name }
 
185
                    puts "%s: %s" % [klass, list.join(", ")]
 
186
 
 
187
                    @hosts += list
 
188
                end
 
189
            end
 
190
        elsif ! @classes.empty?
 
191
            $stderr.puts "You must be using LDAP to specify host classes"
 
192
            exit(24)
 
193
        end
 
194
 
 
195
        if @tags.empty?
 
196
            @tags = ""
 
197
        else
 
198
            @tags = @tags.join(",")
 
199
        end
 
200
 
 
201
        @children = {}
 
202
 
 
203
        # If we get a signal, then kill all of our children and get out.
 
204
        [:INT, :TERM].each do |signal|
 
205
            trap(signal) do
 
206
                Puppet.notice "Caught #{signal}; shutting down"
 
207
                @children.each do |pid, host|
 
208
                    Process.kill("INT", pid)
 
209
                end
 
210
 
 
211
                waitall
 
212
 
 
213
                exit(1)
 
214
            end
 
215
        end
 
216
 
 
217
    end
 
218
 
 
219
end