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
@@ -6,264 +6,264 @@ require 'fileutils'
6
6
  require 'puppet/type/state'
7
7
  require 'puppet/server/fileserver'
8
8
 
9
- # We put all of the states in separate files, because there are so many
10
- # of them.
11
- require 'puppet/type/pfile/type'
12
- require 'puppet/type/pfile/create'
13
- require 'puppet/type/pfile/checksum'
14
- require 'puppet/type/pfile/uid'
15
- require 'puppet/type/pfile/mode'
16
- require 'puppet/type/pfile/group'
17
- require 'puppet/type/pfile/source'
18
-
19
9
  module Puppet
20
- class Type
21
- class PFile < Type
22
- @doc = "Manages local files, including setting ownership and
23
- permissions, and allowing creation of both files and directories."
24
-
25
- @states = [
26
- Puppet::State::PFileCreate,
27
- Puppet::State::PFileChecksum,
28
- Puppet::State::PFileSource,
29
- Puppet::State::PFileUID,
30
- Puppet::State::PFileGroup,
31
- Puppet::State::PFileMode,
32
- Puppet::State::PFileType
33
- ]
34
-
35
- @parameters = [
36
- :path,
37
- :backup,
38
- :linkmaker,
39
- :recurse,
40
- :ignore
41
- ]
42
-
43
- @paramdoc[:path] = "The path to the file to manage. Must be fully
44
- qualified."
45
-
46
- @paramdoc[:backup] = "Whether files should be backed up before
47
- being replaced. If a ``filebucket`` is specified, files will be
10
+ newtype(:file) do
11
+ @doc = "Manages local files, including setting ownership and
12
+ permissions, creation of both files and directories, and
13
+ retrieving entire files from remote servers. As Puppet matures, it
14
+ expected that the ``file`` element will be used less and less to
15
+ manage content, and instead native elements will be used to do so.
16
+
17
+ If you find that you are often copying files in from a central
18
+ location, rather than using native elements, please contact
19
+ Reductive Labs and we can hopefully work with you to develop a
20
+ native element to support what you are doing."
21
+
22
+ newparam(:path) do
23
+ desc "The path to the file to manage. Must be fully qualified."
24
+ isnamevar
25
+ end
26
+
27
+ newparam(:backup) do
28
+ desc "Whether files should be backed up before
29
+ being replaced. If a filebucket_ is specified, files will be
48
30
  backed up there; else, they will be backed up in the same directory
49
31
  with a ``.puppet-bak`` extension."
50
32
 
51
- @paramdoc[:linkmaker] = "An internal parameter used by the *symlink*
33
+ defaultto true
34
+
35
+ munge do |value|
36
+ case value
37
+ when false, "false":
38
+ false
39
+ when true, "true":
40
+ ".puppet-bak"
41
+ when Array:
42
+ case value[0]
43
+ when "filebucket":
44
+ if bucket = Puppet.type(:filebucket).bucket(value[1])
45
+ bucket
46
+ else
47
+ self.fail "Could not retrieve filebucket %s" %
48
+ value[1]
49
+ end
50
+ else
51
+ self.fail "Invalid backup object type %s" %
52
+ value[0].inspect
53
+ end
54
+ else
55
+ self.fail "Invalid backup type %s" %
56
+ value.inspect
57
+ end
58
+ end
59
+ end
60
+
61
+ newparam(:linkmaker) do
62
+ desc "An internal parameter used by the *symlink*
52
63
  type to do recursive link creation."
64
+ end
53
65
 
54
- @paramdoc[:recurse] = "Whether and how deeply to do recursive
66
+ newparam(:recurse) do
67
+ desc "Whether and how deeply to do recursive
55
68
  management. **false**/*true*/*inf*/*number*"
56
69
 
57
- @paramdoc[:ignore] = "A parameter which omits action on files matching
70
+ munge do |value|
71
+ value
72
+ end
73
+ end
74
+
75
+ newparam(:ignore) do
76
+ desc "A parameter which omits action on files matching
58
77
  specified patterns during recursion. Uses Ruby's builtin globbing
59
78
  engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``.
60
79
  Matches that would descend into the directory structure are ignored,
61
80
  e.g., ``*/*``."
81
+
82
+ defaultto false
62
83
 
63
- #no longer a parameter
64
- # @paramdoc[:source] = "Where to retrieve the contents of the files.
65
- # Currently only supports local copying, but will eventually
66
- # support multiple protocols for copying. Arguments are specified
67
- # using either a full local path or using a URI (currently only
68
- # *file* is supported as a protocol)."
69
-
70
-
71
-
72
- @name = :file
73
- @namevar = :path
84
+ validate do |value|
85
+ unless value.is_a?(Array) or value.is_a?(String) or value == false
86
+ self.devfail "Ignore must be a string or an Array"
87
+ end
88
+ end
89
+ end
90
+
91
+ autorequire(:file) do
92
+ cur = []
93
+ # Skip the nil in the beginning and don't add ourselves as a prereq
94
+ # either.
95
+ self.name.split(File::SEPARATOR)[1..-2].collect { |dir|
96
+ cur << dir
97
+ "/" + cur.join(File::SEPARATOR)
98
+ }
99
+ end
100
+
101
+ validate do
102
+ if self[:content] and self[:source]
103
+ self.fail "You cannot specify both content and a source"
104
+ end
105
+ end
74
106
 
75
- @depthfirst = false
107
+ @depthfirst = false
76
108
 
77
- PINPARAMS = [:mode, :type, :owner, :group, :checksum]
78
109
 
110
+ def argument?(arg)
111
+ @arghash.include?(arg)
112
+ end
79
113
 
80
- def argument?(arg)
81
- @arghash.include?(arg)
114
+ def handlebackup(file = nil)
115
+ # let the path be specified
116
+ file ||= self[:path]
117
+ # if they specifically don't want a backup, then just say
118
+ # we're good
119
+ unless FileTest.exists?(file)
120
+ return true
82
121
  end
83
122
 
84
- def handlebackup(file = nil)
85
- # let the path be specified
86
- file ||= self[:path]
87
- # if they specifically don't want a backup, then just say
88
- # we're good
89
- unless FileTest.exists?(file)
90
- return true
91
- end
92
-
93
- unless self[:backup]
94
- return true
95
- end
123
+ unless self[:backup]
124
+ return true
125
+ end
96
126
 
97
- case File.stat(file).ftype
98
- when "directory":
99
- # we don't need to backup directories
127
+ case File.stat(file).ftype
128
+ when "directory":
129
+ # we don't need to backup directories
130
+ return true
131
+ when "file":
132
+ backup = self[:backup]
133
+ case backup
134
+ when Puppet::Client::Dipper:
135
+ sum = backup.backup(file)
136
+ self.info "Filebucketed %s with sum %s" %
137
+ [file, sum]
100
138
  return true
101
- when "file":
102
- backup = self[:backup]
103
- case backup
104
- when Puppet::Client::Dipper:
105
- sum = backup.backup(file)
106
- self.info "Filebucketed %s with sum %s" %
107
- [file, sum]
108
- return true
109
- when String:
110
- newfile = file + backup
111
- if FileTest.exists?(newfile)
112
- begin
113
- File.unlink(newfile)
114
- rescue => detail
115
- self.err "Could not remove old backup: %s" %
116
- detail
117
- return false
118
- end
119
- end
139
+ when String:
140
+ newfile = file + backup
141
+ if FileTest.exists?(newfile)
120
142
  begin
121
- FileUtils.cp(file,
122
- file + backup)
123
- return true
143
+ File.unlink(newfile)
124
144
  rescue => detail
125
- # since they said they want a backup, let's error out
126
- # if we couldn't make one
127
- raise Puppet::Error.new("Could not back %s up: %s" %
128
- [file, detail.message])
145
+ self.err "Could not remove old backup: %s" %
146
+ detail
147
+ return false
129
148
  end
130
- else
131
- self.err "Invalid backup type %s" % backup
132
- return false
149
+ end
150
+ begin
151
+ FileUtils.cp(file,
152
+ file + backup)
153
+ return true
154
+ rescue => detail
155
+ # since they said they want a backup, let's error out
156
+ # if we couldn't make one
157
+ self.fail "Could not back %s up: %s" %
158
+ [file, detail.message]
133
159
  end
134
160
  else
135
- self.notice "Cannot backup files of type %s" %
136
- File.stat(file).ftype
161
+ self.err "Invalid backup type %s" % backup
137
162
  return false
138
163
  end
164
+ else
165
+ self.notice "Cannot backup files of type %s" %
166
+ File.stat(file).ftype
167
+ return false
139
168
  end
140
-
141
- def handleignore(children)
142
- @parameters[:ignore].each { |ignore|
143
- ignored = []
144
- Dir.glob(File.join(self.name,ignore), File::FNM_DOTMATCH) { |match|
145
- ignored.push(File.basename(match))
146
- }
147
- children = children - ignored
169
+ end
170
+
171
+ def handleignore(children)
172
+ return children unless self[:ignore]
173
+ self[:ignore].each { |ignore|
174
+ ignored = []
175
+ Dir.glob(File.join(self.name,ignore), File::FNM_DOTMATCH) { |match|
176
+ ignored.push(File.basename(match))
148
177
  }
149
- return children
150
- end
151
-
152
- def initialize(hash)
153
- # clean out as many references to any file paths as possible
154
- # this was the source of many, many bugs
155
-
156
- @arghash = self.argclean(hash)
157
- @arghash.delete(self.class.namevar)
158
-
159
- if @arghash.include?(:source)
160
- @arghash.delete(:source)
161
- end
162
-
163
- @stat = nil
164
- @parameters = Hash.new(false)
165
-
166
- # default to true
167
- self[:backup] = true
168
-
169
- # Used for caching clients
170
- @clients = {}
171
-
172
- super
173
- end
178
+ children = children - ignored
179
+ }
180
+ return children
181
+ end
182
+
183
+ def initialize(hash)
184
+ # clean out as many references to any file paths as possible
185
+ # this was the source of many, many bugs
174
186
 
175
- def parambackup=(value)
176
- case value
177
- when false, "false":
178
- @parameters[:backup] = false
179
- when true, "true":
180
- @parameters[:backup] = ".puppet-bak"
181
- when Array:
182
- case value[0]
183
- when "filebucket":
184
- if bucket = Puppet::Type::PFileBucket.bucket(value[1])
185
- @parameters[:backup] = bucket
186
- else
187
- @parameters[:backup] = ".puppet-bak"
188
- raise Puppet::Error,
189
- "Could not retrieve filebucket %s" %
190
- value[1]
191
- end
192
- else
193
- raise Puppet::Error, "Invalid backup object type %s" %
194
- value[0].inspect
195
- end
196
- else
197
- raise Puppet::Error, "Invalid backup type %s" %
198
- value.inspect
199
- end
200
- end
201
-
202
- def paramignore=(value)
203
-
204
- #Make sure the value of ignore is in correct type
205
- unless value.is_a?(Array) or value.is_a?(String)
206
- raise Puppet::DevError.new("Ignore must be a string or an Array")
207
- end
208
-
209
- @parameters[:ignore] = value
210
- end
187
+ @arghash = self.argclean(hash)
188
+ @arghash.delete(self.class.namevar)
211
189
 
212
- def newchild(path, hash = {})
213
- # make local copy of arguments
214
- args = @arghash.dup
190
+ if @arghash.include?(:source)
191
+ @arghash.delete(:source)
192
+ end
215
193
 
216
- if path =~ %r{^#{File::SEPARATOR}}
217
- raise Puppet::DevError.new(
218
- "Must pass relative paths to PFile#newchild()"
219
- )
220
- else
221
- path = File.join(self.name, path)
222
- end
194
+ @stat = nil
195
+
196
+ # Used for caching clients
197
+ @clients = {}
198
+
199
+ super
200
+ end
201
+
202
+ # Create a new file or directory object as a child to the current
203
+ # object.
204
+ def newchild(path, local, hash = {})
205
+ # make local copy of arguments
206
+ args = @arghash.dup
207
+
208
+ if path =~ %r{^#{File::SEPARATOR}}
209
+ self.devfail(
210
+ "Must pass relative paths to PFile#newchild()"
211
+ )
212
+ else
213
+ path = File.join(self.name, path)
214
+ end
223
215
 
224
- args[:path] = path
216
+ args[:path] = path
225
217
 
226
- unless hash.include?(:recurse)
227
- if args.include?(:recurse)
228
- if args[:recurse].is_a?(Integer)
229
- self.notice "Decrementing recurse on %s" % path
230
- args[:recurse] -= 1 # reduce the level of recursion
231
- end
218
+ unless hash.include?(:recurse)
219
+ if args.include?(:recurse)
220
+ if args[:recurse].is_a?(Integer)
221
+ args[:recurse] -= 1 # reduce the level of recursion
232
222
  end
233
-
234
223
  end
235
224
 
236
- hash.each { |key,value|
237
- args[key] = value
225
+ end
226
+
227
+ hash.each { |key,value|
228
+ args[key] = value
229
+ }
230
+
231
+ child = nil
232
+ klass = nil
233
+
234
+ # We specifically look in @parameters here, because 'linkmaker' isn't
235
+ # a valid attribute for subclasses, so using 'self[:linkmaker]' throws
236
+ # an error.
237
+ if @parameters.include?(:linkmaker) and
238
+ args.include?(:source) and ! FileTest.directory?(args[:source])
239
+ klass = Puppet.type(:symlink)
240
+
241
+ self.debug "%s is a link" % path
242
+ # clean up the args a lot for links
243
+ old = args.dup
244
+ args = {
245
+ :target => old[:source],
246
+ :path => path
238
247
  }
248
+ else
249
+ klass = self.class
250
+ end
239
251
 
240
- child = nil
241
- klass = nil
242
- if @parameters[:linkmaker] and args.include?(:source) and
243
- ! FileTest.directory?(args[:source])
244
- klass = Puppet::Type::Symlink
245
-
246
- self.debug "%s is a link" % path
247
- # clean up the args a lot for links
248
- old = args.dup
249
- args = {
250
- :target => old[:source],
251
- :path => path
252
- }
253
- else
254
- klass = self.class
252
+ # The child might already exist because 'localrecurse' runs
253
+ # before 'sourcerecurse'. I could push the override stuff into
254
+ # a separate method or something, but the work is the same other
255
+ # than this last bit, so it doesn't really make sense.
256
+ if child = klass[path]
257
+ unless @children.include?(child)
258
+ self.debug "Not managing more explicit file %s" %
259
+ path
260
+ return nil
255
261
  end
256
262
 
257
- # The child might already exist because 'localrecurse' runs
258
- # before 'sourcerecurse'. I could push the override stuff into
259
- # a separate method or something, but the work is the same other
260
- # than this last bit, so it doesn't really make sense.
261
- if child = klass[path]
262
- unless @children.include?(child)
263
- self.notice "Not managing more explicit file %s" %
264
- path
265
- return nil
266
- end
263
+ # This is only necessary for sourcerecurse, because we might have
264
+ # created the object with different 'should' values than are
265
+ # set remotely.
266
+ unless local
267
267
  args.each { |var,value|
268
268
  next if var == :path
269
269
  next if var == :name
@@ -272,298 +272,322 @@ module Puppet
272
272
  child[var] = value
273
273
  end
274
274
  }
275
- else # create it anew
276
- #notice "Creating new file with args %s" % args.inspect
277
- args[:parent] = self
278
- begin
279
- child = klass.implicitcreate(args)
280
-
281
- # implicit creation can return nil
282
- if child.nil?
283
- return nil
284
- end
285
- @children << child
286
- rescue Puppet::Error => detail
287
- self.notice(
288
- "Cannot manage: %s" %
289
- [detail.message]
290
- )
291
- self.debug args.inspect
292
- child = nil
293
- rescue => detail
294
- self.notice(
295
- "Cannot manage: %s" %
296
- [detail]
297
- )
298
- self.debug args.inspect
299
- child = nil
275
+ end
276
+ else # create it anew
277
+ #notice "Creating new file with args %s" % args.inspect
278
+ args[:parent] = self
279
+ begin
280
+ child = klass.implicitcreate(args)
281
+
282
+ # implicit creation can return nil
283
+ if child.nil?
284
+ return nil
300
285
  end
286
+ @children << child
287
+ rescue Puppet::Error => detail
288
+ self.notice(
289
+ "Cannot manage: %s" %
290
+ [detail.message]
291
+ )
292
+ self.debug args.inspect
293
+ child = nil
294
+ rescue => detail
295
+ self.notice(
296
+ "Cannot manage: %s" %
297
+ [detail]
298
+ )
299
+ self.debug args.inspect
300
+ child = nil
301
301
  end
302
- return child
303
302
  end
304
-
305
- # Paths are special for files, because we don't actually want to show
306
- # the parent's full path.
307
- def path
308
- unless defined? @path
309
- if defined? @parent
310
- # We only need to behave specially when our parent is also
311
- # a file
312
- if @parent.is_a?(self.class)
313
- # Remove the parent file name
314
- ppath = @parent.path.sub(/\/?file=.+/, '')
315
- @path = []
316
- if ppath != "/" and ppath != ""
317
- @path << ppath
318
- end
319
- @path << self.class.name.to_s + "=" + self.name
320
- else
321
- super
303
+ return child
304
+ end
305
+
306
+ # Paths are special for files, because we don't actually want to show
307
+ # the parent's full path.
308
+ def path
309
+ unless defined? @path
310
+ if defined? @parent
311
+ # We only need to behave specially when our parent is also
312
+ # a file
313
+ if @parent.is_a?(self.class)
314
+ # Remove the parent file name
315
+ ppath = @parent.path.sub(/\/?file=.+/, '')
316
+ @path = []
317
+ if ppath != "/" and ppath != ""
318
+ @path << ppath
322
319
  end
320
+ @path << self.class.name.to_s + "=" + self.name
323
321
  else
324
- # The top-level name is always puppet[top], so we don't
325
- # bother with that. And we don't add the hostname
326
- # here, it gets added in the log server thingy.
327
- if self.name == "puppet[top]"
328
- @path = ["/"]
329
- else
330
- # We assume that if we don't have a parent that we
331
- # should not cache the path
332
- @path = [self.class.name.to_s + "=" + self.name]
333
- end
322
+ super
334
323
  end
335
- end
336
-
337
- return @path.join("/")
338
- end
339
-
340
- # Recurse into the directory. This basically just calls 'localrecurse'
341
- # and maybe 'sourcerecurse'.
342
- def recurse
343
- recurse = @parameters[:recurse]
344
- # we might have a string, rather than a number
345
- if recurse.is_a?(String)
346
- if recurse =~ /^[0-9]+$/
347
- recurse = Integer(recurse)
348
- #elsif recurse =~ /^inf/ # infinite recursion
349
- else # anything else is infinite recursion
350
- recurse = true
324
+ else
325
+ # The top-level name is always puppet[top], so we don't
326
+ # bother with that. And we don't add the hostname
327
+ # here, it gets added in the log server thingy.
328
+ if self.name == "puppet[top]"
329
+ @path = ["/"]
330
+ else
331
+ # We assume that if we don't have a parent that we
332
+ # should not cache the path
333
+ @path = [self.class.name.to_s + "=" + self.name]
351
334
  end
352
335
  end
336
+ end
353
337
 
354
- # are we at the end of the recursion?
355
- if recurse == 0
356
- self.info "finished recursing"
357
- return
338
+ return @path.join("/")
339
+ end
340
+
341
+ # Recurse into the directory. This basically just calls 'localrecurse'
342
+ # and maybe 'sourcerecurse'.
343
+ def recurse
344
+ recurse = self[:recurse]
345
+ # we might have a string, rather than a number
346
+ if recurse.is_a?(String)
347
+ if recurse =~ /^[0-9]+$/
348
+ recurse = Integer(recurse)
349
+ #elsif recurse =~ /^inf/ # infinite recursion
350
+ else # anything else is infinite recursion
351
+ recurse = true
358
352
  end
353
+ end
359
354
 
360
- if recurse.is_a?(Integer)
361
- recurse -= 1
362
- end
355
+ # are we at the end of the recursion?
356
+ if recurse == 0
357
+ self.info "finished recursing"
358
+ return
359
+ end
363
360
 
364
- self.localrecurse(recurse)
365
- if @states.include?(:source)
366
- self.sourcerecurse(recurse)
367
- end
361
+ if recurse.is_a?(Integer)
362
+ recurse -= 1
368
363
  end
369
364
 
370
- def localrecurse(recurse)
371
- unless FileTest.exist?(self.name) and self.stat.directory?
372
- #self.info "%s is not a directory; not recursing" %
373
- # self.name
374
- return
375
- end
365
+ self.localrecurse(recurse)
366
+ if @states.include?(:source)
367
+ self.sourcerecurse(recurse)
368
+ end
369
+ end
376
370
 
377
- unless FileTest.directory? self.name
378
- raise Puppet::Error.new(
379
- "Uh, somehow trying to manage non-dir %s" % self.name
380
- )
381
- end
382
- unless FileTest.readable? self.name
383
- self.notice "Cannot manage %s: permission denied" % self.name
384
- return
385
- end
371
+ def localrecurse(recurse)
372
+ unless FileTest.exist?(self.name) and self.stat.directory?
373
+ #self.info "%s is not a directory; not recursing" %
374
+ # self.name
375
+ return
376
+ end
386
377
 
387
- children = Dir.entries(self.name)
388
-
389
- #Get rid of ignored children
390
- if @parameters.include?(:ignore)
391
- children = handleignore(children)
392
- end
393
-
394
- added = []
395
- children.each { |file|
396
- file = File.basename(file)
397
- next if file =~ /^\.\.?$/ # skip . and ..
398
- if child = self.newchild(file, :recurse => recurse)
399
- unless @children.include?(child)
400
- self.push child
401
- added.push file
378
+ unless FileTest.readable? self.name
379
+ self.notice "Cannot manage %s: permission denied" % self.name
380
+ return
381
+ end
402
382
 
403
- end
404
- child.retrieve
383
+ children = Dir.entries(self.name)
384
+
385
+ #Get rid of ignored children
386
+ if @parameters.include?(:ignore)
387
+ children = handleignore(children)
388
+ end
389
+
390
+ added = []
391
+ children.each { |file|
392
+ file = File.basename(file)
393
+ next if file =~ /^\.\.?$/ # skip . and ..
394
+ if child = self.newchild(file, true, :recurse => recurse)
395
+ unless @children.include?(child)
396
+ self.push child
397
+ added.push file
405
398
  end
406
- }
399
+ end
400
+ }
401
+ end
402
+
403
+ # This recurses against the remote source and makes sure the local
404
+ # and remote structures match. It's run after 'localrecurse'.
405
+ def sourcerecurse(recurse)
406
+ # FIXME sourcerecurse should support purging non-remote files
407
+ source = @states[:source].source
408
+
409
+ unless ! source.nil? and source !~ /^\s*$/
410
+ self.notice "source %s does not exist" % @states[:source].should
411
+ return nil
412
+ end
413
+
414
+ sourceobj, path = uri2obj(source)
415
+
416
+ # we'll set this manually as necessary
417
+ if @arghash.include?(:ensure)
418
+ @arghash.delete(:ensure)
407
419
  end
408
420
 
409
- # This recurses against the remote source and makes sure the local
410
- # and remote structures match. It's run after 'localrecurse'.
411
- def sourcerecurse(recurse)
412
- # FIXME sourcerecurse should support purging non-remote files
413
- source = @states[:source].source
414
-
415
- sourceobj, path = uri2obj(source)
416
-
417
- # we'll set this manually as necessary
418
- if @arghash.include?(:create)
419
- @arghash.delete(:create)
421
+ # okay, we've got our source object; now we need to
422
+ # build up a local file structure to match the remote
423
+ # one
424
+
425
+ server = sourceobj.server
426
+ sum = "md5"
427
+ if state = self.state(:checksum)
428
+ sum = state.checktype
429
+ end
430
+ r = false
431
+ if recurse
432
+ unless recurse == 0
433
+ r = 1
420
434
  end
435
+ end
421
436
 
422
- # okay, we've got our source object; now we need to
423
- # build up a local file structure to match the remote
424
- # one
437
+ ignore = self[:ignore]
425
438
 
426
- server = sourceobj.server
427
- sum = "md5"
428
- if state = self.state(:checksum)
429
- sum = state.checktype
439
+ #self.warning "Listing path %s" % path.inspect
440
+ desc = server.list(path, r, ignore)
441
+
442
+ desc.split("\n").each { |line|
443
+ file, type = line.split("\t")
444
+ next if file == "/"
445
+ name = file.sub(/^\//, '')
446
+ #self.warning "child name is %s" % name
447
+ args = {:source => source + file}
448
+ if type == file
449
+ args[:recurse] = nil
430
450
  end
431
- r = false
432
- if recurse
433
- unless recurse == 0
434
- r = 1
435
- end
451
+ self.newchild(name, false, args)
452
+ #self.newchild(hash, source, recurse)
453
+ #hash2child(hash, source, recurse)
454
+ }
455
+ end
456
+
457
+ # a wrapper method to make sure the file exists before doing anything
458
+ def retrieve
459
+ if @states.include?(:source)
460
+ # This probably isn't the best place for it, but we need
461
+ # to make sure that we have a corresponding checksum state.
462
+ unless @states.include?(:checksum)
463
+ self[:checksum] = "md5"
436
464
  end
465
+ @states[:source].retrieve
466
+ end
437
467
 
438
- ignore = @parameters[:ignore]
439
-
440
- #self.warning "Listing path %s" % path.inspect
441
- desc = server.list(path, r, ignore)
442
-
443
- desc.split("\n").each { |line|
444
- file, type = line.split("\t")
445
- next if file == "/"
446
- name = file.sub(/^\//, '')
447
- #self.warning "child name is %s" % name
448
- args = {:source => source + file}
449
- if type == file
450
- args[:recurse] = nil
451
- end
452
- self.newchild(name, args)
453
- #self.newchild(hash, source, recurse)
454
- #hash2child(hash, source, recurse)
468
+ if @parameters.include?(:recurse)
469
+ self.recurse
470
+ end
471
+
472
+ unless stat = self.stat(true)
473
+ self.debug "File does not exist"
474
+ @states.each { |name,state|
475
+ # We've already retreived the source, and we don't
476
+ # want to overwrite whatever it did. This is a bit
477
+ # of a hack, but oh well, source is definitely special.
478
+ next if name == :source
479
+ state.is = :absent
455
480
  }
481
+ return
456
482
  end
457
483
 
458
- # a wrapper method to make sure the file exists before doing anything
459
- def retrieve
460
- if @states.include?(:source)
461
- # This probably isn't the best place for it, but we need
462
- # to make sure that we have a corresponding checksum state.
463
- unless @states.include?(:checksum)
464
- self[:checksum] = "md5"
465
- end
466
- @states[:source].retrieve
467
- end
484
+ super
485
+ end
468
486
 
469
- if @parameters.include?(:recurse)
470
- self.recurse
487
+ # Set the checksum, from another state. There are multiple states that
488
+ # modify the contents of a file, and they need the ability to make sure
489
+ # that the checksum value is in sync.
490
+ def setchecksum(sum = nil)
491
+ if @states.include? :checksum
492
+ if sum
493
+ @states[:checksum].checksum = sum
494
+ else
495
+ # If they didn't pass in a sum, then tell checksum to
496
+ # figure it out.
497
+ @states[:checksum].retrieve
498
+ @states[:checksum].checksum = @states[:checksum].is
471
499
  end
500
+ end
501
+ end
472
502
 
473
- unless stat = self.stat(true)
474
- self.debug "File does not exist"
475
- @states.each { |name,state|
476
- # We've already retreived the source, and we don't
477
- # want to overwrite whatever it did. This is a bit
478
- # of a hack, but oh well, source is definitely special.
479
- next if name == :source
480
- state.is = :notfound
481
- }
482
- return
503
+ def stat(refresh = false)
504
+ if @stat.nil? or refresh == true
505
+ begin
506
+ @stat = File.lstat(self.name)
507
+ rescue Errno::ENOENT => error
508
+ @stat = nil
509
+ rescue => error
510
+ self.debug "Failed to stat %s: %s" %
511
+ [self.name,error]
512
+ @stat = nil
483
513
  end
484
-
485
- super
486
514
  end
487
515
 
488
- def stat(refresh = false)
489
- if @stat.nil? or refresh == true
490
- begin
491
- @stat = File.lstat(self.name)
492
- rescue Errno::ENOENT => error
493
- @stat = nil
494
- rescue => error
495
- self.debug "Failed to stat %s: %s" %
496
- [self.name,error]
497
- @stat = nil
498
- end
499
- end
516
+ return @stat
517
+ end
500
518
 
501
- return @stat
519
+ def uri2obj(source)
520
+ sourceobj = FileSource.new
521
+ path = nil
522
+ if source =~ /^\//
523
+ source = "file://localhost/%s" % source
524
+ sourceobj.mount = "localhost"
525
+ sourceobj.local = true
526
+ end
527
+ begin
528
+ uri = URI.parse(source)
529
+ rescue => detail
530
+ self.fail "Could not understand source %s: %s" %
531
+ [source, detail.to_s]
502
532
  end
503
533
 
504
- def uri2obj(source)
505
- sourceobj = FileSource.new
506
- path = nil
507
- if source =~ /^\//
508
- source = "file://localhost/%s" % source
509
- sourceobj.mount = "localhost"
510
- sourceobj.local = true
534
+ case uri.scheme
535
+ when "file":
536
+ unless defined? @@localfileserver
537
+ @@localfileserver = Puppet::Server::FileServer.new(
538
+ :Local => true,
539
+ :Mount => { "/" => "localhost" },
540
+ :Config => false
541
+ )
542
+ #@@localfileserver.mount("/", "localhost")
511
543
  end
512
- begin
513
- uri = URI.parse(source)
514
- rescue => detail
515
- raise Puppet::Error, "Could not understand source %s: %s" %
516
- [source, detail.to_s]
544
+ sourceobj.server = @@localfileserver
545
+ path = "/localhost" + uri.path
546
+ when "puppet":
547
+ args = { :Server => uri.host }
548
+ if uri.port
549
+ args[:Port] = uri.port
517
550
  end
551
+ # FIXME We should cache a copy of this server
552
+ #sourceobj.server = Puppet::NetworkClient.new(args)
553
+ unless @clients.include?(source)
554
+ @clients[source] = Puppet::Client::FileClient.new(args)
555
+ end
556
+ sourceobj.server = @clients[source]
518
557
 
519
- case uri.scheme
520
- when "file":
521
- unless defined? @@localfileserver
522
- @@localfileserver = Puppet::Server::FileServer.new(
523
- :Local => true,
524
- :Mount => { "/" => "localhost" },
525
- :Config => false
526
- )
527
- #@@localfileserver.mount("/", "localhost")
528
- end
529
- sourceobj.server = @@localfileserver
530
- path = "/localhost" + uri.path
531
- when "puppet":
532
- args = { :Server => uri.host }
533
- if uri.port
534
- args[:Port] = uri.port
535
- end
536
- # FIXME We should cache a copy of this server
537
- #sourceobj.server = Puppet::NetworkClient.new(args)
538
- unless @clients.include?(source)
539
- @clients[source] = Puppet::Client::FileClient.new(args)
540
- end
541
- sourceobj.server = @clients[source]
542
-
543
- tmp = uri.path
544
- if tmp =~ %r{^/(\w+)}
545
- sourceobj.mount = $1
546
- path = tmp
547
- #path = tmp.sub(%r{^/\w+},'') || "/"
548
- else
549
- raise Puppet::Error, "Invalid source path %s" % tmp
550
- end
558
+ tmp = uri.path
559
+ if tmp =~ %r{^/(\w+)}
560
+ sourceobj.mount = $1
561
+ path = tmp
562
+ #path = tmp.sub(%r{^/\w+},'') || "/"
551
563
  else
552
- raise Puppet::Error,
553
- "Got other recursive file proto %s from %s" %
554
- [uri.scheme, source]
564
+ self.fail "Invalid source path %s" % tmp
555
565
  end
556
-
557
- return [sourceobj, path.sub(/\/\//, '/')]
566
+ else
567
+ self.fail "Got other recursive file proto %s from %s" %
568
+ [uri.scheme, source]
558
569
  end
559
- end # Puppet::Type::PFile
560
- end # Puppet::Type
570
+
571
+ return [sourceobj, path.sub(/\/\//, '/')]
572
+ end
573
+ end # Puppet.type(:pfile)
561
574
 
562
575
  # the filesource class can't include the path, because the path
563
576
  # changes for every file instance
564
577
  class FileSource
565
578
  attr_accessor :mount, :root, :server, :local
566
579
  end
567
- end
568
580
 
569
- # $Id$
581
+ # We put all of the states in separate files, because there are so many
582
+ # of them. The order these are loaded is important, because it determines
583
+ # the order they are in the state list.
584
+ require 'puppet/type/pfile/checksum'
585
+ require 'puppet/type/pfile/content' # can create the file
586
+ require 'puppet/type/pfile/source' # can create the file
587
+ require 'puppet/type/pfile/ensure' # can create the file
588
+ require 'puppet/type/pfile/uid'
589
+ require 'puppet/type/pfile/group'
590
+ require 'puppet/type/pfile/mode'
591
+ require 'puppet/type/pfile/type'
592
+ end
593
+ # $Id: pfile.rb 883 2006-02-08 16:53:34Z luke $