summaryrefslogtreecommitdiffstats
path: root/lib/puppet/client.rb
blob: ae74492404f1bc00ab98411f6f9b3f039474ebb9 (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
# 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 SignalObserver

        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
        end

        def initcerts
            unless self.readcert
                unless self.requestcert
                    return nil
                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

                @driver = Puppet::NetworkClient.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

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

        # FIXME this should probably not store every single time.
        def shutdown
            if self.stopping
                Puppet.notice "Already in shutdown"
            else
                self.stopping = true
                Puppet::Storage.store
                exit
            end
        end

        # Start listening for events.  We're pretty much just listening for
        # timer events here.
        def start
            # Create our timer
            timer = EventLoop::Timer.new(
                :interval => Puppet[:runinterval],
                :tolerance => 1,
                :start? => true
            )

            # Stick it in the loop
            EventLoop.current.monitor_timer timer

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

            # And run indefinitely
            observe_signal timer, :alarm do
                if self.scheduled?
                    self.runnow
                end
            end
        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/status'
    end
end

# $Id$