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
@@ -6,6 +6,7 @@ module Puppet
6
6
  # a class for storing state
7
7
  class Storage
8
8
  include Singleton
9
+ include Puppet::Util
9
10
 
10
11
  def initialize
11
12
  self.class.load
@@ -47,19 +48,21 @@ module Puppet
47
48
  end
48
49
  return
49
50
  end
50
- Puppet::Util.readlock(Puppet[:statefile]) do |file|
51
- begin
52
- @@state = YAML.load(file)
53
- rescue => detail
54
- Puppet.err "Checksumfile %s is corrupt (%s); replacing" %
55
- [Puppet[:statefile], detail]
51
+ Puppet::Util.benchmark(:debug, "Loaded state") do
52
+ Puppet::Util.readlock(Puppet[:statefile]) do |file|
56
53
  begin
57
- File.rename(Puppet[:statefile],
58
- Puppet[:statefile] + ".bad")
59
- rescue
60
- raise Puppet::Error,
61
- "Could not rename corrupt %s; remove manually" %
62
- Puppet[:statefile]
54
+ @@state = YAML.load(file)
55
+ rescue => detail
56
+ Puppet.err "Checksumfile %s is corrupt (%s); replacing" %
57
+ [Puppet[:statefile], detail]
58
+ begin
59
+ File.rename(Puppet[:statefile],
60
+ Puppet[:statefile] + ".bad")
61
+ rescue
62
+ raise Puppet::Error,
63
+ "Could not rename corrupt %s; remove manually" %
64
+ Puppet[:statefile]
65
+ end
63
66
  end
64
67
  end
65
68
  end
@@ -79,27 +82,18 @@ module Puppet
79
82
  def self.store
80
83
  Puppet.config.use(:puppet)
81
84
  Puppet.debug "Storing state"
82
- # unless FileTest.directory?(File.dirname(Puppet[:statefile]))
83
- # begin
84
- # Puppet.recmkdir(File.dirname(Puppet[:statefile]))
85
- # Puppet.info "Creating state directory %s" %
86
- # File.dirname(Puppet[:statefile])
87
- # rescue => detail
88
- # Puppet.err "Could not create state file: %s" % detail
89
- # return
90
- # end
91
- # end
92
85
 
93
86
  unless FileTest.exist?(Puppet[:statefile])
94
87
  Puppet.info "Creating state file %s" % Puppet[:statefile]
95
88
  end
96
89
 
97
- Puppet::Util.writelock(Puppet[:statefile], 0600) do |file|
98
- file.print YAML.dump(@@state)
90
+ Puppet::Util.benchmark(:debug, "Stored state") do
91
+ Puppet::Util.writelock(Puppet[:statefile], 0660) do |file|
92
+ file.print YAML.dump(@@state)
93
+ end
99
94
  end
100
- Puppet.debug "Stored state"
101
95
  end
102
96
  end
103
97
  end
104
98
 
105
- # $Id: storage.rb 965 2006-03-02 07:30:14Z luke $
99
+ # $Id: storage.rb 1098 2006-04-10 22:13:10Z luke $
@@ -1,38 +1,34 @@
1
1
  # the class that actually walks our object/state tree, collects the changes,
2
2
  # and performs them
3
3
 
4
- # there are two directions of walking:
5
- # - first we recurse down the tree and collect changes
6
- # - then we walk back up the tree through 'refresh' after the changes
7
-
8
4
  require 'puppet'
9
5
  require 'puppet/statechange'
10
6
 
11
- #---------------------------------------------------------------
12
7
  module Puppet
13
8
  class Transaction
14
9
  attr_accessor :toplevel, :component, :objects
15
10
 
16
- #---------------------------------------------------------------
11
+
12
+ Puppet.config.setdefaults(:transaction,
13
+ :tags => ["", "Tags to use to find objects. If this is set, then
14
+ only objects tagged with the specified tags will be applied. Values must
15
+ be comma-separated."]
16
+ )
17
+
17
18
  # a bit of a gross hack; a global list of objects that have failed to sync,
18
19
  # so that we can verify during later syncs that our dependencies haven't
19
20
  # failed
20
21
  def Transaction.init
21
22
  @@failures = Hash.new(0)
22
23
  Puppet::Metric.init
23
- @@changed = []
24
24
  end
25
- #---------------------------------------------------------------
26
25
 
27
- #---------------------------------------------------------------
28
26
  # for now, just store the changes for executing linearly
29
27
  # later, we might execute them as we receive them
30
28
  def change(change)
31
29
  @changes.push change
32
30
  end
33
- #---------------------------------------------------------------
34
31
 
35
- #---------------------------------------------------------------
36
32
  # okay, here's the deal:
37
33
  # a given transaction maps directly to a component, and each transaction
38
34
  # will only ever receive changes from its respective component
@@ -46,7 +42,19 @@ class Transaction
46
42
 
47
43
  count = 0
48
44
  now = Time.now
45
+ tags = Puppet[:tags]
46
+ if tags == ""
47
+ tags = nil
48
+ else
49
+ tags = tags.split(/\s*,\s*/)
50
+ end
49
51
  events = @objects.find_all { |child|
52
+ if tags
53
+ child.tagged?(tags)
54
+ else
55
+ true # match everything when there are no tags
56
+ end
57
+ }.find_all { |child|
50
58
  child.scheduled?
51
59
  }.collect { |child|
52
60
  # these children are all Puppet::Type instances
@@ -67,7 +75,6 @@ class Transaction
67
75
  # use an array, so that changes can return more than one
68
76
  # event if they want
69
77
  events = [change.forward].flatten.reject { |e| e.nil? }
70
- #@@changed.push change.state.parent
71
78
  rescue => detail
72
79
  change.state.err "change from %s to %s failed: %s" %
73
80
  [change.state.is_to_s, change.state.should_to_s, detail]
@@ -94,60 +101,13 @@ class Transaction
94
101
  }.flatten.reject { |child|
95
102
  child.nil? # remove empties
96
103
  }
97
- # events = @changes.collect { |change|
98
- # if change.is_a?(Puppet::StateChange)
99
- # change.transaction = self
100
- # events = nil
101
- # begin
102
- # # use an array, so that changes can return more than one
103
- # # event if they want
104
- # events = [change.forward].flatten.reject { |e| e.nil? }
105
- # #@@changed.push change.state.parent
106
- # rescue => detail
107
- # change.state.err "change from %s to %s failed: %s" %
108
- # [change.state.is_to_s, change.state.should_to_s, detail]
109
- # #Puppet.err("%s failed: %s" % [change.to_s,detail])
110
- # if Puppet[:debug]
111
- # puts detail.backtrace
112
- # end
113
- # next
114
- # # FIXME this should support using onerror to determine
115
- # # behaviour; or more likely, the client calling us
116
- # # should do so
117
- # end
118
- #
119
- # # This is kinda lame, because it can result in the same
120
- # # object being modified multiple times, but that's difficult
121
- # # to avoid as long as we're syncing each state individually.
122
- # change.state.parent.cache(:synced, now)
123
- #
124
- # unless events.nil? or (events.is_a?(Array) and events.empty?)
125
- # change.changed = true
126
- # end
127
- # events
128
- # else
129
- # puts caller
130
- # raise Puppet::DevError,
131
- # "Transactions cannot handle objects of type %s" % change.class
132
- # end
133
- # }.flatten.reject { |event|
134
- # event.nil?
135
- # }
136
104
 
137
105
  Puppet.debug "Finishing transaction %s with %s changes" %
138
106
  [self.object_id, count]
139
- #@triggerevents = []
140
- events.each { |event|
141
- object = event.source
142
- #Puppet::Event::Subscriptions.propagate(object, event, self)
143
- object.propagate(event, self)
144
- }
145
107
 
146
- #events += @triggerevents
108
+ self.propagate(events)
147
109
  end
148
- #---------------------------------------------------------------
149
110
 
150
- #---------------------------------------------------------------
151
111
  # this should only be called by a Puppet::Container object now
152
112
  # and it should only receive an array
153
113
  def initialize(objects)
@@ -165,26 +125,36 @@ class Transaction
165
125
  end
166
126
 
167
127
  @changes = []
128
+ end
168
129
 
169
- # change collection is in-band, and message generation is out-of-band
170
- # of course, exception raising is also out-of-band
171
- now = Time.now.to_i
172
- # @changes = @objects.find_all { |child|
173
- # child.scheduled?
174
- # }.collect { |child|
175
- # # these children are all Puppet::Type instances
176
- # # not all of the children will return a change, and Containers
177
- # # return transactions
178
- # #ary = child.evaluate
179
- # #ary
180
- # child.evaluate
181
- # }.flatten.reject { |child|
182
- # child.nil? # remove empties
183
- # }
130
+ # Respond to each of the events. This method walks up the parent tree,
131
+ # triggering each parent in turn. It's important that the transaction
132
+ # itself know whether a given subscription fails, so that it can respond
133
+ # appropriately (when we get to the point where we're responding to events).
134
+ def propagate(events)
135
+ events.each do |event|
136
+ source = event.source
137
+
138
+ while source
139
+ Puppet::Event::Subscription.trigger(source, event) do |sub|
140
+ begin
141
+ sub.trigger(self)
142
+ rescue => detail
143
+ sub.target.err "Failed to respond to %s: %s" % [event, detail]
144
+ if Puppet[:debug]
145
+ puts detail.backtrace
146
+ end
147
+ end
148
+ end
149
+
150
+ # Reset the source if there's a parent obj
151
+ source = source.parent
152
+ end
153
+ #Puppet::Event::Subscriptions.propagate(object, event, self)
154
+ end
184
155
  end
185
- #---------------------------------------------------------------
186
156
 
187
- #---------------------------------------------------------------
157
+ # Roll all completed changes back.
188
158
  def rollback
189
159
  events = @changes.reverse.collect { |change|
190
160
  if change.is_a?(Puppet::StateChange)
@@ -196,7 +166,6 @@ class Transaction
196
166
  #change.transaction = self
197
167
  begin
198
168
  change.backward
199
- #@@changed.push change.state.parent
200
169
  rescue => detail
201
170
  Puppet.err("%s rollback failed: %s" % [change,detail])
202
171
  if Puppet[:debug]
@@ -220,30 +189,18 @@ class Transaction
220
189
  end
221
190
  }.flatten.reject { |e| e.nil? }
222
191
 
223
- #@triggerevents = []
224
- events.each { |event|
225
- object = event.source
226
- object.propagate(event, self)
227
- }
228
-
229
- #events += @triggerevents
192
+ self.propagate(events)
230
193
  end
231
- #---------------------------------------------------------------
232
194
 
233
- #---------------------------------------------------------------
234
195
  def triggered(object, method)
235
196
  @triggered[object][method] += 1
236
197
  #@triggerevents << ("%s_%sed" % [object.class.name.to_s, method.to_s]).intern
237
198
  end
238
- #---------------------------------------------------------------
239
199
 
240
- #---------------------------------------------------------------
241
200
  def triggered?(object, method)
242
201
  @triggered[object][method]
243
202
  end
244
- #---------------------------------------------------------------
245
203
  end
246
204
  end
247
- #---------------------------------------------------------------
248
205
 
249
- # $Id: transaction.rb 965 2006-03-02 07:30:14Z luke $
206
+ # $Id: transaction.rb 1005 2006-03-11 22:18:59Z luke $
@@ -9,7 +9,10 @@ require 'puppet/util'
9
9
  # see the bottom of the file for the rest of the inclusions
10
10
 
11
11
  module Puppet
12
+ # The type is unknown
13
+ class UnknownTypeError < Puppet::Error; end
12
14
  class Type < Puppet::Element
15
+
13
16
  # Types (which map to elements in the languages) are entirely composed of
14
17
  # attribute value pairs. Generally, Puppet calls any of these things an
15
18
  # 'attribute', but these attributes always take one of three specific
@@ -19,7 +22,8 @@ class Type < Puppet::Element
19
22
  # that it is clear whether it operates on all attributes (thus has 'attr' in
20
23
  # the method name, or whether it operates on a specific type of attributes.
21
24
  attr_accessor :children, :parent
22
- attr_accessor :file, :line, :tags
25
+ attr_accessor :file, :line
26
+ attr_reader :tags
23
27
 
24
28
  attr_writer :implicit
25
29
  def implicit?
@@ -61,7 +65,6 @@ class Type < Puppet::Element
61
65
  include Enumerable
62
66
 
63
67
  def inspect
64
- Puppet.info "inspecting class with name %s" % self.name
65
68
  "Type(%s)" % self.name
66
69
  end
67
70
 
@@ -215,6 +218,17 @@ class Type < Puppet::Element
215
218
  name = name.intern
216
219
  end
217
220
 
221
+ unless @types.include? name
222
+ begin
223
+ require "puppet/type/#{name}"
224
+ unless @types.include? name
225
+ Puppet.warning "Loaded puppet/type/#{name} but no class was created"
226
+ end
227
+ rescue LoadError
228
+ # nothing
229
+ end
230
+ end
231
+
218
232
  @types[name]
219
233
  end
220
234
 
@@ -417,6 +431,9 @@ class Type < Puppet::Element
417
431
  param = Class.new(Puppet::Parameter) do
418
432
  @name = name
419
433
  end
434
+
435
+ param.initvars
436
+
420
437
  param.ismetaparameter
421
438
  param.class_eval(&block)
422
439
  const_set("MetaParam" + name.to_s.capitalize,param)
@@ -440,6 +457,9 @@ class Type < Puppet::Element
440
457
  param = Class.new(Puppet::Parameter) do
441
458
  @name = name
442
459
  end
460
+
461
+ param.initvars
462
+
443
463
  param.element = self
444
464
  param.class_eval(&block)
445
465
  const_set("Parameter" + name.to_s.capitalize,param)
@@ -475,6 +495,9 @@ class Type < Puppet::Element
475
495
  s = Class.new(parent) do
476
496
  @name = name
477
497
  end
498
+
499
+ s.initvars
500
+
478
501
  const_set("State" + name.to_s.capitalize,s)
479
502
  s.class_eval(&block)
480
503
  @states ||= []
@@ -919,7 +942,8 @@ class Type < Puppet::Element
919
942
  end
920
943
  param = klass.new
921
944
  param.parent = self
922
- if value
945
+
946
+ unless value.nil?
923
947
  param.value = value
924
948
  end
925
949
 
@@ -1000,7 +1024,11 @@ class Type < Puppet::Element
1000
1024
  # Remove an object. The argument determines whether the object's
1001
1025
  # subscriptions get eliminated, too.
1002
1026
  def remove(rmdeps = true)
1003
- @children.each { |child|
1027
+ # Our children remove themselves from our @children array (else the object
1028
+ # we called this on at the top would not be removed), so we duplicate the
1029
+ # array and iterate over that. If we don't do this, only half of the
1030
+ # objects get removed.
1031
+ @children.dup.each { |child|
1004
1032
  child.remove(rmdeps)
1005
1033
  }
1006
1034
 
@@ -1308,7 +1336,7 @@ class Type < Puppet::Element
1308
1336
  if attrs.include?(namevar)
1309
1337
  attrs.delete(namevar)
1310
1338
  else
1311
- self.devfail "My namevar isn't a valid attribute...?"
1339
+ self.devfail "My namevar isn\'t a valid attribute...?"
1312
1340
  end
1313
1341
  else
1314
1342
  self.devfail "I was not passed a namevar"
@@ -1325,6 +1353,8 @@ class Type < Puppet::Element
1325
1353
  if hash.include?(name)
1326
1354
  begin
1327
1355
  self[name] = hash[name]
1356
+ rescue ArgumentError, Puppet::Error, TypeError
1357
+ raise
1328
1358
  rescue => detail
1329
1359
  self.devfail(
1330
1360
  "Could not set %s on %s: %s" %
@@ -1375,8 +1405,13 @@ class Type < Puppet::Element
1375
1405
  obj = nil
1376
1406
  # Support them passing objects directly, to save some effort.
1377
1407
  if dep.is_a? Puppet::Type
1408
+ self.info "requiring %s" % dep.name
1378
1409
  type = dep.class.name
1379
1410
  obj = dep
1411
+
1412
+ # Now change our dependency to just the string, instead of
1413
+ # the object itself.
1414
+ dep = dep.name
1380
1415
  else
1381
1416
  # Skip autorequires that we aren't managing
1382
1417
  unless obj = typeobj[dep]
@@ -1452,8 +1487,36 @@ class Type < Puppet::Element
1452
1487
  return schedule.match?(self.cached(:checked).to_i)
1453
1488
  end
1454
1489
 
1490
+ # Add a new tag.
1455
1491
  def tag(tag)
1456
- @tags << tag
1492
+ tag = tag.intern if tag.is_a? String
1493
+ unless @tags.include? tag
1494
+ @tags << tag
1495
+ end
1496
+ end
1497
+
1498
+ # Define the initial list of tags.
1499
+ def tags=(list)
1500
+ list = [list] unless list.is_a? Array
1501
+
1502
+ @tags = list.collect do |t|
1503
+ case t
1504
+ when String: t.intern
1505
+ when Symbol: t
1506
+ else
1507
+ self.warning "Ignoring tag %s of type %s" % [tag.inspect, tag.class]
1508
+ end
1509
+ end
1510
+ end
1511
+
1512
+ # Figure out of any of the specified tags apply to this object. This is an
1513
+ # OR operation.
1514
+ def tagged?(tags)
1515
+ tags = [tags] unless tags.is_a? Array
1516
+
1517
+ tags = tags.collect { |t| t.intern }
1518
+
1519
+ return tags.find { |tag| @tags.include? tag }
1457
1520
  end
1458
1521
 
1459
1522
  # Is the specified parameter set?
@@ -1622,6 +1685,34 @@ class Type < Puppet::Element
1622
1685
  self.name
1623
1686
  end
1624
1687
 
1688
+ # Convert to a transportable object
1689
+ def to_trans
1690
+ # Collect all of the "is" values
1691
+ retrieve()
1692
+
1693
+ trans = TransObject.new(self.name, self.class.name)
1694
+
1695
+ states().each do |state|
1696
+ trans[state.name] = state.is
1697
+ end
1698
+
1699
+ @parameters.each do |name, param|
1700
+ # Avoid adding each instance name as both the name and the namevar
1701
+ next if param.class.isnamevar? and param.value == self.name
1702
+ trans[name] = param.value
1703
+ end
1704
+
1705
+ @metaparams.each do |name, param|
1706
+ trans[name] = param.value
1707
+ end
1708
+
1709
+ trans.tags = self.tags
1710
+
1711
+ # FIXME I'm currently ignoring 'parent' and 'path'
1712
+
1713
+ return trans
1714
+ end
1715
+
1625
1716
  # instance methods dealing with actually doing work
1626
1717
 
1627
1718
  public
@@ -1725,7 +1816,7 @@ class Type < Puppet::Element
1725
1816
  # now record how many changes we've resulted in
1726
1817
  Puppet::Metric.add(self.class,self,:changes,changes.length)
1727
1818
  if changes.length > 0
1728
- self.info "%s change(s)" %
1819
+ self.debug "%s change(s)" %
1729
1820
  [changes.length]
1730
1821
  end
1731
1822
  self.cache(:checked, now)
@@ -1746,9 +1837,11 @@ class Type < Puppet::Element
1746
1837
 
1747
1838
  states.each { |state|
1748
1839
  unless state.insync?
1749
- self.debug("%s is not in sync: %s vs %s" %
1750
- [state, state.is.inspect, state.should.inspect])
1840
+ state.debug("Not in sync: %s vs %s" %
1841
+ [state.is.inspect, state.should.inspect])
1751
1842
  insync = false
1843
+ #else
1844
+ # state.debug("In sync")
1752
1845
  end
1753
1846
  }
1754
1847
 
@@ -1845,16 +1938,6 @@ class Type < Puppet::Element
1845
1938
  }
1846
1939
  end
1847
1940
 
1848
- # Trigger any associated subscriptions, and then pass the event up to our
1849
- # parent.
1850
- def propagate(event, transaction)
1851
- Puppet::Event::Subscription.trigger(self, event, transaction)
1852
-
1853
- if defined? @parent
1854
- @parent.propagate(event, transaction)
1855
- end
1856
- end
1857
-
1858
1941
  def requires?(object)
1859
1942
  req = false
1860
1943
  self.eachdependency { |dep|
@@ -1989,6 +2072,13 @@ class Type < Puppet::Element
1989
2072
  on all packages."
1990
2073
 
1991
2074
  munge do |args|
2075
+ # If they've specified all, collect all known states
2076
+ if args == :all
2077
+ args = @parent.class.states.collect do |state|
2078
+ state.name
2079
+ end
2080
+ end
2081
+
1992
2082
  unless args.is_a?(Array)
1993
2083
  args = [args]
1994
2084
  end
@@ -2004,6 +2094,8 @@ class Type < Puppet::Element
2004
2094
  end
2005
2095
  next if @parent.statedefined?(state)
2006
2096
 
2097
+ next unless @parent.class.validstate?(state).checkable?
2098
+
2007
2099
  @parent.newstate(state)
2008
2100
  }
2009
2101
  end
@@ -2101,23 +2193,15 @@ class Type < Puppet::Element
2101
2193
  currently the default)."
2102
2194
  defaultto :notice
2103
2195
 
2104
- validate do |loglevel|
2105
- if loglevel.is_a?(String)
2106
- loglevel = loglevel.intern
2107
- end
2108
- unless Puppet::Log.validlevel?(loglevel)
2109
- self.fail "Invalid log level %s" % loglevel
2110
- end
2111
- end
2196
+ newvalues(*Puppet::Log.levels)
2197
+ newvalues(:verbose)
2112
2198
 
2113
2199
  munge do |loglevel|
2114
- if loglevel.is_a?(String)
2115
- loglevel = loglevel.intern
2116
- end
2117
- if loglevel == :verbose
2118
- loglevel = :info
2200
+ val = super(loglevel)
2201
+ if val == :verbose
2202
+ val = :info
2119
2203
  end
2120
- loglevel
2204
+ val
2121
2205
  end
2122
2206
  end
2123
2207
 
@@ -2169,7 +2253,7 @@ class Type < Puppet::Element
2169
2253
  if obj = @parent.class[other]
2170
2254
  unless obj == @parent
2171
2255
  self.fail(
2172
- "%s an not create alias %s: object already exists" %
2256
+ "%s can not create alias %s: object already exists" %
2173
2257
  [@parent.name, other]
2174
2258
  )
2175
2259
  end
@@ -2179,6 +2263,29 @@ class Type < Puppet::Element
2179
2263
  end
2180
2264
  end
2181
2265
  end
2266
+
2267
+ newmetaparam(:tag) do
2268
+ desc "Add the specified tags to the associated element. While all elements
2269
+ are automatically tagged with as much information as possible
2270
+ (e.g., each class and component containing the element), it can
2271
+ be useful to add your own tags to a given element.
2272
+
2273
+ Tags are currently useful for things like applying a subset of a
2274
+ host's configuration:
2275
+
2276
+ puppetd -v --tag mytag --onetime
2277
+
2278
+ This way, when you're testing a configuration you can run just the
2279
+ portion you're testing."
2280
+
2281
+ munge do |tags|
2282
+ tags = [tags] unless tags.is_a? Array
2283
+
2284
+ tags.each do |tag|
2285
+ @parent.tag(tag)
2286
+ end
2287
+ end
2288
+ end
2182
2289
  end # Puppet::Type
2183
2290
  end
2184
2291
 
@@ -2197,4 +2304,4 @@ require 'puppet/type/user'
2197
2304
  require 'puppet/type/tidy'
2198
2305
  require 'puppet/type/parsedtype'
2199
2306
 
2200
- # $Id: type.rb 966 2006-03-02 17:12:26Z luke $
2307
+ # $Id: type.rb 1129 2006-04-21 19:14:59Z luke $