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
|
# The client for interacting with the puppetmaster config server.
require 'sync'
require 'timeout'
require 'puppet/network/http_pool'
require 'puppet/util'
class Puppet::Configurer
require 'puppet/configurer/fact_handler'
require 'puppet/configurer/plugin_handler'
include Puppet::Configurer::FactHandler
include Puppet::Configurer::PluginHandler
# For benchmarking
include Puppet::Util
attr_accessor :catalog
attr_reader :compile_time
# Provide more helpful strings to the logging that the Agent does
def self.to_s
"Puppet configuration client"
end
class << self
# Puppetd should only have one instance running, and we need a way
# to retrieve it.
attr_accessor :instance
include Puppet::Util
end
# How to lock instances of this class.
def self.lockfile_path
Puppet[:puppetdlockfile]
end
def clear
@catalog.clear(true) if @catalog
@catalog = nil
end
# Initialize and load storage
def dostorage
begin
Puppet::Util::Storage.load
@compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
Puppet.err "Corrupt state file %s: %s" % [Puppet[:statefile], detail]
begin
::File.unlink(Puppet[:statefile])
retry
rescue => detail
raise Puppet::Error.new("Cannot remove %s: %s" %
[Puppet[:statefile], detail])
end
end
end
# Just so we can specify that we are "the" instance.
def initialize
Puppet.settings.use(:main, :ssl, :puppetd)
self.class.instance = self
@running = false
@splayed = false
end
# Prepare for catalog retrieval. Downloads everything necessary, etc.
def prepare
dostorage()
download_plugins()
download_fact_plugins()
upload_facts()
end
# Get the remote catalog, yo. Returns nil if no catalog can be found.
def retrieve_catalog
name = Facter.value("hostname")
catalog_class = Puppet::Resource::Catalog
# First try it with no cache, then with the cache.
result = nil
begin
duration = thinmark do
result = catalog_class.find(name, :ignore_cache => true)
end
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not retrieve catalog from remote server: %s" % detail
end
unless result
begin
duration = thinmark do
result = catalog_class.find(name, :ignore_terminus => true)
end
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not retrieve catalog from cache: %s" % detail
end
end
return nil unless result
convert_catalog(result, duration)
end
# Convert a plain resource catalog into our full host catalog.
def convert_catalog(result, duration)
catalog = result.to_ral
catalog.retrieval_duration = duration
catalog.host_config = true
catalog.write_class_file
return catalog
end
# The code that actually runs the catalog.
# This just passes any options on to the catalog,
# which accepts :tags and :ignoreschedules.
def run(options = {})
prepare()
unless catalog = retrieve_catalog
Puppet.err "Could not retrieve catalog; skipping run"
return
end
begin
benchmark(:notice, "Finished catalog run") do
catalog.apply(options)
end
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Failed to apply catalog: %s" % detail
end
# Now close all of our existing http connections, since there's no
# reason to leave them lying open.
Puppet::Network::HttpPool.clear_http_instances
end
private
def self.timeout
timeout = Puppet[:configtimeout]
case timeout
when String
if timeout =~ /^\d+$/
timeout = Integer(timeout)
else
raise ArgumentError, "Configuration timeout must be an integer"
end
when Integer # nothing
else
raise ArgumentError, "Configuration timeout must be an integer"
end
return timeout
end
end
|