puppet 0.13.1 → 0.13.2

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.

Files changed (44) hide show
  1. data/CHANGELOG +4 -0
  2. data/Rakefile +2 -2
  3. data/bin/puppet +29 -0
  4. data/bin/puppetd +35 -1
  5. data/conf/redhat/puppet.spec +1 -1
  6. data/lib/puppet.rb +1 -1
  7. data/lib/puppet/client/master.rb +34 -3
  8. data/lib/puppet/filetype.rb +6 -2
  9. data/lib/puppet/networkclient.rb +4 -1
  10. data/lib/puppet/parameter.rb +35 -38
  11. data/lib/puppet/parser/ast/node.rb +1 -0
  12. data/lib/puppet/parser/interpreter.rb +129 -2
  13. data/lib/puppet/parser/scope.rb +44 -6
  14. data/lib/puppet/type.rb +47 -37
  15. data/lib/puppet/type/cron.rb +25 -10
  16. data/lib/puppet/type/exec.rb +165 -71
  17. data/lib/puppet/type/nameservice.rb +2 -17
  18. data/lib/puppet/type/package.rb +31 -7
  19. data/lib/puppet/type/package/sun.rb +11 -6
  20. data/lib/puppet/type/parsedtype.rb +94 -60
  21. data/lib/puppet/type/parsedtype/host.rb +5 -12
  22. data/lib/puppet/type/parsedtype/port.rb +53 -32
  23. data/lib/puppet/type/parsedtype/sshkey.rb +8 -4
  24. data/lib/puppet/type/pfile.rb +6 -4
  25. data/lib/puppet/type/pfile/ensure.rb +1 -6
  26. data/lib/puppet/type/state.rb +34 -74
  27. data/lib/puppet/type/symlink.rb +30 -19
  28. data/lib/puppet/type/user.rb +63 -11
  29. data/lib/puppet/util.rb +54 -60
  30. data/test/client/master.rb +72 -0
  31. data/test/language/interpreter.rb +94 -0
  32. data/test/other/log.rb +8 -1
  33. data/test/puppet/utiltest.rb +101 -1
  34. data/test/test +12 -5
  35. data/test/types/cron.rb +21 -1
  36. data/test/types/exec.rb +46 -2
  37. data/test/types/group.rb +15 -3
  38. data/test/types/host.rb +43 -4
  39. data/test/types/port.rb +67 -6
  40. data/test/types/sshkey.rb +45 -4
  41. data/test/types/symlink.rb +4 -4
  42. data/test/types/type.rb +41 -3
  43. data/test/types/user.rb +23 -2
  44. metadata +3 -2
@@ -52,7 +52,7 @@ class State
52
52
  # things like useradd, in which creation can be done with all
53
53
  # information in one swell foop.
54
54
  def allatonce?
55
- Puppet.info "Returning allatonce %s" % @allatonce
55
+ #Puppet.info "Returning allatonce %s" % @allatonce
56
56
  if defined? @allatonce
57
57
  return @allatonce
58
58
  else
@@ -139,21 +139,6 @@ class State
139
139
  return nil
140
140
  end
141
141
  end
142
- # # if the object needs to be created or deleted,
143
- # # depend on another method to do it all at once
144
- # if @is == :absent or self.should == :absent
145
- # Puppet.info "creating"
146
- # event = syncname()
147
- #
148
- # Puppet.info "created with event %s" % event
149
- #
150
- # return event
151
- # # if the whole object is created at once, just return
152
- # # an event saying so
153
- # #if self.class.allatonce?
154
- # # return event
155
- # #end
156
- # end
157
142
 
158
143
  unless @parent.exists?
159
144
  self.devfail "%s %s does not exist; cannot set %s" %
@@ -244,4 +229,4 @@ else
244
229
  end
245
230
 
246
231
 
247
- # $Id: nameservice.rb 841 2006-01-18 17:24:15Z luke $
232
+ # $Id: nameservice.rb 914 2006-02-15 21:04:14Z luke $
@@ -168,8 +168,8 @@ module Puppet
168
168
  return true
169
169
  end
170
170
  else
171
- self.debug "@is is %s, latest %s is %s" %
172
- [@is, @parent.name, latest]
171
+ #self.debug "@is is %s, latest %s is %s" %
172
+ # [@is, @parent.name, latest]
173
173
  end
174
174
  when :absent
175
175
  if @is == :absent
@@ -280,12 +280,19 @@ module Puppet
280
280
  desc "A read-only parameter set by the package."
281
281
  end
282
282
 
283
- newparam(:answerfile) do
283
+ newparam(:adminfile) do
284
+ desc "A file containing package defaults for installing packages.
285
+ This is currently only used on Solaris. The value will be
286
+ validated according to system rules, which in the case of
287
+ Solaris means that it should either be a fully qualified path
288
+ or it should be in /var/sadm/install/admin."
289
+ end
290
+
291
+ newparam(:responsefile) do
284
292
  desc "A file containing any necessary answers to questions asked by
285
293
  the package. This is currently only used on Solaris. The
286
- value will be validated according to system rules, which in
287
- the case of Solaris means that it should either be a fully qualified
288
- path or it should be in /var/sadm/install/admin."
294
+ value will be validated according to system rules, but it should
295
+ generally be a fully qualified path."
289
296
  end
290
297
 
291
298
  # FIXME Version is screwy -- most package systems can't specify a
@@ -321,6 +328,23 @@ module Puppet
321
328
  newparam(:description) do
322
329
  desc "A read-only parameter set by the package."
323
330
  end
331
+
332
+ autorequire(:file) do
333
+ autos = []
334
+ [:responsefile, :adminfile].each { |param|
335
+ if val = self[param]
336
+ autos << val
337
+ end
338
+ }
339
+
340
+ if source = self[:source]
341
+ if source =~ /^#{File::SEPARATOR}/
342
+ autos << source
343
+ end
344
+ end
345
+ autos
346
+ end
347
+
324
348
  @listed = false
325
349
 
326
350
  @allowedmethods = [:types]
@@ -569,4 +593,4 @@ require 'puppet/type/package/yum.rb'
569
593
  require 'puppet/type/package/sun.rb'
570
594
  require 'puppet/type/package/bsd.rb'
571
595
 
572
- # $Id: package.rb 888 2006-02-08 22:57:07Z luke $
596
+ # $Id: package.rb 913 2006-02-15 18:34:00Z luke $
@@ -6,12 +6,17 @@ module Puppet
6
6
  end
7
7
  #cmd = "pkgadd -d %s -n %s 2>&1" % [self[:source], self[:name]]
8
8
  cmd = ["pkgadd"]
9
- cmd += ["-d", self[:source]]
10
- cmd += ["-n", self[:name]]
11
9
 
12
- if self[:answerfile]
13
- cmd += ["-a", self[:answerfile]]
10
+ if self[:adminfile]
11
+ cmd += ["-a", self[:adminfile]]
12
+ end
13
+
14
+ if self[:responsefile]
15
+ cmd += ["-r", self[:responsefile]]
14
16
  end
17
+
18
+ cmd += ["-d", self[:source]]
19
+ cmd += ["-n", self[:name]]
15
20
  cmd << "2>&1"
16
21
  cmd = cmd.join(" ")
17
22
 
@@ -33,6 +38,7 @@ module Puppet
33
38
  "BASEDIR" => :root,
34
39
  "HOTLINE" => nil,
35
40
  "EMAIL" => nil,
41
+ "VSTOCK" => nil,
36
42
  "VENDOR" => :vendor,
37
43
  "DESC" => :description,
38
44
  "PSTAMP" => nil,
@@ -58,8 +64,7 @@ module Puppet
58
64
  hash[names[name]] = value
59
65
  end
60
66
  else
61
- self.err "'pkginfo' returned invalid name %s" %
62
- name
67
+ self.notice "Ignoring unknown name %s" % name
63
68
  end
64
69
  when /\s+\d+.+/:
65
70
  # nothing; we're ignoring the FILES info
@@ -9,6 +9,31 @@ module Puppet
9
9
  # the 'should' value to the 'is' value and to do support the right logging
10
10
  # and such.
11
11
  class ParsedParam < Puppet::State
12
+ def self.isoptional
13
+ @isoptional = true
14
+ end
15
+
16
+ def self.isoptional?
17
+ if defined? @isoptional
18
+ return @isoptional
19
+ else
20
+ return false
21
+ end
22
+ end
23
+
24
+ # By default, support ':absent' as a value for optional
25
+ # parameters. Any parameters that define their own validation
26
+ # need to do this manuallly.
27
+ validate do |value|
28
+ if self.class.isoptional? and (
29
+ value == "absent" or value == :absent
30
+ )
31
+ return :absent
32
+ else
33
+ return value
34
+ end
35
+ end
36
+
12
37
  # Fix things so that the fields have to match exactly, instead
13
38
  # of only kinda
14
39
  def insync?
@@ -32,40 +57,39 @@ module Puppet
32
57
  end
33
58
  end
34
59
 
35
- # Determine whether the host entry should be destroyed, and figure
36
- # out which event to return. Finally, call @parent.sync to write the
37
- # host tab.
60
+ # If the ensure state is out of sync, it will always be called
61
+ # first, so I don't need to worry about that.
38
62
  def sync(nostore = false)
39
63
  ebase = @parent.class.name.to_s
40
- if @is == :absent
41
- #@is = self.should
42
- tail = "created"
43
-
44
- # If we're creating it, then sync all of the other states
45
- # but tell them not to store (we'll store just once,
46
- # at the end).
47
- unless nostore
48
- @parent.eachstate { |state|
49
- next if state == self or state.name == :ensure
50
- state.sync(true)
51
- }
64
+
65
+ tail = nil
66
+ if self.class.name == :ensure
67
+ # We're either creating or destroying the object
68
+ if @is == :absent
69
+ #@is = self.should
70
+ tail = "created"
71
+
72
+ # If we're creating it, then sync all of the other states
73
+ # but tell them not to store (we'll store just once,
74
+ # at the end).
75
+ unless nostore
76
+ @parent.eachstate { |state|
77
+ next if state == self or state.name == :ensure
78
+ state.sync(true)
79
+ }
80
+ end
81
+ elsif self.should == :absent
82
+ @parent.remove(true)
83
+ tail = "deleted"
52
84
  end
53
- elsif self.should == :absent
54
- @parent.remove(true)
55
- tail = "deleted"
56
- #elsif @is == @should
57
- elsif self.insync?
58
- self.info "Already in sync: %s vs %s" %
59
- [@is.inspect, @should.inspect]
60
- return nil
61
85
  else
62
- #@is = self.should
63
- # Mark that we've synced it, but don't copy the value, because
64
- # that will make the 'change' log inscrutable.
86
+ # We don't do the work here, it gets done in 'store'
65
87
  tail = "changed"
66
88
  end
67
89
  @synced = self.should
68
90
 
91
+ # This should really only be done once per run, rather than
92
+ # every time. I guess we need some kind of 'flush' mechanism.
69
93
  if nostore
70
94
  self.retrieve
71
95
  else
@@ -106,7 +130,7 @@ module Puppet
106
130
  super
107
131
  end
108
132
 
109
- # In addition to removing the instances in @objects, Cron has to remove
133
+ # In addition to removing the instances in @objects, we have to remove
110
134
  # per-user host tab information.
111
135
  def self.clear
112
136
  @instances = []
@@ -126,8 +150,9 @@ module Puppet
126
150
  # Return the header placed at the top of each generated file, warning
127
151
  # users that modifying this file manually is probably a bad idea.
128
152
  def self.header
129
- %{# HEADER: This file was autogenerated at #{Time.now} by puppet. While it
130
- # HEADER: can still be managed manually, it is definitely not recommended.\n}
153
+ %{# HEADER: This file was autogenerated at #{Time.now}
154
+ # HEADER: by puppet. While it can still be managed manually, it
155
+ # HEADER: is definitely not recommended.\n}
131
156
  end
132
157
 
133
158
  # Store a new instance of a host. Called from Host#initialize.
@@ -160,20 +185,30 @@ module Puppet
160
185
  # we've set up our naming stuff correctly everywhere.
161
186
 
162
187
  # Mark found objects as present
163
- Puppet.debug "Found %s %s" % [self.name, obj.name]
164
188
  obj.is = [:ensure, :present]
189
+ hash.each { |param, value|
190
+ if state = obj.state(param)
191
+ state.is = value
192
+ elsif val = obj[param]
193
+ obj[param] = val
194
+ else
195
+ # There is a value on disk, but it should go away
196
+ obj.is = [param, value]
197
+ obj[param] = :absent
198
+ end
199
+ }
165
200
  else
166
201
  # create a new obj, since no existing one seems to
167
202
  # match
168
- obj = self.create(
169
- :name => hash[:name]
170
- ) or return false
203
+ obj = self.create(:name => hash[:name])
204
+
205
+ # We can't just pass the hash in at object creation time,
206
+ # because it sets the should value, not the is value.
171
207
  hash.delete(:name)
208
+ hash.each { |param, value|
209
+ obj.is = [param, value]
210
+ }
172
211
  end
173
-
174
- hash.each { |param, value|
175
- obj.is = [param, value]
176
- }
177
212
  end
178
213
 
179
214
  # Retrieve the text for the file. Returns nil in the unlikely
@@ -205,14 +240,6 @@ module Puppet
205
240
  else
206
241
  @fileobj.write(self.to_file())
207
242
  end
208
-
209
- #self.each { |obj|
210
- # obj.each { |state|
211
- # obj.notice "Changing from %s to %s" %
212
- # [state.is.inspect, state.should.inspect]
213
- # state.is = state.should
214
- # }
215
- #}
216
243
  end
217
244
 
218
245
  # Collect all Host instances convert them into literal text.
@@ -223,9 +250,6 @@ module Puppet
223
250
  # Don't write out objects that should be absent
224
251
  if obj.is_a?(self)
225
252
  if obj.should(:ensure) == :absent
226
- #obj.warning "removing; is = %s, should = %s" %
227
- # [obj.is(:ensure).inspect, obj.should(:ensure).inspect]
228
- #obj.is = [:ensure, :absent]
229
253
  true
230
254
  end
231
255
  end
@@ -239,7 +263,7 @@ module Puppet
239
263
 
240
264
  return str
241
265
  else
242
- Puppet.notice "No host instances"
266
+ Puppet.notice "No %s instances" % self.name
243
267
  return ""
244
268
  end
245
269
  end
@@ -256,17 +280,9 @@ module Puppet
256
280
  self.store
257
281
  end
258
282
 
259
- # We just find any state and check whether it's marked absent
283
+ # hash2obj marks the 'ensure' state as present
260
284
  def exists?
261
- name, state = @states.find { |name, state|
262
- state.is_a?(Puppet::State::ParsedParam)
263
- }
264
-
265
- if state.is == :absent
266
- return false
267
- else
268
- return true
269
- end
285
+ @states.include?(:ensure) and @states[:ensure].is == :present
270
286
  end
271
287
 
272
288
  def destroy
@@ -286,6 +302,24 @@ module Puppet
286
302
  def store
287
303
  self.class.store()
288
304
  end
305
+
306
+ def value(name)
307
+ unless name.is_a? Symbol
308
+ name = name.intern
309
+ end
310
+ if @states.include? name
311
+ val = @states[name].value
312
+ if val == :absent
313
+ return nil
314
+ else
315
+ return val
316
+ end
317
+ elsif @parameters.include? name
318
+ return @parameters[name].value
319
+ else
320
+ return nil
321
+ end
322
+ end
289
323
  end
290
324
  end
291
325
  end
@@ -293,4 +327,4 @@ end
293
327
  require 'puppet/type/parsedtype/host'
294
328
  require 'puppet/type/parsedtype/port'
295
329
 
296
- # $Id: parsedtype.rb 898 2006-02-13 17:13:09Z luke $
330
+ # $Id: parsedtype.rb 915 2006-02-15 21:56:54Z luke $
@@ -5,6 +5,7 @@ require 'puppet/type/state'
5
5
 
6
6
  module Puppet
7
7
  newtype(:host, Puppet::Type::ParsedType) do
8
+
8
9
  newstate(:ip) do
9
10
  desc "The host's IP address."
10
11
  end
@@ -73,12 +74,6 @@ module Puppet
73
74
  @fields = [:ip, :name, :alias]
74
75
 
75
76
  @filetype = Puppet::FileType.filetype(:flat)
76
- # case Facter["operatingsystem"].value
77
- # when "Solaris":
78
- # @filetype = Puppet::FileType::SunOS
79
- # else
80
- # @filetype = Puppet::CronType::Default
81
- # end
82
77
 
83
78
  # Parse a host file
84
79
  #
@@ -117,8 +112,6 @@ module Puppet
117
112
  hash.delete(:alias)
118
113
  end
119
114
 
120
- Puppet.notice "sending %s" % hash.inspect
121
-
122
115
  hash2obj(hash)
123
116
 
124
117
  hash.clear
@@ -129,10 +122,10 @@ module Puppet
129
122
 
130
123
  # Convert the current object into a host-style string.
131
124
  def to_record
132
- str = "%s\t%s" % [self.state(:ip).should, self[:name]]
125
+ str = "%s\t%s" % [self.state(:ip).value, self[:name]]
133
126
 
134
- if state = self.state(:alias)
135
- str += "\t%s" % state.should.join("\t")
127
+ if value = self.value(:alias)
128
+ str += "\t%s" % value.join("\t")
136
129
  end
137
130
 
138
131
  str
@@ -140,4 +133,4 @@ module Puppet
140
133
  end
141
134
  end
142
135
 
143
- # $Id: host.rb 831 2006-01-16 20:01:20Z luke $
136
+ # $Id: host.rb 910 2006-02-15 07:20:36Z luke $
@@ -28,12 +28,22 @@ module Puppet
28
28
  # We actually want to return the whole array here, not just the first
29
29
  # value.
30
30
  def should
31
- @should
31
+ if defined? @should
32
+ if @should[0] == :absent
33
+ return :absent
34
+ else
35
+ return @should
36
+ end
37
+ else
38
+ return nil
39
+ end
32
40
  end
33
41
 
34
42
  validate do |value|
35
- unless value == "udp" or value == "tcp"
36
- raise Puppet::Error, "Protocols can be either 'udp' or 'tcp'"
43
+ valids = ["udp", "tcp", "ddp", :absent]
44
+ unless valids.include? value
45
+ raise Puppet::Error,
46
+ "Protocols can be either 'udp' or 'tcp', not %s" % value
37
47
  end
38
48
  end
39
49
  end
@@ -44,13 +54,16 @@ module Puppet
44
54
 
45
55
  newstate(:description) do
46
56
  desc "The port description."
57
+ isoptional
47
58
  end
48
59
 
49
60
  newstate(:alias) do
50
- desc "Any aliases the port might have. Multiple values must be specified
51
- as an array. Note that this state has the same name as one of the
52
- metaparams; using this state to set aliases will make those aliases
53
- available in your Puppet scripts and also on disk."
61
+ desc "Any aliases the port might have. Multiple values must be
62
+ specified as an array. Note that this state has the same name as
63
+ one of the metaparams; using this state to set aliases will make
64
+ those aliases available in your Puppet scripts and also on disk."
65
+
66
+ isoptional
54
67
 
55
68
  # We have to override the feeding mechanism; it might be nil or
56
69
  # white-space separated
@@ -71,18 +84,32 @@ module Puppet
71
84
  # We actually want to return the whole array here, not just the first
72
85
  # value.
73
86
  def should
74
- @should
87
+ if defined? @should
88
+ if @should[0] == :absent
89
+ return :absent
90
+ else
91
+ return @should
92
+ end
93
+ else
94
+ return nil
95
+ end
75
96
  end
76
97
 
77
98
  validate do |value|
78
- if value =~ /\s/
79
- raise Puppet::Error, "Aliases cannot have whitespace in them"
99
+ if value.is_a? String and value =~ /\s/
100
+ raise Puppet::Error,
101
+ "Aliases cannot have whitespace in them: %s" %
102
+ value.inspect
80
103
  end
81
104
  end
82
105
 
83
106
  munge do |value|
84
- # Add the :alias metaparam in addition to the state
85
- @parent.newmetaparam(@parent.class.metaparamclass(:alias), value)
107
+ unless value == "absent" or value == :absent
108
+ # Add the :alias metaparam in addition to the state
109
+ @parent.newmetaparam(
110
+ @parent.class.metaparamclass(:alias), value
111
+ )
112
+ end
86
113
  value
87
114
  end
88
115
  end
@@ -101,12 +128,6 @@ module Puppet
101
128
  @fields = [:ip, :name, :alias]
102
129
 
103
130
  @filetype = Puppet::FileType.filetype(:flat)
104
- # case Facter["operatingsystem"].value
105
- # when "Solaris":
106
- # @filetype = Puppet::FileType::SunOS
107
- # else
108
- # @filetype = Puppet::CronType::Default
109
- # end
110
131
 
111
132
  # Parse a services file
112
133
  #
@@ -122,10 +143,6 @@ module Puppet
122
143
  # add comments and blank lines to the list as they are
123
144
  @instances << line
124
145
  else
125
- #if match = /^(\S+)\s+(\d+)\/(\w+)/.match(line)
126
- # Puppet.warning "%s %s %s" % [$1, $2, $3]
127
- # next
128
- #if line.sub(/^(\S+)\s+(\d+)\/(\w+)\s*(\S*)$/.match(line)
129
146
  if line.sub!(/^(\S+)\s+(\d+)\/(\w+)\s*/, '')
130
147
  hash[:name] = $1
131
148
  hash[:number] = $2
@@ -134,6 +151,9 @@ module Puppet
134
151
  unless line == ""
135
152
  line.sub!(/^([^#]+)\s*/) do |value|
136
153
  aliases = $1
154
+
155
+ # Remove any trailing whitespace
156
+ aliases.strip!
137
157
  unless aliases =~ /^\s*$/
138
158
  hash[:alias] = aliases
139
159
  end
@@ -175,6 +195,9 @@ module Puppet
175
195
  unless @states.include?(:protocols)
176
196
  return false
177
197
  end
198
+
199
+ # This method is only called from parsing, so we only worry
200
+ # about 'is' values.
178
201
  proto = self.state(:protocols).is
179
202
 
180
203
  if proto.nil? or proto == :absent
@@ -192,9 +215,7 @@ module Puppet
192
215
  unless proto.include?(hash[:protocols])
193
216
  # We are missing their proto
194
217
  proto << hash[:protocols]
195
- #Puppet.info "new proto is %s" % proto.inspect
196
218
  @states[:protocols].is = proto
197
- #Puppet.info "new value is %s" % @states[:protocols].is.inspect
198
219
  end
199
220
  end
200
221
 
@@ -206,20 +227,20 @@ module Puppet
206
227
  return true
207
228
  end
208
229
 
209
- # Convert the current object into a host-style string.
230
+ # Convert the current object into one or more services entry.
210
231
  def to_record
211
- self.state(:protocols).should.collect { |proto|
212
- str = "%s\t%s/%s" % [self[:name], self.state(:number).should,
232
+ self.state(:protocols).value.collect { |proto|
233
+ str = "%s\t%s/%s" % [self[:name], self.value(:number),
213
234
  proto]
214
235
 
215
- if state = self.state(:alias)
216
- str += "\t%s" % state.should.join(" ")
236
+ if value = self.value(:alias) and value != :absent
237
+ str += "\t%s" % value.join(" ")
217
238
  else
218
239
  str += "\t"
219
240
  end
220
241
 
221
- if state = self.state(:description)
222
- str += "\t# %s" % state.should
242
+ if value = self.value(:description) and value != :absent
243
+ str += "\t# %s" % value
223
244
  else
224
245
  str += "\t"
225
246
  end
@@ -229,4 +250,4 @@ module Puppet
229
250
  end
230
251
  end
231
252
 
232
- # $Id: port.rb 831 2006-01-16 20:01:20Z luke $
253
+ # $Id: port.rb 915 2006-02-15 21:56:54Z luke $