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
data/lib/puppet/type/exec.rb
CHANGED
@@ -1,67 +1,112 @@
|
|
1
|
+
module Puppet
|
2
|
+
newtype(:exec) do
|
3
|
+
@doc = "Executes external commands. It is critical that all commands
|
4
|
+
executed using this mechanism can be run multiple times without
|
5
|
+
harm, i.e., they are *idempotent*. One useful way to create idempotent
|
6
|
+
commands is to use the *creates* parameter.
|
7
|
+
|
8
|
+
It is worth noting that ``exec`` is special, in that it is not
|
9
|
+
currently considered an error to have multiple ``exec`` instances
|
10
|
+
with the same name. This was done purely because it had to be this
|
11
|
+
way in order to get certain functionality, but it complicates things.
|
12
|
+
In particular, you will not be able to use ``exec`` instances that
|
13
|
+
share their commands with other instances as a dependency, since
|
14
|
+
Puppet has no way of knowing which instance you mean.
|
15
|
+
|
16
|
+
For example::
|
17
|
+
|
18
|
+
# defined in the production class
|
19
|
+
exec { \"make\":
|
20
|
+
cwd => \"/prod/build/dir\"
|
21
|
+
}
|
22
|
+
|
23
|
+
. etc. .
|
24
|
+
|
25
|
+
# defined in the test class
|
26
|
+
exec { \"make\":
|
27
|
+
cwd => \"/test/build/dir\"
|
28
|
+
}
|
29
|
+
|
30
|
+
Any other type would throw an error, complaining that you had
|
31
|
+
the same instance being managed in multiple places, but these are
|
32
|
+
obviously different images, so ``exec`` had to be treated specially.
|
33
|
+
|
34
|
+
It is recommended to avoid duplicate names whenever possible.
|
35
|
+
|
36
|
+
There is a strong tendency to use ``exec`` to do whatever work Puppet
|
37
|
+
can't already do; while this is obviously acceptable (and unavoidable)
|
38
|
+
in the short term, it is highly recommended to migrate work from ``exec``
|
39
|
+
to real Puppet element types as quickly as possible. If you find that
|
40
|
+
you are doing a lot of work with ``exec``, please at least notify
|
41
|
+
us at Reductive Labs what you are doing, and hopefully we can work with
|
42
|
+
you to get a native element type for the work you are doing. In general,
|
43
|
+
it is a Puppet bug if you need ``exec`` to do your work."
|
44
|
+
|
45
|
+
require 'open3'
|
46
|
+
require 'puppet/type/state'
|
47
|
+
|
48
|
+
newstate(:returns) do |state|
|
49
|
+
munge do |value|
|
50
|
+
value.to_s
|
51
|
+
end
|
1
52
|
|
2
|
-
|
3
|
-
require 'puppet/type/state'
|
53
|
+
defaultto "0"
|
4
54
|
|
5
|
-
module Puppet
|
6
|
-
# okay, how do we deal with parameters that don't have operations
|
7
|
-
# associated with them?
|
8
|
-
class State
|
9
|
-
# this always runs
|
10
|
-
class Returns < Puppet::State
|
11
55
|
attr_reader :output
|
12
|
-
|
13
|
-
|
14
|
-
executed command returns something else."
|
15
|
-
@name = :returns
|
56
|
+
desc "The expected return code. An error will be returned if the
|
57
|
+
executed command returns something else. Defaults to 0."
|
16
58
|
|
17
59
|
# Make output a bit prettier
|
18
60
|
def change_to_s
|
19
61
|
return "executed successfully"
|
20
62
|
end
|
21
63
|
|
22
|
-
#
|
23
|
-
|
24
|
-
# exists and such
|
25
|
-
def retrieve
|
26
|
-
if file = @parent[:creates]
|
27
|
-
if FileTest.exists?(file)
|
28
|
-
@is = true
|
29
|
-
@should = [true]
|
30
|
-
return
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
64
|
+
# Verify that we have the executable
|
65
|
+
def checkexe
|
34
66
|
cmd = self.parent[:command]
|
35
67
|
if cmd =~ /^\//
|
36
68
|
exe = cmd.split(/ /)[0]
|
37
69
|
unless FileTest.exists?(exe)
|
38
|
-
|
70
|
+
self.fail(
|
39
71
|
"Could not find executable %s" % exe
|
40
72
|
)
|
41
73
|
end
|
42
74
|
unless FileTest.executable?(exe)
|
43
|
-
|
75
|
+
self.fail(
|
44
76
|
"%s is not executable" % exe
|
45
77
|
)
|
46
78
|
end
|
47
79
|
elsif path = self.parent[:path]
|
48
80
|
exe = cmd.split(/ /)[0]
|
49
81
|
tmppath = ENV["PATH"]
|
50
|
-
ENV["PATH"] = self.parent[:path]
|
82
|
+
ENV["PATH"] = self.parent[:path].join(":")
|
51
83
|
|
52
84
|
path = %{which #{exe}}.chomp
|
53
85
|
if path == ""
|
54
|
-
|
86
|
+
self.fail(
|
55
87
|
"Could not find command '%s'" % exe
|
56
88
|
)
|
57
89
|
end
|
58
90
|
ENV["PATH"] = tmppath
|
59
91
|
else
|
60
|
-
|
92
|
+
self.fail(
|
61
93
|
"%s is somehow not qualified with no search path" %
|
62
94
|
self.parent[:command]
|
63
95
|
)
|
64
96
|
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# because this command always runs,
|
100
|
+
# we're just using retrieve to verify that the command
|
101
|
+
# exists and such
|
102
|
+
def retrieve
|
103
|
+
if file = @parent[:creates]
|
104
|
+
if FileTest.exists?(file)
|
105
|
+
@is = true
|
106
|
+
@should = [true]
|
107
|
+
return
|
108
|
+
end
|
109
|
+
end
|
65
110
|
|
66
111
|
if self.parent[:refreshonly]
|
67
112
|
# if refreshonly is enabled, then set things so we
|
@@ -77,27 +122,24 @@ module Puppet
|
|
77
122
|
def sync
|
78
123
|
olddir = nil
|
79
124
|
|
125
|
+
self.checkexe
|
126
|
+
|
80
127
|
# We need a dir to change to, even if it's just the cwd
|
81
128
|
dir = self.parent[:cwd] || Dir.pwd
|
82
129
|
tmppath = ENV["PATH"]
|
83
130
|
|
131
|
+
event = :executed_command
|
84
132
|
begin
|
85
133
|
# Do our chdir
|
86
134
|
Dir.chdir(dir) {
|
87
|
-
|
135
|
+
if self.parent[:path]
|
136
|
+
ENV["PATH"] = self.parent[:path].join(":")
|
137
|
+
end
|
88
138
|
|
89
139
|
# The user and group default to nil, which 'asuser'
|
90
140
|
# handlers correctly
|
91
141
|
Puppet::Util.asuser(@parent[:user], @parent[:group]) {
|
92
142
|
# capture both stdout and stderr
|
93
|
-
|
94
|
-
#stdin, stdout, stderr = Open3.popen3(self.parent[:command])
|
95
|
-
#@output = stdout.read
|
96
|
-
#err = stderr.read
|
97
|
-
|
98
|
-
#stderr = Puppet::Util.capture_stderr {
|
99
|
-
# @output = %x{#{self.parent[:command]}}
|
100
|
-
#}
|
101
143
|
if @parent[:user]
|
102
144
|
unless defined? @@alreadywarned
|
103
145
|
Puppet.warning(
|
@@ -109,12 +151,6 @@ module Puppet
|
|
109
151
|
else
|
110
152
|
@output = %x{#{self.parent[:command]} 2>&1}
|
111
153
|
end
|
112
|
-
|
113
|
-
#if err != ""
|
114
|
-
# stderr.split(/\n/).each { |line|
|
115
|
-
# self.send(:err, line)
|
116
|
-
# }
|
117
|
-
#end
|
118
154
|
}
|
119
155
|
status = $?
|
120
156
|
|
@@ -125,6 +161,7 @@ module Puppet
|
|
125
161
|
|
126
162
|
# if we've had a failure, up the log level
|
127
163
|
loglevel = :err
|
164
|
+
event = :failed_command
|
128
165
|
end
|
129
166
|
|
130
167
|
# and log
|
@@ -133,131 +170,76 @@ module Puppet
|
|
133
170
|
}
|
134
171
|
}
|
135
172
|
rescue Errno::ENOENT => detail
|
136
|
-
|
173
|
+
self.fail detail.to_s
|
137
174
|
ensure
|
138
175
|
# reset things to how we found them
|
139
176
|
ENV["PATH"] = tmppath
|
140
177
|
end
|
141
178
|
|
142
|
-
return
|
179
|
+
return event
|
143
180
|
end
|
144
181
|
end
|
145
|
-
end
|
146
182
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
@parameters = [
|
157
|
-
:path,
|
158
|
-
:user,
|
159
|
-
:group,
|
160
|
-
:creates,
|
161
|
-
:cwd,
|
162
|
-
:refreshonly,
|
163
|
-
:command
|
164
|
-
]
|
165
|
-
|
166
|
-
@paramdoc[:path] = "The search path used for command execution.
|
167
|
-
Commands must be fully qualified if no path is specified."
|
168
|
-
@paramdoc[:user] = "The user to run the command as. Note that if you use
|
169
|
-
this then any error output is not currently captured. This is mostly
|
170
|
-
because of a bug within Ruby."
|
171
|
-
@paramdoc[:group] = "The group to run the command as."
|
172
|
-
@paramdoc[:cwd] = "The directory from which to run the command. If
|
173
|
-
this directory does not exist, the command will fail."
|
174
|
-
@paramdoc[:refreshonly] = "The command should only be run as a
|
175
|
-
refresh mechanism for when a dependent object is changed."
|
176
|
-
@paramdoc[:command] = "The actual command to execute."
|
177
|
-
@paramdoc[:creates] = "A file that this command creates. If this
|
178
|
-
parameter is provided, then the command will only be run
|
179
|
-
if the specified file does not exist."
|
180
|
-
|
181
|
-
@doc = "Executes external commands. It is critical that all commands
|
182
|
-
executed using this mechanism can be run multiple times without
|
183
|
-
harm, i.e., they are *idempotent*. One useful way to create idempotent
|
184
|
-
commands is to use the *creates* parameter.
|
185
|
-
|
186
|
-
It is worth nothing that ``exec`` is special, in that it is not
|
187
|
-
currently considered an error to have multiple ``exec`` instances
|
188
|
-
with the same name. This was done purely because it had to be this
|
189
|
-
way in order to get certain functionality, but it complicates things.
|
190
|
-
In particular, you will not be able to use ``exec`` instances that
|
191
|
-
share their commands with other instances as a dependency, since
|
192
|
-
Puppet has no way of knowing which instance you mean.
|
193
|
-
|
194
|
-
It is recommended to avoid duplicate names whenever possible."
|
195
|
-
@name = :exec
|
196
|
-
@namevar = :command
|
197
|
-
|
198
|
-
# Exec names are not isomorphic with the objects.
|
199
|
-
@isomorphic = false
|
200
|
-
|
201
|
-
def initialize(hash)
|
202
|
-
# default to erroring on a non-zero return
|
203
|
-
if hash.include?("returns")
|
204
|
-
if hash["returns"].is_a?(Fixnum)
|
205
|
-
hash["returns"] = hash["returns"].to_s
|
206
|
-
end
|
207
|
-
elsif hash.include?(:returns)
|
208
|
-
if hash[:returns].is_a?(Fixnum)
|
209
|
-
hash[:returns] = hash[:returns].to_s
|
210
|
-
end
|
211
|
-
else
|
212
|
-
hash[:returns] = "0"
|
213
|
-
end
|
214
|
-
|
215
|
-
super
|
183
|
+
newparam(:command) do
|
184
|
+
isnamevar
|
185
|
+
desc "The actual command to execute. Must either be fully qualified
|
186
|
+
or a search path for the command must be provided. If the command
|
187
|
+
succeeds, any output produced will be logged at the instance's
|
188
|
+
normal log level (usually ``notice``), but if the command fails
|
189
|
+
(meaning its return code does not match the specified code) then
|
190
|
+
any output is logged at the ``err`` log level."
|
191
|
+
end
|
216
192
|
|
217
|
-
|
218
|
-
|
219
|
-
|
193
|
+
newparam(:path) do
|
194
|
+
desc "The search path used for command execution.
|
195
|
+
Commands must be fully qualified if no path is specified. Paths
|
196
|
+
can be specified as an array or as a colon-separated list."
|
220
197
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
end
|
227
|
-
end
|
198
|
+
# Support both arrays and colon-separated fields.
|
199
|
+
def value=(*values)
|
200
|
+
@value = values.collect { |val|
|
201
|
+
val.split(":")
|
202
|
+
}.flatten
|
228
203
|
end
|
204
|
+
end
|
229
205
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
return self.state(:returns).output
|
235
|
-
end
|
236
|
-
end
|
206
|
+
newparam(:user) do
|
207
|
+
desc "The user to run the command as. Note that if you
|
208
|
+
use this then any error output is not currently captured. This
|
209
|
+
is because of a bug within Ruby."
|
237
210
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
unless file =~ %r{^#{File::SEPARATOR}}
|
242
|
-
raise Puppet::Error, "'creates' files must be fully qualified."
|
211
|
+
munge do |user|
|
212
|
+
unless Process.uid == 0
|
213
|
+
self.fail "Only root can execute commands as other users"
|
243
214
|
end
|
244
|
-
|
245
|
-
end
|
215
|
+
require 'etc'
|
246
216
|
|
247
|
-
|
248
|
-
|
249
|
-
|
217
|
+
method = :getpwnam
|
218
|
+
case user
|
219
|
+
when Integer
|
220
|
+
method = :getpwuid
|
221
|
+
when /^\d+$/
|
222
|
+
user = user.to_i
|
223
|
+
method = :getpwuid
|
250
224
|
end
|
251
|
-
|
252
|
-
|
253
|
-
|
225
|
+
begin
|
226
|
+
Etc.send(method, user)
|
227
|
+
rescue ArgumentError
|
228
|
+
self.fail "No such user %s" % user
|
254
229
|
end
|
255
230
|
|
256
|
-
|
231
|
+
return user
|
257
232
|
end
|
233
|
+
end
|
234
|
+
|
235
|
+
newparam(:group) do
|
236
|
+
desc "The group to run the command as. This seems to work quite
|
237
|
+
haphazardly on different platforms -- it is a platform issue
|
238
|
+
not a Ruby or Puppet one, since the same variety exists when
|
239
|
+
running commnands as different users in the shell."
|
258
240
|
|
259
241
|
# Execute the command as the specified group
|
260
|
-
|
242
|
+
munge do |group|
|
261
243
|
require 'etc'
|
262
244
|
method = :getgrnam
|
263
245
|
case group
|
@@ -270,47 +252,125 @@ module Puppet
|
|
270
252
|
begin
|
271
253
|
Etc.send(method, group)
|
272
254
|
rescue ArgumentError
|
273
|
-
|
255
|
+
self.fail "No such group %s" % group
|
274
256
|
end
|
275
257
|
|
276
|
-
|
258
|
+
group
|
277
259
|
end
|
260
|
+
end
|
278
261
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
262
|
+
newparam(:cwd) do
|
263
|
+
desc "The directory from which to run the command. If
|
264
|
+
this directory does not exist, the command will fail."
|
265
|
+
|
266
|
+
munge do |dir|
|
267
|
+
if dir.is_a?(Array)
|
268
|
+
dir = dir[0]
|
284
269
|
end
|
285
|
-
require 'etc'
|
286
270
|
|
287
|
-
|
288
|
-
|
289
|
-
when Integer
|
290
|
-
method = :getpwuid
|
291
|
-
when /^\d+$/
|
292
|
-
user = user.to_i
|
293
|
-
method = :getpwuid
|
271
|
+
unless File.directory?(dir)
|
272
|
+
self.fail "Directory '%s' does not exist" % dir
|
294
273
|
end
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
274
|
+
|
275
|
+
dir
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
newparam(:refreshonly) do
|
280
|
+
desc "The command should only be run as a
|
281
|
+
refresh mechanism for when a dependent object is changed. It only
|
282
|
+
makes sense to use this option when this command depends on some
|
283
|
+
other object; it is useful for triggering an action::
|
284
|
+
|
285
|
+
# Pull down the main aliases file
|
286
|
+
file { \"/etc/aliases\":
|
287
|
+
source => \"puppet://server/module/aliases\"
|
288
|
+
}
|
289
|
+
|
290
|
+
# Rebuild the database, but only when the file changes
|
291
|
+
exec { newaliases:
|
292
|
+
path => [\"/usr/bin\", \"/usr/sbin\"],
|
293
|
+
require => file[\"/etc/aliases\"],
|
294
|
+
refreshonly => true
|
295
|
+
}
|
296
|
+
|
297
|
+
"
|
298
|
+
end
|
299
|
+
|
300
|
+
newparam(:creates) do
|
301
|
+
desc "A file that this command creates. If this
|
302
|
+
parameter is provided, then the command will only be run
|
303
|
+
if the specified file does not exist.
|
304
|
+
|
305
|
+
::
|
306
|
+
|
307
|
+
exec { \"tar xf /my/tar/file.tar\":
|
308
|
+
cwd => \"/var/tmp\",
|
309
|
+
creates => \"/var/tmp/myfile\",
|
310
|
+
path => [\"/usr/bin\", \"/usr/sbin\"]
|
311
|
+
}
|
312
|
+
|
313
|
+
"
|
314
|
+
|
315
|
+
# FIXME if they try to set this and fail, then we should probably
|
316
|
+
# fail the entire exec, right?
|
317
|
+
validate do |file|
|
318
|
+
unless file =~ %r{^#{File::SEPARATOR}}
|
319
|
+
self.fail "'creates' files must be fully qualified."
|
299
320
|
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
# Exec names are not isomorphic with the objects.
|
325
|
+
@isomorphic = false
|
326
|
+
|
327
|
+
validate do
|
328
|
+
# if we're not fully qualified, require a path
|
329
|
+
if self[:command] !~ /^\//
|
330
|
+
if self[:path].nil?
|
331
|
+
self.fail "both unqualifed and specified no search path"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
autorequire(:file) do
|
337
|
+
reqs = []
|
300
338
|
|
301
|
-
|
339
|
+
# Stick the cwd in there if we have it
|
340
|
+
if self[:cwd]
|
341
|
+
reqs << self[:cwd]
|
302
342
|
end
|
303
343
|
|
304
|
-
|
305
|
-
|
306
|
-
|
344
|
+
tmp = self[:command].dup
|
345
|
+
|
346
|
+
# And search the command line for files, adding any we find. This
|
347
|
+
# will also catch the command itself if it's fully qualified. It might
|
348
|
+
# not be a bad idea to add unqualified files, but, well, that's a
|
349
|
+
# bit more annoying to do.
|
350
|
+
while tmp.sub!(%r{(#{File::SEPARATOR}\S+)}, '')
|
351
|
+
reqs << $1
|
307
352
|
end
|
308
353
|
|
309
|
-
|
310
|
-
|
354
|
+
reqs
|
355
|
+
end
|
356
|
+
|
357
|
+
def output
|
358
|
+
if self.state(:returns).nil?
|
359
|
+
return nil
|
360
|
+
else
|
361
|
+
return self.state(:returns).output
|
311
362
|
end
|
312
363
|
end
|
364
|
+
|
365
|
+
# this might be a very, very bad idea...
|
366
|
+
def refresh
|
367
|
+
self.state(:returns).sync
|
368
|
+
end
|
369
|
+
|
370
|
+
def to_s
|
371
|
+
"exec(%s)" % self.name
|
372
|
+
end
|
313
373
|
end
|
314
374
|
end
|
315
375
|
|
316
|
-
# $Id: exec.rb
|
376
|
+
# $Id: exec.rb 841 2006-01-18 17:24:15Z luke $
|