puppet 0.9.2 → 0.13.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 (213) hide show
  1. data/CHANGELOG +58 -0
  2. data/README +21 -18
  3. data/Rakefile +176 -36
  4. data/bin/puppet +34 -48
  5. data/bin/puppetca +41 -28
  6. data/bin/puppetd +87 -65
  7. data/bin/puppetdoc +99 -23
  8. data/bin/puppetmasterd +72 -91
  9. data/conf/redhat/client.init +80 -0
  10. data/conf/redhat/client.sysconfig +11 -0
  11. data/conf/redhat/fileserver.conf +12 -0
  12. data/conf/redhat/puppet.spec +130 -0
  13. data/conf/redhat/server.init +89 -0
  14. data/conf/redhat/server.sysconfig +9 -0
  15. data/examples/code/allatonce +2 -2
  16. data/examples/code/assignments +1 -1
  17. data/examples/code/classing +2 -2
  18. data/examples/code/components +2 -2
  19. data/examples/code/file.bl +5 -5
  20. data/examples/code/filedefaults +2 -2
  21. data/examples/code/fileparsing +1 -1
  22. data/examples/code/filerecursion +1 -1
  23. data/examples/code/functions +1 -1
  24. data/examples/code/groups +1 -1
  25. data/examples/code/importing +1 -1
  26. data/examples/code/nodes +1 -1
  27. data/examples/code/one +1 -1
  28. data/examples/code/relationships +2 -2
  29. data/examples/code/simpletests +5 -5
  30. data/examples/code/snippets/argumentdefaults +2 -2
  31. data/examples/code/snippets/casestatement +16 -8
  32. data/examples/code/snippets/classheirarchy.pp +4 -4
  33. data/examples/code/snippets/classincludes.pp +4 -4
  34. data/examples/code/snippets/classpathtest +2 -2
  35. data/examples/code/snippets/componentmetaparams.pp +11 -0
  36. data/examples/code/snippets/dirchmod +5 -5
  37. data/examples/code/snippets/emptyclass.pp +9 -0
  38. data/examples/code/snippets/failmissingexecpath.pp +1 -1
  39. data/examples/code/snippets/falsevalues.pp +1 -1
  40. data/examples/code/snippets/filecreate +5 -5
  41. data/examples/code/snippets/implicititeration +5 -5
  42. data/examples/code/snippets/multipleinstances +4 -4
  43. data/examples/code/snippets/namevartest +3 -3
  44. data/examples/code/snippets/scopetest +1 -1
  45. data/examples/code/snippets/selectorvalues.pp +3 -3
  46. data/examples/code/snippets/simpledefaults +2 -2
  47. data/examples/code/snippets/simpleselector +5 -5
  48. data/examples/code/snippets/singleary.pp +19 -0
  49. data/examples/root/etc/init.d/sleeper +3 -2
  50. data/ext/emacs/puppet-mode-init.el +6 -0
  51. data/ext/emacs/puppet-mode.el +189 -0
  52. data/ext/ldap/puppet.schema +17 -0
  53. data/ext/{module:puppet → module_puppet} +30 -31
  54. data/ext/vim/filetype.vim +9 -0
  55. data/ext/vim/puppet.vim +87 -0
  56. data/install.rb +63 -30
  57. data/lib/puppet.rb +216 -122
  58. data/lib/puppet/client.rb +51 -416
  59. data/lib/puppet/client/ca.rb +17 -0
  60. data/lib/puppet/client/dipper.rb +78 -0
  61. data/lib/puppet/client/file.rb +20 -0
  62. data/lib/puppet/client/log.rb +17 -0
  63. data/lib/puppet/client/master.rb +246 -0
  64. data/lib/puppet/client/proxy.rb +27 -0
  65. data/lib/puppet/client/status.rb +7 -0
  66. data/lib/puppet/config.rb +563 -13
  67. data/lib/puppet/daemon.rb +50 -22
  68. data/lib/puppet/element.rb +4 -4
  69. data/lib/puppet/event-loop.rb +1 -0
  70. data/lib/puppet/event-loop/better-definers.rb +367 -0
  71. data/lib/puppet/event-loop/event-loop.rb +355 -0
  72. data/lib/puppet/event-loop/signal-system.rb +220 -0
  73. data/lib/puppet/event.rb +9 -11
  74. data/lib/puppet/filetype.rb +195 -0
  75. data/lib/puppet/log.rb +35 -12
  76. data/lib/puppet/metric.rb +2 -2
  77. data/lib/puppet/networkclient.rb +145 -0
  78. data/lib/puppet/parameter.rb +335 -0
  79. data/lib/puppet/parser/ast.rb +42 -1453
  80. data/lib/puppet/parser/ast/astarray.rb +88 -0
  81. data/lib/puppet/parser/ast/branch.rb +47 -0
  82. data/lib/puppet/parser/ast/caseopt.rb +66 -0
  83. data/lib/puppet/parser/ast/casestatement.rb +78 -0
  84. data/lib/puppet/parser/ast/classdef.rb +78 -0
  85. data/lib/puppet/parser/ast/compdef.rb +111 -0
  86. data/lib/puppet/parser/ast/component.rb +105 -0
  87. data/lib/puppet/parser/ast/hostclass.rb +82 -0
  88. data/lib/puppet/parser/ast/leaf.rb +86 -0
  89. data/lib/puppet/parser/ast/node.rb +103 -0
  90. data/lib/puppet/parser/ast/nodedef.rb +68 -0
  91. data/lib/puppet/parser/ast/objectdef.rb +336 -0
  92. data/lib/puppet/parser/ast/objectparam.rb +30 -0
  93. data/lib/puppet/parser/ast/objectref.rb +76 -0
  94. data/lib/puppet/parser/ast/selector.rb +60 -0
  95. data/lib/puppet/parser/ast/typedefaults.rb +45 -0
  96. data/lib/puppet/parser/ast/vardef.rb +44 -0
  97. data/lib/puppet/parser/interpreter.rb +31 -14
  98. data/lib/puppet/parser/lexer.rb +2 -4
  99. data/lib/puppet/parser/parser.rb +332 -242
  100. data/lib/puppet/parser/scope.rb +55 -38
  101. data/lib/puppet/server.rb +43 -44
  102. data/lib/puppet/server/authstore.rb +3 -6
  103. data/lib/puppet/server/ca.rb +5 -2
  104. data/lib/puppet/server/filebucket.rb +2 -4
  105. data/lib/puppet/server/fileserver.rb +28 -12
  106. data/lib/puppet/server/logger.rb +15 -4
  107. data/lib/puppet/server/master.rb +62 -7
  108. data/lib/puppet/sslcertificates.rb +41 -607
  109. data/lib/puppet/sslcertificates/ca.rb +291 -0
  110. data/lib/puppet/sslcertificates/certificate.rb +283 -0
  111. data/lib/puppet/statechange.rb +6 -1
  112. data/lib/puppet/storage.rb +67 -56
  113. data/lib/puppet/transaction.rb +25 -9
  114. data/lib/puppet/transportable.rb +102 -22
  115. data/lib/puppet/type.rb +1096 -315
  116. data/lib/puppet/type/component.rb +30 -21
  117. data/lib/puppet/type/cron.rb +409 -448
  118. data/lib/puppet/type/exec.rb +234 -174
  119. data/lib/puppet/type/group.rb +65 -82
  120. data/lib/puppet/type/nameservice.rb +247 -3
  121. data/lib/puppet/type/nameservice/netinfo.rb +29 -40
  122. data/lib/puppet/type/nameservice/objectadd.rb +52 -66
  123. data/lib/puppet/type/nameservice/posix.rb +6 -194
  124. data/lib/puppet/type/package.rb +447 -295
  125. data/lib/puppet/type/package/apt.rb +51 -50
  126. data/lib/puppet/type/package/bsd.rb +82 -0
  127. data/lib/puppet/type/package/dpkg.rb +85 -88
  128. data/lib/puppet/type/package/rpm.rb +67 -63
  129. data/lib/puppet/type/package/sun.rb +119 -98
  130. data/lib/puppet/type/package/yum.rb +41 -37
  131. data/lib/puppet/type/parsedtype.rb +295 -0
  132. data/lib/puppet/type/parsedtype/host.rb +143 -0
  133. data/lib/puppet/type/parsedtype/port.rb +232 -0
  134. data/lib/puppet/type/parsedtype/sshkey.rb +129 -0
  135. data/lib/puppet/type/pfile.rb +484 -460
  136. data/lib/puppet/type/pfile/checksum.rb +237 -181
  137. data/lib/puppet/type/pfile/content.rb +67 -0
  138. data/lib/puppet/type/pfile/ensure.rb +212 -0
  139. data/lib/puppet/type/pfile/group.rb +106 -105
  140. data/lib/puppet/type/pfile/mode.rb +98 -101
  141. data/lib/puppet/type/pfile/source.rb +228 -209
  142. data/lib/puppet/type/pfile/type.rb +18 -21
  143. data/lib/puppet/type/pfile/uid.rb +127 -130
  144. data/lib/puppet/type/pfilebucket.rb +68 -63
  145. data/lib/puppet/type/schedule.rb +341 -0
  146. data/lib/puppet/type/service.rb +351 -255
  147. data/lib/puppet/type/service/base.rb +9 -14
  148. data/lib/puppet/type/service/debian.rb +32 -38
  149. data/lib/puppet/type/service/init.rb +130 -130
  150. data/lib/puppet/type/service/smf.rb +48 -20
  151. data/lib/puppet/type/state.rb +229 -16
  152. data/lib/puppet/type/symlink.rb +51 -63
  153. data/lib/puppet/type/tidy.rb +105 -102
  154. data/lib/puppet/type/user.rb +118 -180
  155. data/lib/puppet/util.rb +100 -6
  156. data/test/certmgr/certmgr.rb +0 -1
  157. data/test/client/client.rb +4 -4
  158. data/test/executables/puppetbin.rb +7 -14
  159. data/test/executables/puppetca.rb +18 -24
  160. data/test/executables/puppetd.rb +7 -16
  161. data/test/executables/puppetmasterd.rb +7 -9
  162. data/test/executables/puppetmodule.rb +11 -16
  163. data/test/language/ast.rb +11 -7
  164. data/test/language/interpreter.rb +1 -1
  165. data/test/language/scope.rb +2 -0
  166. data/test/language/snippets.rb +30 -5
  167. data/test/language/transportable.rb +77 -0
  168. data/test/other/config.rb +316 -0
  169. data/test/other/events.rb +22 -21
  170. data/test/other/log.rb +14 -14
  171. data/test/other/metrics.rb +4 -8
  172. data/test/other/overrides.rb +5 -5
  173. data/test/other/relationships.rb +4 -2
  174. data/test/other/storage.rb +64 -3
  175. data/test/other/transactions.rb +20 -20
  176. data/test/parser/parser.rb +7 -4
  177. data/test/puppet/conffiles.rb +12 -12
  178. data/test/puppet/defaults.rb +13 -11
  179. data/test/puppet/utiltest.rb +14 -11
  180. data/test/puppettest.rb +156 -48
  181. data/test/server/bucket.rb +2 -2
  182. data/test/server/fileserver.rb +6 -6
  183. data/test/server/logger.rb +19 -11
  184. data/test/server/master.rb +33 -4
  185. data/test/server/server.rb +2 -7
  186. data/test/types/basic.rb +5 -7
  187. data/test/types/component.rb +22 -18
  188. data/test/types/cron.rb +111 -44
  189. data/test/types/exec.rb +116 -59
  190. data/test/types/file.rb +262 -137
  191. data/test/types/filebucket.rb +13 -15
  192. data/test/types/fileignoresource.rb +12 -16
  193. data/test/types/filesources.rb +73 -48
  194. data/test/types/filetype.rb +13 -15
  195. data/test/types/group.rb +15 -13
  196. data/test/types/host.rb +146 -0
  197. data/test/types/package.rb +74 -63
  198. data/test/types/port.rb +139 -0
  199. data/test/types/query.rb +8 -8
  200. data/test/types/schedule.rb +335 -0
  201. data/test/types/service.rb +137 -21
  202. data/test/types/sshkey.rb +140 -0
  203. data/test/types/symlink.rb +3 -5
  204. data/test/types/tidy.rb +5 -14
  205. data/test/types/type.rb +67 -11
  206. data/test/types/user.rb +25 -23
  207. metadata +186 -122
  208. data/lib/puppet/type/pfile/create.rb +0 -108
  209. data/lib/puppet/type/pprocess.rb +0 -97
  210. data/lib/puppet/type/typegen.rb +0 -149
  211. data/lib/puppet/type/typegen/filerecord.rb +0 -243
  212. data/lib/puppet/type/typegen/filetype.rb +0 -316
  213. data/test/other/state.rb +0 -106
@@ -1,116 +1,137 @@
1
1
  module Puppet
2
- module PackagingType
3
- module Sun
4
- def query
5
- names = {
6
- "PKGINST" => :name,
7
- "NAME" => nil,
8
- "CATEGORY" => :category,
9
- "ARCH" => :platform,
10
- "VERSION" => :install,
11
- "BASEDIR" => :root,
12
- "HOTLINE" => nil,
13
- "EMAIL" => nil,
14
- "VENDOR" => :vendor,
15
- "DESC" => :description,
16
- "PSTAMP" => nil,
17
- "INSTDATE" => nil,
18
- "STATUS" => nil,
19
- "FILES" => nil
20
- }
2
+ Puppet.type(:package).newpkgtype(:sunpkg) do
3
+ def install
4
+ unless self[:source]
5
+ raise Puppet::Error, "Sun packages must specify a package source"
6
+ end
7
+ #cmd = "pkgadd -d %s -n %s 2>&1" % [self[:source], self[:name]]
8
+ cmd = ["pkgadd"]
9
+ cmd += ["-d", self[:source]]
10
+ cmd += ["-n", self[:name]]
11
+
12
+ if self[:answerfile]
13
+ cmd += ["-a", self[:answerfile]]
14
+ end
15
+ cmd << "2>&1"
16
+ cmd = cmd.join(" ")
21
17
 
22
- hash = {}
18
+ self.info "Executing %s" % cmd.inspect
19
+ output = %x{#{cmd} 2>&1}
20
+
21
+ unless $? == 0
22
+ raise Puppet::PackageError.new(output)
23
+ end
24
+ end
23
25
 
24
- # list out all of the packages
25
- open("| pkginfo -l %s 2>/dev/null" % self.name) { |process|
26
- # we're using the long listing, so each line is a separate
27
- # piece of information
28
- process.each { |line|
29
- case line
30
- when /^$/: # ignore
31
- when /\s*([A-Z]+):\s+(.+)/:
32
- name = $1
33
- value = $2
34
- if names.include?(name)
35
- unless names[name].nil?
36
- hash[names[name]] = value
37
- end
38
- else
39
- self.err "'pkginfo' returned invalid name %s" %
40
- name
26
+ def query
27
+ names = {
28
+ "PKGINST" => :name,
29
+ "NAME" => nil,
30
+ "CATEGORY" => :category,
31
+ "ARCH" => :platform,
32
+ "VERSION" => :ensure,
33
+ "BASEDIR" => :root,
34
+ "HOTLINE" => nil,
35
+ "EMAIL" => nil,
36
+ "VENDOR" => :vendor,
37
+ "DESC" => :description,
38
+ "PSTAMP" => nil,
39
+ "INSTDATE" => nil,
40
+ "STATUS" => nil,
41
+ "FILES" => nil
42
+ }
43
+
44
+ hash = {}
45
+
46
+ # list out all of the packages
47
+ open("| pkginfo -l %s 2>/dev/null" % self.name) { |process|
48
+ # we're using the long listing, so each line is a separate
49
+ # piece of information
50
+ process.each { |line|
51
+ case line
52
+ when /^$/: # ignore
53
+ when /\s*([A-Z]+):\s+(.+)/:
54
+ name = $1
55
+ value = $2
56
+ if names.include?(name)
57
+ unless names[name].nil?
58
+ hash[names[name]] = value
41
59
  end
42
- when /\s+\d+.+/:
43
- # nothing; we're ignoring the FILES info
60
+ else
61
+ self.err "'pkginfo' returned invalid name %s" %
62
+ name
44
63
  end
45
- }
64
+ when /\s+\d+.+/:
65
+ # nothing; we're ignoring the FILES info
66
+ end
46
67
  }
68
+ }
47
69
 
48
- if hash.empty?
49
- return nil
50
- else
51
- return hash
52
- end
70
+ if hash.empty?
71
+ return nil
72
+ else
73
+ return hash
53
74
  end
75
+ end
54
76
 
55
- def list
56
- packages = []
57
- hash = {}
58
- names = {
59
- "PKGINST" => :name,
60
- "NAME" => nil,
61
- "CATEGORY" => :category,
62
- "ARCH" => :platform,
63
- "VERSION" => :install,
64
- "BASEDIR" => :root,
65
- "HOTLINE" => nil,
66
- "EMAIL" => nil,
67
- "VENDOR" => :vendor,
68
- "DESC" => :description,
69
- "PSTAMP" => nil,
70
- "INSTDATE" => nil,
71
- "STATUS" => nil,
72
- "FILES" => nil
73
- }
77
+ def list
78
+ packages = []
79
+ hash = {}
80
+ names = {
81
+ "PKGINST" => :name,
82
+ "NAME" => nil,
83
+ "CATEGORY" => :category,
84
+ "ARCH" => :platform,
85
+ "VERSION" => :ensure,
86
+ "BASEDIR" => :root,
87
+ "HOTLINE" => nil,
88
+ "EMAIL" => nil,
89
+ "VENDOR" => :vendor,
90
+ "DESC" => :description,
91
+ "PSTAMP" => nil,
92
+ "INSTDATE" => nil,
93
+ "STATUS" => nil,
94
+ "FILES" => nil
95
+ }
74
96
 
75
- # list out all of the packages
76
- open("| pkginfo -l") { |process|
77
- # we're using the long listing, so each line is a separate
78
- # piece of information
79
- process.each { |line|
80
- case line
81
- when /^$/:
82
- packages.push Puppet::Type::Package.installedpkg(hash)
83
- hash.clear
84
- when /\s*(\w+):\s+(.+)/:
85
- name = $1
86
- value = $2
87
- if names.include?(name)
88
- unless names[name].nil?
89
- hash[names[name]] = value
90
- end
91
- else
92
- raise "Could not find %s" % name
97
+ # list out all of the packages
98
+ open("| pkginfo -l 2>&1") { |process|
99
+ # we're using the long listing, so each line is a separate
100
+ # piece of information
101
+ process.each { |line|
102
+ case line
103
+ when /^$/:
104
+ packages.push Puppet.type(:package).installedpkg(hash)
105
+ hash.clear
106
+ when /\s*(\w+):\s+(.+)/:
107
+ name = $1
108
+ value = $2
109
+ if names.include?(name)
110
+ unless names[name].nil?
111
+ hash[names[name]] = value
93
112
  end
94
- when /\s+\d+.+/:
95
- # nothing; we're ignoring the FILES info
113
+ else
114
+ raise "Could not find %s" % name
96
115
  end
97
- }
116
+ when /\s+\d+.+/:
117
+ # nothing; we're ignoring the FILES info
118
+ end
98
119
  }
99
- return packages
100
- end
120
+ }
121
+ return packages
122
+ end
101
123
 
102
- # we need package retrieval mechanisms before we can have package
103
- # installation mechanisms...
104
- #type.install = proc { |pkg|
105
- # raise "installation not implemented yet"
106
- #}
124
+ # we need package retrieval mechanisms before we can have package
125
+ # installation mechanisms...
126
+ #type.install = proc { |pkg|
127
+ # raise "installation not implemented yet"
128
+ #}
107
129
 
108
- def remove
109
- cmd = "pkgrm -n %s" % self.name
110
- output = %x{#{cmd}}
111
- if $? != 0
112
- raise output
113
- end
130
+ def uninstall
131
+ cmd = "pkgrm -n %s 2>&1" % self.name
132
+ output = %x{#{cmd}}
133
+ if $? != 0
134
+ raise Puppet::Error, "Removal of %s failed: %s" % [self.name, output]
114
135
  end
115
136
  end
116
137
  end
@@ -1,58 +1,62 @@
1
1
  module Puppet
2
- module PackagingType
2
+ Puppet.type(:package).newpkgtype(:yum, :rpm) do
3
3
  # A derivative of DPKG; this is how most people actually manage
4
4
  # Debian boxes, and the only thing that differs is that it can
5
5
  # install packages from remote sites.
6
- module Yum
7
- include RPM
8
6
 
9
- # Install a package using 'apt-get'.
10
- def install
11
- cmd = "yum -y install %s" % self.name
7
+ # Install a package using 'apt-get'.
8
+ def install
9
+ cmd = "yum -y install %s" % self.name
12
10
 
13
- self.info "Executing %s" % cmd.inspect
14
- output = %x{#{cmd} 2>&1}
11
+ self.info "Executing %s" % cmd.inspect
12
+ output = %x{#{cmd} 2>&1}
15
13
 
16
- unless $? == 0
17
- raise Puppet::PackageError.new(output)
18
- end
14
+ unless $? == 0
15
+ raise Puppet::PackageError.new(output)
19
16
  end
17
+ end
20
18
 
21
- # What's the latest package version available?
22
- def latest
23
- cmd = "yum list %s" % self.name
24
- output = %x{#{cmd} 2>&1}
25
-
26
- unless $? == 0
27
- raise Puppet::PackageError.new(output)
28
- end
19
+ # What's the latest package version available?
20
+ def latest
21
+ cmd = "yum list %s" % self.name
22
+ self.info "Executing %s" % cmd.inspect
23
+ output = %x{#{cmd} 2>&1}
29
24
 
30
- if output =~ /#{self.name}\S+\s+(\S+)\s/
31
- return $1
32
- else
33
- self.debug "No version"
34
- if Puppet[:debug]
35
- print output
36
- end
25
+ unless $? == 0
26
+ raise Puppet::PackageError.new(output)
27
+ end
37
28
 
38
- return nil
29
+ if output =~ /#{self.name}\S+\s+(\S+)\s/
30
+ return $1
31
+ else
32
+ self.debug "No version"
33
+ if Puppet[:debug]
34
+ print output
39
35
  end
36
+
37
+ return nil
40
38
  end
39
+ end
41
40
 
42
- def update
43
- cmd = "yum -y update %s" % self.name
41
+ def update
42
+ # Yum can't update packages that aren't there; we have to install
43
+ # them first
44
+ if self.is(:ensure) == :absent
45
+ self.info "performing initial install"
46
+ return self.install
47
+ end
48
+ cmd = "yum -y update %s" % self.name
44
49
 
45
- self.info "Executing %s" % cmd.inspect
46
- output = %x{#{cmd} 2>&1}
50
+ self.info "Executing %s" % cmd.inspect
51
+ output = %x{#{cmd} 2>&1}
47
52
 
48
- unless $? == 0
49
- raise Puppet::PackageError.new(output)
50
- end
53
+ unless $? == 0
54
+ raise Puppet::PackageError.new(output)
51
55
  end
56
+ end
52
57
 
53
- def versionable?
54
- false
55
- end
58
+ def versionable?
59
+ false
56
60
  end
57
61
  end
58
62
  end
@@ -0,0 +1,295 @@
1
+ require 'etc'
2
+ require 'facter'
3
+ require 'puppet/filetype'
4
+ require 'puppet/type/state'
5
+
6
+ module Puppet
7
+ class State
8
+ # The base parameter for all of these types. Its only job is to copy
9
+ # the 'should' value to the 'is' value and to do support the right logging
10
+ # and such.
11
+ class ParsedParam < Puppet::State
12
+ # Fix things so that the fields have to match exactly, instead
13
+ # of only kinda
14
+ def insync?
15
+ self.is == self.should
16
+ end
17
+
18
+ # Normally this would retrieve the current value, but our state is not
19
+ # actually capable of doing so.
20
+ def retrieve
21
+ # If we've synced, then just copy the values over and return.
22
+ # This allows this state to behave like any other state.
23
+ if defined? @synced and @synced
24
+ # by default, we only copy over the first value.
25
+ @is = @synced
26
+ @synced = false
27
+ return
28
+ end
29
+
30
+ unless defined? @is and ! @is.nil?
31
+ @is = :absent
32
+ end
33
+ end
34
+
35
+ # Determine whether the host entry should be destroyed, and figure
36
+ # out which event to return. Finally, call @parent.sync to write the
37
+ # host tab.
38
+ def sync(nostore = false)
39
+ ebase = @parent.class.name.to_s
40
+ if @is == :absent
41
+ #@is = self.should
42
+ tail = "created"
43
+
44
+ # If we're creating it, then sync all of the other states
45
+ # but tell them not to store (we'll store just once,
46
+ # at the end).
47
+ unless nostore
48
+ @parent.eachstate { |state|
49
+ next if state == self or state.name == :ensure
50
+ state.sync(true)
51
+ }
52
+ end
53
+ elsif self.should == :absent
54
+ @parent.remove(true)
55
+ tail = "deleted"
56
+ #elsif @is == @should
57
+ elsif self.insync?
58
+ self.info "already in sync"
59
+ return nil
60
+ else
61
+ #@is = self.should
62
+ # Mark that we've synced it, but don't copy the value, because
63
+ # that will make the 'change' log inscrutable.
64
+ tail = "changed"
65
+ end
66
+ @synced = self.should
67
+
68
+ if nostore
69
+ self.retrieve
70
+ else
71
+ @parent.store
72
+ end
73
+
74
+ return (ebase + "_" + tail).intern
75
+ end
76
+ end
77
+ end
78
+
79
+ class Type
80
+ # The collection of classes that are just simple records aggregated
81
+ # into a file. See 'host.rb' for an example.
82
+ class ParsedType < Puppet::Type
83
+ @name = :parsedtype
84
+ class << self
85
+ attr_accessor :filetype, :hostfile, :fileobj, :fields, :path
86
+ end
87
+
88
+ # Override 'newstate' so that all states default to having the
89
+ # correct parent type
90
+ def self.newstate(name, parent = nil, &block)
91
+ parent ||= Puppet::State::ParsedParam
92
+ super(name, parent, &block)
93
+ end
94
+
95
+ # Add another type var.
96
+ def self.initvars
97
+ @instances = []
98
+ super
99
+ end
100
+
101
+ # Override the Puppet::Type#[]= method so that we can store the
102
+ # instances in per-user arrays. Then just call +super+.
103
+ def self.[]=(name, object)
104
+ self.instance(object)
105
+ super
106
+ end
107
+
108
+ # In addition to removing the instances in @objects, Cron has to remove
109
+ # per-user host tab information.
110
+ def self.clear
111
+ @instances = []
112
+ @fileobj = nil
113
+ super
114
+ end
115
+
116
+ # Override the default Puppet::Type method, because instances
117
+ # also need to be deleted from the @instances hash
118
+ def self.delete(child)
119
+ if @instances.include?(child)
120
+ @instances.delete(child)
121
+ end
122
+ super
123
+ end
124
+
125
+ # Return the header placed at the top of each generated file, warning
126
+ # users that modifying this file manually is probably a bad idea.
127
+ def self.header
128
+ %{# HEADER: This file was autogenerated at #{Time.now} by puppet. While it
129
+ # HEADER: can still be managed manually, it is definitely not recommended.\n}
130
+ end
131
+
132
+ # Store a new instance of a host. Called from Host#initialize.
133
+ def self.instance(obj)
134
+ unless @instances.include?(obj)
135
+ @instances << obj
136
+ end
137
+ end
138
+
139
+ # Parse a file
140
+ #
141
+ # Subclasses must override this method.
142
+ def self.parse(text)
143
+ raise Puppet::DevError, "Parse was not overridden in %s" %
144
+ self.name
145
+ end
146
+
147
+ # Convert the hash to an object.
148
+ def self.hash2obj(hash)
149
+ obj = nil
150
+
151
+ unless hash.include?(:name) and hash[:name]
152
+ raise Puppet::DevError, "Hash was not passed with name"
153
+ end
154
+
155
+ # if the obj already exists with that name...
156
+ if obj = self[hash[:name]]
157
+ # We're assuming here that objects with the same name
158
+ # are the same object, which *should* be the case, assuming
159
+ # we've set up our naming stuff correctly everywhere.
160
+
161
+ # Mark found objects as present
162
+ Puppet.debug "Found %s %s" % [self.name, obj.name]
163
+ obj.is = [:ensure, :present]
164
+ else
165
+ # create a new obj, since no existing one seems to
166
+ # match
167
+ obj = self.create(
168
+ :name => hash[:name]
169
+ ) or return false
170
+ hash.delete(:name)
171
+ end
172
+
173
+ hash.each { |param, value|
174
+ obj.is = [param, value]
175
+ }
176
+ end
177
+
178
+ # Retrieve the text for the file. Returns nil in the unlikely
179
+ # event that it doesn't exist.
180
+ def self.retrieve
181
+ @fileobj ||= @filetype.new(@path)
182
+ text = @fileobj.read
183
+ if text.nil? or text == ""
184
+ # there is no host file
185
+ return nil
186
+ else
187
+ # First we mark all of our objects absent; any objects
188
+ # subsequently found will be marked present
189
+ self.each { |obj|
190
+ obj.each { |state|
191
+ state.is = :absent
192
+ }
193
+ }
194
+ self.parse(text)
195
+ end
196
+ end
197
+
198
+ # Write out the file.
199
+ def self.store
200
+ @fileobj ||= @filetype.new(@path)
201
+
202
+ if @instances.empty?
203
+ Puppet.notice "No %s instances for %s" % [self.name, @path]
204
+ else
205
+ @fileobj.write(self.to_file())
206
+ end
207
+
208
+ #self.each { |obj|
209
+ # obj.each { |state|
210
+ # obj.notice "Changing from %s to %s" %
211
+ # [state.is.inspect, state.should.inspect]
212
+ # state.is = state.should
213
+ # }
214
+ #}
215
+ end
216
+
217
+ # Collect all Host instances convert them into literal text.
218
+ def self.to_file
219
+ str = self.header()
220
+ unless @instances.empty?
221
+ str += @instances.reject { |obj|
222
+ # Don't write out objects that should be absent
223
+ if obj.is_a?(self)
224
+ if obj.should(:ensure) == :absent
225
+ #obj.warning "removing; is = %s, should = %s" %
226
+ # [obj.is(:ensure).inspect, obj.should(:ensure).inspect]
227
+ #obj.is = [:ensure, :absent]
228
+ true
229
+ end
230
+ end
231
+ }.collect { |obj|
232
+ if obj.is_a?(self)
233
+ obj.to_record
234
+ else
235
+ obj.to_s
236
+ end
237
+ }.join("\n") + "\n"
238
+
239
+ return str
240
+ else
241
+ Puppet.notice "No host instances"
242
+ return ""
243
+ end
244
+ end
245
+
246
+ # Return the last time the hosts file was loaded. Could
247
+ # be used for reducing writes, but currently is not.
248
+ def self.loaded?(user)
249
+ @fileobj ||= @filetype.new(@path)
250
+ @fileobj.loaded
251
+ end
252
+
253
+ def create
254
+ self[:ensure] = :present
255
+ self.store
256
+ end
257
+
258
+ # We just find any state and check whether it's marked absent
259
+ def exists?
260
+ name, state = @states.find { |name, state|
261
+ state.is_a?(Puppet::State::ParsedParam)
262
+ }
263
+
264
+ if state.is == :absent
265
+ return false
266
+ else
267
+ return true
268
+ end
269
+ end
270
+
271
+ def destroy
272
+ self[:ensure] = :absent
273
+ self.store
274
+ end
275
+
276
+ # Override the default Puppet::Type method because we need to call
277
+ # the +@filetype+ retrieve method.
278
+ def retrieve
279
+ self.class.retrieve()
280
+
281
+ self.eachstate { |st| st.retrieve }
282
+ end
283
+
284
+ # Write the entire host file out.
285
+ def store
286
+ self.class.store()
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ require 'puppet/type/parsedtype/host'
293
+ require 'puppet/type/parsedtype/port'
294
+
295
+ # $Id: parsedtype.rb 847 2006-01-23 22:38:39Z luke $