puppet 0.9.2 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +58 -0
- data/README +21 -18
- data/Rakefile +176 -36
- data/bin/puppet +34 -48
- data/bin/puppetca +41 -28
- data/bin/puppetd +87 -65
- data/bin/puppetdoc +99 -23
- data/bin/puppetmasterd +72 -91
- data/conf/redhat/client.init +80 -0
- data/conf/redhat/client.sysconfig +11 -0
- data/conf/redhat/fileserver.conf +12 -0
- data/conf/redhat/puppet.spec +130 -0
- data/conf/redhat/server.init +89 -0
- data/conf/redhat/server.sysconfig +9 -0
- data/examples/code/allatonce +2 -2
- data/examples/code/assignments +1 -1
- data/examples/code/classing +2 -2
- data/examples/code/components +2 -2
- data/examples/code/file.bl +5 -5
- data/examples/code/filedefaults +2 -2
- data/examples/code/fileparsing +1 -1
- data/examples/code/filerecursion +1 -1
- data/examples/code/functions +1 -1
- data/examples/code/groups +1 -1
- data/examples/code/importing +1 -1
- data/examples/code/nodes +1 -1
- data/examples/code/one +1 -1
- data/examples/code/relationships +2 -2
- data/examples/code/simpletests +5 -5
- data/examples/code/snippets/argumentdefaults +2 -2
- data/examples/code/snippets/casestatement +16 -8
- data/examples/code/snippets/classheirarchy.pp +4 -4
- data/examples/code/snippets/classincludes.pp +4 -4
- data/examples/code/snippets/classpathtest +2 -2
- data/examples/code/snippets/componentmetaparams.pp +11 -0
- data/examples/code/snippets/dirchmod +5 -5
- data/examples/code/snippets/emptyclass.pp +9 -0
- data/examples/code/snippets/failmissingexecpath.pp +1 -1
- data/examples/code/snippets/falsevalues.pp +1 -1
- data/examples/code/snippets/filecreate +5 -5
- data/examples/code/snippets/implicititeration +5 -5
- data/examples/code/snippets/multipleinstances +4 -4
- data/examples/code/snippets/namevartest +3 -3
- data/examples/code/snippets/scopetest +1 -1
- data/examples/code/snippets/selectorvalues.pp +3 -3
- data/examples/code/snippets/simpledefaults +2 -2
- data/examples/code/snippets/simpleselector +5 -5
- data/examples/code/snippets/singleary.pp +19 -0
- data/examples/root/etc/init.d/sleeper +3 -2
- data/ext/emacs/puppet-mode-init.el +6 -0
- data/ext/emacs/puppet-mode.el +189 -0
- data/ext/ldap/puppet.schema +17 -0
- data/ext/{module:puppet → module_puppet} +30 -31
- data/ext/vim/filetype.vim +9 -0
- data/ext/vim/puppet.vim +87 -0
- data/install.rb +63 -30
- data/lib/puppet.rb +216 -122
- data/lib/puppet/client.rb +51 -416
- data/lib/puppet/client/ca.rb +17 -0
- data/lib/puppet/client/dipper.rb +78 -0
- data/lib/puppet/client/file.rb +20 -0
- data/lib/puppet/client/log.rb +17 -0
- data/lib/puppet/client/master.rb +246 -0
- data/lib/puppet/client/proxy.rb +27 -0
- data/lib/puppet/client/status.rb +7 -0
- data/lib/puppet/config.rb +563 -13
- data/lib/puppet/daemon.rb +50 -22
- data/lib/puppet/element.rb +4 -4
- data/lib/puppet/event-loop.rb +1 -0
- data/lib/puppet/event-loop/better-definers.rb +367 -0
- data/lib/puppet/event-loop/event-loop.rb +355 -0
- data/lib/puppet/event-loop/signal-system.rb +220 -0
- data/lib/puppet/event.rb +9 -11
- data/lib/puppet/filetype.rb +195 -0
- data/lib/puppet/log.rb +35 -12
- data/lib/puppet/metric.rb +2 -2
- data/lib/puppet/networkclient.rb +145 -0
- data/lib/puppet/parameter.rb +335 -0
- data/lib/puppet/parser/ast.rb +42 -1453
- data/lib/puppet/parser/ast/astarray.rb +88 -0
- data/lib/puppet/parser/ast/branch.rb +47 -0
- data/lib/puppet/parser/ast/caseopt.rb +66 -0
- data/lib/puppet/parser/ast/casestatement.rb +78 -0
- data/lib/puppet/parser/ast/classdef.rb +78 -0
- data/lib/puppet/parser/ast/compdef.rb +111 -0
- data/lib/puppet/parser/ast/component.rb +105 -0
- data/lib/puppet/parser/ast/hostclass.rb +82 -0
- data/lib/puppet/parser/ast/leaf.rb +86 -0
- data/lib/puppet/parser/ast/node.rb +103 -0
- data/lib/puppet/parser/ast/nodedef.rb +68 -0
- data/lib/puppet/parser/ast/objectdef.rb +336 -0
- data/lib/puppet/parser/ast/objectparam.rb +30 -0
- data/lib/puppet/parser/ast/objectref.rb +76 -0
- data/lib/puppet/parser/ast/selector.rb +60 -0
- data/lib/puppet/parser/ast/typedefaults.rb +45 -0
- data/lib/puppet/parser/ast/vardef.rb +44 -0
- data/lib/puppet/parser/interpreter.rb +31 -14
- data/lib/puppet/parser/lexer.rb +2 -4
- data/lib/puppet/parser/parser.rb +332 -242
- data/lib/puppet/parser/scope.rb +55 -38
- data/lib/puppet/server.rb +43 -44
- data/lib/puppet/server/authstore.rb +3 -6
- data/lib/puppet/server/ca.rb +5 -2
- data/lib/puppet/server/filebucket.rb +2 -4
- data/lib/puppet/server/fileserver.rb +28 -12
- data/lib/puppet/server/logger.rb +15 -4
- data/lib/puppet/server/master.rb +62 -7
- data/lib/puppet/sslcertificates.rb +41 -607
- data/lib/puppet/sslcertificates/ca.rb +291 -0
- data/lib/puppet/sslcertificates/certificate.rb +283 -0
- data/lib/puppet/statechange.rb +6 -1
- data/lib/puppet/storage.rb +67 -56
- data/lib/puppet/transaction.rb +25 -9
- data/lib/puppet/transportable.rb +102 -22
- data/lib/puppet/type.rb +1096 -315
- data/lib/puppet/type/component.rb +30 -21
- data/lib/puppet/type/cron.rb +409 -448
- data/lib/puppet/type/exec.rb +234 -174
- data/lib/puppet/type/group.rb +65 -82
- data/lib/puppet/type/nameservice.rb +247 -3
- data/lib/puppet/type/nameservice/netinfo.rb +29 -40
- data/lib/puppet/type/nameservice/objectadd.rb +52 -66
- data/lib/puppet/type/nameservice/posix.rb +6 -194
- data/lib/puppet/type/package.rb +447 -295
- data/lib/puppet/type/package/apt.rb +51 -50
- data/lib/puppet/type/package/bsd.rb +82 -0
- data/lib/puppet/type/package/dpkg.rb +85 -88
- data/lib/puppet/type/package/rpm.rb +67 -63
- data/lib/puppet/type/package/sun.rb +119 -98
- data/lib/puppet/type/package/yum.rb +41 -37
- data/lib/puppet/type/parsedtype.rb +295 -0
- data/lib/puppet/type/parsedtype/host.rb +143 -0
- data/lib/puppet/type/parsedtype/port.rb +232 -0
- data/lib/puppet/type/parsedtype/sshkey.rb +129 -0
- data/lib/puppet/type/pfile.rb +484 -460
- data/lib/puppet/type/pfile/checksum.rb +237 -181
- data/lib/puppet/type/pfile/content.rb +67 -0
- data/lib/puppet/type/pfile/ensure.rb +212 -0
- data/lib/puppet/type/pfile/group.rb +106 -105
- data/lib/puppet/type/pfile/mode.rb +98 -101
- data/lib/puppet/type/pfile/source.rb +228 -209
- data/lib/puppet/type/pfile/type.rb +18 -21
- data/lib/puppet/type/pfile/uid.rb +127 -130
- data/lib/puppet/type/pfilebucket.rb +68 -63
- data/lib/puppet/type/schedule.rb +341 -0
- data/lib/puppet/type/service.rb +351 -255
- data/lib/puppet/type/service/base.rb +9 -14
- data/lib/puppet/type/service/debian.rb +32 -38
- data/lib/puppet/type/service/init.rb +130 -130
- data/lib/puppet/type/service/smf.rb +48 -20
- data/lib/puppet/type/state.rb +229 -16
- data/lib/puppet/type/symlink.rb +51 -63
- data/lib/puppet/type/tidy.rb +105 -102
- data/lib/puppet/type/user.rb +118 -180
- data/lib/puppet/util.rb +100 -6
- data/test/certmgr/certmgr.rb +0 -1
- data/test/client/client.rb +4 -4
- data/test/executables/puppetbin.rb +7 -14
- data/test/executables/puppetca.rb +18 -24
- data/test/executables/puppetd.rb +7 -16
- data/test/executables/puppetmasterd.rb +7 -9
- data/test/executables/puppetmodule.rb +11 -16
- data/test/language/ast.rb +11 -7
- data/test/language/interpreter.rb +1 -1
- data/test/language/scope.rb +2 -0
- data/test/language/snippets.rb +30 -5
- data/test/language/transportable.rb +77 -0
- data/test/other/config.rb +316 -0
- data/test/other/events.rb +22 -21
- data/test/other/log.rb +14 -14
- data/test/other/metrics.rb +4 -8
- data/test/other/overrides.rb +5 -5
- data/test/other/relationships.rb +4 -2
- data/test/other/storage.rb +64 -3
- data/test/other/transactions.rb +20 -20
- data/test/parser/parser.rb +7 -4
- data/test/puppet/conffiles.rb +12 -12
- data/test/puppet/defaults.rb +13 -11
- data/test/puppet/utiltest.rb +14 -11
- data/test/puppettest.rb +156 -48
- data/test/server/bucket.rb +2 -2
- data/test/server/fileserver.rb +6 -6
- data/test/server/logger.rb +19 -11
- data/test/server/master.rb +33 -4
- data/test/server/server.rb +2 -7
- data/test/types/basic.rb +5 -7
- data/test/types/component.rb +22 -18
- data/test/types/cron.rb +111 -44
- data/test/types/exec.rb +116 -59
- data/test/types/file.rb +262 -137
- data/test/types/filebucket.rb +13 -15
- data/test/types/fileignoresource.rb +12 -16
- data/test/types/filesources.rb +73 -48
- data/test/types/filetype.rb +13 -15
- data/test/types/group.rb +15 -13
- data/test/types/host.rb +146 -0
- data/test/types/package.rb +74 -63
- data/test/types/port.rb +139 -0
- data/test/types/query.rb +8 -8
- data/test/types/schedule.rb +335 -0
- data/test/types/service.rb +137 -21
- data/test/types/sshkey.rb +140 -0
- data/test/types/symlink.rb +3 -5
- data/test/types/tidy.rb +5 -14
- data/test/types/type.rb +67 -11
- data/test/types/user.rb +25 -23
- metadata +186 -122
- data/lib/puppet/type/pfile/create.rb +0 -108
- data/lib/puppet/type/pprocess.rb +0 -97
- data/lib/puppet/type/typegen.rb +0 -149
- data/lib/puppet/type/typegen/filerecord.rb +0 -243
- data/lib/puppet/type/typegen/filetype.rb +0 -316
- data/test/other/state.rb +0 -106
@@ -0,0 +1,341 @@
|
|
1
|
+
module Puppet
|
2
|
+
newtype(:schedule) do
|
3
|
+
@doc = "Defined schedules for Puppet. The important thing to understand
|
4
|
+
about how schedules are currently implemented in Puppet is that they
|
5
|
+
can only be used to stop an element from being applied, they never
|
6
|
+
guarantee that it is applied.
|
7
|
+
|
8
|
+
Every time Puppet applies its configuration, it will collect the
|
9
|
+
list of elements whose schedule does not eliminate them from
|
10
|
+
running right then, but there is currently no system in place to
|
11
|
+
guarantee that a given element runs at a given time. If you
|
12
|
+
specify a very restrictive schedule and Puppet happens to run at a
|
13
|
+
time within that schedule, then the elements will get applied;
|
14
|
+
otherwise, that work may never get done.
|
15
|
+
|
16
|
+
Thus, it behooves you to use wider scheduling (e.g., over a couple of
|
17
|
+
hours) combined with periods and repetitions. For instance, if you
|
18
|
+
wanted to restrict certain elements to only running once, between
|
19
|
+
the hours of two and 4 AM, then you would use this schedule::
|
20
|
+
|
21
|
+
schedule { maint:
|
22
|
+
range => \"2 - 4\",
|
23
|
+
period => daily,
|
24
|
+
repeat => 1
|
25
|
+
}
|
26
|
+
|
27
|
+
With this schedule, the first time that Puppet runs between 2 and 4 AM,
|
28
|
+
all elements with this schedule will get applied, but they won't
|
29
|
+
get applied again between 2 and 4 because they will have already
|
30
|
+
run once that day, and they won't get applied outside that schedule
|
31
|
+
because they will be outside the scheduled range.
|
32
|
+
|
33
|
+
Puppet automatically creates a schedule for each valid period with the
|
34
|
+
same name as that period (e.g., hourly and daily). Additionally,
|
35
|
+
a schedule named *puppet* is created and used as the default,
|
36
|
+
with the following attributes::
|
37
|
+
|
38
|
+
schedule { puppet:
|
39
|
+
period => hourly,
|
40
|
+
repeat => 2
|
41
|
+
}
|
42
|
+
|
43
|
+
This will cause elements to be applied every 30 minutes by default.
|
44
|
+
"
|
45
|
+
|
46
|
+
@states = []
|
47
|
+
|
48
|
+
newparam(:name) do
|
49
|
+
desc "The name of the schedule. This name is used to retrieve the
|
50
|
+
schedule when assigning it to an object::
|
51
|
+
|
52
|
+
schedule { daily:
|
53
|
+
period => daily,
|
54
|
+
range => [2, 4]
|
55
|
+
}
|
56
|
+
|
57
|
+
exec { \"/usr/bin/apt-get update\":
|
58
|
+
schedule => daily
|
59
|
+
}
|
60
|
+
|
61
|
+
"
|
62
|
+
isnamevar
|
63
|
+
end
|
64
|
+
|
65
|
+
newparam(:range) do
|
66
|
+
desc "The earliest and latest that an element can be applied. This
|
67
|
+
is always a range within a 24 hour period, and hours must be
|
68
|
+
specified in numbers between 0 and 23, inclusive. Minutes and
|
69
|
+
seconds can be provided, using the normal colon as a separator.
|
70
|
+
For instance::
|
71
|
+
|
72
|
+
schedule { maintenance:
|
73
|
+
range => \"1:30 - 4:30\"
|
74
|
+
}
|
75
|
+
|
76
|
+
This is mostly useful for restricting certain elements to being
|
77
|
+
applied in maintenance windows or during off-peak hours."
|
78
|
+
|
79
|
+
# This is lame; states all use arrays as values, but parameters don't.
|
80
|
+
# That's going to hurt eventually.
|
81
|
+
validate do |values|
|
82
|
+
values = [values] unless values.is_a?(Array)
|
83
|
+
values.each { |value|
|
84
|
+
unless value.is_a?(String) and
|
85
|
+
value =~ /\d+(:\d+){0,2}\s*-\s*\d+(:\d+){0,2}/
|
86
|
+
self.fail "Invalid range value '%s'" % value
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
munge do |values|
|
92
|
+
values = [values] unless values.is_a?(Array)
|
93
|
+
ret = []
|
94
|
+
|
95
|
+
values.each { |value|
|
96
|
+
range = []
|
97
|
+
# Split each range value into a hour, minute, second triad
|
98
|
+
value.split(/\s*-\s*/).each { |val|
|
99
|
+
# Add the values as an array.
|
100
|
+
range << val.split(":").collect { |n| n.to_i }
|
101
|
+
}
|
102
|
+
|
103
|
+
if range.length != 2
|
104
|
+
self.fail "Invalid range %s" % value
|
105
|
+
end
|
106
|
+
|
107
|
+
if range[0][0] > range[1][0]
|
108
|
+
self.fail(("Invalid range %s; " % value) +
|
109
|
+
"ranges cannot span days."
|
110
|
+
)
|
111
|
+
end
|
112
|
+
ret << range
|
113
|
+
}
|
114
|
+
|
115
|
+
# Now our array of arrays
|
116
|
+
ret
|
117
|
+
end
|
118
|
+
|
119
|
+
def match?(previous, now)
|
120
|
+
# The lowest-level array is of the hour, minute, second triad
|
121
|
+
# then it's an array of two of those, to present the limits
|
122
|
+
# then it's array of those ranges
|
123
|
+
unless @value[0][0].is_a?(Array)
|
124
|
+
@value = [@value]
|
125
|
+
end
|
126
|
+
|
127
|
+
@value.each do |value|
|
128
|
+
limits = value.collect do |range|
|
129
|
+
ary = [now.year, now.month, now.day, range[0]]
|
130
|
+
if range[1]
|
131
|
+
ary << range[1]
|
132
|
+
else
|
133
|
+
ary << now.min
|
134
|
+
end
|
135
|
+
|
136
|
+
if range[2]
|
137
|
+
ary << range[2]
|
138
|
+
else
|
139
|
+
ary << now.sec
|
140
|
+
end
|
141
|
+
|
142
|
+
time = Time.local(*ary)
|
143
|
+
|
144
|
+
unless time.hour == range[0]
|
145
|
+
self.devfail(
|
146
|
+
"Incorrectly converted time: %s: %s vs %s" %
|
147
|
+
[time, time.hour, range[0]]
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
time
|
152
|
+
end
|
153
|
+
|
154
|
+
unless limits[0] < limits[1]
|
155
|
+
self.info(
|
156
|
+
"Assuming upper limit should be that time the next day"
|
157
|
+
)
|
158
|
+
|
159
|
+
ary = limits[1].to_a
|
160
|
+
ary[3] += 1
|
161
|
+
limits[1] = Time.local(*ary)
|
162
|
+
|
163
|
+
#self.devfail("Lower limit is above higher limit: %s" %
|
164
|
+
# limits.inspect
|
165
|
+
#)
|
166
|
+
end
|
167
|
+
|
168
|
+
#self.info limits.inspect
|
169
|
+
#self.notice now
|
170
|
+
return now.between?(*limits)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Else, return false, since our current time isn't between
|
174
|
+
# any valid times
|
175
|
+
return false
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
newparam(:periodmatch) do
|
180
|
+
desc "Whether periods should be matched by number (e.g., the two times
|
181
|
+
are in the same hour) or by distance (e.g., the two times are
|
182
|
+
60 minutes apart). *number*/**distance**"
|
183
|
+
|
184
|
+
newvalues(:number, :distance)
|
185
|
+
|
186
|
+
defaultto :distance
|
187
|
+
end
|
188
|
+
|
189
|
+
newparam(:period) do
|
190
|
+
desc "The period of repetition for an element. Choose from among
|
191
|
+
a fixed list of *hourly*, *daily*, *weekly*, and *monthly*.
|
192
|
+
The default is for an element to get applied every time that
|
193
|
+
Puppet runs, whatever that period is.
|
194
|
+
|
195
|
+
Note that the period defines how often a given element will get
|
196
|
+
applied but not when; if you would like to restrict the hours
|
197
|
+
that a given element can be applied (e.g., only at night during
|
198
|
+
a maintenance window) then use the ``range`` attribute.
|
199
|
+
|
200
|
+
If the provided periods are not sufficient, you can provide a
|
201
|
+
value to the *repeat* attribute, which will cause Puppet to
|
202
|
+
schedule the affected elements evenly in the period the
|
203
|
+
specified number of times. Take this schedule::
|
204
|
+
|
205
|
+
schedule { veryoften:
|
206
|
+
period => hourly,
|
207
|
+
repeat => 6
|
208
|
+
}
|
209
|
+
|
210
|
+
This can cause Puppet to apply that element up to every 10 minutes.
|
211
|
+
|
212
|
+
At the moment, Puppet cannot guarantee that level of
|
213
|
+
repetition; that is, it can run up to every 10 minutes, but
|
214
|
+
internal factors might prevent it from actually running that
|
215
|
+
often (e.g., long-running Puppet runs will squash conflictingly
|
216
|
+
scheduled runs).
|
217
|
+
|
218
|
+
See the ``periodmatch`` attribute for tuning whether to match
|
219
|
+
times by their distance apart or by their specific value."
|
220
|
+
|
221
|
+
newvalues(:hourly, :daily, :weekly, :monthly)
|
222
|
+
|
223
|
+
@@scale = {
|
224
|
+
:hourly => 3600,
|
225
|
+
:daily => 86400,
|
226
|
+
:weekly => 604800,
|
227
|
+
:monthly => 2592000
|
228
|
+
}
|
229
|
+
@@methods = {
|
230
|
+
:hourly => :hour,
|
231
|
+
:daily => :day,
|
232
|
+
:monthly => :month,
|
233
|
+
:weekly => proc do |prev, now|
|
234
|
+
prev.strftime("%U") == now.strftime("%U")
|
235
|
+
end
|
236
|
+
}
|
237
|
+
|
238
|
+
def match?(previous, now)
|
239
|
+
value = self.value
|
240
|
+
case @parent[:periodmatch]
|
241
|
+
when :number
|
242
|
+
method = @@methods[value]
|
243
|
+
if method.is_a?(Proc)
|
244
|
+
return method.call(previous, now)
|
245
|
+
else
|
246
|
+
# We negate it, because if they're equal we don't run
|
247
|
+
val = now.send(method) != previous.send(method)
|
248
|
+
return val
|
249
|
+
end
|
250
|
+
when :distance
|
251
|
+
scale = @@scale[value]
|
252
|
+
|
253
|
+
# If the number of seconds between the two times is greater
|
254
|
+
# than the unit of time, we match. We divide the scale
|
255
|
+
# by the repeat, so that we'll repeat that often within
|
256
|
+
# the scale.
|
257
|
+
return (now.to_i - previous.to_i) >= (scale / @parent[:repeat])
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
newparam(:repeat) do
|
263
|
+
desc "How often the application gets repeated in a given period.
|
264
|
+
Defaults to 1."
|
265
|
+
|
266
|
+
defaultto 1
|
267
|
+
|
268
|
+
validate do |value|
|
269
|
+
unless value.is_a?(Integer) or value =~ /^\d+$/
|
270
|
+
raise Puppet::Error,
|
271
|
+
"Repeat must be a number"
|
272
|
+
end
|
273
|
+
|
274
|
+
# This implicitly assumes that 'periodmatch' is distance -- that
|
275
|
+
# is, if there's no value, we assume it's a valid value.
|
276
|
+
return unless @parent[:periodmatch]
|
277
|
+
|
278
|
+
if value != 1 and @parent[:periodmatch] != :distance
|
279
|
+
raise Puppet::Error,
|
280
|
+
"Repeat must be 1 unless periodmatch is 'distance', not '%s'" %
|
281
|
+
@parent[:periodmatch]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
munge do |value|
|
286
|
+
unless value.is_a?(Integer)
|
287
|
+
value = Integer(value)
|
288
|
+
end
|
289
|
+
|
290
|
+
value
|
291
|
+
end
|
292
|
+
|
293
|
+
def match?(previous, now)
|
294
|
+
true
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def self.mkdefaultschedules
|
299
|
+
Puppet.info "Creating default schedules"
|
300
|
+
# Create our default schedule
|
301
|
+
self.create(
|
302
|
+
:name => "puppet",
|
303
|
+
:period => :hourly,
|
304
|
+
:repeat => "2"
|
305
|
+
)
|
306
|
+
|
307
|
+
# And then one for every period
|
308
|
+
@parameters.find { |p| p.name == :period }.values.each { |value|
|
309
|
+
self.create(
|
310
|
+
:name => value.to_s,
|
311
|
+
:period => value
|
312
|
+
)
|
313
|
+
}
|
314
|
+
end
|
315
|
+
|
316
|
+
def match?(previous = nil, now = nil)
|
317
|
+
|
318
|
+
# If we've got a value, then convert it to a Time instance
|
319
|
+
if previous
|
320
|
+
previous = Time.at(previous)
|
321
|
+
end
|
322
|
+
|
323
|
+
now ||= Time.now
|
324
|
+
|
325
|
+
# Pull them in order
|
326
|
+
self.class.allattrs.each { |param|
|
327
|
+
if @parameters.include?(param) and
|
328
|
+
@parameters[param].respond_to?(:match?)
|
329
|
+
#self.notice "Trying to match %s" % param
|
330
|
+
return false unless @parameters[param].match?(previous, now)
|
331
|
+
end
|
332
|
+
}
|
333
|
+
|
334
|
+
# If we haven't returned false, then return true; in other words,
|
335
|
+
# any provided schedules need to all match
|
336
|
+
return true
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
# $Id: schedule.rb 848 2006-01-24 06:01:58Z luke $
|
data/lib/puppet/type/service.rb
CHANGED
@@ -5,58 +5,68 @@
|
|
5
5
|
# which is why they have a search path for initscripts and such
|
6
6
|
|
7
7
|
module Puppet
|
8
|
-
class State
|
9
|
-
# Handle whether the service is started at boot time.
|
10
|
-
class ServiceEnabled < State
|
11
|
-
@doc = "Whether a service should be enabled to start at boot.
|
12
|
-
**true**/*false*/*runlevel*"
|
13
|
-
@name = :enabled
|
14
8
|
|
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
|
-
when :disabled
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
9
|
+
newtype(:service) do
|
10
|
+
@doc = "Manage running services. Service support unfortunately varies
|
11
|
+
widely by platform -- some platforms have very little if any
|
12
|
+
concept of a running service, and some have a very codified and
|
13
|
+
powerful concept. Puppet's service support will generally be able
|
14
|
+
to make up for any inherent shortcomings (e.g., if there is no
|
15
|
+
'status' command, then Puppet will look in the process table for a
|
16
|
+
command matching the service name), but the more information you
|
17
|
+
can provide the better behaviour you will get. Or, you can just
|
18
|
+
use a platform that has very good service support."
|
19
|
+
|
20
|
+
attr_reader :stat
|
21
|
+
|
22
|
+
# newstate(:enabled) do
|
23
|
+
# desc "Whether a service should be enabled to start at boot.
|
24
|
+
# **true**/*false*/*runlevel*"
|
25
|
+
#
|
26
|
+
# def retrieve
|
27
|
+
# unless @parent.respond_to?(:enabled?)
|
28
|
+
# raise Puppet::Error, "Service %s does not support enabling"
|
29
|
+
# end
|
30
|
+
# @is = @parent.enabled?
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# munge do |should|
|
34
|
+
# @runlevel = nil
|
35
|
+
# case should
|
36
|
+
# when true: return :enabled
|
37
|
+
# when false: return :disabled
|
38
|
+
# when /^\d+$/:
|
39
|
+
# @runlevel = should
|
40
|
+
# return :enabled
|
41
|
+
# else
|
42
|
+
# raise Puppet::Error, "Invalid 'enabled' value %s" % should
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# def sync
|
47
|
+
# case self.should
|
48
|
+
# when :enabled
|
49
|
+
# unless @parent.respond_to?(:enable)
|
50
|
+
# raise Puppet::Error, "Service %s does not support enabling"
|
51
|
+
# end
|
52
|
+
# @parent.enable(@runlevel)
|
53
|
+
# return :service_enabled
|
54
|
+
# when :disabled
|
55
|
+
# unless @parent.respond_to?(:disable)
|
56
|
+
# raise Puppet::Error,
|
57
|
+
# "Service %s does not support disabling"
|
58
|
+
# end
|
59
|
+
# @parent.disable
|
60
|
+
# return :service_disabled
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
# end
|
53
64
|
|
54
65
|
# Handle whether the service should actually be running right now.
|
55
|
-
|
56
|
-
|
57
|
-
@name = :running
|
66
|
+
newstate(:running) do
|
67
|
+
desc "Whether a service should be running. **true**/*false*"
|
58
68
|
|
59
|
-
|
69
|
+
munge do |should|
|
60
70
|
case should
|
61
71
|
when false,0,"0", "stopped", :stopped:
|
62
72
|
should = :stopped
|
@@ -64,10 +74,9 @@ module Puppet
|
|
64
74
|
should = :running
|
65
75
|
else
|
66
76
|
self.warning "%s: interpreting '%s' as false" %
|
67
|
-
[self.class,should]
|
77
|
+
[self.class,should.inspect]
|
68
78
|
should = 0
|
69
79
|
end
|
70
|
-
self.debug "Service should is %s" % should
|
71
80
|
return should
|
72
81
|
end
|
73
82
|
|
@@ -81,260 +90,347 @@ module Puppet
|
|
81
90
|
case self.should
|
82
91
|
when :running
|
83
92
|
@parent.start
|
84
|
-
|
93
|
+
self.info "started"
|
94
|
+
return :service_started
|
85
95
|
when :stopped
|
96
|
+
self.info "stopped"
|
86
97
|
@parent.stop
|
87
|
-
|
98
|
+
return :service_stopped
|
88
99
|
else
|
89
100
|
self.debug "Not running '%s' and shouldn't be running" %
|
90
101
|
self
|
91
102
|
end
|
92
103
|
end
|
93
104
|
end
|
94
|
-
end
|
95
105
|
|
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
|
-
assumed to be true."
|
121
|
-
@paramdoc[:name] = "The name of the service to run. This name
|
122
|
-
is used to find the init script in the search path."
|
123
|
-
@paramdoc[:path] = "The search path for finding init scripts.
|
124
|
-
There is currently no default, but hopefully soon there will
|
125
|
-
be a reasonable default for all platforms."
|
126
|
-
@paramdoc[:pattern] = "The pattern to search for in the process table.
|
127
|
-
This is used for stopping services on platforms that do not
|
128
|
-
support init scripts, and is also used for determining service
|
129
|
-
status on those service whose init scripts do not include a status
|
130
|
-
command."
|
131
|
-
@paramdoc[:restart] = "Specify a *restart* command manually. If left
|
132
|
-
unspecified, the restart method will be determined automatically."
|
133
|
-
@paramdoc[:start] = "Specify a *start* command manually. If left
|
134
|
-
unspecified, the start method will be determined automatically."
|
135
|
-
@paramdoc[:status] = "Specify a *status* command manually. If left
|
136
|
-
unspecified, the status method will be determined automatically."
|
137
|
-
@paramdoc[:stop] = "Specify a *stop* command manually. If left
|
138
|
-
unspecified, the stop method will be determined automatically."
|
139
|
-
|
140
|
-
@doc = "Manage running services. Rather than supporting managing
|
141
|
-
individual processes, puppet uses init scripts to simplify
|
142
|
-
specification of how to start, stop, or test processes. The
|
143
|
-
`path` parameter is provided to enable creation of multiple
|
144
|
-
init script directories, including supporting them for normal
|
145
|
-
users."
|
146
|
-
@name = :service
|
147
|
-
@namevar = :name
|
148
|
-
|
149
|
-
# Return the service type we're using. Default to the Service
|
150
|
-
# class itself, but could be set to a module.
|
151
|
-
class << self
|
152
|
-
attr_accessor :svctype
|
106
|
+
newparam(:type) do
|
107
|
+
desc "The service type. For most platforms, it does not make
|
108
|
+
sense to change set this parameter, as the default is based on
|
109
|
+
the builtin service facilities. The service types available are:
|
110
|
+
|
111
|
+
* ``base``: You must specify everything.
|
112
|
+
* ``init``: Assumes ``start`` and ``stop`` commands exist, but you
|
113
|
+
must specify everything else.
|
114
|
+
* ``debian``: Debian's own specific version of ``init``.
|
115
|
+
* ``smf``: Solaris 10's new Service Management Facility.
|
116
|
+
"
|
117
|
+
|
118
|
+
defaultto { @parent.class.defaulttype }
|
119
|
+
|
120
|
+
# Make sure we've got the actual module, not just a string
|
121
|
+
# representing the module.
|
122
|
+
munge do |type|
|
123
|
+
if type.is_a?(String)
|
124
|
+
type = @parent.class.svctype(type.intern)
|
125
|
+
end
|
126
|
+
Puppet.debug "Service type is %s" % type.name
|
127
|
+
@parent.extend(type)
|
128
|
+
|
129
|
+
return type
|
153
130
|
end
|
131
|
+
end
|
132
|
+
newparam(:binary) do
|
133
|
+
desc "The path to the daemon. This is only used for
|
134
|
+
systems that do not support init scripts. This binary will be
|
135
|
+
used to start the service if no ``start`` parameter is
|
136
|
+
provided."
|
137
|
+
end
|
138
|
+
newparam(:hasstatus) do
|
139
|
+
desc "Declare the the service's init script has a
|
140
|
+
functional status command. Based on testing, it was found
|
141
|
+
that a large number of init scripts on different platforms do
|
142
|
+
not support any kind of status command; thus, you must specify
|
143
|
+
manually whether the service you are running has such a
|
144
|
+
command (or you can specify a specific command using the
|
145
|
+
``status`` parameter).
|
146
|
+
|
147
|
+
If you do not specify anything, then the service name will be
|
148
|
+
looked for in the process table."
|
149
|
+
end
|
150
|
+
newparam(:name) do
|
151
|
+
desc "The name of the service to run. This name
|
152
|
+
is used to find the service in whatever service subsystem it
|
153
|
+
is in."
|
154
|
+
isnamevar
|
155
|
+
end
|
156
|
+
newparam(:path) do
|
157
|
+
desc "The search path for finding init scripts."
|
158
|
+
|
159
|
+
munge do |value|
|
160
|
+
paths = []
|
161
|
+
if value.is_a?(Array)
|
162
|
+
paths += value.flatten.collect { |p|
|
163
|
+
p.split(":")
|
164
|
+
}.flatten
|
165
|
+
else
|
166
|
+
paths = value.split(":")
|
167
|
+
end
|
154
168
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
@defsvctype = nil
|
159
|
-
os = Facter["operatingsystem"].value
|
160
|
-
case os
|
161
|
-
when "Linux":
|
162
|
-
case Facter["distro"].value
|
163
|
-
when "Debian":
|
164
|
-
@defsvctype = Puppet::ServiceTypes::DebianSvc
|
165
|
-
end
|
166
|
-
when "SunOS":
|
167
|
-
release = Float(Facter["operatingsystemrelease"].value)
|
168
|
-
if release < 5.10
|
169
|
-
@defsvctype = Puppet::ServiceTypes::InitSvc
|
170
|
-
else
|
171
|
-
@defsvctype = Puppet::ServiceTypes::SMFSvc
|
172
|
-
end
|
169
|
+
paths.each do |path|
|
170
|
+
if FileTest.directory?(path)
|
171
|
+
next
|
173
172
|
end
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
173
|
+
unless FileTest.directory?(path)
|
174
|
+
@parent.info("Search path %s is not a directory" % [path])
|
175
|
+
end
|
176
|
+
unless FileTest.exists?(path)
|
177
|
+
@parent.info("Search path %s does not exist" % [path])
|
178
178
|
end
|
179
|
+
paths.delete(path)
|
179
180
|
end
|
180
181
|
|
181
|
-
|
182
|
+
paths
|
183
|
+
end
|
184
|
+
end
|
185
|
+
newparam(:pattern) do
|
186
|
+
desc "The pattern to search for in the process table.
|
187
|
+
This is used for stopping services on platforms that do not
|
188
|
+
support init scripts, and is also used for determining service
|
189
|
+
status on those service whose init scripts do not include a status
|
190
|
+
command.
|
191
|
+
|
192
|
+
If this is left unspecified and is needed to check the status
|
193
|
+
of a service, then the service name will be used instead.
|
194
|
+
|
195
|
+
The pattern can be a simple string or any legal Ruby pattern."
|
196
|
+
defaultto { @parent.name }
|
197
|
+
end
|
198
|
+
newparam(:restart) do
|
199
|
+
desc "Specify a *restart* command manually. If left
|
200
|
+
unspecified, the service will be stopped and then started."
|
201
|
+
end
|
202
|
+
newparam(:start) do
|
203
|
+
desc "Specify a *start* command manually. Most service subsystems
|
204
|
+
support a ``start`` command, so this will not need to be
|
205
|
+
specified."
|
206
|
+
end
|
207
|
+
newparam(:status) do
|
208
|
+
desc "Specify a *status* command manually. If left
|
209
|
+
unspecified, the status method will be determined
|
210
|
+
automatically, usually by looking for the service int he
|
211
|
+
process table."
|
212
|
+
end
|
213
|
+
|
214
|
+
newparam(:stop) do
|
215
|
+
desc "Specify a *stop* command manually."
|
216
|
+
end
|
217
|
+
|
218
|
+
# Create new subtypes of service management.
|
219
|
+
def self.newsvctype(name, parent = nil, &block)
|
220
|
+
if parent
|
221
|
+
parent = self.svctype(parent)
|
182
222
|
end
|
223
|
+
svcname = name
|
224
|
+
mod = Module.new
|
225
|
+
const_set("SvcType" + name.to_s.capitalize,mod)
|
183
226
|
|
184
|
-
#
|
185
|
-
|
186
|
-
|
187
|
-
output = %x(#{cmd} 2>&1)
|
188
|
-
unless $? == 0
|
189
|
-
raise Puppet::Error, "Could not %s %s: %s" %
|
190
|
-
[type, self.name, output.chomp]
|
191
|
-
end
|
227
|
+
# Add our parent, if it exists
|
228
|
+
if parent
|
229
|
+
mod.send(:include, parent)
|
192
230
|
end
|
193
231
|
|
194
|
-
#
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
raise Puppet::Error,
|
199
|
-
"Either a stop command or a pattern must be specified"
|
200
|
-
end
|
201
|
-
ps = Facter["ps"].value
|
202
|
-
unless ps and ps != ""
|
203
|
-
raise Puppet::Error,
|
204
|
-
"You must upgrade Facter to a version that includes 'ps'"
|
232
|
+
# And now define the support methods
|
233
|
+
code = %{
|
234
|
+
def self.name
|
235
|
+
"#{svcname}"
|
205
236
|
end
|
206
|
-
regex = Regexp.new(self[:pattern])
|
207
|
-
IO.popen(ps) { |table|
|
208
|
-
table.each { |line|
|
209
|
-
if regex.match(line)
|
210
|
-
ary = line.sub(/^\s+/, '').split(/\s+/)
|
211
|
-
return ary[1]
|
212
|
-
end
|
213
|
-
}
|
214
|
-
}
|
215
237
|
|
216
|
-
|
217
|
-
|
238
|
+
def self.inspect
|
239
|
+
"SvcType(#{svcname})"
|
240
|
+
end
|
218
241
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
# We have to extend the object before we call 'super', so that
|
223
|
-
# the parameter methods are called correctly.
|
224
|
-
type = hash[:type] ||
|
225
|
-
hash["type"] ||
|
226
|
-
self.class.defaulttype
|
242
|
+
def self.to_s
|
243
|
+
"SvcType(#{svcname})"
|
244
|
+
end
|
227
245
|
|
228
|
-
|
229
|
-
|
246
|
+
def svctype
|
247
|
+
"#{svcname}"
|
230
248
|
end
|
249
|
+
}
|
231
250
|
|
232
|
-
|
233
|
-
#self.info "extending with %s" % type
|
234
|
-
self.extend(type)
|
251
|
+
mod.module_eval(code)
|
235
252
|
|
236
|
-
|
253
|
+
mod.module_eval(&block)
|
237
254
|
|
238
|
-
|
239
|
-
|
240
|
-
|
255
|
+
@modules ||= Hash.new do |hash, key|
|
256
|
+
if key.is_a?(String)
|
257
|
+
key = key.intern
|
241
258
|
end
|
242
259
|
|
243
|
-
|
244
|
-
|
245
|
-
|
260
|
+
if hash.include?(key)
|
261
|
+
hash[key]
|
262
|
+
else
|
263
|
+
nil
|
246
264
|
end
|
247
265
|
end
|
266
|
+
@modules[name] = mod
|
267
|
+
end
|
268
|
+
|
269
|
+
# Retrieve a service type.
|
270
|
+
def self.svctype(name)
|
271
|
+
@modules[name]
|
272
|
+
end
|
248
273
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
274
|
+
# Retrieve the default type for the current platform.
|
275
|
+
def self.defaulttype
|
276
|
+
unless defined? @defsvctype
|
277
|
+
@defsvctype = nil
|
278
|
+
os = Facter["operatingsystem"].value
|
279
|
+
case os
|
280
|
+
when "Debian":
|
281
|
+
@defsvctype = self.svctype(:debian)
|
282
|
+
when "Solaris":
|
283
|
+
release = Facter["operatingsystemrelease"].value
|
284
|
+
if release.sub(/5\./,'').to_i < 10
|
285
|
+
@defsvctype = self.svctype(:init)
|
286
|
+
else
|
287
|
+
@defsvctype = self.svctype(:smf)
|
288
|
+
end
|
258
289
|
else
|
259
|
-
|
290
|
+
if Facter["kernel"] == "Linux"
|
291
|
+
Puppet.notice "Using service type %s for %s" %
|
292
|
+
["init", Facter["operatingsystem"].value]
|
293
|
+
@defsvctype = self.svctype(:init)
|
294
|
+
end
|
260
295
|
end
|
261
|
-
end
|
262
296
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
297
|
+
unless @defsvctype
|
298
|
+
Puppet.notice "Defaulting to base service type"
|
299
|
+
@defsvctype = self.svctype(:base)
|
300
|
+
end
|
267
301
|
end
|
268
302
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
303
|
+
Puppet.debug "Default service type is %s" % @defsvctype.name
|
304
|
+
|
305
|
+
return @defsvctype
|
306
|
+
end
|
307
|
+
|
308
|
+
# Execute a command. Basically just makes sure it exits with a 0
|
309
|
+
# code.
|
310
|
+
def execute(type, cmd)
|
311
|
+
self.info "Executing %s" % cmd.inspect
|
312
|
+
output = %x(#{cmd} 2>&1)
|
313
|
+
unless $? == 0
|
314
|
+
self.fail "Could not %s %s: %s" %
|
315
|
+
[type, self.name, output.chomp]
|
278
316
|
end
|
317
|
+
end
|
279
318
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
319
|
+
# Get the process ID for a running process. Requires the 'pattern'
|
320
|
+
# parameter.
|
321
|
+
def getpid
|
322
|
+
unless self[:pattern]
|
323
|
+
self.fail "Either a stop command or a pattern must be specified"
|
324
|
+
end
|
325
|
+
ps = Facter["ps"].value
|
326
|
+
unless ps and ps != ""
|
327
|
+
self.fail(
|
328
|
+
"You must upgrade Facter to a version that includes 'ps'"
|
288
329
|
)
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
if
|
294
|
-
|
295
|
-
|
296
|
-
return :stopped
|
330
|
+
end
|
331
|
+
regex = Regexp.new(self[:pattern])
|
332
|
+
IO.popen(ps) { |table|
|
333
|
+
table.each { |line|
|
334
|
+
if regex.match(line)
|
335
|
+
ary = line.sub(/^\s+/, '').split(/\s+/)
|
336
|
+
return ary[1]
|
297
337
|
end
|
298
|
-
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
return nil
|
342
|
+
end
|
343
|
+
|
344
|
+
# Initialize the service. This is basically responsible for merging
|
345
|
+
# in the right module.
|
346
|
+
def initialize(hash)
|
347
|
+
super
|
348
|
+
|
349
|
+
# and then see if it needs to be checked
|
350
|
+
if self.respond_to?(:configchk)
|
351
|
+
self.configchk
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
# Retrieve the service type.
|
356
|
+
def type2module(type)
|
357
|
+
self.class.svctype(type)
|
358
|
+
end
|
359
|
+
|
360
|
+
# Basically just a synonym for restarting. Used to respond
|
361
|
+
# to events.
|
362
|
+
def refresh
|
363
|
+
self.restart
|
364
|
+
end
|
365
|
+
|
366
|
+
# How to restart the process.
|
367
|
+
def restart
|
368
|
+
if self[:restart] or self.respond_to?(:restartcmd)
|
369
|
+
cmd = self[:restart] || self.restartcmd
|
370
|
+
self.execute("restart", cmd)
|
371
|
+
else
|
372
|
+
self.stop
|
373
|
+
self.start
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
# Check if the process is running. Prefer the 'status' parameter,
|
378
|
+
# then 'statuscmd' method, then look in the process table. We give
|
379
|
+
# the object the option to not return a status command, which might
|
380
|
+
# happen if, for instance, it has an init script (and thus responds to
|
381
|
+
# 'statuscmd') but does not have 'hasstatus' enabled.
|
382
|
+
def status
|
383
|
+
if self[:status] or (
|
384
|
+
self.respond_to?(:statuscmd) and self.statuscmd
|
385
|
+
)
|
386
|
+
cmd = self[:status] || self.statuscmd
|
387
|
+
self.info "Executing %s" % cmd.inspect
|
388
|
+
output = %x(#{cmd} 2>&1)
|
389
|
+
self.debug "%s status returned %s" %
|
390
|
+
[self.name, output.inspect]
|
391
|
+
if $? == 0
|
299
392
|
return :running
|
300
393
|
else
|
301
394
|
return :stopped
|
302
395
|
end
|
396
|
+
elsif pid = self.getpid
|
397
|
+
return :running
|
398
|
+
else
|
399
|
+
return :stopped
|
303
400
|
end
|
401
|
+
end
|
304
402
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
403
|
+
# Run the 'start' parameter command, or the specified 'startcmd'.
|
404
|
+
def start
|
405
|
+
cmd = self[:start] || self.startcmd
|
406
|
+
self.execute("start", cmd)
|
407
|
+
end
|
310
408
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
end
|
327
|
-
output = %x("kill #{pid} 2>&1")
|
328
|
-
if $? != 0
|
329
|
-
raise Puppet::Error,
|
330
|
-
"Could not kill %s, PID %s: %s" %
|
331
|
-
[self.name, pid, output]
|
332
|
-
end
|
333
|
-
return true
|
409
|
+
# Stop the service. If a 'stop' parameter is specified, it
|
410
|
+
# takes precedence; otherwise checks if the object responds to
|
411
|
+
# a 'stopcmd' method, and if so runs that; otherwise, looks
|
412
|
+
# for the process in the process table.
|
413
|
+
# This method will generally not be overridden by submodules.
|
414
|
+
def stop
|
415
|
+
if self[:stop]
|
416
|
+
return self[:stop]
|
417
|
+
elsif self.respond_to?(:stopcmd)
|
418
|
+
self.execute("stop", self.stopcmd)
|
419
|
+
else
|
420
|
+
pid = getpid
|
421
|
+
unless pid
|
422
|
+
self.info "%s is not running" % self.name
|
423
|
+
return false
|
334
424
|
end
|
425
|
+
output = %x("kill #{pid} 2>&1")
|
426
|
+
if $? != 0
|
427
|
+
self.fail "Could not kill %s, PID %s: %s" %
|
428
|
+
[self.name, pid, output]
|
429
|
+
end
|
430
|
+
return true
|
335
431
|
end
|
336
|
-
|
337
|
-
|
432
|
+
end
|
433
|
+
end
|
338
434
|
end
|
339
435
|
|
340
436
|
# Load all of the different service types. We could probably get away with
|
@@ -344,4 +440,4 @@ require 'puppet/type/service/init'
|
|
344
440
|
require 'puppet/type/service/debian'
|
345
441
|
require 'puppet/type/service/smf'
|
346
442
|
|
347
|
-
# $Id: service.rb
|
443
|
+
# $Id: service.rb 887 2006-02-08 22:56:56Z luke $
|