puppet 0.13.6 → 0.16.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.

Files changed (149) hide show
  1. data/CHANGELOG +57 -0
  2. data/Rakefile +38 -410
  3. data/bin/puppet +14 -12
  4. data/bin/puppetca +1 -3
  5. data/bin/puppetd +25 -7
  6. data/bin/puppetdoc +161 -104
  7. data/bin/puppetmasterd +4 -4
  8. data/conf/epm.list +8 -0
  9. data/conf/redhat/client.init +6 -1
  10. data/conf/redhat/no-chuser-0.15.1.patch +38 -0
  11. data/conf/redhat/puppet.spec +20 -5
  12. data/conf/redhat/puppetd.conf +1 -1
  13. data/conf/redhat/puppetmasterd.conf +1 -1
  14. data/conf/redhat/server.init +2 -4
  15. data/examples/code/snippets/{casestatement → casestatement.pp} +12 -1
  16. data/examples/code/snippets/selectorvalues.pp +15 -0
  17. data/examples/code/snippets/singleselector.pp +22 -0
  18. data/examples/code/snippets/tag.pp +9 -0
  19. data/ext/module_puppet +1 -1
  20. data/install.rb +303 -303
  21. data/lib/puppet.rb +7 -9
  22. data/lib/puppet/client.rb +18 -5
  23. data/lib/puppet/client/dipper.rb +12 -10
  24. data/lib/puppet/client/master.rb +113 -41
  25. data/lib/puppet/client/pelement.rb +20 -0
  26. data/lib/puppet/config.rb +113 -6
  27. data/lib/puppet/element.rb +1 -3
  28. data/lib/puppet/event.rb +12 -23
  29. data/lib/puppet/filetype.rb +93 -5
  30. data/lib/puppet/inifile.rb +201 -0
  31. data/lib/puppet/log.rb +18 -6
  32. data/lib/puppet/parameter.rb +80 -29
  33. data/lib/puppet/parser/ast.rb +6 -4
  34. data/lib/puppet/parser/ast/caseopt.rb +13 -4
  35. data/lib/puppet/parser/ast/casestatement.rb +2 -2
  36. data/lib/puppet/parser/ast/component.rb +4 -14
  37. data/lib/puppet/parser/ast/hostclass.rb +1 -1
  38. data/lib/puppet/parser/ast/leaf.rb +12 -0
  39. data/lib/puppet/parser/ast/node.rb +4 -4
  40. data/lib/puppet/parser/ast/objectdef.rb +5 -51
  41. data/lib/puppet/parser/ast/selector.rb +2 -0
  42. data/lib/puppet/parser/ast/tag.rb +26 -0
  43. data/lib/puppet/parser/interpreter.rb +89 -74
  44. data/lib/puppet/parser/lexer.rb +4 -3
  45. data/lib/puppet/parser/parser.rb +440 -378
  46. data/lib/puppet/parser/scope.rb +844 -887
  47. data/lib/puppet/server.rb +12 -1
  48. data/lib/puppet/server/authconfig.rb +166 -0
  49. data/lib/puppet/server/authstore.rb +8 -6
  50. data/lib/puppet/server/ca.rb +23 -26
  51. data/lib/puppet/server/filebucket.rb +24 -23
  52. data/lib/puppet/server/fileserver.rb +116 -47
  53. data/lib/puppet/server/master.rb +58 -19
  54. data/lib/puppet/server/pelement.rb +176 -0
  55. data/lib/puppet/server/rights.rb +78 -0
  56. data/lib/puppet/server/servlet.rb +19 -6
  57. data/lib/puppet/sslcertificates.rb +4 -2
  58. data/lib/puppet/sslcertificates/ca.rb +66 -34
  59. data/lib/puppet/storage.rb +20 -26
  60. data/lib/puppet/transaction.rb +49 -92
  61. data/lib/puppet/type.rb +142 -35
  62. data/lib/puppet/type/cron.rb +29 -14
  63. data/lib/puppet/type/exec.rb +92 -35
  64. data/lib/puppet/type/group.rb +29 -11
  65. data/lib/puppet/type/nameservice.rb +50 -1
  66. data/lib/puppet/type/nameservice/netinfo.rb +68 -1
  67. data/lib/puppet/type/nameservice/objectadd.rb +1 -0
  68. data/lib/puppet/type/package.rb +150 -109
  69. data/lib/puppet/type/package/apple.rb +27 -0
  70. data/lib/puppet/type/package/apt.rb +1 -0
  71. data/lib/puppet/type/package/darwinport.rb +97 -0
  72. data/lib/puppet/type/package/dpkg.rb +10 -2
  73. data/lib/puppet/type/package/freebsd.rb +19 -0
  74. data/lib/puppet/type/package/{bsd.rb → openbsd.rb} +36 -7
  75. data/lib/puppet/type/package/ports.rb +98 -0
  76. data/lib/puppet/type/package/rpm.rb +43 -7
  77. data/lib/puppet/type/package/sun.rb +53 -36
  78. data/lib/puppet/type/package/yum.rb +5 -16
  79. data/lib/puppet/type/parsedtype.rb +41 -29
  80. data/lib/puppet/type/parsedtype/host.rb +13 -5
  81. data/lib/puppet/type/parsedtype/mount.rb +250 -0
  82. data/lib/puppet/type/parsedtype/port.rb +8 -6
  83. data/lib/puppet/type/pfile.rb +284 -30
  84. data/lib/puppet/type/pfile/checksum.rb +96 -68
  85. data/lib/puppet/type/pfile/content.rb +16 -13
  86. data/lib/puppet/type/pfile/ensure.rb +64 -126
  87. data/lib/puppet/type/pfile/group.rb +12 -5
  88. data/lib/puppet/type/pfile/mode.rb +16 -4
  89. data/lib/puppet/type/pfile/source.rb +47 -73
  90. data/lib/puppet/type/pfile/target.rb +81 -0
  91. data/lib/puppet/type/pfile/uid.rb +10 -3
  92. data/lib/puppet/type/pfilebucket.rb +12 -3
  93. data/lib/puppet/type/schedule.rb +5 -1
  94. data/lib/puppet/type/service.rb +138 -66
  95. data/lib/puppet/type/service/debian.rb +9 -3
  96. data/lib/puppet/type/service/init.rb +51 -56
  97. data/lib/puppet/type/service/smf.rb +16 -6
  98. data/lib/puppet/type/state.rb +71 -32
  99. data/lib/puppet/type/symlink.rb +12 -7
  100. data/lib/puppet/type/tidy.rb +5 -1
  101. data/lib/puppet/type/user.rb +116 -20
  102. data/lib/puppet/type/yumrepo.rb +314 -0
  103. data/lib/puppet/util.rb +84 -14
  104. data/test/client/client.rb +41 -18
  105. data/test/client/master.rb +50 -4
  106. data/test/executables/puppetbin.rb +31 -4
  107. data/test/executables/puppetca.rb +18 -2
  108. data/test/language/ast.rb +201 -31
  109. data/test/language/interpreter.rb +8 -2
  110. data/test/{parser → language}/lexer.rb +1 -1
  111. data/test/language/node.rb +84 -0
  112. data/test/{parser → language}/parser.rb +1 -1
  113. data/test/language/scope.rb +101 -2
  114. data/test/language/snippets.rb +23 -2
  115. data/test/other/config.rb +99 -1
  116. data/test/other/filetype.rb +95 -0
  117. data/test/other/inifile.rb +114 -0
  118. data/test/other/log.rb +3 -2
  119. data/test/other/transactions.rb +55 -10
  120. data/test/puppet/utiltest.rb +25 -1
  121. data/test/puppettest.rb +140 -46
  122. data/test/server/authconfig.rb +56 -0
  123. data/test/server/bucket.rb +32 -18
  124. data/test/server/fileserver.rb +75 -30
  125. data/test/server/master.rb +27 -4
  126. data/test/server/pelement.rb +298 -0
  127. data/test/server/rights.rb +41 -0
  128. data/test/server/server.rb +2 -2
  129. data/test/tagging/tagging.rb +100 -1
  130. data/test/types/basic.rb +3 -3
  131. data/test/types/cron.rb +24 -1
  132. data/test/types/exec.rb +99 -1
  133. data/test/types/file.rb +298 -2
  134. data/test/types/filebucket.rb +4 -15
  135. data/test/types/filesources.rb +43 -14
  136. data/test/types/group.rb +1 -13
  137. data/test/types/mount.rb +277 -0
  138. data/test/types/package.rb +164 -33
  139. data/test/types/parameter.rb +107 -0
  140. data/test/types/port.rb +2 -1
  141. data/test/types/service.rb +37 -2
  142. data/test/types/state.rb +92 -0
  143. data/test/types/symlink.rb +30 -2
  144. data/test/types/tidy.rb +2 -14
  145. data/test/types/type.rb +35 -1
  146. data/test/types/user.rb +110 -1
  147. data/test/types/yumrepo.rb +95 -0
  148. metadata +316 -290
  149. data/test/types/filetype.rb +0 -160
@@ -27,7 +27,11 @@ module Puppet
27
27
  if self.class.name == :command
28
28
  return super
29
29
  else
30
- return @is == @should
30
+ if @is.is_a? Array
31
+ return @is == @should
32
+ else
33
+ return @is == @should[0]
34
+ end
31
35
  end
32
36
  end
33
37
 
@@ -90,7 +94,7 @@ module Puppet
90
94
  end
91
95
 
92
96
  def should_to_s
93
- if @should.empty?
97
+ if ! defined? @should or @should.empty?
94
98
  return "*"
95
99
  else
96
100
  return @should.join(",")
@@ -204,19 +208,15 @@ module Puppet
204
208
 
205
209
  The user defaults to whomever Puppet is running as."
206
210
 
207
- defaultto Process.uid
211
+ defaultto { ENV["USER"] }
208
212
 
209
- validate do |user|
210
- require 'etc'
213
+ def value=(value)
214
+ super
211
215
 
212
- begin
213
- parent.uid = Puppet::Util.uid(user)
214
- #obj = Etc.getpwnam(user)
215
- rescue ArgumentError
216
- self.fail "User %s not found" % user
216
+ # Make sure the user is not an array
217
+ if @value.is_a? Array
218
+ @value = @value[0]
217
219
  end
218
-
219
- user
220
220
  end
221
221
  end
222
222
 
@@ -314,6 +314,15 @@ module Puppet
314
314
  end
315
315
  end
316
316
 
317
+ def self.list
318
+ # Look for cron jobs for each user
319
+ Puppet::Type.type(:user).list.each { |user|
320
+ self.retrieve(user.name)
321
+ }
322
+
323
+ self.collect { |c| c }
324
+ end
325
+
317
326
  # Parse a user's cron job into individual cron objects.
318
327
  #
319
328
  # Autogenerates names for any jobs that don't already have one; these
@@ -400,6 +409,13 @@ module Puppet
400
409
  # method. Returns nil if there was no cron job; else, returns the
401
410
  # number of cron instances found.
402
411
  def self.retrieve(user)
412
+ # First make sure the user exists
413
+ begin
414
+ Puppet::Util.uid(user)
415
+ rescue ArgumentError
416
+ raise Puppet::Error, "User %s not found" % user
417
+ end
418
+
403
419
  @tabs[user] ||= @filetype.new(user)
404
420
  text = @tabs[user].read
405
421
  if $? != 0
@@ -480,7 +496,6 @@ module Puppet
480
496
 
481
497
  def create
482
498
  # nothing
483
- self.info "creating"
484
499
  self.store
485
500
  end
486
501
 
@@ -544,4 +559,4 @@ module Puppet
544
559
  end
545
560
  end
546
561
 
547
- # $Id: cron.rb 910 2006-02-15 07:20:36Z luke $
562
+ # $Id: cron.rb 1127 2006-04-21 02:36:30Z luke $
@@ -138,12 +138,8 @@ module Puppet
138
138
 
139
139
  loglevel = @parent[:loglevel]
140
140
  if status.exitstatus.to_s != self.should.to_s
141
- err("%s returned %s instead of %s" %
141
+ self.fail("%s returned %s instead of %s" %
142
142
  [self.parent[:command], status.exitstatus, self.should.to_s])
143
-
144
- # if we've had a failure, up the log level
145
- loglevel = :err
146
- event = :failed_command
147
143
  end
148
144
 
149
145
  if log = @parent[:logoutput]
@@ -244,14 +240,14 @@ module Puppet
244
240
  desc "The directory from which to run the command. If
245
241
  this directory does not exist, the command will fail."
246
242
 
243
+ validate do |dir|
244
+ self.fail("CWD must be a fully qualified path") unless dir
245
+ end
246
+
247
247
  munge do |dir|
248
248
  if dir.is_a?(Array)
249
249
  dir = dir[0]
250
250
  end
251
-
252
- unless File.directory?(dir)
253
- self.fail "Directory '%s' does not exist" % dir
254
- end
255
251
 
256
252
  dir
257
253
  end
@@ -288,9 +284,11 @@ module Puppet
288
284
 
289
285
  "
290
286
 
287
+ newvalues(:true, :false)
288
+
291
289
  # We always fail this test, because we're only supposed to run
292
290
  # on refresh.
293
- def check
291
+ def check(value)
294
292
  false
295
293
  end
296
294
  end
@@ -312,16 +310,22 @@ module Puppet
312
310
 
313
311
  # FIXME if they try to set this and fail, then we should probably
314
312
  # fail the entire exec, right?
315
- validate do |file|
316
- unless file =~ %r{^#{File::SEPARATOR}}
317
- self.fail "'creates' files must be fully qualified."
313
+ validate do |files|
314
+ files = [files] unless files.is_a? Array
315
+
316
+ files.each do |file|
317
+ self.fail("'creates' must be set to a fully qualified path") unless file
318
+
319
+ unless file =~ %r{^#{File::SEPARATOR}}
320
+ self.fail "'creates' files must be fully qualified."
321
+ end
318
322
  end
319
323
  end
320
324
 
321
325
  # If the file exists, return false (i.e., don't run the command),
322
326
  # else return true
323
- def check
324
- return ! FileTest.exists?(self.value)
327
+ def check(value)
328
+ return ! FileTest.exists?(value)
325
329
  end
326
330
  end
327
331
 
@@ -341,9 +345,17 @@ module Puppet
341
345
  which is to say that it must be fully qualified if the path is not set.
342
346
  "
343
347
 
348
+ validate do |cmds|
349
+ cmds = [cmds] unless cmds.is_a? Array
350
+
351
+ cmds.each do |cmd|
352
+ @parent.validatecmd(cmd)
353
+ end
354
+ end
355
+
344
356
  # Return true if the command does not return 0.
345
- def check
346
- output, status = @parent.run(self.value)
357
+ def check(value)
358
+ output, status = @parent.run(value, true)
347
359
 
348
360
  return status.exitstatus != 0
349
361
  end
@@ -364,9 +376,17 @@ module Puppet
364
376
  which is to say that it must be fully qualified if the path is not set.
365
377
  "
366
378
 
379
+ validate do |cmds|
380
+ cmds = [cmds] unless cmds.is_a? Array
381
+
382
+ cmds.each do |cmd|
383
+ @parent.validatecmd(cmd)
384
+ end
385
+ end
386
+
367
387
  # Return true if the command returns 0.
368
- def check
369
- output, status = @parent.run(self.value)
388
+ def check(value)
389
+ output, status = @parent.run(value, true)
370
390
 
371
391
  return status.exitstatus == 0
372
392
  end
@@ -376,14 +396,10 @@ module Puppet
376
396
  @isomorphic = false
377
397
 
378
398
  validate do
379
- # if we're not fully qualified, require a path
380
- if self[:command] !~ /^\//
381
- if self[:path].nil?
382
- self.fail "both unqualifed and specified no search path"
383
- end
384
- end
399
+ validatecmd(self[:command])
385
400
  end
386
401
 
402
+ # FIXME exec should autorequire any exec that 'creates' our cwd
387
403
  autorequire(:file) do
388
404
  reqs = []
389
405
 
@@ -399,11 +415,16 @@ module Puppet
399
415
  [:onlyif, :unless].each { |param|
400
416
  next unless tmp = self[param]
401
417
 
402
- # And search the command line for files, adding any we find. This
403
- # will also catch the command itself if it's fully qualified. It might
404
- # not be a bad idea to add unqualified files, but, well, that's a
405
- # bit more annoying to do.
406
- reqs += tmp.scan(%r{(#{File::SEPARATOR}\S+)})
418
+ tmp = [tmp] unless tmp.is_a? Array
419
+
420
+ tmp.each do |line|
421
+ # And search the command line for files, adding any we
422
+ # find. This will also catch the command itself if it's
423
+ # fully qualified. It might not be a bad idea to add
424
+ # unqualified files, but, well, that's a bit more annoying
425
+ # to do.
426
+ reqs += line.scan(%r{(#{File::SEPARATOR}\S+)})
427
+ end
407
428
  }
408
429
 
409
430
  # For some reason, the += isn't causing a flattening
@@ -412,12 +433,20 @@ module Puppet
412
433
  reqs
413
434
  end
414
435
 
436
+ def self.list
437
+ self.collect { |i| i }
438
+ end
439
+
415
440
  # Verify that we pass all of the checks.
416
441
  def check
417
442
  self.class.checks.each { |check|
418
443
  if @parameters.include?(check)
419
- unless @parameters[check].check
420
- return false
444
+ val = @parameters[check].value
445
+ val = [val] unless val.is_a? Array
446
+ val.each do |value|
447
+ unless @parameters[check].check(value)
448
+ return false
449
+ end
421
450
  end
422
451
  end
423
452
  }
@@ -439,11 +468,30 @@ module Puppet
439
468
  end
440
469
 
441
470
  # Run a command.
442
- def run(command)
471
+ def run(command, check = false)
443
472
  output = nil
444
473
  status = nil
445
474
  tmppath = ENV["PATH"]
446
- dir = self[:cwd] || Dir.pwd
475
+
476
+ dir = nil
477
+
478
+ if dir = self[:cwd]
479
+ unless File.directory?(dir)
480
+ if check
481
+ dir = nil
482
+ else
483
+ self.fail "Working directory '%s' does not exist" % dir
484
+ end
485
+ end
486
+ end
487
+
488
+ dir ||= Dir.pwd
489
+
490
+ if check
491
+ debug "Executing check '#{command}'"
492
+ else
493
+ debug "Executing '#{command}'"
494
+ end
447
495
  begin
448
496
  # Do our chdir
449
497
  Dir.chdir(dir) {
@@ -482,7 +530,16 @@ module Puppet
482
530
  def to_s
483
531
  "exec(%s)" % self.name
484
532
  end
533
+
534
+ def validatecmd(cmd)
535
+ # if we're not fully qualified, require a path
536
+ if cmd !~ /^\//
537
+ if self[:path].nil?
538
+ self.fail "both unqualifed and specified no search path"
539
+ end
540
+ end
541
+ end
485
542
  end
486
543
  end
487
544
 
488
- # $Id: exec.rb 922 2006-02-16 19:10:34Z luke $
545
+ # $Id: exec.rb 1125 2006-04-20 19:38:48Z luke $
@@ -112,15 +112,23 @@ module Puppet
112
112
 
113
113
  def autogen
114
114
  highest = 0
115
- Etc.group { |group|
116
- if group.gid > highest
117
- unless group.gid > 65000
118
- highest = group.gid
115
+
116
+ # Make sure we don't use the same value multiple times
117
+ if defined? @@prevauto
118
+ @@prevauto += 1
119
+ else
120
+ Etc.group { |group|
121
+ if group.gid > highest
122
+ unless group.gid > 65000
123
+ highest = group.gid
124
+ end
119
125
  end
120
- end
121
- }
126
+ }
127
+
128
+ @@prevauto = highest + 1
129
+ end
122
130
 
123
- return highest + 1
131
+ return @@prevauto
124
132
  end
125
133
 
126
134
  munge do |gid|
@@ -136,15 +144,14 @@ module Puppet
136
144
  self.devfail "Invalid GID %s" % gid
137
145
  end
138
146
  if gid == :auto
147
+ # FIXME this should be done at sync time, not
148
+ # here.
139
149
  unless self.class.autogen?
140
150
  gid = autogen()
141
- @parent.log "autogenerated value as %s" % gid
142
151
  end
143
152
  end
144
153
  end
145
154
 
146
- self.info "Setting gid to %s" % gid
147
-
148
155
  return gid
149
156
  end
150
157
  end
@@ -164,6 +171,17 @@ module Puppet
164
171
  isnamevar
165
172
  end
166
173
 
174
+ # List all groups
175
+ def self.listbyname
176
+ groups = []
177
+ while ent = Etc.getgrent
178
+ groups << ent.name
179
+ end
180
+ Etc.endgrent
181
+
182
+ return groups
183
+ end
184
+
167
185
  def exists?
168
186
  self.class.parentmodule.exists?(self)
169
187
  end
@@ -204,4 +222,4 @@ module Puppet
204
222
  end
205
223
  end
206
224
 
207
- # $Id: group.rb 966 2006-03-02 17:12:26Z luke $
225
+ # $Id: group.rb 1125 2006-04-20 19:38:48Z luke $
@@ -11,6 +11,27 @@ class Type
11
11
  # netinfo types if that were the case.
12
12
  attr_accessor :netinfodir
13
13
 
14
+ # Create an instance for every object that exists on the machine
15
+ def list
16
+ listbyname.collect do |name|
17
+ obj = nil
18
+ check = @states.collect { |st| st.name }
19
+ if obj = self[name]
20
+ obj[:check] = check
21
+ else
22
+ # unless it exists, create it as an unmanaged object
23
+ obj = self.create(:name => name, :check => check)
24
+ end
25
+
26
+ next unless obj # In case there was an error somewhere
27
+
28
+ obj.retrieve
29
+
30
+
31
+ obj
32
+ end
33
+ end
34
+
14
35
  def newstate(*args, &block)
15
36
  s = super(*args, &block)
16
37
 
@@ -110,6 +131,33 @@ class State
110
131
  end
111
132
  end
112
133
 
134
+ # The list of all groups the user is a member of. Different
135
+ # user mgmt systems will need to override this method.
136
+ def grouplist
137
+ groups = []
138
+
139
+ # Reset our group list
140
+ Etc.setgrent
141
+
142
+ user = @parent[:name]
143
+
144
+ # Now iterate across all of the groups, adding each one our
145
+ # user is a member of
146
+ while group = Etc.getgrent
147
+ members = group.mem
148
+
149
+ if members.include? user
150
+ groups << group.name
151
+ end
152
+ end
153
+
154
+ # We have to close the file, so each listing is a separate
155
+ # reading of the file.
156
+ Etc.endgrent
157
+
158
+ groups
159
+ end
160
+
113
161
  # Sync the information.
114
162
  def sync
115
163
  event = nil
@@ -194,6 +242,7 @@ class State
194
242
  Puppet.debug "%s is not allatonce" % @parent.class.name
195
243
  if type == "create"
196
244
  @parent.eachstate { |state|
245
+ next if state.name == :ensure
197
246
  state.sync
198
247
  state.retrieve
199
248
  }
@@ -215,4 +264,4 @@ else
215
264
  end
216
265
 
217
266
 
218
- # $Id: nameservice.rb 966 2006-03-02 17:12:26Z luke $
267
+ # $Id: nameservice.rb 1125 2006-04-20 19:38:48Z luke $