summaryrefslogtreecommitdiffstats
path: root/lib/puppet/client.rb
blob: 4f2718b7d50a8c23764f569095fbb1ab2164f21b (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
184
185
186
187
188
189
190
191
192
193
194
# the available clients

require 'puppet'
require 'puppet/networkclient'

module Puppet
    # FIXME this still isn't a good design, because none of the handlers overlap
    # so i could just as easily include them all in the main module
    # but at least it's better organized for now
    class Client
        include Puppet
        include Puppet::Daemon

        include Puppet::Util

        # FIXME The cert stuff should only come up with networking, so it
        # should be in the network client, not the normal client.  But if i do
        # that, it's hard to tell whether the certs have been initialized.
        include Puppet::Daemon
        attr_reader :secureinit
        attr_accessor :schedule, :lastrun, :local, :stopping

        class << self
            attr_reader :drivername, :handler
            attr_accessor :netclient
        end

        def initcerts
            unless self.readcert
                #if self.is_a? Puppet::Client::CA
                    unless self.requestcert
                        return nil
                    end
                #else
                #    return nil
                #end
                #unless self.requestcert
                #end
            end

            # unless we have a driver, we're a local client and we can't add
            # certs anyway, so it doesn't matter
            unless @driver
                return true
            end

            self.setcerts
        end

        def initialize(hash)
            # to whom do we connect?
            @server = nil
            @nil = nil
            @secureinit = hash[:NoSecureInit] || true

            if hash.include?(:FQDN)
                @fqdn = hash[:FQDN]
            else
                self.fqdn
            end

            if hash.include?(:Cache)
                @cache = hash[:Cache]
            else
                @cache = true
            end

            driverparam = self.class.drivername
            if hash.include?(:Server)
                if $noclientnetworking
                    raise NetworkClientError.new("Networking not available: %s" %
                        $nonetworking)
                end

                args = {:Server => hash[:Server]}
                args[:Port] = hash[:Port] || Puppet[:masterport]

                if self.readcert
                    args[:Certificate] = @cert
                    args[:Key] = @key
                    args[:CAFile] = @cacertfile
                end

                netclient = nil
                unless netclient = self.class.netclient
                    unless handler = self.class.handler
                        raise Puppet::DevError,
                            "Class %s has no handler defined" % self.class
                    end
                    namespace = self.class.handler.interface.prefix
                    netclient = Puppet::NetworkClient.netclient(namespace)
                    self.class.netclient = netclient
                end
                @driver = netclient.new(args)
                @local = false
            elsif hash.include?(driverparam)
                @driver = hash[driverparam]
                @local = true
            else
                raise ClientError, "%s must be passed a Server or %s" %
                    [self.class, driverparam]
            end
        end

        # Are we a local client?
        def local?
            if defined? @local and @local
                true
            else
                false
            end
        end

        # A wrapper method to run and then store the last run time
        def runnow
            if self.stopping
                Puppet.notice "In shutdown progress; skipping run"
                return
            end
            begin
                self.run
                self.lastrun = Time.now.to_i
            rescue => detail
                if Puppet[:trace]
                    puts detail.backtrace
                end
                Puppet.err "Could not run %s: %s" % [self.class, detail]
            end
        end

        def run
            raise Puppet::DevError, "Client type %s did not override run" %
                self.class
        end

        def scheduled?
            if sched = self.schedule
                return sched.match?(self.lastrun)
            else
                return true
            end
        end

        def setcerts
            @driver.cert = @cert
            @driver.key = @key
            @driver.ca_file = @cacertfile
        end

        def shutdown
            if self.stopping
                Puppet.notice "Already in shutdown"
            else
                self.stopping = true
                if self.respond_to? :running? and self.running?
                    Puppet::Storage.store
                end
                rmpidfile()
            end
        end

        # Start listening for events.  We're pretty much just listening for
        # timer events here.
        def start
            setpidfile()
            # Create our timer.  Puppet will handle observing it and such.
            timer = Puppet.newtimer(
                :interval => Puppet[:runinterval],
                :tolerance => 1,
                :start? => true
            ) do
                if self.scheduled?
                    self.runnow
                end
            end

            # Run once before we start following the timer
            self.runnow
        end

        require 'puppet/client/proxy'
        require 'puppet/client/ca'
        require 'puppet/client/dipper'
        require 'puppet/client/file'
        require 'puppet/client/log'
        require 'puppet/client/master'
        require 'puppet/client/runner'
        require 'puppet/client/status'
        require 'puppet/client/reporter'
        require 'puppet/client/pelement'
    end
end

# $Id$