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,420 @@
1
+ # Define the different packaging systems. Each package system is implemented
2
+ # in a module, which then gets used to individually extend each package object.
3
+ # This allows packages to exist on the same machine using different packaging
4
+ # systems.
5
+
6
+ require 'puppet/type/state'
7
+ require 'puppet/type/package/dpkg.rb'
8
+ require 'puppet/type/package/apt.rb'
9
+ require 'puppet/type/package/rpm.rb'
10
+ require 'puppet/type/package/yum.rb'
11
+ require 'puppet/type/package/sun.rb'
12
+
13
+ module Puppet
14
+ class PackageError < Puppet::Error; end
15
+ class State
16
+ class PackageInstalled < Puppet::State
17
+ @name = :install
18
+
19
+ @doc = "What state the package should be in. Specifying *true* will
20
+ only result in a change if the package is not installed at all; use
21
+ *latest* to keep the package (and, depending on the package system, its
22
+ prerequisites) up to date. Specifying *false* will uninstall the
23
+ package if it is installed. *true*/*false*/*latest*/``version``"
24
+
25
+ # Override the parent method, because we've got all kinds of
26
+ # funky definitions of 'in sync'.
27
+ def insync?
28
+ # Iterate across all of the should values, and see how they turn out.
29
+ @should.each { |should|
30
+ case should
31
+ when :installed
32
+ unless @is == :notinstalled
33
+ return true
34
+ end
35
+ when :latest
36
+ latest = @parent.latest
37
+ if @is == latest
38
+ return true
39
+ else
40
+ self.debug "latest %s is %s" % [@parent.name, latest]
41
+ end
42
+ when :notinstalled
43
+ if @is == :notinstalled
44
+ return true
45
+ end
46
+ when @is
47
+ return true
48
+ end
49
+ }
50
+
51
+ return false
52
+ end
53
+
54
+ # This retrieves the current state
55
+ def retrieve
56
+ unless defined? @is
57
+ @parent.retrieve
58
+ end
59
+ end
60
+
61
+ def shouldprocess(value)
62
+ # possible values are: true, false, and a version number
63
+ case value
64
+ when "latest":
65
+ unless @parent.respond_to?(:latest)
66
+ self.err @parent.inspect
67
+ raise Puppet::Error,
68
+ "Package type %s does not support querying versions" %
69
+ @parent[:type]
70
+ end
71
+ return :latest
72
+ when true, :installed:
73
+ return :installed
74
+ when false, :notinstalled:
75
+ return :notinstalled
76
+ else
77
+ # We allow them to set a should value however they want,
78
+ # but only specific package types will be able to use this
79
+ # value
80
+ return value
81
+ end
82
+ end
83
+
84
+ def sync
85
+ method = nil
86
+ event = nil
87
+ case @should[0]
88
+ when :installed:
89
+ method = :install
90
+ event = :package_installed
91
+ when :notinstalled:
92
+ method = :remove
93
+ event = :package_removed
94
+ when :latest
95
+ if @is == :notinstalled
96
+ method = :install
97
+ event = :package_installed
98
+ else
99
+ method = :update
100
+ event = :package_updated
101
+ end
102
+ else
103
+ unless ! @parent.respond_to?(:versionable?) or @parent.versionable?
104
+ self.warning value
105
+ raise Puppet::Error,
106
+ "Package type %s does not support specifying versions" %
107
+ @parent[:type]
108
+ else
109
+ method = :install
110
+ event = :package_installed
111
+ end
112
+ end
113
+
114
+ if @parent.respond_to?(method)
115
+ begin
116
+ @parent.send(method)
117
+ rescue => detail
118
+ self.err "Could not run %s: %s" % [method, detail.to_s]
119
+ raise
120
+ end
121
+ else
122
+ raise Puppet::Error, "Packages of type %s do not support %s" %
123
+ [@parent[:type], method]
124
+ end
125
+
126
+ return event
127
+ end
128
+ end
129
+ end
130
+
131
+ class Type
132
+ # packages are complicated because each package format has completely
133
+ # different commands. We need some way to convert specific packages
134
+ # into the general package object...
135
+ class Package < Type
136
+ attr_reader :version, :pkgtype
137
+
138
+ @pkgtypes = [
139
+ Puppet::PackagingType::APT,
140
+ Puppet::PackagingType::DPKG,
141
+ Puppet::PackagingType::RPM,
142
+ Puppet::PackagingType::Yum,
143
+ Puppet::PackagingType::Sun
144
+ ]
145
+
146
+ @pkgtypehash = {}
147
+
148
+ # Now collect the name of each type and store it thusly
149
+ @pkgtypes.each { |type|
150
+ if type.respond_to?(:typename)
151
+ @pkgtypehash[type.typename] = type
152
+ else
153
+ name = type.to_s.sub(/.+::/, '').downcase.intern
154
+ @pkgtypehash[name] = type
155
+ end
156
+ }
157
+
158
+ @states = [
159
+ Puppet::State::PackageInstalled
160
+ ]
161
+ #:version,
162
+ @parameters = [
163
+ :name,
164
+ :type,
165
+ :instance,
166
+ :status,
167
+ :category,
168
+ :platform,
169
+ :root,
170
+ :vendor,
171
+ :description
172
+ ]
173
+
174
+ @paramdoc[:name] = "The package name."
175
+ @paramdoc[:type] = "The package format. Currently supports " +
176
+ @pkgtypes.collect {|t|
177
+ "``" + t.name.to_s + "``"
178
+ }.join(", ") + "."
179
+ @paramdoc[:instance] = "A read-only parameter set by the package."
180
+ @paramdoc[:status] = "A read-only parameter set by the package."
181
+ #@paramdoc[:version] = "A read-only parameter set by the package."
182
+ @paramdoc[:category] = "A read-only parameter set by the package."
183
+ @paramdoc[:platform] = "A read-only parameter set by the package."
184
+ @paramdoc[:root] = "A read-only parameter set by the package."
185
+ @paramdoc[:vendor] = "A read-only parameter set by the package."
186
+ @paramdoc[:description] = "A read-only parameter set by the package."
187
+
188
+ @doc = "Manage packages. Eventually will support retrieving packages
189
+ from remote sources but currently only supports packaging
190
+ systems which can retrieve their own packages, like ``apt``."
191
+ @name = :package
192
+ @namevar = :name
193
+ @listed = false
194
+
195
+ @allowedmethods = [:types]
196
+
197
+ @default = nil
198
+ @platform = nil
199
+
200
+ class << self
201
+ attr_reader :listed
202
+ end
203
+
204
+ def self.clear
205
+ @listed = false
206
+ super
207
+ end
208
+
209
+ # Cache and return the default package type for our current
210
+ # platform.
211
+ def self.default
212
+ if @default.nil?
213
+ self.init
214
+ end
215
+
216
+ return @default
217
+ end
218
+
219
+ # Figure out what the default package type is for the platform
220
+ # on which we're running.
221
+ def self.init
222
+ unless @platform = Facter["operatingsystem"].value.downcase
223
+ raise Puppet::DevError.new(
224
+ "Must know platform for package management"
225
+ )
226
+ end
227
+ case @platform
228
+ when "sunos": @default = :sun
229
+ when "linux":
230
+ case Facter["distro"].value.downcase
231
+ when "gentoo":
232
+ Puppet.notice "No support for gentoo yet"
233
+ @default = nil
234
+ when "debian": @default = :apt
235
+ when "fedora": @default = :yum
236
+ when "redhat": @default = :rpm
237
+ else
238
+ Puppet.warning "Using rpm as default type for %s" %
239
+ Facter["distro"].value
240
+ @default = :rpm
241
+ end
242
+ else
243
+ @default = nil
244
+ end
245
+ end
246
+
247
+ def self.getpkglist
248
+ if @types.nil?
249
+ if @default.nil?
250
+ self.init
251
+ end
252
+ @types = [@default]
253
+ end
254
+
255
+ list = @types.collect { |type|
256
+ if typeobj = Puppet::PackagingType[type]
257
+ # pull all of the objects
258
+ typeobj.list
259
+ else
260
+ raise "Could not find package type '%s'" % type
261
+ end
262
+ }.flatten
263
+ @listed = true
264
+ return list
265
+ end
266
+
267
+ def Package.installedpkg(hash)
268
+ # this is from code, so we don't have to do as much checking
269
+ name = hash[:name]
270
+ hash.delete(:name)
271
+
272
+ # if it already exists, modify the existing one
273
+ if object = Package[name]
274
+ states = {}
275
+ object.eachstate { |state|
276
+ Puppet.debug "Adding %s" % state.name.inspect
277
+ states[state.name] = state
278
+ }
279
+ hash.each { |var,value|
280
+ if states.include?(var)
281
+ Puppet.debug "%s is a set state" % var.inspect
282
+ states[var].is = value
283
+ else
284
+ Puppet.debug "%s is not a set state" % var.inspect
285
+ if object[var] and object[var] != value
286
+ Puppet.warning "Overriding %s => %s on %s with %s" %
287
+ [var,object[var],name,value]
288
+ end
289
+
290
+ #object.state(var).is = value
291
+
292
+ # swap the values if we're a state
293
+ if states.include?(var)
294
+ Puppet.debug "Swapping %s because it's a state" % var
295
+ states[var].is = value
296
+ states[var].should = nil
297
+ else
298
+ Puppet.debug "%s is not a state" % var.inspect
299
+ Puppet.debug "States are %s" % states.keys.collect { |st|
300
+ st.inspect
301
+ }.join(" ")
302
+ end
303
+ end
304
+ }
305
+ return object
306
+ else # just create it
307
+ obj = self.create(:name => name)
308
+ hash.each { |var,value|
309
+ obj.addis(var,value)
310
+ }
311
+ return obj
312
+ end
313
+ end
314
+
315
+ # Retrieve a package type by name; names are symbols.
316
+ def self.pkgtype(pkgtype)
317
+ if pkgtype.is_a?(String)
318
+ pkgtype = pkgtype.intern
319
+ end
320
+ return @pkgtypehash[pkgtype]
321
+ end
322
+
323
+ # okay, there are two ways that a package could be created...
324
+ # either through the language, in which case the hash's values should
325
+ # be set in 'should', or through comparing against the system, in which
326
+ # case the hash's values should be set in 'is'
327
+ def initialize(hash)
328
+ type = hash["type"] || hash[:type] || self.class.default
329
+ self.type2module(type)
330
+
331
+ super
332
+
333
+ self.debug "Extending to package type %s" % [@type]
334
+
335
+ unless @states.include?(:install)
336
+ self.debug "Defaulting to installing a package"
337
+ self[:install] = true
338
+ end
339
+
340
+ unless @parameters.include?(:type)
341
+ self[:type] = self.class.default
342
+ end
343
+ end
344
+
345
+ def retrieve
346
+ if hash = self.query
347
+ hash.each { |param, value|
348
+ unless self.class.validarg?(param)
349
+ hash.delete(param)
350
+ end
351
+ }
352
+
353
+ hash.each { |param, value|
354
+ self.is = [param, value]
355
+ }
356
+ else
357
+ self.class.validstates.each { |name|
358
+ self.is = [name, :notinstalled]
359
+ }
360
+ end
361
+ end
362
+
363
+ # Extend the package with the appropriate package type.
364
+ def type2module(typename)
365
+ if type = self.class.pkgtype(typename)
366
+ @type = type
367
+ self.extend(type)
368
+ else
369
+ raise Puppet::Error, "Invalid package type %s" % typename
370
+ end
371
+ end
372
+ end # Puppet::Type::Package
373
+ end
374
+
375
+ # this is how we retrieve packages
376
+ class PackageSource
377
+ attr_accessor :uri
378
+ attr_writer :retrieve
379
+
380
+ @@sources = Hash.new(false)
381
+
382
+ def PackageSource.get(file)
383
+ type = file.sub(%r{:.+},'')
384
+ source = nil
385
+ if source = @@sources[type]
386
+ return source.retrieve(file)
387
+ else
388
+ raise "Unknown package source: %s" % type
389
+ end
390
+ end
391
+
392
+ def initialize(name)
393
+ if block_given?
394
+ yield self
395
+ end
396
+
397
+ @@sources[name] = self
398
+ end
399
+
400
+ def retrieve(path)
401
+ @retrieve.call(path)
402
+ end
403
+
404
+ end
405
+
406
+ PackageSource.new("file") { |obj|
407
+ obj.retrieve = proc { |path|
408
+ # this might not work for windows...
409
+ file = path.sub(%r{^file://},'')
410
+
411
+ if FileTest.exists?(file)
412
+ return file
413
+ else
414
+ raise "File %s does not exist" % file
415
+ end
416
+ }
417
+ }
418
+ end
419
+
420
+ # $Id: package.rb 731 2005-10-26 04:44:25Z luke $
@@ -0,0 +1,70 @@
1
+ module Puppet
2
+ module PackagingType
3
+ # A derivative of DPKG; this is how most people actually manage
4
+ # Debian boxes, and the only thing that differs is that it can
5
+ # install packages from remote sites.
6
+ module APT
7
+ include DPKG
8
+
9
+ # Install a package using 'apt-get'. This function needs to support
10
+ # installing a specific version.
11
+ def install
12
+ should = self.should(:install)
13
+
14
+ str = self.name
15
+ case should
16
+ when true, false, Symbol
17
+ # pass
18
+ else
19
+ # Add the package version
20
+ str += "=%s" % should
21
+ end
22
+ cmd = "apt-get -q -y install %s" % str
23
+
24
+ self.info "Executing %s" % cmd.inspect
25
+ output = %x{#{cmd} 2>&1}
26
+
27
+ unless $? == 0
28
+ raise Puppet::PackageError.new(output)
29
+ end
30
+ end
31
+
32
+ # What's the latest package version available?
33
+ def latest
34
+ cmd = "apt-cache showpkg %s" % self.name
35
+ output = %x{#{cmd} 2>&1}
36
+
37
+ unless $? == 0
38
+ raise Puppet::PackageError.new(output)
39
+ end
40
+
41
+ if output =~ /Versions:\s*\n((\n|.)+)^$/
42
+ versions = $1
43
+ version = versions.split(/\n/).collect { |version|
44
+ if version =~ /^([^\(]+)\(/
45
+ $1
46
+ else
47
+ self.warning "Could not match version '%s'" % version
48
+ nil
49
+ end
50
+ }.reject { |vers| vers.nil? }.sort[-1]
51
+
52
+ unless version
53
+ self.debug "No latest version"
54
+ if Puppet[:debug]
55
+ print output
56
+ end
57
+ end
58
+
59
+ return version
60
+ else
61
+ self.err "Could not match string"
62
+ end
63
+ end
64
+
65
+ def update
66
+ self.install
67
+ end
68
+ end
69
+ end
70
+ end