puppet 0.9.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 (182) hide show
  1. data/CHANGELOG +0 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +17 -0
  4. data/README +24 -0
  5. data/Rakefile +294 -0
  6. data/TODO +4 -0
  7. data/bin/cf2puppet +186 -0
  8. data/bin/puppet +176 -0
  9. data/bin/puppetca +213 -0
  10. data/bin/puppetd +246 -0
  11. data/bin/puppetdoc +184 -0
  12. data/bin/puppetmasterd +258 -0
  13. data/examples/code/allatonce +13 -0
  14. data/examples/code/assignments +11 -0
  15. data/examples/code/classing +35 -0
  16. data/examples/code/components +73 -0
  17. data/examples/code/execs +16 -0
  18. data/examples/code/failers/badclassnoparam +10 -0
  19. data/examples/code/failers/badclassparam +10 -0
  20. data/examples/code/failers/badcompnoparam +9 -0
  21. data/examples/code/failers/badcompparam +9 -0
  22. data/examples/code/failers/badtypeparam +3 -0
  23. data/examples/code/file.bl +11 -0
  24. data/examples/code/filedefaults +10 -0
  25. data/examples/code/fileparsing +116 -0
  26. data/examples/code/filerecursion +15 -0
  27. data/examples/code/functions +3 -0
  28. data/examples/code/groups +7 -0
  29. data/examples/code/head +30 -0
  30. data/examples/code/importing +8 -0
  31. data/examples/code/nodes +20 -0
  32. data/examples/code/one +8 -0
  33. data/examples/code/relationships +34 -0
  34. data/examples/code/selectors +28 -0
  35. data/examples/code/simpletests +11 -0
  36. data/examples/code/snippets/argumentdefaults +14 -0
  37. data/examples/code/snippets/casestatement +39 -0
  38. data/examples/code/snippets/classheirarchy.pp +15 -0
  39. data/examples/code/snippets/classincludes.pp +17 -0
  40. data/examples/code/snippets/classpathtest +11 -0
  41. data/examples/code/snippets/dirchmod +19 -0
  42. data/examples/code/snippets/failmissingexecpath.pp +13 -0
  43. data/examples/code/snippets/falsevalues.pp +3 -0
  44. data/examples/code/snippets/filecreate +11 -0
  45. data/examples/code/snippets/implicititeration +15 -0
  46. data/examples/code/snippets/multipleinstances +7 -0
  47. data/examples/code/snippets/namevartest +9 -0
  48. data/examples/code/snippets/scopetest +13 -0
  49. data/examples/code/snippets/selectorvalues.pp +22 -0
  50. data/examples/code/snippets/simpledefaults +5 -0
  51. data/examples/code/snippets/simpleselector +38 -0
  52. data/examples/code/svncommit +13 -0
  53. data/examples/root/bin/sleeper +69 -0
  54. data/examples/root/etc/configfile +0 -0
  55. data/examples/root/etc/debian-passwd +29 -0
  56. data/examples/root/etc/debian-syslog.conf +71 -0
  57. data/examples/root/etc/init.d/sleeper +65 -0
  58. data/examples/root/etc/otherfile +0 -0
  59. data/examples/root/etc/puppet/fileserver.conf +3 -0
  60. data/examples/root/etc/puppet/puppetmasterd.conf +10 -0
  61. data/ext/module:puppet +195 -0
  62. data/install.rb +270 -0
  63. data/lib/puppet.rb +249 -0
  64. data/lib/puppet/base64.rb +19 -0
  65. data/lib/puppet/client.rb +519 -0
  66. data/lib/puppet/config.rb +49 -0
  67. data/lib/puppet/daemon.rb +208 -0
  68. data/lib/puppet/element.rb +71 -0
  69. data/lib/puppet/event.rb +259 -0
  70. data/lib/puppet/log.rb +321 -0
  71. data/lib/puppet/metric.rb +250 -0
  72. data/lib/puppet/parsedfile.rb +38 -0
  73. data/lib/puppet/parser/ast.rb +1560 -0
  74. data/lib/puppet/parser/interpreter.rb +150 -0
  75. data/lib/puppet/parser/lexer.rb +226 -0
  76. data/lib/puppet/parser/parser.rb +1354 -0
  77. data/lib/puppet/parser/scope.rb +755 -0
  78. data/lib/puppet/server.rb +170 -0
  79. data/lib/puppet/server/authstore.rb +227 -0
  80. data/lib/puppet/server/ca.rb +140 -0
  81. data/lib/puppet/server/filebucket.rb +147 -0
  82. data/lib/puppet/server/fileserver.rb +477 -0
  83. data/lib/puppet/server/logger.rb +43 -0
  84. data/lib/puppet/server/master.rb +103 -0
  85. data/lib/puppet/server/servlet.rb +247 -0
  86. data/lib/puppet/sslcertificates.rb +737 -0
  87. data/lib/puppet/statechange.rb +150 -0
  88. data/lib/puppet/storage.rb +95 -0
  89. data/lib/puppet/transaction.rb +179 -0
  90. data/lib/puppet/transportable.rb +151 -0
  91. data/lib/puppet/type.rb +1354 -0
  92. data/lib/puppet/type/component.rb +141 -0
  93. data/lib/puppet/type/cron.rb +543 -0
  94. data/lib/puppet/type/exec.rb +316 -0
  95. data/lib/puppet/type/group.rb +152 -0
  96. data/lib/puppet/type/nameservice.rb +3 -0
  97. data/lib/puppet/type/nameservice/netinfo.rb +173 -0
  98. data/lib/puppet/type/nameservice/objectadd.rb +146 -0
  99. data/lib/puppet/type/nameservice/posix.rb +200 -0
  100. data/lib/puppet/type/package.rb +420 -0
  101. data/lib/puppet/type/package/apt.rb +70 -0
  102. data/lib/puppet/type/package/dpkg.rb +108 -0
  103. data/lib/puppet/type/package/rpm.rb +81 -0
  104. data/lib/puppet/type/package/sun.rb +117 -0
  105. data/lib/puppet/type/package/yum.rb +58 -0
  106. data/lib/puppet/type/pfile.rb +569 -0
  107. data/lib/puppet/type/pfile/checksum.rb +219 -0
  108. data/lib/puppet/type/pfile/create.rb +108 -0
  109. data/lib/puppet/type/pfile/group.rb +129 -0
  110. data/lib/puppet/type/pfile/mode.rb +131 -0
  111. data/lib/puppet/type/pfile/source.rb +264 -0
  112. data/lib/puppet/type/pfile/type.rb +31 -0
  113. data/lib/puppet/type/pfile/uid.rb +166 -0
  114. data/lib/puppet/type/pfilebucket.rb +80 -0
  115. data/lib/puppet/type/pprocess.rb +97 -0
  116. data/lib/puppet/type/service.rb +347 -0
  117. data/lib/puppet/type/service/base.rb +17 -0
  118. data/lib/puppet/type/service/debian.rb +50 -0
  119. data/lib/puppet/type/service/init.rb +145 -0
  120. data/lib/puppet/type/service/smf.rb +29 -0
  121. data/lib/puppet/type/state.rb +182 -0
  122. data/lib/puppet/type/symlink.rb +183 -0
  123. data/lib/puppet/type/tidy.rb +183 -0
  124. data/lib/puppet/type/typegen.rb +149 -0
  125. data/lib/puppet/type/typegen/filerecord.rb +243 -0
  126. data/lib/puppet/type/typegen/filetype.rb +316 -0
  127. data/lib/puppet/type/user.rb +290 -0
  128. data/lib/puppet/util.rb +138 -0
  129. data/test/certmgr/certmgr.rb +265 -0
  130. data/test/client/client.rb +203 -0
  131. data/test/executables/puppetbin.rb +53 -0
  132. data/test/executables/puppetca.rb +79 -0
  133. data/test/executables/puppetd.rb +71 -0
  134. data/test/executables/puppetmasterd.rb +153 -0
  135. data/test/executables/puppetmodule.rb +60 -0
  136. data/test/language/ast.rb +412 -0
  137. data/test/language/interpreter.rb +71 -0
  138. data/test/language/scope.rb +412 -0
  139. data/test/language/snippets.rb +445 -0
  140. data/test/other/events.rb +111 -0
  141. data/test/other/log.rb +195 -0
  142. data/test/other/metrics.rb +92 -0
  143. data/test/other/overrides.rb +115 -0
  144. data/test/other/parsedfile.rb +31 -0
  145. data/test/other/relationships.rb +113 -0
  146. data/test/other/state.rb +106 -0
  147. data/test/other/storage.rb +39 -0
  148. data/test/other/transactions.rb +235 -0
  149. data/test/parser/lexer.rb +120 -0
  150. data/test/parser/parser.rb +180 -0
  151. data/test/puppet/conffiles.rb +104 -0
  152. data/test/puppet/defaults.rb +100 -0
  153. data/test/puppet/error.rb +23 -0
  154. data/test/puppet/utiltest.rb +120 -0
  155. data/test/puppettest.rb +774 -0
  156. data/test/server/authstore.rb +209 -0
  157. data/test/server/bucket.rb +227 -0
  158. data/test/server/ca.rb +201 -0
  159. data/test/server/fileserver.rb +710 -0
  160. data/test/server/logger.rb +175 -0
  161. data/test/server/master.rb +150 -0
  162. data/test/server/server.rb +130 -0
  163. data/test/tagging/tagging.rb +80 -0
  164. data/test/test +51 -0
  165. data/test/types/basic.rb +119 -0
  166. data/test/types/component.rb +272 -0
  167. data/test/types/cron.rb +261 -0
  168. data/test/types/exec.rb +273 -0
  169. data/test/types/file.rb +616 -0
  170. data/test/types/filebucket.rb +167 -0
  171. data/test/types/fileignoresource.rb +287 -0
  172. data/test/types/filesources.rb +587 -0
  173. data/test/types/filetype.rb +162 -0
  174. data/test/types/group.rb +271 -0
  175. data/test/types/package.rb +205 -0
  176. data/test/types/query.rb +101 -0
  177. data/test/types/service.rb +100 -0
  178. data/test/types/symlink.rb +93 -0
  179. data/test/types/tidy.rb +124 -0
  180. data/test/types/type.rb +135 -0
  181. data/test/types/user.rb +371 -0
  182. metadata +243 -0
@@ -0,0 +1,49 @@
1
+ module Puppet # :nodoc:
2
+ # The class for handling configuration files.
3
+ class Config < Hash
4
+ # Slight override, since we can't seem to have a subclass where all instances
5
+ # have the same default block.
6
+ def [](section)
7
+ unless self.has_key?(section)
8
+ self[section] = {}
9
+ end
10
+ super
11
+ end
12
+
13
+ def initialize(file)
14
+ text = nil
15
+
16
+ begin
17
+ text = File.read(file)
18
+ rescue Errno::ENOENT
19
+ raise Puppet::Error, "No such file %s" % file
20
+ rescue Errno::EACCES
21
+ raise Puppet::Error, "Permission denied to file %s" % file
22
+ end
23
+
24
+ # Store it for later, in a way that we can test and such.
25
+ @file = Puppet::ParsedFile.new(file)
26
+
27
+ @values = Hash.new { |names, name|
28
+ names[name] = {}
29
+ }
30
+
31
+ section = "puppet"
32
+ text.split(/\n/).each { |line|
33
+ case line
34
+ when /^\[(\w+)\]$/: section = $1 # Section names
35
+ when /^\s*#/: next # Skip comments
36
+ when /^\s*$/: next # Skip blanks
37
+ when /^\s*(\w+)\s+(.+)$/: # settings
38
+ var = $1
39
+ value = $2
40
+ self[section][var] = value
41
+ else
42
+ raise Puppet::Error, "Could not match line %s" % line
43
+ end
44
+ }
45
+ end
46
+ end
47
+ end
48
+
49
+ # $Id: config.rb 738 2005-10-31 22:50:09Z luke $
@@ -0,0 +1,208 @@
1
+ # helper functions for daemons
2
+
3
+ require 'puppet'
4
+
5
+ module Puppet # :nodoc:
6
+ # A module that handles operations common to all daemons.
7
+ module Daemon
8
+ # Put the daemon into the background.
9
+ def daemonize
10
+ if pid = fork()
11
+ Process.detach(pid)
12
+ exit(0)
13
+ end
14
+
15
+ # Get rid of console logging
16
+ Puppet::Log.close(:console)
17
+
18
+ Process.setsid
19
+ Dir.chdir("/")
20
+ begin
21
+ $stdin.reopen "/dev/null"
22
+ $stdout.reopen "/dev/null", "a"
23
+ $stderr.reopen $stdout
24
+ Puppet::Log.reopen
25
+ rescue => detail
26
+ File.open("/tmp/daemonout", "w") { |f|
27
+ f.puts "Could not start %s: %s" % [$0, detail]
28
+ }
29
+ Puppet.err "Could not start %s: %s" % [$0, detail]
30
+ exit(12)
31
+ end
32
+
33
+ name = $0.gsub(/.+#{File::SEPARATOR}/,'')
34
+ @pidfile = File.join(Puppet[:puppetvar], name + ".pid")
35
+ if FileTest.exists?(@pidfile)
36
+ Puppet.info "Deleting old pid file"
37
+ begin
38
+ File.unlink(@pidfile)
39
+ rescue Errno::EACCES
40
+ Puppet.err "Could not delete old PID file; cannot create new one"
41
+ return
42
+ end
43
+ end
44
+
45
+ begin
46
+ File.open(@pidfile, "w") { |f| f.puts $$ }
47
+ rescue => detail
48
+ Puppet.err "Could not create PID file: %s" % detail
49
+ end
50
+ Puppet.info "pid file is %s" % @pidfile
51
+ end
52
+
53
+ def fqdn
54
+ unless defined? @fqdn and @fqdn
55
+ hostname = Facter["hostname"].value
56
+ domain = Facter["domain"].value
57
+ @fqdn = [hostname, domain].join(".")
58
+ end
59
+ return @fqdn
60
+ end
61
+
62
+ def httplog
63
+ args = []
64
+ # yuck; separate http logs
65
+ file = nil
66
+ if self.is_a?(Puppet::Server)
67
+ file = Puppet[:masterhttplog]
68
+ else
69
+ file = Puppet[:httplog]
70
+ end
71
+
72
+ unless FileTest.exists?(File.dirname(file))
73
+ Puppet.recmkdir(File.dirname(file))
74
+ end
75
+ args << file
76
+ if Puppet[:debug]
77
+ args << WEBrick::Log::DEBUG
78
+ end
79
+
80
+ log = WEBrick::Log.new(*args)
81
+
82
+ return log
83
+ end
84
+
85
+ def readcert
86
+ return unless @secureinit
87
+ # verify we've got all of the certs set up and such
88
+
89
+ if defined? @cert and defined? @key and @cert and @key
90
+ return true
91
+ end
92
+
93
+ # we are not going to encrypt our key, but we need at a minimum
94
+ # a keyfile and a certfile
95
+ @certfile = File.join(Puppet[:certdir], [@fqdn, "pem"].join("."))
96
+ @cacertfile = File.join(Puppet[:certdir], ["ca", "pem"].join("."))
97
+ @keyfile = File.join(Puppet[:privatekeydir], [@fqdn, "pem"].join("."))
98
+ @publickeyfile = File.join(Puppet[:publickeydir], [@fqdn, "pem"].join("."))
99
+
100
+ if File.exists?(@keyfile)
101
+ # load the key
102
+ @key = OpenSSL::PKey::RSA.new(File.read(@keyfile))
103
+ else
104
+ return false
105
+ end
106
+
107
+ if File.exists?(@certfile)
108
+ if File.exists?(@cacertfile)
109
+ @cacert = OpenSSL::X509::Certificate.new(File.read(@cacertfile))
110
+ else
111
+ raise Puppet::Error, "Found cert file with no ca cert file"
112
+ end
113
+ @cert = OpenSSL::X509::Certificate.new(File.read(@certfile))
114
+ else
115
+ return false
116
+ end
117
+ return true
118
+ end
119
+
120
+ def requestcert
121
+ retrieved = false
122
+ # create the directories involved
123
+ [Puppet[:certdir], Puppet[:privatekeydir], Puppet[:csrdir],
124
+ Puppet[:publickeydir]].each { |dir|
125
+ unless FileTest.exists?(dir)
126
+ Puppet.recmkdir(dir, 0770)
127
+ end
128
+ }
129
+
130
+ if self.readcert
131
+ Puppet.info "Certificate already exists; not requesting"
132
+ return true
133
+ end
134
+
135
+ unless defined? @key and @key
136
+ # create a new one and store it
137
+ Puppet.info "Creating a new SSL key at %s" % @keyfile
138
+ @key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
139
+ File.open(@keyfile, "w", 0660) { |f| f.print @key.to_pem }
140
+ File.open(@publickeyfile, "w", 0660) { |f|
141
+ f.print @key.public_key.to_pem
142
+ }
143
+ end
144
+
145
+ unless defined? @driver
146
+ Puppet.err "Cannot request a certificate without a defined target"
147
+ return false
148
+ end
149
+
150
+ Puppet.info "Creating a new certificate request for %s" % @fqdn
151
+ name = OpenSSL::X509::Name.new([["CN", @fqdn]])
152
+
153
+ @csr = OpenSSL::X509::Request.new
154
+ @csr.version = 0
155
+ @csr.subject = name
156
+ @csr.public_key = @key.public_key
157
+ @csr.sign(@key, OpenSSL::Digest::MD5.new)
158
+
159
+ Puppet.info "Requesting certificate"
160
+
161
+ begin
162
+ cert, cacert = @driver.getcert(@csr.to_pem)
163
+ rescue => detail
164
+ raise Puppet::Error.new("Certificate retrieval failed: %s" %
165
+ detail)
166
+ end
167
+
168
+ if cert.nil? or cert == ""
169
+ return nil
170
+ end
171
+ File.open(@certfile, "w", 0660) { |f| f.print cert }
172
+ File.open(@cacertfile, "w", 0660) { |f| f.print cacert }
173
+ begin
174
+ @cert = OpenSSL::X509::Certificate.new(cert)
175
+ @cacert = OpenSSL::X509::Certificate.new(cacert)
176
+ retrieved = true
177
+ rescue => detail
178
+ raise Puppet::Error.new(
179
+ "Invalid certificate: %s" % detail
180
+ )
181
+ end
182
+
183
+ unless @cert.check_private_key(@key)
184
+ raise Puppet::DevError, "Received invalid certificate"
185
+ end
186
+ return retrieved
187
+ end
188
+
189
+ # Shut down our server
190
+ def shutdown
191
+ # Remove our pid file
192
+ if defined? @pidfile and @pidfile and FileTest.exists?(@pidfile)
193
+ begin
194
+ File.unlink(@pidfile)
195
+ rescue => detail
196
+ Puppet.err "Could not remove PID file %s: %s" % [@pidfile, detail]
197
+ end
198
+ end
199
+
200
+ # And close all logs
201
+ Puppet::Log.close
202
+
203
+ super
204
+ end
205
+ end
206
+ end
207
+
208
+ # $Id: daemon.rb 732 2005-10-28 05:39:59Z luke $
@@ -0,0 +1,71 @@
1
+ # included so we can test object types
2
+ require 'puppet'
3
+
4
+ # the base class for both types and states
5
+ # very little functionality; basically just defines the interface
6
+ # and provides a few simple across-the-board functions like 'noop'
7
+ class Puppet::Element
8
+ include Puppet
9
+ attr_writer :noop
10
+
11
+ class << self
12
+ attr_accessor :doc, :nodoc
13
+ end
14
+
15
+ # all of our subclasses must respond to each of these methods...
16
+ @@interface_methods = [
17
+ :retrieve, :insync?, :sync, :evaluate
18
+ ]
19
+
20
+ # so raise an error if a method that isn't overridden gets called
21
+ @@interface_methods.each { |method|
22
+ self.send(:define_method,method) {
23
+ raise Puppet::DevError, "%s has not overridden %s" %
24
+ [self.class,method]
25
+ }
26
+ }
27
+
28
+ Puppet::Util.logmethods(self, true)
29
+
30
+ # for testing whether we should actually do anything
31
+ def noop
32
+ unless defined? @noop
33
+ @noop = false
34
+ end
35
+ return @noop || Puppet[:noop] || false
36
+ end
37
+
38
+ # return the full path to us, for logging and rollback
39
+ # some classes (e.g., FileTypeRecords) will have to override this
40
+ def path
41
+ unless defined? @path
42
+ if defined? @parent and @parent
43
+ if self.is_a?(Puppet::Type::Component)
44
+ @path = [@parent.path, self.name]
45
+ else
46
+ @path = [@parent.path, self.class.name.to_s + "=" + self.name]
47
+ end
48
+ else
49
+ # The top-level name is always puppet[top], so we don't bother with
50
+ # that. And we don't add the hostname here, it gets added
51
+ # in the log server thingy.
52
+ if self.name == "puppet[top]"
53
+ @path = ["/"]
54
+ else
55
+ # We assume that if we don't have a parent that we should not
56
+ # cache the path
57
+ if self.is_a?(Puppet::Type::Component)
58
+ @path = [self.name]
59
+ else
60
+ @path = [self.class.name.to_s + "=" + self.name]
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ return @path.join("/")
67
+ end
68
+
69
+ end
70
+
71
+ # $Id: element.rb 742 2005-11-16 17:12:11Z luke $
@@ -0,0 +1,259 @@
1
+ require 'puppet'
2
+ require 'puppet/type'
3
+
4
+ module Puppet
5
+ # events are transient packets of information; they result in one or more (or none)
6
+ # subscriptions getting triggered, and then they get cleared
7
+ # eventually, these will be passed on to some central event system
8
+ class Event
9
+ include Puppet
10
+
11
+ # subscriptions are permanent associations determining how different
12
+ # objects react to an event
13
+ class Subscription
14
+ include Puppet
15
+ attr_accessor :event, :callback
16
+
17
+ # Remove the existing subscriptions and such
18
+ def self.clear
19
+ self.init
20
+ end
21
+
22
+ # Remove a subscription
23
+ def self.delete(sub)
24
+ type, name = sub.targetarray
25
+ if @dependencies[type][name].include?(sub)
26
+ @dependencies[type][name].delete(sub)
27
+ end
28
+
29
+ type, name = sub.sourcearray
30
+ if @subscriptions[type][name].include?(sub)
31
+ @subscriptions[type][name].delete(sub)
32
+ end
33
+ end
34
+
35
+ # Initialize our class variables. This is in a method so it can
36
+ # be called to clear the variables, too.
37
+ def self.init
38
+ # A hash of subscriptions and another of dependencies, organized by
39
+ # type, then by name. I'm storing them all here, so that I don't
40
+ # have to store the subscriptions with the individual objects,
41
+ # which makes creating and destroying objects as necessary much
42
+ # easier.
43
+ @subscriptions = Hash.new { |hash, key|
44
+ hash[key] = Hash.new { |shash, skey|
45
+ # Each object has an array of subscriptions
46
+ shash[skey] = []
47
+ }
48
+ }
49
+
50
+ @dependencies = Hash.new { |hash, key|
51
+ hash[key] = Hash.new { |shash, skey|
52
+ # Each object has an array of subscriptions
53
+ shash[skey] = []
54
+ }
55
+ }
56
+ end
57
+
58
+ self.init
59
+
60
+ # Store the new subscription in a central hash.
61
+ def self.newsub(sub)
62
+ # The dependencies map allows me to look up a subscription by
63
+ # target -- find out which objects a given object is subscribed
64
+ # to, and thus find out which objects that given object depends
65
+ # upon.
66
+ # DEPENDENCIES == TARGET
67
+ ttype, tname = sub.targetarray
68
+ @dependencies[ttype][tname] << sub
69
+
70
+ # Subscriptions are the list of subscriptions for a given object,
71
+ # i.e., the list of all objects that care about a given object's
72
+ # events.
73
+ # SUBSCRIPTION == SOURCE
74
+ stype, sname = sub.sourcearray
75
+ @subscriptions[stype][sname] << sub
76
+ end
77
+
78
+ # Trigger the subscriptions related to an event, and then pass it up
79
+ # as appropriate
80
+ def self.trigger(source, event, transaction)
81
+ type, name = self.split(source)
82
+
83
+ @subscriptions[type][name].each { |sub|
84
+ if sub.match?(event)
85
+ sub.trigger(transaction)
86
+ end
87
+ }
88
+ end
89
+
90
+ # Look up an object by type and name. This is used because we
91
+ # store symbolic links in our subscription hash rather than storing
92
+ # actual object references.
93
+ def self.retrieve(ary)
94
+ type, name = ary
95
+ typeobj = Puppet::Type.type(type)
96
+
97
+ unless typeobj
98
+ return nil
99
+ end
100
+
101
+ obj = typeobj[name]
102
+ return obj
103
+ end
104
+
105
+ # Split an object into its type and name
106
+ def self.split(object)
107
+ return [object.class.name, object.name]
108
+ end
109
+
110
+ # Retrieve all of the subscriptions that result in a dependency.
111
+ # We return the whole dependency here, because it is being returned
112
+ # to the object that made the subscription.
113
+ def self.dependencies(target)
114
+ type, name = self.split(target)
115
+ return @dependencies[type][name]
116
+ end
117
+
118
+ # Return all objects that are subscribed to us. We are only willing
119
+ # to return the object, not the subscription object, because the
120
+ # source shouldn't need to know things like the event or method that
121
+ # we're subscribed to.
122
+ def self.subscribers(source)
123
+ type, name = self.split(source)
124
+ return @subscriptions[type][name].collect { |sub|
125
+ sub.target
126
+ }
127
+ end
128
+
129
+ # The hash here must include the target and source objects, the event,
130
+ # and the callback to call.
131
+ def initialize(hash)
132
+ hash.each { |param,value|
133
+ # assign each value appropriately
134
+ # this is probably wicked-slow
135
+ self.send(param.to_s + "=",value)
136
+ }
137
+
138
+ self.class.newsub(self)
139
+ #Puppet.debug "New Subscription: '%s' => '%s'" %
140
+ # [@source,@event]
141
+ end
142
+
143
+ # Determine whether the passed event matches our event
144
+ def match?(event)
145
+ if event == :NONE or @event == :NONE
146
+ return false
147
+ elsif @event == :ALL_EVENTS or event == :ALL_EVENTS or event == @event
148
+ return true
149
+ else
150
+ return false
151
+ end
152
+ end
153
+
154
+ # The source is the event source.
155
+ def source=(object)
156
+ type, name = self.class.split(object)
157
+ @source = [type, name]
158
+ end
159
+
160
+ def source
161
+ self.class.retrieve(@source)
162
+ end
163
+
164
+ def sourcearray
165
+ @source
166
+ end
167
+
168
+ # The target is the object who will receive the callbacks, i.e.,
169
+ # a source generates an event, which results in a callback on the
170
+ # target.
171
+ def target=(object)
172
+ type, name = self.class.split(object)
173
+ @target = [type, name]
174
+ end
175
+
176
+ def target
177
+ self.class.retrieve(@target)
178
+ end
179
+
180
+ def targetarray
181
+ @target
182
+ end
183
+
184
+ # Trigger a subscription, which basically calls the associated method
185
+ # on the target object.
186
+ def trigger(transaction)
187
+ event = nil
188
+
189
+ if @event == :NONE
190
+ # just ignore these subscriptions
191
+ return
192
+ end
193
+
194
+ if transaction.triggered?(self.target, @callback) > 0
195
+ Puppet.debug "%s has already run" % self
196
+ else
197
+ # We need to call the method, so that it gets retrieved
198
+ # as a real object.
199
+ target = self.target
200
+ #Puppet.debug "'%s' matched '%s'; triggering '%s' on '%s'" %
201
+ # [@source,@event,@method,target]
202
+ begin
203
+ if target.respond_to?(@callback)
204
+ event = target.send(@callback)
205
+ else
206
+ Puppet.debug(
207
+ "'%s' of type '%s' does not respond to '%s'" %
208
+ [target,target.class,@callback.inspect]
209
+ )
210
+ end
211
+ rescue => detail
212
+ # um, what the heck do i do when an object fails to
213
+ # refresh? shouldn't that result in the transaction
214
+ # rolling back? the 'onerror' metaparam will be used
215
+ # to determine behaviour in that case
216
+ Puppet.err "'%s' failed to %s: '%s'" %
217
+ [target,@callback,detail]
218
+ raise
219
+ #raise "We need to roll '%s' transaction back" %
220
+ #transaction
221
+ end
222
+ transaction.triggered(target, @callback)
223
+ end
224
+ return event
225
+ end
226
+ end
227
+
228
+ attr_accessor :event, :source, :transaction
229
+
230
+ @@events = []
231
+
232
+ @@subscriptions = []
233
+
234
+ def initialize(args)
235
+ unless args.include?(:event) and args.include?(:source)
236
+ raise Puppet::DevError, "Event.new called incorrectly"
237
+ end
238
+
239
+ @change = args[:change]
240
+ @event = args[:event]
241
+ @source = args[:source]
242
+ @transaction = args[:transaction]
243
+
244
+ #Puppet.info "%s: %s(%s)" %
245
+ #Puppet.info "%s: %s changed from %s to %s" %
246
+ # [@object,@state.name, @state.is,@state.should]
247
+
248
+ # initially, just stuff all instances into a central bucket
249
+ # to be handled as a batch
250
+ #@@events.push self
251
+ end
252
+
253
+ def to_s
254
+ self.event.to_s
255
+ end
256
+ end
257
+ end
258
+
259
+ # $Id: event.rb 710 2005-10-01 19:57:07Z luke $