puppet 0.18.4 → 0.22.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. data/CHANGELOG +288 -0
  2. data/README +2 -2
  3. data/Rakefile +78 -5
  4. data/bin/puppet +28 -36
  5. data/bin/puppetca +81 -38
  6. data/bin/puppetd +65 -62
  7. data/bin/puppetdoc +409 -140
  8. data/bin/puppetmasterd +59 -47
  9. data/bin/puppetrun +38 -23
  10. data/conf/freebsd/puppetd +26 -0
  11. data/conf/freebsd/puppetmasterd +26 -0
  12. data/conf/gentoo/conf.d/puppet +5 -0
  13. data/conf/gentoo/conf.d/puppetmaster +12 -0
  14. data/conf/gentoo/init.d/puppet +38 -0
  15. data/conf/gentoo/init.d/puppetmaster +50 -0
  16. data/conf/gentoo/puppet/fileserver.conf +12 -0
  17. data/conf/gentoo/puppet/puppetca.conf +29 -0
  18. data/conf/gentoo/puppet/puppetd.conf +29 -0
  19. data/conf/gentoo/puppet/puppetmasterd.conf +29 -0
  20. data/conf/redhat/client.init +10 -5
  21. data/conf/redhat/client.sysconfig +1 -1
  22. data/conf/redhat/fileserver.conf +2 -2
  23. data/conf/redhat/logrotate +1 -1
  24. data/conf/redhat/no-lockdir.patch +13 -0
  25. data/conf/redhat/puppet.spec +65 -8
  26. data/conf/redhat/puppetd.conf +0 -4
  27. data/conf/redhat/server.init +3 -6
  28. data/conf/solaris/pkginfo +1 -1
  29. data/conf/solaris/smf/svc-puppetd +2 -2
  30. data/conf/suse/client.init +142 -0
  31. data/conf/suse/puppet.spec +221 -0
  32. data/conf/suse/server.init +162 -0
  33. data/examples/code/mac_automount.pp +16 -0
  34. data/examples/root/bin/sleeper +3 -5
  35. data/examples/root/etc/init.d/sleeper +8 -2
  36. data/examples/root/etc/puppet/fileserver.conf +12 -2
  37. data/examples/root/etc/puppet/namespaceauth.conf +20 -0
  38. data/examples/root/etc/puppet/puppetd.conf +4 -0
  39. data/examples/root/etc/puppet/puppetmasterd.conf +6 -9
  40. data/examples/root/etc/puppet/tagmail.conf +1 -0
  41. data/ext/emacs/puppet-mode.el +46 -1
  42. data/ext/logcheck/puppet +15 -0
  43. data/ext/module_puppet +15 -23
  44. data/ext/vim/puppet.vim +4 -2
  45. data/install.rb +2 -1
  46. data/lib/puppet.rb +76 -207
  47. data/lib/puppet/configuration.rb +331 -0
  48. data/lib/puppet/daemon.rb +63 -246
  49. data/lib/puppet/dsl.rb +371 -0
  50. data/lib/puppet/element.rb +8 -26
  51. data/lib/puppet/error.rb +54 -0
  52. data/lib/puppet/event.rb +8 -243
  53. data/lib/puppet/{base64.rb → external/base64.rb} +0 -0
  54. data/lib/puppet/external/event-loop.rb +1 -0
  55. data/lib/puppet/{event-loop → external/event-loop}/better-definers.rb +0 -0
  56. data/lib/puppet/{event-loop → external/event-loop}/event-loop.rb +2 -2
  57. data/lib/puppet/{event-loop → external/event-loop}/signal-system.rb +1 -1
  58. data/lib/puppet/external/gratr.rb +33 -0
  59. data/lib/puppet/external/gratr/adjacency_graph.rb +257 -0
  60. data/lib/puppet/external/gratr/base.rb +34 -0
  61. data/lib/puppet/external/gratr/biconnected.rb +116 -0
  62. data/lib/puppet/external/gratr/chinese_postman.rb +123 -0
  63. data/lib/puppet/external/gratr/common.rb +73 -0
  64. data/lib/puppet/external/gratr/comparability.rb +92 -0
  65. data/lib/puppet/external/gratr/digraph.rb +116 -0
  66. data/lib/puppet/external/gratr/digraph_distance.rb +185 -0
  67. data/lib/puppet/external/gratr/dot.rb +90 -0
  68. data/lib/puppet/external/gratr/edge.rb +145 -0
  69. data/lib/puppet/external/gratr/graph.rb +303 -0
  70. data/lib/puppet/external/gratr/graph_api.rb +83 -0
  71. data/lib/puppet/external/gratr/import.rb +44 -0
  72. data/lib/puppet/external/gratr/labels.rb +90 -0
  73. data/lib/puppet/external/gratr/maximum_flow.rb +64 -0
  74. data/lib/puppet/external/gratr/rdot.rb +327 -0
  75. data/lib/puppet/external/gratr/search.rb +409 -0
  76. data/lib/puppet/external/gratr/strong_components.rb +127 -0
  77. data/lib/puppet/external/gratr/undirected_graph.rb +153 -0
  78. data/lib/puppet/{lock.rb → external/lock.rb} +1 -1
  79. data/lib/puppet/feature/base.rb +20 -0
  80. data/lib/puppet/feature/rails.rb +52 -0
  81. data/lib/puppet/metatype/attributes.rb +719 -0
  82. data/lib/puppet/metatype/closure.rb +111 -0
  83. data/lib/puppet/metatype/container.rb +94 -0
  84. data/lib/puppet/metatype/evaluation.rb +118 -0
  85. data/lib/puppet/metatype/instances.rb +261 -0
  86. data/lib/puppet/metatype/manager.rb +169 -0
  87. data/lib/puppet/metatype/metaparams.rb +409 -0
  88. data/lib/puppet/metatype/providers.rb +260 -0
  89. data/lib/puppet/metatype/relationships.rb +116 -0
  90. data/lib/puppet/metatype/schedules.rb +39 -0
  91. data/lib/puppet/metatype/tags.rb +39 -0
  92. data/lib/puppet/modules.rb +113 -0
  93. data/lib/puppet/network/authconfig.rb +168 -0
  94. data/lib/puppet/network/authorization.rb +84 -0
  95. data/lib/puppet/network/authstore.rb +293 -0
  96. data/lib/puppet/network/client.rb +187 -0
  97. data/lib/puppet/network/client/ca.rb +56 -0
  98. data/lib/puppet/network/client/dipper.rb +81 -0
  99. data/lib/puppet/network/client/file.rb +7 -0
  100. data/lib/puppet/network/client/logger.rb +6 -0
  101. data/lib/puppet/network/client/master.rb +644 -0
  102. data/lib/puppet/{client → network/client}/proxy.rb +3 -3
  103. data/lib/puppet/{client/reporter.rb → network/client/report.rb} +4 -7
  104. data/lib/puppet/{client/pelement.rb → network/client/resource.rb} +6 -19
  105. data/lib/puppet/network/client/runner.rb +13 -0
  106. data/lib/puppet/network/client/status.rb +5 -0
  107. data/lib/puppet/network/client_request.rb +32 -0
  108. data/lib/puppet/network/handler.rb +33 -0
  109. data/lib/puppet/{server → network/handler}/ca.rb +5 -6
  110. data/lib/puppet/network/handler/filebucket.rb +180 -0
  111. data/lib/puppet/{server → network/handler}/fileserver.rb +277 -219
  112. data/lib/puppet/{server → network/handler}/logger.rb +3 -5
  113. data/lib/puppet/{server → network/handler}/master.rb +42 -8
  114. data/lib/puppet/network/handler/report.rb +158 -0
  115. data/lib/puppet/network/handler/resource.rb +190 -0
  116. data/lib/puppet/{server → network/handler}/runner.rb +17 -18
  117. data/lib/puppet/network/handler/status.rb +13 -0
  118. data/lib/puppet/network/rights.rb +74 -0
  119. data/lib/puppet/network/server.rb +5 -0
  120. data/lib/puppet/network/server/mongrel.rb +138 -0
  121. data/lib/puppet/network/server/webrick.rb +153 -0
  122. data/lib/puppet/network/xmlrpc/client.rb +129 -0
  123. data/lib/puppet/network/xmlrpc/processor.rb +91 -0
  124. data/lib/puppet/network/xmlrpc/server.rb +20 -0
  125. data/lib/puppet/network/xmlrpc/webrick_servlet.rb +121 -0
  126. data/lib/puppet/parameter.rb +390 -346
  127. data/lib/puppet/parser/ast.rb +116 -147
  128. data/lib/puppet/parser/ast/astarray.rb +17 -33
  129. data/lib/puppet/parser/ast/branch.rb +2 -0
  130. data/lib/puppet/parser/ast/caseopt.rb +7 -12
  131. data/lib/puppet/parser/ast/casestatement.rb +23 -32
  132. data/lib/puppet/parser/ast/collection.rb +19 -80
  133. data/lib/puppet/parser/ast/collexpr.rb +81 -0
  134. data/lib/puppet/parser/ast/component.rb +160 -89
  135. data/lib/puppet/parser/ast/else.rb +30 -0
  136. data/lib/puppet/parser/ast/function.rb +9 -2
  137. data/lib/puppet/parser/ast/hostclass.rb +47 -131
  138. data/lib/puppet/parser/ast/ifstatement.rb +43 -0
  139. data/lib/puppet/parser/ast/leaf.rb +10 -21
  140. data/lib/puppet/parser/ast/node.rb +32 -79
  141. data/lib/puppet/parser/ast/resourcedef.rb +222 -0
  142. data/lib/puppet/parser/ast/{typedefaults.rb → resourcedefaults.rb} +10 -16
  143. data/lib/puppet/parser/ast/resourceoverride.rb +62 -0
  144. data/lib/puppet/parser/ast/{objectparam.rb → resourceparam.rb} +12 -6
  145. data/lib/puppet/parser/ast/resourceref.rb +44 -0
  146. data/lib/puppet/parser/ast/selector.rb +16 -8
  147. data/lib/puppet/parser/ast/tag.rb +3 -1
  148. data/lib/puppet/parser/ast/vardef.rb +8 -12
  149. data/lib/puppet/parser/collector.rb +181 -0
  150. data/lib/puppet/parser/functions.rb +191 -36
  151. data/lib/puppet/parser/interpreter.rb +802 -380
  152. data/lib/puppet/parser/lexer.rb +86 -19
  153. data/lib/puppet/parser/parser.rb +1123 -960
  154. data/lib/puppet/parser/resource.rb +353 -0
  155. data/lib/puppet/parser/resource/param.rb +57 -0
  156. data/lib/puppet/parser/resource/reference.rb +71 -0
  157. data/lib/puppet/parser/scope.rb +573 -1000
  158. data/lib/puppet/parser/templatewrapper.rb +54 -0
  159. data/lib/puppet/pgraph.rb +208 -0
  160. data/lib/puppet/propertychange.rb +143 -0
  161. data/lib/puppet/provider.rb +302 -0
  162. data/lib/puppet/provider/cron/crontab.rb +187 -0
  163. data/lib/puppet/provider/group/groupadd.rb +29 -0
  164. data/lib/puppet/provider/group/netinfo.rb +12 -0
  165. data/lib/puppet/provider/group/pw.rb +31 -0
  166. data/lib/puppet/provider/host/netinfo.rb +18 -0
  167. data/lib/puppet/provider/host/parsed.rb +73 -0
  168. data/lib/puppet/provider/mount.rb +57 -0
  169. data/lib/puppet/provider/mount/netinfo.rb +38 -0
  170. data/lib/puppet/provider/mount/parsed.rb +37 -0
  171. data/lib/puppet/provider/nameservice.rb +344 -0
  172. data/lib/puppet/provider/nameservice/netinfo.rb +210 -0
  173. data/lib/puppet/provider/nameservice/objectadd.rb +45 -0
  174. data/lib/puppet/provider/nameservice/pw.rb +22 -0
  175. data/lib/puppet/provider/package/apple.rb +53 -0
  176. data/lib/puppet/provider/package/apt.rb +119 -0
  177. data/lib/puppet/provider/package/aptitude.rb +30 -0
  178. data/lib/puppet/provider/package/aptrpm.rb +79 -0
  179. data/lib/puppet/provider/package/blastwave.rb +114 -0
  180. data/lib/puppet/provider/package/darwinport.rb +88 -0
  181. data/lib/puppet/provider/package/dpkg.rb +109 -0
  182. data/lib/puppet/provider/package/freebsd.rb +43 -0
  183. data/lib/puppet/provider/package/gem.rb +104 -0
  184. data/lib/puppet/provider/package/openbsd.rb +93 -0
  185. data/lib/puppet/provider/package/pkgdmg.rb +119 -0
  186. data/lib/puppet/provider/package/portage.rb +112 -0
  187. data/lib/puppet/provider/package/ports.rb +94 -0
  188. data/lib/puppet/provider/package/rpm.rb +125 -0
  189. data/lib/puppet/provider/package/rug.rb +53 -0
  190. data/lib/puppet/provider/package/sun.rb +168 -0
  191. data/lib/puppet/provider/package/sunfreeware.rb +9 -0
  192. data/lib/puppet/provider/package/up2date.rb +45 -0
  193. data/lib/puppet/provider/package/yum.rb +54 -0
  194. data/lib/puppet/provider/parsedfile.rb +342 -0
  195. data/lib/puppet/provider/port/parsed.rb +174 -0
  196. data/lib/puppet/provider/service/base.rb +136 -0
  197. data/lib/puppet/provider/service/debian.rb +32 -0
  198. data/lib/puppet/provider/service/gentoo.rb +49 -0
  199. data/lib/puppet/{type → provider}/service/init.rb +42 -40
  200. data/lib/puppet/provider/service/redhat.rb +59 -0
  201. data/lib/puppet/{type → provider}/service/smf.rb +24 -13
  202. data/lib/puppet/provider/sshkey/parsed.rb +36 -0
  203. data/lib/puppet/provider/user/netinfo.rb +106 -0
  204. data/lib/puppet/provider/user/pw.rb +41 -0
  205. data/lib/puppet/provider/user/useradd.rb +67 -0
  206. data/lib/puppet/provider/zone/solaris.rb +208 -0
  207. data/lib/puppet/rails.rb +102 -66
  208. data/lib/puppet/rails/database/001_add_indexes.rb +38 -0
  209. data/lib/puppet/rails/database/schema.rb +89 -0
  210. data/lib/puppet/rails/external/tagging/acts_as_taggable.rb +62 -0
  211. data/lib/puppet/rails/external/tagging/init.rb +5 -0
  212. data/lib/puppet/rails/external/tagging/tag.rb +50 -0
  213. data/lib/puppet/rails/external/tagging/tagging.rb +12 -0
  214. data/lib/puppet/rails/fact_name.rb +7 -0
  215. data/lib/puppet/rails/fact_value.rb +5 -0
  216. data/lib/puppet/rails/host.rb +95 -46
  217. data/lib/puppet/rails/param_name.rb +28 -0
  218. data/lib/puppet/rails/param_value.rb +5 -0
  219. data/lib/puppet/rails/puppet_class.rb +9 -0
  220. data/lib/puppet/rails/resource.rb +95 -0
  221. data/lib/puppet/rails/source_file.rb +5 -0
  222. data/lib/puppet/relationship.rb +63 -0
  223. data/lib/puppet/reports/log.rb +14 -0
  224. data/lib/puppet/reports/rrdgraph.rb +114 -10
  225. data/lib/puppet/reports/store.rb +64 -0
  226. data/lib/puppet/reports/tagmail.rb +144 -71
  227. data/lib/puppet/sslcertificates.rb +38 -5
  228. data/lib/puppet/sslcertificates/ca.rb +142 -37
  229. data/lib/puppet/sslcertificates/certificate.rb +3 -3
  230. data/lib/puppet/sslcertificates/inventory.rb +53 -0
  231. data/lib/puppet/sslcertificates/support.rb +128 -0
  232. data/lib/puppet/transaction.rb +568 -189
  233. data/lib/puppet/transaction/report.rb +14 -3
  234. data/lib/puppet/transportable.rb +18 -10
  235. data/lib/puppet/type.rb +279 -2299
  236. data/lib/puppet/type/component.rb +63 -63
  237. data/lib/puppet/type/cron.rb +294 -710
  238. data/lib/puppet/type/exec.rb +185 -129
  239. data/lib/puppet/type/group.rb +38 -89
  240. data/lib/puppet/type/host.rb +110 -0
  241. data/lib/puppet/type/mount.rb +189 -0
  242. data/lib/puppet/type/notify.rb +47 -0
  243. data/lib/puppet/type/package.rb +129 -257
  244. data/lib/puppet/type/parsedtype.rb +172 -297
  245. data/lib/puppet/type/pfile.rb +540 -319
  246. data/lib/puppet/type/pfile/checksum.rb +103 -76
  247. data/lib/puppet/type/pfile/content.rb +16 -10
  248. data/lib/puppet/type/pfile/ensure.rb +52 -34
  249. data/lib/puppet/type/pfile/group.rb +25 -18
  250. data/lib/puppet/type/pfile/mode.rb +7 -4
  251. data/lib/puppet/type/pfile/{uid.rb → owner.rb} +21 -17
  252. data/lib/puppet/type/pfile/source.rb +119 -124
  253. data/lib/puppet/type/pfile/target.rb +29 -45
  254. data/lib/puppet/type/pfile/type.rb +2 -2
  255. data/lib/puppet/type/pfilebucket.rb +18 -14
  256. data/lib/puppet/type/port.rb +121 -0
  257. data/lib/puppet/type/property.rb +530 -0
  258. data/lib/puppet/type/resources.rb +150 -0
  259. data/lib/puppet/type/schedule.rb +38 -22
  260. data/lib/puppet/type/service.rb +70 -326
  261. data/lib/puppet/type/sshkey.rb +76 -0
  262. data/lib/puppet/type/tidy.rb +197 -97
  263. data/lib/puppet/type/user.rb +107 -183
  264. data/lib/puppet/type/yumrepo.rb +53 -34
  265. data/lib/puppet/type/zone.rb +55 -208
  266. data/lib/puppet/util.rb +239 -201
  267. data/lib/puppet/util/autoload.rb +107 -0
  268. data/lib/puppet/util/classgen.rb +208 -0
  269. data/lib/puppet/{config.rb → util/config.rb} +102 -54
  270. data/lib/puppet/util/docs.rb +104 -0
  271. data/lib/puppet/util/errors.rb +55 -0
  272. data/lib/puppet/util/execution.rb +22 -0
  273. data/lib/puppet/util/feature.rb +76 -0
  274. data/lib/puppet/util/fileparsing.rb +380 -0
  275. data/lib/puppet/util/filetype.rb +300 -0
  276. data/lib/puppet/util/graph.rb +39 -0
  277. data/lib/puppet/util/inifile.rb +209 -0
  278. data/lib/puppet/util/loadedfile.rb +71 -0
  279. data/lib/puppet/util/log.rb +549 -0
  280. data/lib/puppet/util/logging.rb +20 -0
  281. data/lib/puppet/util/metaid.rb +22 -0
  282. data/lib/puppet/util/methodhelper.rb +37 -0
  283. data/lib/puppet/util/metric.rb +160 -0
  284. data/lib/puppet/util/package.rb +31 -0
  285. data/lib/puppet/util/pidlock.rb +68 -0
  286. data/lib/puppet/util/plist.rb +24 -0
  287. data/lib/puppet/util/plist/generator.rb +226 -0
  288. data/lib/puppet/util/plist/parser.rb +227 -0
  289. data/lib/puppet/util/posix.rb +87 -0
  290. data/lib/puppet/util/provider_features.rb +170 -0
  291. data/lib/puppet/util/rails/collection_merger.rb +42 -0
  292. data/lib/puppet/util/storage.rb +103 -0
  293. data/lib/puppet/util/subclass_loader.rb +83 -0
  294. data/lib/puppet/util/suidmanager.rb +86 -0
  295. data/lib/puppet/util/variables.rb +39 -0
  296. data/lib/puppet/util/warnings.rb +15 -0
  297. data/test/Rakefile +97 -0
  298. data/test/certmgr/ca.rb +81 -0
  299. data/test/certmgr/certmgr.rb +77 -50
  300. data/test/certmgr/inventory.rb +79 -0
  301. data/test/certmgr/support.rb +81 -0
  302. data/test/executables/filebucket.rb +49 -0
  303. data/test/executables/puppetbin.rb +28 -12
  304. data/test/executables/puppetca.rb +75 -54
  305. data/test/executables/puppetd.rb +10 -13
  306. data/test/executables/puppetmasterd.rb +12 -17
  307. data/test/executables/puppetmodule.rb +18 -17
  308. data/test/language/ast.rb +242 -798
  309. data/test/language/ast/casestatement.rb +104 -0
  310. data/test/language/ast/component.rb +133 -0
  311. data/test/language/ast/hostclass.rb +162 -0
  312. data/test/language/ast/selector.rb +62 -0
  313. data/test/language/ast/variable.rb +31 -0
  314. data/test/language/collector.rb +369 -0
  315. data/test/language/functions.rb +305 -18
  316. data/test/language/interpreter.rb +894 -125
  317. data/test/language/lexer.rb +98 -12
  318. data/test/language/node.rb +37 -53
  319. data/test/language/parser.rb +455 -148
  320. data/test/language/resource.rb +535 -0
  321. data/test/language/scope.rb +451 -561
  322. data/test/language/snippets.rb +101 -111
  323. data/test/language/transportable.rb +6 -8
  324. data/test/lib/mocha.rb +19 -0
  325. data/test/lib/mocha/any_instance_method.rb +35 -0
  326. data/test/lib/mocha/auto_verify.rb +113 -0
  327. data/test/lib/mocha/central.rb +35 -0
  328. data/test/lib/mocha/class_method.rb +62 -0
  329. data/test/lib/mocha/expectation.rb +295 -0
  330. data/test/lib/mocha/expectation_error.rb +6 -0
  331. data/test/lib/mocha/infinite_range.rb +27 -0
  332. data/test/lib/mocha/inspect.rb +37 -0
  333. data/test/lib/mocha/instance_method.rb +8 -0
  334. data/test/lib/mocha/metaclass.rb +7 -0
  335. data/test/lib/mocha/mock.rb +20 -0
  336. data/test/lib/mocha/mock_methods.rb +122 -0
  337. data/test/lib/mocha/object.rb +100 -0
  338. data/test/lib/mocha/pretty_parameters.rb +28 -0
  339. data/test/lib/mocha/setup_and_teardown.rb +23 -0
  340. data/test/lib/mocha/standalone.rb +30 -0
  341. data/test/lib/mocha/test_case_adapter.rb +49 -0
  342. data/test/lib/mocha_standalone.rb +2 -0
  343. data/test/lib/puppettest.rb +294 -0
  344. data/test/lib/puppettest/certificates.rb +61 -0
  345. data/test/lib/puppettest/exetest.rb +123 -0
  346. data/test/lib/puppettest/fakes.rb +194 -0
  347. data/test/lib/puppettest/fileparsing.rb +33 -0
  348. data/test/lib/puppettest/filetesting.rb +231 -0
  349. data/test/lib/puppettest/graph.rb +41 -0
  350. data/test/lib/puppettest/parsertesting.rb +392 -0
  351. data/test/lib/puppettest/railstesting.rb +56 -0
  352. data/test/lib/puppettest/reporttesting.rb +19 -0
  353. data/test/lib/puppettest/resourcetesting.rb +73 -0
  354. data/test/lib/puppettest/servertest.rb +72 -0
  355. data/test/lib/puppettest/support.rb +8 -0
  356. data/test/lib/puppettest/support/assertions.rb +101 -0
  357. data/test/lib/puppettest/support/helpers.rb +23 -0
  358. data/test/lib/puppettest/support/resources.rb +37 -0
  359. data/test/lib/puppettest/support/utils.rb +160 -0
  360. data/test/lib/puppettest/testcase.rb +48 -0
  361. data/test/lib/rake/puppet_test_loader.rb +17 -0
  362. data/test/lib/rake/puppet_testtask.rb +17 -0
  363. data/test/lib/spec.rb +8 -0
  364. data/test/lib/spec/callback.rb +11 -0
  365. data/test/lib/spec/callback/callback_container.rb +60 -0
  366. data/test/lib/spec/callback/extensions/module.rb +24 -0
  367. data/test/lib/spec/callback/extensions/object.rb +37 -0
  368. data/test/lib/spec/deprecated.rb +3 -0
  369. data/test/lib/spec/expectations.rb +59 -0
  370. data/test/lib/spec/expectations/differs/default.rb +62 -0
  371. data/test/lib/spec/expectations/errors.rb +6 -0
  372. data/test/lib/spec/expectations/extensions.rb +3 -0
  373. data/test/lib/spec/expectations/extensions/object.rb +109 -0
  374. data/test/lib/spec/expectations/extensions/proc.rb +57 -0
  375. data/test/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  376. data/test/lib/spec/expectations/handler.rb +47 -0
  377. data/test/lib/spec/expectations/should.rb +5 -0
  378. data/test/lib/spec/expectations/should/base.rb +64 -0
  379. data/test/lib/spec/expectations/should/change.rb +69 -0
  380. data/test/lib/spec/expectations/should/have.rb +128 -0
  381. data/test/lib/spec/expectations/should/not.rb +74 -0
  382. data/test/lib/spec/expectations/should/should.rb +81 -0
  383. data/test/lib/spec/expectations/sugar.rb +47 -0
  384. data/test/lib/spec/matchers.rb +160 -0
  385. data/test/lib/spec/matchers/be.rb +161 -0
  386. data/test/lib/spec/matchers/be_close.rb +37 -0
  387. data/test/lib/spec/matchers/change.rb +120 -0
  388. data/test/lib/spec/matchers/eql.rb +43 -0
  389. data/test/lib/spec/matchers/equal.rb +43 -0
  390. data/test/lib/spec/matchers/has.rb +44 -0
  391. data/test/lib/spec/matchers/have.rb +140 -0
  392. data/test/lib/spec/matchers/include.rb +50 -0
  393. data/test/lib/spec/matchers/match.rb +41 -0
  394. data/test/lib/spec/matchers/raise_error.rb +100 -0
  395. data/test/lib/spec/matchers/respond_to.rb +35 -0
  396. data/test/lib/spec/matchers/satisfy.rb +47 -0
  397. data/test/lib/spec/matchers/throw_symbol.rb +75 -0
  398. data/test/lib/spec/mocks.rb +232 -0
  399. data/test/lib/spec/mocks/argument_expectation.rb +132 -0
  400. data/test/lib/spec/mocks/error_generator.rb +85 -0
  401. data/test/lib/spec/mocks/errors.rb +10 -0
  402. data/test/lib/spec/mocks/extensions/object.rb +3 -0
  403. data/test/lib/spec/mocks/message_expectation.rb +231 -0
  404. data/test/lib/spec/mocks/methods.rb +40 -0
  405. data/test/lib/spec/mocks/mock.rb +26 -0
  406. data/test/lib/spec/mocks/mock_handler.rb +166 -0
  407. data/test/lib/spec/mocks/order_group.rb +29 -0
  408. data/test/lib/spec/rake/spectask.rb +173 -0
  409. data/test/lib/spec/rake/verify_rcov.rb +47 -0
  410. data/test/lib/spec/runner.rb +132 -0
  411. data/test/lib/spec/runner/backtrace_tweaker.rb +55 -0
  412. data/test/lib/spec/runner/command_line.rb +34 -0
  413. data/test/lib/spec/runner/context.rb +154 -0
  414. data/test/lib/spec/runner/context_eval.rb +142 -0
  415. data/test/lib/spec/runner/context_runner.rb +55 -0
  416. data/test/lib/spec/runner/drb_command_line.rb +21 -0
  417. data/test/lib/spec/runner/execution_context.rb +17 -0
  418. data/test/lib/spec/runner/extensions/kernel.rb +17 -0
  419. data/test/lib/spec/runner/extensions/object.rb +32 -0
  420. data/test/lib/spec/runner/formatter.rb +5 -0
  421. data/test/lib/spec/runner/formatter/base_text_formatter.rb +118 -0
  422. data/test/lib/spec/runner/formatter/html_formatter.rb +219 -0
  423. data/test/lib/spec/runner/formatter/progress_bar_formatter.rb +27 -0
  424. data/test/lib/spec/runner/formatter/rdoc_formatter.rb +22 -0
  425. data/test/lib/spec/runner/formatter/specdoc_formatter.rb +23 -0
  426. data/test/lib/spec/runner/heckle_runner.rb +71 -0
  427. data/test/lib/spec/runner/heckle_runner_win.rb +10 -0
  428. data/test/lib/spec/runner/option_parser.rb +224 -0
  429. data/test/lib/spec/runner/reporter.rb +105 -0
  430. data/test/lib/spec/runner/spec_matcher.rb +25 -0
  431. data/test/lib/spec/runner/spec_parser.rb +41 -0
  432. data/test/lib/spec/runner/spec_should_raise_handler.rb +74 -0
  433. data/test/lib/spec/runner/specification.rb +114 -0
  434. data/test/lib/spec/translator.rb +87 -0
  435. data/test/lib/spec/version.rb +30 -0
  436. data/test/lib/stubba.rb +2 -0
  437. data/test/network/authconfig.rb +72 -0
  438. data/test/network/authorization.rb +138 -0
  439. data/test/network/authstore.rb +450 -0
  440. data/test/network/client/ca.rb +38 -0
  441. data/test/{client → network/client}/client.rb +107 -24
  442. data/test/network/client/dipper.rb +35 -0
  443. data/test/network/client/master.rb +627 -0
  444. data/test/{client/pelement.rb → network/client/resource.rb} +13 -29
  445. data/test/network/client_request.rb +39 -0
  446. data/test/network/daemon.rb +71 -0
  447. data/test/{server → network/handler}/bucket.rb +103 -27
  448. data/test/{server → network/handler}/ca.rb +14 -19
  449. data/test/{server → network/handler}/fileserver.rb +443 -68
  450. data/test/network/handler/handler.rb +64 -0
  451. data/test/{server → network/handler}/logger.rb +26 -26
  452. data/test/network/handler/master.rb +352 -0
  453. data/test/network/handler/report.rb +185 -0
  454. data/test/{server/pelement.rb → network/handler/resource.rb} +25 -38
  455. data/test/{server → network/handler}/runner.rb +17 -16
  456. data/test/network/rights.rb +38 -0
  457. data/test/network/server/webrick.rb +140 -0
  458. data/test/network/xmlrpc/client.rb +68 -0
  459. data/test/network/xmlrpc/processor.rb +80 -0
  460. data/test/network/xmlrpc/server.rb +28 -0
  461. data/test/network/xmlrpc/webrick_servlet.rb +26 -0
  462. data/test/other/dsl.rb +218 -0
  463. data/test/other/events.rb +22 -15
  464. data/test/other/overrides.rb +9 -14
  465. data/test/other/pgraph.rb +289 -0
  466. data/test/other/propertychange.rb +142 -0
  467. data/test/other/provider.rb +162 -0
  468. data/test/other/puppet.rb +63 -10
  469. data/test/other/relationship.rb +74 -0
  470. data/test/other/relationships.rb +199 -123
  471. data/test/other/report.rb +152 -23
  472. data/test/other/transactions.rb +824 -78
  473. data/test/puppet/conffiles.rb +16 -11
  474. data/test/puppet/defaults.rb +7 -10
  475. data/test/puppet/{error.rb → errortest.rb} +5 -8
  476. data/test/puppet/modules.rb +58 -0
  477. data/test/puppet/tc_suidmanager.rb +107 -0
  478. data/test/rails/host.rb +177 -0
  479. data/test/rails/rails.rb +27 -0
  480. data/test/rails/railsparameter.rb +62 -0
  481. data/test/rails/railsresource.rb +100 -0
  482. data/test/ral/manager/attributes.rb +296 -0
  483. data/test/ral/manager/manager.rb +55 -0
  484. data/test/ral/manager/provider.rb +54 -0
  485. data/test/ral/manager/type.rb +837 -0
  486. data/test/ral/providers/cron/crontab.rb +346 -0
  487. data/test/ral/providers/group.rb +252 -0
  488. data/test/ral/providers/host/netinfo.rb +58 -0
  489. data/test/ral/providers/host/parsed.rb +226 -0
  490. data/test/ral/providers/mount/netinfo.rb +80 -0
  491. data/test/ral/providers/mount/parsed.rb +223 -0
  492. data/test/ral/providers/nameservice.rb +33 -0
  493. data/test/ral/providers/package.rb +253 -0
  494. data/test/ral/providers/package/apt.rb +89 -0
  495. data/test/ral/providers/package/aptitude.rb +69 -0
  496. data/test/ral/providers/package/aptrpm.rb +89 -0
  497. data/test/ral/providers/package/dpkg.rb +64 -0
  498. data/test/ral/providers/parsedfile.rb +668 -0
  499. data/test/ral/providers/parsedport.rb +233 -0
  500. data/test/ral/providers/provider.rb +423 -0
  501. data/test/{types → ral/providers}/service.rb +20 -121
  502. data/test/ral/providers/service/base.rb +75 -0
  503. data/test/ral/providers/sshkey/parsed.rb +111 -0
  504. data/test/ral/providers/user.rb +567 -0
  505. data/test/ral/providers/user/useradd.rb +250 -0
  506. data/test/ral/types/basic.rb +90 -0
  507. data/test/ral/types/component.rb +113 -0
  508. data/test/ral/types/cron.rb +480 -0
  509. data/test/{types → ral/types}/exec.rb +278 -82
  510. data/test/ral/types/file.rb +1799 -0
  511. data/test/ral/types/file/target.rb +363 -0
  512. data/test/{types → ral/types}/filebucket.rb +15 -17
  513. data/test/{types → ral/types}/fileignoresource.rb +9 -15
  514. data/test/ral/types/filesources.rb +1046 -0
  515. data/test/ral/types/group.rb +169 -0
  516. data/test/ral/types/host.rb +155 -0
  517. data/test/ral/types/mount.rb +312 -0
  518. data/test/ral/types/package.rb +85 -0
  519. data/test/ral/types/parameter.rb +172 -0
  520. data/test/ral/types/port.rb +148 -0
  521. data/test/ral/types/property.rb +343 -0
  522. data/test/ral/types/resources.rb +221 -0
  523. data/test/{types → ral/types}/schedule.rb +34 -12
  524. data/test/ral/types/service.rb +37 -0
  525. data/test/{types → ral/types}/sshkey.rb +75 -65
  526. data/test/ral/types/tidy.rb +240 -0
  527. data/test/ral/types/user.rb +493 -0
  528. data/test/{types → ral/types}/yumrepo.rb +7 -11
  529. data/test/{types → ral/types}/zone.rb +45 -45
  530. data/test/tagging/tagging.rb +17 -26
  531. data/test/util/autoload.rb +130 -0
  532. data/test/util/classgen.rb +227 -0
  533. data/test/{other → util}/config.rb +373 -113
  534. data/test/util/execution.rb +34 -0
  535. data/test/util/features.rb +94 -0
  536. data/test/util/fileparsing.rb +677 -0
  537. data/test/{other → util}/filetype.rb +9 -12
  538. data/test/util/graph.rb +108 -0
  539. data/test/{other → util}/inifile.rb +24 -11
  540. data/test/util/loadedfile.rb +106 -0
  541. data/test/{other → util}/log.rb +96 -50
  542. data/test/{other → util}/metrics.rb +7 -17
  543. data/test/util/package.rb +27 -0
  544. data/test/util/pidlock.rb +126 -0
  545. data/test/util/posixtest.rb +173 -0
  546. data/test/util/storage.rb +123 -0
  547. data/test/util/subclass_loader.rb +100 -0
  548. data/test/util/utiltest.rb +368 -0
  549. metadata +449 -169
  550. data/examples/code/classing +0 -35
  551. data/examples/code/failers/badclassnoparam +0 -10
  552. data/examples/code/failers/badclassparam +0 -10
  553. data/examples/code/failers/badcompnoparam +0 -9
  554. data/examples/code/failers/badcompparam +0 -9
  555. data/examples/code/failers/badtypeparam +0 -3
  556. data/examples/code/failers/noobjectrvalue +0 -1
  557. data/examples/code/snippets/aliastest.pp +0 -16
  558. data/examples/code/snippets/argumentdefaults +0 -14
  559. data/examples/code/snippets/casestatement.pp +0 -58
  560. data/examples/code/snippets/classheirarchy.pp +0 -15
  561. data/examples/code/snippets/classincludes.pp +0 -17
  562. data/examples/code/snippets/classpathtest +0 -11
  563. data/examples/code/snippets/componentmetaparams.pp +0 -11
  564. data/examples/code/snippets/deepclassheirarchy.pp +0 -23
  565. data/examples/code/snippets/defineoverrides.pp +0 -17
  566. data/examples/code/snippets/dirchmod +0 -19
  567. data/examples/code/snippets/emptyclass.pp +0 -9
  568. data/examples/code/snippets/emptyexec.pp +0 -3
  569. data/examples/code/snippets/failmissingexecpath.pp +0 -13
  570. data/examples/code/snippets/falsevalues.pp +0 -3
  571. data/examples/code/snippets/filecreate +0 -11
  572. data/examples/code/snippets/implicititeration +0 -15
  573. data/examples/code/snippets/multipleinstances +0 -7
  574. data/examples/code/snippets/namevartest +0 -9
  575. data/examples/code/snippets/scopetest +0 -13
  576. data/examples/code/snippets/selectorvalues.pp +0 -42
  577. data/examples/code/snippets/simpledefaults +0 -5
  578. data/examples/code/snippets/simpleselector +0 -38
  579. data/examples/code/snippets/singleary.pp +0 -19
  580. data/examples/code/snippets/singlequote.pp +0 -11
  581. data/examples/code/snippets/singleselector.pp +0 -22
  582. data/examples/code/snippets/tag.pp +0 -9
  583. data/examples/code/snippets/tagged.pp +0 -35
  584. data/lib/puppet/client.rb +0 -177
  585. data/lib/puppet/client/ca.rb +0 -21
  586. data/lib/puppet/client/dipper.rb +0 -76
  587. data/lib/puppet/client/file.rb +0 -20
  588. data/lib/puppet/client/log.rb +0 -17
  589. data/lib/puppet/client/master.rb +0 -531
  590. data/lib/puppet/client/runner.rb +0 -17
  591. data/lib/puppet/client/status.rb +0 -7
  592. data/lib/puppet/event-loop.rb +0 -1
  593. data/lib/puppet/filetype.rb +0 -308
  594. data/lib/puppet/inifile.rb +0 -201
  595. data/lib/puppet/log.rb +0 -524
  596. data/lib/puppet/metric.rb +0 -132
  597. data/lib/puppet/networkclient.rb +0 -175
  598. data/lib/puppet/parsedfile.rb +0 -58
  599. data/lib/puppet/parser/ast/classdef.rb +0 -79
  600. data/lib/puppet/parser/ast/compdef.rb +0 -75
  601. data/lib/puppet/parser/ast/nodedef.rb +0 -73
  602. data/lib/puppet/parser/ast/objectdef.rb +0 -284
  603. data/lib/puppet/parser/ast/objectref.rb +0 -77
  604. data/lib/puppet/rails/database.rb +0 -40
  605. data/lib/puppet/rails/rails_object.rb +0 -42
  606. data/lib/puppet/rails/rails_parameter.rb +0 -5
  607. data/lib/puppet/server.rb +0 -196
  608. data/lib/puppet/server/authconfig.rb +0 -177
  609. data/lib/puppet/server/authstore.rb +0 -226
  610. data/lib/puppet/server/filebucket.rb +0 -155
  611. data/lib/puppet/server/pelement.rb +0 -188
  612. data/lib/puppet/server/report.rb +0 -184
  613. data/lib/puppet/server/rights.rb +0 -78
  614. data/lib/puppet/server/servlet.rb +0 -274
  615. data/lib/puppet/statechange.rb +0 -129
  616. data/lib/puppet/storage.rb +0 -98
  617. data/lib/puppet/type/nameservice.rb +0 -264
  618. data/lib/puppet/type/nameservice/netinfo.rb +0 -232
  619. data/lib/puppet/type/nameservice/objectadd.rb +0 -146
  620. data/lib/puppet/type/nameservice/posix.rb +0 -12
  621. data/lib/puppet/type/nameservice/pw.rb +0 -107
  622. data/lib/puppet/type/package/apple.rb +0 -41
  623. data/lib/puppet/type/package/apt.rb +0 -107
  624. data/lib/puppet/type/package/blastwave.rb +0 -136
  625. data/lib/puppet/type/package/darwinport.rb +0 -97
  626. data/lib/puppet/type/package/dpkg.rb +0 -113
  627. data/lib/puppet/type/package/freebsd.rb +0 -19
  628. data/lib/puppet/type/package/gem.rb +0 -119
  629. data/lib/puppet/type/package/openbsd.rb +0 -112
  630. data/lib/puppet/type/package/ports.rb +0 -103
  631. data/lib/puppet/type/package/rpm.rb +0 -121
  632. data/lib/puppet/type/package/sun.rb +0 -174
  633. data/lib/puppet/type/package/sunfreeware.rb +0 -7
  634. data/lib/puppet/type/package/yum.rb +0 -52
  635. data/lib/puppet/type/parsedtype/host.rb +0 -144
  636. data/lib/puppet/type/parsedtype/mount.rb +0 -271
  637. data/lib/puppet/type/parsedtype/port.rb +0 -261
  638. data/lib/puppet/type/parsedtype/sshkey.rb +0 -123
  639. data/lib/puppet/type/service/base.rb +0 -12
  640. data/lib/puppet/type/service/debian.rb +0 -46
  641. data/lib/puppet/type/service/redhat.rb +0 -38
  642. data/lib/puppet/type/state.rb +0 -393
  643. data/lib/puppet/type/symlink.rb +0 -186
  644. data/test/client/master.rb +0 -207
  645. data/test/language/rails.rb +0 -105
  646. data/test/other/parsedfile.rb +0 -58
  647. data/test/other/storage.rb +0 -100
  648. data/test/puppet/utiltest.rb +0 -299
  649. data/test/puppettest.rb +0 -1170
  650. data/test/server/authconfig.rb +0 -56
  651. data/test/server/authstore.rb +0 -218
  652. data/test/server/master.rb +0 -201
  653. data/test/server/report.rb +0 -93
  654. data/test/server/rights.rb +0 -41
  655. data/test/server/server.rb +0 -152
  656. data/test/test +0 -61
  657. data/test/types/basic.rb +0 -117
  658. data/test/types/component.rb +0 -298
  659. data/test/types/cron.rb +0 -718
  660. data/test/types/file.rb +0 -1314
  661. data/test/types/filesources.rb +0 -590
  662. data/test/types/group.rb +0 -323
  663. data/test/types/host.rb +0 -186
  664. data/test/types/mount.rb +0 -294
  665. data/test/types/package.rb +0 -538
  666. data/test/types/parameter.rb +0 -107
  667. data/test/types/port.rb +0 -201
  668. data/test/types/query.rb +0 -101
  669. data/test/types/state.rb +0 -92
  670. data/test/types/symlink.rb +0 -120
  671. data/test/types/tidy.rb +0 -102
  672. data/test/types/type.rb +0 -469
  673. data/test/types/user.rb +0 -563
@@ -3,11 +3,12 @@ require 'cgi'
3
3
  require 'etc'
4
4
  require 'uri'
5
5
  require 'fileutils'
6
- require 'puppet/type/state'
7
- require 'puppet/server/fileserver'
6
+ require 'puppet/type/property'
7
+ require 'puppet/network/handler'
8
8
 
9
9
  module Puppet
10
10
  newtype(:file) do
11
+ include Puppet::Util::MethodHelper
11
12
  @doc = "Manages local files, including setting ownership and
12
13
  permissions, creation of both files and directories, and
13
14
  retrieving entire files from remote servers. As Puppet matures, it
@@ -32,13 +33,20 @@ module Puppet
32
33
 
33
34
  newparam(:backup) do
34
35
  desc "Whether files should be backed up before
35
- being replaced. If a filebucket is specified, files will be
36
- backed up there; else, they will be backed up in the same directory
37
- with a ``.puppet-bak`` extension,, and no backups
38
- will be made if backup is ``false``.
36
+ being replaced. The preferred method of backing files up is via
37
+ a ``filebucket``, which stores files by their MD5 sums and allows
38
+ easy retrieval without littering directories with backups. You
39
+ can specify a local filebucket or a network-accessible
40
+ server-based filebucket by setting ``backup => bucket-name``.
41
+ Alternatively, if you specify any value that begins with a ``.``
42
+ (e.g., ``.puppet-bak``), then Puppet will use copy the file in
43
+ the same directory with that value as the extension of the
44
+ backup. Setting ``backup => false`` disables all backups of the
45
+ file in question.
39
46
 
40
- To use filebuckets, you must first create a filebucket in your
41
- configuration:
47
+ Puppet automatically creates a local filebucket named ``puppet`` and
48
+ defaults to backing up there. To use a server-based filebucket,
49
+ you must specify one in your configuration::
42
50
 
43
51
  filebucket { main:
44
52
  server => puppet
@@ -47,7 +55,7 @@ module Puppet
47
55
  The ``puppetmasterd`` daemon creates a filebucket by default,
48
56
  so you can usually back up to your main server with this
49
57
  configuration. Once you've described the bucket in your
50
- configuration, you can use it in any file:
58
+ configuration, you can use it in any file::
51
59
 
52
60
  file { \"/my/file\":
53
61
  source => \"/path/in/nfs/or/something\",
@@ -56,7 +64,7 @@ module Puppet
56
64
 
57
65
  This will back the file up to the central server.
58
66
 
59
- At this point, the only benefits to doing so are that you do not
67
+ At this point, the benefits of using a filebucket are that you do not
60
68
  have backup files lying around on each of your machines, a given
61
69
  version of a file is only backed up once, and you can restore
62
70
  any given file manually, no matter how old. Eventually,
@@ -64,37 +72,46 @@ module Puppet
64
72
  filebucketed files.
65
73
  "
66
74
 
67
- attr_reader :bucket
68
- defaultto ".puppet-bak"
69
-
75
+ defaultto do
76
+ # Make sure the default file bucket exists.
77
+ obj = Puppet::Type.type(:filebucket)["puppet"] ||
78
+ Puppet::Type.type(:filebucket).create(:name => "puppet")
79
+ obj.bucket
80
+ end
81
+
70
82
  munge do |value|
83
+ # I don't really know how this is happening.
84
+ if value.is_a?(Array)
85
+ value = value.shift
86
+ end
71
87
  case value
72
88
  when false, "false", :false:
73
89
  false
74
90
  when true, "true", ".puppet-bak", :true:
75
91
  ".puppet-bak"
92
+ when /^\./
93
+ value
76
94
  when String:
77
95
  # We can't depend on looking this up right now,
78
96
  # we have to do it after all of the objects
79
97
  # have been instantiated.
80
- @bucket = value
81
- value
98
+ if bucketobj = Puppet::Type.type(:filebucket)[value]
99
+ @parent.bucket = bucketobj.bucket
100
+ bucketobj.title
101
+ else
102
+ # Set it to the string; finish() turns it into a
103
+ # filebucket.
104
+ @parent.bucket = value
105
+ value
106
+ end
107
+ when Puppet::Network::Client.client(:Dipper):
108
+ @parent.bucket = value
109
+ value.name
82
110
  else
83
111
  self.fail "Invalid backup type %s" %
84
112
  value.inspect
85
113
  end
86
114
  end
87
-
88
- # Provide a straight-through hook for setting the bucket.
89
- def bucket=(bucket)
90
- @value = bucket
91
- @bucket = bucket
92
- end
93
- end
94
-
95
- newparam(:linkmaker) do
96
- desc "An internal parameter used by the *symlink*
97
- type to do recursive link creation."
98
115
  end
99
116
 
100
117
  newparam(:recurse) do
@@ -102,17 +119,40 @@ module Puppet
102
119
  management."
103
120
 
104
121
  newvalues(:true, :false, :inf, /^[0-9]+$/)
122
+
123
+ # Replace the validation so that we allow numbers in
124
+ # addition to string representations of them.
125
+ validate { |arg| }
105
126
  munge do |value|
106
127
  newval = super(value)
107
128
  case newval
108
129
  when :true, :inf: true
109
130
  when :false: false
131
+ when Integer, Fixnum, Bignum: value
132
+ when /^\d+$/: Integer(value)
110
133
  else
111
- newval
134
+ raise ArgumentError, "Invalid recurse value %s" % value.inspect
112
135
  end
113
136
  end
114
137
  end
115
138
 
139
+ newparam(:replace, :boolean => true) do
140
+ desc "Whether or not to replace a file that is
141
+ sourced but exists. This is useful for using file sources
142
+ purely for initialization."
143
+ newvalues(:true, :false)
144
+ aliasvalue(:yes, :true)
145
+ aliasvalue(:no, :false)
146
+ defaultto :true
147
+ end
148
+
149
+ newparam(:force, :boolean => true) do
150
+ desc "Force the file operation. Currently only used when replacing
151
+ directories with links."
152
+ newvalues(:true, :false)
153
+ defaultto false
154
+ end
155
+
116
156
  newparam(:ignore) do
117
157
  desc "A parameter which omits action on files matching
118
158
  specified patterns during recursion. Uses Ruby's builtin globbing
@@ -145,26 +185,78 @@ module Puppet
145
185
  defaultto :ignore
146
186
  end
147
187
 
148
- autorequire(:file) do
149
- cur = []
150
- pary = self[:path].split(File::SEPARATOR)
151
- pary.shift # remove the initial nil
152
- pary.pop # remove us
188
+ newparam(:purge, :boolean => true) do
189
+ desc "Whether unmanaged files should be purged. If you have a filebucket
190
+ configured the purged files will be uploaded, but if you do not,
191
+ this will destroy data. Only use this option for generated
192
+ files unless you really know what you are doing. This option only
193
+ makes sense when recursively managing directories.
194
+
195
+ Note that when using ``purge`` with ``source``, Puppet will purge any files
196
+ that are not on the remote system."
153
197
 
154
- pary.inject([""]) do |ary, dir|
155
- ary << dir
156
- cur << ary.join(File::SEPARATOR)
157
- ary
198
+ defaultto :false
199
+
200
+ newvalues(:true, :false)
201
+ end
202
+
203
+ newparam(:sourceselect) do
204
+ desc "Whether to copy all valid sources, or just the first one. This parameter
205
+ is only used in recursive copies; by default, the first valid source is the
206
+ only one used as a recursive source, but if this parameter is set to ``all``,
207
+ then all valid sources will have all of their contents copied to the local host,
208
+ and for sources that have the same file, the source earlier in the list will
209
+ be used."
210
+
211
+ defaultto :first
212
+
213
+ newvalues(:first, :all)
214
+ end
215
+
216
+ attr_accessor :bucket
217
+
218
+ # Autorequire any parent directories.
219
+ autorequire(:file) do
220
+ if self[:path]
221
+ File.dirname(self[:path])
222
+ else
223
+ Puppet.err "no path for %s, somehow; cannot setup autorequires" % self.ref
224
+ nil
158
225
  end
226
+ end
159
227
 
160
- cur
228
+ # Autorequire the owner and group of the file.
229
+ {:user => :owner, :group => :group}.each do |type, property|
230
+ autorequire(type) do
231
+ if @parameters.include?(property)
232
+ # The user/group property automatically converts to IDs
233
+ next unless should = @parameters[property].shouldorig
234
+ val = should[0]
235
+ if val.is_a?(Integer) or val =~ /^\d+$/
236
+ nil
237
+ else
238
+ val
239
+ end
240
+ end
241
+ end
161
242
  end
243
+
244
+ CREATORS = [:content, :source, :target]
162
245
 
163
246
  validate do
164
- if self[:content] and self[:source]
165
- self.fail "You cannot specify both content and a source"
247
+ count = 0
248
+ CREATORS.each do |param|
249
+ count += 1 if self.should(param)
250
+ end
251
+ if count > 1
252
+ self.fail "You cannot specify more than one of %s" % CREATORS.collect { |p| p.to_s}.join(", ")
166
253
  end
167
254
  end
255
+
256
+ def self.[](path)
257
+ return nil unless path
258
+ super(path.gsub(/\/+/, '/').sub(/\/$/, ''))
259
+ end
168
260
 
169
261
  # List files, but only one level deep.
170
262
  def self.list(base = "/")
@@ -199,13 +291,13 @@ module Puppet
199
291
  # Determine the user to write files as.
200
292
  def asuser
201
293
  if self.should(:owner) and ! self.should(:owner).is_a?(Symbol)
202
- writeable = Puppet::Util.asuser(self.should(:owner)) {
294
+ writeable = Puppet::Util::SUIDManager.asuser(self.should(:owner)) {
203
295
  FileTest.writable?(File.dirname(self[:path]))
204
296
  }
205
297
 
206
298
  # If the parent directory is writeable, then we execute
207
299
  # as the user in question. Otherwise we'll rely on
208
- # the 'owner' state to do things.
300
+ # the 'owner' property to do things.
209
301
  if writeable
210
302
  asuser = self.should(:owner)
211
303
  end
@@ -215,32 +307,43 @@ module Puppet
215
307
  end
216
308
 
217
309
  # We have to do some extra finishing, to retrieve our bucket if
218
- # there is one
310
+ # there is one.
219
311
  def finish
220
312
  # Let's cache these values, since there should really only be
221
313
  # a couple of these buckets
222
314
  @@filebuckets ||= {}
223
315
 
224
316
  # Look up our bucket, if there is one
225
- if @parameters.include?(:backup) and bucket = @parameters[:backup].bucket
317
+ if bucket = self.bucket
226
318
  case bucket
227
319
  when String:
228
320
  if obj = @@filebuckets[bucket]
229
321
  # This sets the @value on :backup, too
230
- @parameters[:backup].bucket = obj
231
- elsif obj = Puppet.type(:filebucket).bucket(bucket)
322
+ self.bucket = obj
323
+ elsif bucket == "puppet"
324
+ obj = Puppet::Network::Client.client(:Dipper).new(
325
+ :Path => Puppet[:clientbucketdir]
326
+ )
327
+ self.bucket = obj
232
328
  @@filebuckets[bucket] = obj
233
- @parameters[:backup].bucket = obj
329
+ elsif obj = Puppet::Type.type(:filebucket).bucket(bucket)
330
+ @@filebuckets[bucket] = obj
331
+ self.bucket = obj
234
332
  else
235
333
  self.fail "Could not find filebucket %s" % bucket
236
334
  end
237
- when Puppet::Client::Dipper: # things are hunky-dorey
335
+ when Puppet::Network::Client.client(:Dipper): # things are hunky-dorey
238
336
  else
239
337
  self.fail "Invalid bucket type %s" % bucket.class
240
338
  end
241
339
  end
242
340
  super
243
341
  end
342
+
343
+ # Create any children via recursion or whatever.
344
+ def eval_generate
345
+ recurse()
346
+ end
244
347
 
245
348
  # Deal with backups.
246
349
  def handlebackup(file = nil)
@@ -262,9 +365,9 @@ module Puppet
262
365
  # we don't need to backup directories when recurse is on
263
366
  return true
264
367
  else
265
- backup = self[:backup]
368
+ backup = self.bucket || self[:backup]
266
369
  case backup
267
- when Puppet::Client::Dipper:
370
+ when Puppet::Network::Client.client(:Dipper):
268
371
  notice "Recursively backing up to filebucket"
269
372
  require 'find'
270
373
  Find.find(self[:path]) do |f|
@@ -275,21 +378,12 @@ module Puppet
275
378
  end
276
379
  end
277
380
 
278
- require 'fileutils'
279
- FileUtils.rmtree(self[:path])
280
381
  return true
281
382
  when String:
282
383
  newfile = file + backup
283
384
  # Just move it, since it's a directory.
284
385
  if FileTest.exists?(newfile)
285
- begin
286
- File.unlink(newfile)
287
- rescue => detail
288
- puts detail.backtrace
289
- self.err "Could not remove old backup: %s" %
290
- detail
291
- return false
292
- end
386
+ remove_backup(newfile)
293
387
  end
294
388
  begin
295
389
  bfile = file + backup
@@ -310,9 +404,9 @@ module Puppet
310
404
  end
311
405
  end
312
406
  when "file":
313
- backup = self[:backup]
407
+ backup = self.bucket || self[:backup]
314
408
  case backup
315
- when Puppet::Client::Dipper:
409
+ when Puppet::Network::Client.client(:Dipper):
316
410
  sum = backup.backup(file)
317
411
  self.info "Filebucketed to %s with sum %s" %
318
412
  [backup.name, sum]
@@ -320,13 +414,7 @@ module Puppet
320
414
  when String:
321
415
  newfile = file + backup
322
416
  if FileTest.exists?(newfile)
323
- begin
324
- File.unlink(newfile)
325
- rescue => detail
326
- self.err "Could not remove old backup: %s" %
327
- detail
328
- return false
329
- end
417
+ remove_backup(newfile)
330
418
  end
331
419
  begin
332
420
  # FIXME Shouldn't this just use a Puppet object with
@@ -347,6 +435,7 @@ module Puppet
347
435
  self.err "Invalid backup type %s" % backup.inspect
348
436
  return false
349
437
  end
438
+ when "link": return true
350
439
  else
351
440
  self.notice "Cannot backup files of type %s" %
352
441
  File.stat(file).ftype
@@ -367,28 +456,133 @@ module Puppet
367
456
  end
368
457
 
369
458
  def initialize(hash)
370
- # clean out as many references to any file paths as possible
371
- # this was the source of many, many bugs
372
- @arghash = self.argclean(hash)
459
+ # Store a copy of the arguments for later.
460
+ tmphash = hash.to_hash
461
+
462
+ # Used for caching clients
463
+ @clients = {}
464
+
465
+ super
466
+
467
+ # Get rid of any duplicate slashes, and remove any trailing slashes.
468
+ @title = @title.gsub(/\/+/, "/").sub(/\/$/, "")
469
+
470
+ # Clean out as many references to any file paths as possible.
471
+ # This was the source of many, many bugs.
472
+ @arghash = tmphash
373
473
  @arghash.delete(self.class.namevar)
374
474
 
375
- if @arghash.include?(:source)
376
- @arghash.delete(:source)
475
+ [:source, :parent].each do |param|
476
+ if @arghash.include?(param)
477
+ @arghash.delete(param)
478
+ end
377
479
  end
378
480
 
379
481
  @stat = nil
482
+ end
380
483
 
381
- # Used for caching clients
382
- @clients = {}
484
+ # Build a recursive map of a link source
485
+ def linkrecurse(recurse)
486
+ target = @parameters[:target].should
383
487
 
384
- super
488
+ method = :lstat
489
+ if self[:links] == :follow
490
+ method = :stat
491
+ end
492
+
493
+ targetstat = nil
494
+ unless FileTest.exist?(target)
495
+ return
496
+ end
497
+ # Now stat our target
498
+ targetstat = File.send(method, target)
499
+ unless targetstat.ftype == "directory"
500
+ return
501
+ end
502
+
503
+ # Now that we know our corresponding target is a directory,
504
+ # change our type
505
+ self[:ensure] = :directory
506
+
507
+ unless FileTest.readable? target
508
+ self.notice "Cannot manage %s: permission denied" % self.name
509
+ return
510
+ end
511
+
512
+ children = Dir.entries(target).reject { |d| d =~ /^\.+$/ }
513
+
514
+ # Get rid of ignored children
515
+ if @parameters.include?(:ignore)
516
+ children = handleignore(children)
517
+ end
518
+
519
+ added = []
520
+ children.each do |file|
521
+ Dir.chdir(target) do
522
+ longname = File.join(target, file)
523
+
524
+ # Files know to create directories when recursion
525
+ # is enabled and we're making links
526
+ args = {
527
+ :recurse => recurse,
528
+ :ensure => longname
529
+ }
530
+
531
+ if child = self.newchild(file, true, args)
532
+ added << child
533
+ end
534
+ end
535
+ end
536
+
537
+ added
538
+ end
539
+
540
+ # Build up a recursive map of what's around right now
541
+ def localrecurse(recurse)
542
+ unless FileTest.exist?(self[:path]) and self.stat.directory?
543
+ #self.info "%s is not a directory; not recursing" %
544
+ # self[:path]
545
+ return
546
+ end
547
+
548
+ unless FileTest.readable? self[:path]
549
+ self.notice "Cannot manage %s: permission denied" % self.name
550
+ return
551
+ end
552
+
553
+ children = Dir.entries(self[:path])
554
+
555
+ #Get rid of ignored children
556
+ if @parameters.include?(:ignore)
557
+ children = handleignore(children)
558
+ end
559
+
560
+ added = []
561
+ children.each { |file|
562
+ file = File.basename(file)
563
+ next if file =~ /^\.\.?$/ # skip . and ..
564
+ options = {:recurse => recurse}
565
+
566
+ if child = self.newchild(file, true, options)
567
+ added << child
568
+ end
569
+ }
570
+
571
+ added
385
572
  end
386
573
 
387
574
  # Create a new file or directory object as a child to the current
388
575
  # object.
389
576
  def newchild(path, local, hash = {})
390
577
  # make local copy of arguments
391
- args = @arghash.dup
578
+ args = symbolize_options(@arghash)
579
+
580
+ # There's probably a better way to do this, but we don't want
581
+ # to pass this info on.
582
+ if v = args[:ensure]
583
+ v = symbolize(v)
584
+ args.delete(:ensure)
585
+ end
392
586
 
393
587
  if path =~ %r{^#{File::SEPARATOR}}
394
588
  self.devfail(
@@ -414,31 +608,14 @@ module Puppet
414
608
  }
415
609
 
416
610
  child = nil
417
- klass = nil
418
-
419
- # We specifically look in @parameters here, because 'linkmaker' isn't
420
- # a valid attribute for subclasses, so using 'self[:linkmaker]' throws
421
- # an error.
422
- if @parameters.include?(:linkmaker) and
423
- args.include?(:source) and ! FileTest.directory?(args[:source])
424
- klass = Puppet.type(:symlink)
425
-
426
- # clean up the args a lot for links
427
- old = args.dup
428
- args = {
429
- :ensure => old[:source],
430
- :path => path
431
- }
432
- else
433
- klass = self.class
434
- end
435
-
611
+ klass = self.class
612
+
436
613
  # The child might already exist because 'localrecurse' runs
437
614
  # before 'sourcerecurse'. I could push the override stuff into
438
615
  # a separate method or something, but the work is the same other
439
616
  # than this last bit, so it doesn't really make sense.
440
617
  if child = klass[path]
441
- unless @children.include?(child)
618
+ unless child.parent.object_id == self.object_id
442
619
  self.debug "Not managing more explicit file %s" %
443
620
  path
444
621
  return nil
@@ -451,12 +628,14 @@ module Puppet
451
628
  args.each { |var,value|
452
629
  next if var == :path
453
630
  next if var == :name
631
+
454
632
  # behave idempotently
455
633
  unless child.should(var) == value
456
634
  child[var] = value
457
635
  end
458
636
  }
459
637
  end
638
+ return nil
460
639
  else # create it anew
461
640
  #notice "Creating new file with args %s" % args.inspect
462
641
  args[:parent] = self
@@ -467,7 +646,6 @@ module Puppet
467
646
  if child.nil?
468
647
  return nil
469
648
  end
470
- @children << child
471
649
  rescue Puppet::Error => detail
472
650
  self.notice(
473
651
  "Cannot manage: %s" %
@@ -487,74 +665,87 @@ module Puppet
487
665
  return child
488
666
  end
489
667
 
490
- # Paths are special for files, because we don't actually want to show
491
- # the parent's full path.
492
- def path
493
- unless defined? @path
494
- if defined? @parent
495
- # We only need to behave specially when our parent is also
496
- # a file
497
- if @parent.is_a?(self.class)
498
- # Remove the parent file name
499
- ppath = @parent.path.sub(/\/?file=.+/, '')
500
- @path = []
501
- if ppath != "/" and ppath != ""
502
- @path << ppath
503
- end
504
- @path << self.class.name.to_s + "=" + self.name
505
- else
506
- super
507
- end
668
+ # Files handle paths specially, because they just lengthen their
669
+ # path names, rather than including the full parent's title each
670
+ # time.
671
+ def pathbuilder
672
+ if defined? @parent
673
+ # We only need to behave specially when our parent is also
674
+ # a file
675
+ if @parent.is_a?(self.class)
676
+ # Remove the parent file name
677
+ list = @parent.pathbuilder
678
+ list.pop # remove the parent's path info
679
+ return list << self.ref
508
680
  else
509
- # The top-level name is always puppet[top], so we don't
510
- # bother with that. And we don't add the hostname
511
- # here, it gets added in the log server thingy.
512
- if self.name == "puppet[top]"
513
- @path = ["/"]
514
- else
515
- # We assume that if we don't have a parent that we
516
- # should not cache the path
517
- @path = [self.class.name.to_s + "=" + self.name]
518
- end
681
+ return super
519
682
  end
683
+ else
684
+ return [self.ref]
520
685
  end
521
-
522
- return @path.join("/")
686
+ end
687
+
688
+ # Should we be purging?
689
+ def purge?
690
+ @parameters.include?(:purge) and (self[:purge] == :true or self[:purge] == "true")
523
691
  end
524
692
 
525
693
  # Recurse into the directory. This basically just calls 'localrecurse'
526
- # and maybe 'sourcerecurse'.
694
+ # and maybe 'sourcerecurse', returning the collection of generated
695
+ # files.
527
696
  def recurse
697
+ # are we at the end of the recursion?
698
+ unless self.recurse?
699
+ return
700
+ end
701
+
528
702
  recurse = self[:recurse]
529
703
  # we might have a string, rather than a number
530
704
  if recurse.is_a?(String)
531
705
  if recurse =~ /^[0-9]+$/
532
706
  recurse = Integer(recurse)
533
- #elsif recurse =~ /^inf/ # infinite recursion
534
707
  else # anything else is infinite recursion
535
708
  recurse = true
536
709
  end
537
710
  end
538
711
 
539
- # are we at the end of the recursion?
540
- #if recurse == 0
541
- unless self.recurse?
542
- return
543
- end
544
-
545
712
  if recurse.is_a?(Integer)
546
713
  recurse -= 1
547
714
  end
715
+
716
+ children = []
717
+
718
+ # We want to do link-recursing before normal recursion so that all
719
+ # of the target stuff gets copied over correctly.
720
+ if @parameters.include? :target and ret = self.linkrecurse(recurse)
721
+ children += ret
722
+ end
723
+ if ret = self.localrecurse(recurse)
724
+ children += ret
725
+ end
548
726
 
549
- self.localrecurse(recurse)
550
- if @states.include? :target
551
- self.linkrecurse(recurse)
727
+ # These will be files pulled in by the file source
728
+ sourced = false
729
+ if @parameters.include?(:source)
730
+ ret, sourced = self.sourcerecurse(recurse)
731
+ if ret
732
+ children += ret
733
+ end
552
734
  end
553
- if @states.include?(:source)
554
- self.sourcerecurse(recurse)
735
+
736
+ # The purge check needs to happen after all of the other recursion.
737
+ if self.purge?
738
+ children.each do |child|
739
+ if (sourced and ! sourced.include?(child[:path])) or ! child.managed?
740
+ child[:ensure] = :absent
741
+ end
742
+ end
555
743
  end
744
+
745
+ children
556
746
  end
557
747
 
748
+ # A simple method for determining whether we should be recursing.
558
749
  def recurse?
559
750
  return false unless @parameters.include?(:recurse)
560
751
 
@@ -567,222 +758,192 @@ module Puppet
567
758
  end
568
759
  end
569
760
 
570
- # Build a recursive map of a link source
571
- def linkrecurse(recurse)
572
- target = @states[:target].should
573
-
574
- method = :lstat
575
- if self[:links] == :follow
761
+ # Remove the old backup.
762
+ def remove_backup(newfile)
763
+ if self.class.name == :file and self[:links] != :follow
764
+ method = :lstat
765
+ else
576
766
  method = :stat
577
767
  end
768
+ old = File.send(method, newfile).ftype
578
769
 
579
- targetstat = nil
580
- unless FileTest.exist?(target)
581
- #self.info "%s does not exist; not recursing" %
582
- # target
583
- return
584
- end
585
- # Now stat our target
586
- targetstat = File.send(method, target)
587
- unless targetstat.ftype == "directory"
588
- #self.info "%s is not a directory; not recursing" %
589
- # target
590
- return
770
+ if old == "directory"
771
+ raise Puppet::Error,
772
+ "Will not remove directory backup %s; use a filebucket" %
773
+ newfile
591
774
  end
592
775
 
593
- # Now that we know our corresponding target is a directory,
594
- # change our type
595
- self[:ensure] = :directory
776
+ info "Removing old backup of type %s" %
777
+ File.send(method, newfile).ftype
596
778
 
597
- unless FileTest.readable? target
598
- self.notice "Cannot manage %s: permission denied" % self.name
599
- return
779
+ begin
780
+ File.unlink(newfile)
781
+ rescue => detail
782
+ if Puppet[:trace]
783
+ puts detail.backtrace
784
+ end
785
+ self.err "Could not remove old backup: %s" %
786
+ detail
787
+ return false
600
788
  end
789
+ end
601
790
 
602
- children = Dir.entries(target).reject { |d| d =~ /^\.+$/ }
603
-
604
- #Get rid of ignored children
605
- if @parameters.include?(:ignore)
606
- children = handleignore(children)
607
- end
791
+ # Remove any existing data. This is only used when dealing with
792
+ # links or directories.
793
+ def remove_existing(should)
794
+ return unless s = stat(true)
608
795
 
609
- added = []
610
- children.each do |file|
611
- Dir.chdir(target) do
612
- longname = File.join(target, file)
796
+ unless handlebackup
797
+ self.fail "Could not back up; will not replace"
798
+ end
613
799
 
614
- # Files know to create directories when recursion
615
- # is enabled and we're making links
616
- args = {
617
- :recurse => recurse,
618
- :ensure => longname
619
- }
800
+ unless should.to_s == "link"
801
+ return if s.ftype.to_s == should.to_s
802
+ end
620
803
 
621
- if child = self.newchild(file, true, args)
622
- unless @children.include?(child)
623
- self.push child
624
- added.push file
625
- end
626
- end
804
+ case s.ftype
805
+ when "directory":
806
+ if self[:force] == :true
807
+ debug "Removing existing directory for replacement with %s" %
808
+ should
809
+ FileUtils.rmtree(self[:path])
810
+ else
811
+ notice "Not removing directory; use 'force' to override"
627
812
  end
813
+ when "link", "file":
814
+ debug "Removing existing %s for replacement with %s" %
815
+ [s.ftype, should]
816
+ File.unlink(self[:path])
817
+ else
818
+ self.fail "Could not back up files of type %s" % s.ftype
628
819
  end
629
820
  end
630
821
 
631
- # Build up a recursive map of what's around right now
632
- def localrecurse(recurse)
633
- unless FileTest.exist?(self[:path]) and self.stat.directory?
634
- #self.info "%s is not a directory; not recursing" %
635
- # self[:path]
636
- return
637
- end
822
+ # a wrapper method to make sure the file exists before doing anything
823
+ def retrieve
824
+ unless stat = self.stat(true)
825
+ self.debug "File does not exist"
826
+ properties().each { |property|
827
+ property.is = :absent
828
+ }
829
+
830
+ # If the file doesn't exist but we have a source, then call
831
+ # retrieve on that property
832
+ if @parameters.include?(:source)
833
+ @parameters[:source].retrieve
834
+ end
638
835
 
639
- unless FileTest.readable? self[:path]
640
- self.notice "Cannot manage %s: permission denied" % self.name
641
836
  return
642
837
  end
643
838
 
644
- children = Dir.entries(self[:path])
645
-
646
- #Get rid of ignored children
647
- if @parameters.include?(:ignore)
648
- children = handleignore(children)
649
- end
650
-
651
- added = []
652
- children.each { |file|
653
- file = File.basename(file)
654
- next if file =~ /^\.\.?$/ # skip . and ..
655
- if child = self.newchild(file, true, :recurse => recurse)
656
- unless @children.include?(child)
657
- self.push child
658
- added.push file
659
- end
660
- end
839
+ properties().each { |property|
840
+ property.retrieve
661
841
  }
662
842
  end
663
843
 
664
844
  # This recurses against the remote source and makes sure the local
665
- # and remote structures match. It's run after 'localrecurse'.
845
+ # and remote structures match. It's run after 'localrecurse'. This
846
+ # method only does anything when its corresponding remote entry is
847
+ # a directory; in that case, this method creates file objects that
848
+ # correspond to any contained remote files.
666
849
  def sourcerecurse(recurse)
667
- # FIXME sourcerecurse should support purging non-remote files
668
- source = @states[:source].source
669
-
670
- unless ! source.nil? and source !~ /^\s*$/
671
- self.notice "source %s does not exist" % @states[:source].should
672
- return nil
673
- end
674
-
675
- sourceobj, path = uri2obj(source)
676
-
677
850
  # we'll set this manually as necessary
678
851
  if @arghash.include?(:ensure)
679
852
  @arghash.delete(:ensure)
680
853
  end
681
-
682
- # okay, we've got our source object; now we need to
683
- # build up a local file structure to match the remote
684
- # one
685
-
686
- server = sourceobj.server
687
- sum = "md5"
688
- if state = self.state(:checksum)
689
- sum = state.checktype
690
- end
854
+
691
855
  r = false
692
856
  if recurse
693
857
  unless recurse == 0
694
858
  r = 1
695
859
  end
696
860
  end
697
-
698
- #ignore = self[:ignore] || false
861
+
699
862
  ignore = self[:ignore]
700
863
 
701
- #self.warning "Listing path %s with ignore %s" %
702
- # [path.inspect, ignore.inspect]
703
- desc = server.list(path, self[:links], r, ignore)
704
-
705
- desc.split("\n").each { |line|
706
- file, type = line.split("\t")
707
- next if file == "/"
708
- name = file.sub(/^\//, '')
709
- #self.warning "child name is %s" % name
710
- args = {:source => source + file}
711
- if type == file
712
- args[:recurse] = nil
713
- end
714
- self.newchild(name, false, args)
715
- #self.newchild(hash, source, recurse)
716
- #hash2child(hash, source, recurse)
717
- }
718
- end
864
+ result = []
865
+ found = []
719
866
 
720
- # a wrapper method to make sure the file exists before doing anything
721
- def retrieve
722
- if @states.include?(:source)
723
- # This probably isn't the best place for it, but we need
724
- # to make sure that we have a corresponding checksum state.
725
- unless @states.include?(:checksum)
726
- self[:checksum] = "md5"
727
- end
867
+ # Keep track of all the files we found in the source, so we can purge
868
+ # appropriately.
869
+ sourced = []
870
+
871
+ @parameters[:source].should.each do |source|
872
+ sourceobj, path = uri2obj(source)
728
873
 
729
- # We have to retrieve the source info before the recursion happens,
730
- # although I'm not exactly clear on why.
731
- @states[:source].retrieve
732
- end
874
+ # okay, we've got our source object; now we need to
875
+ # build up a local file structure to match the remote
876
+ # one
733
877
 
734
- if @parameters.include?(:recurse)
735
- self.recurse
736
- end
878
+ server = sourceobj.server
737
879
 
738
- unless stat = self.stat(true)
739
- self.debug "File does not exist"
740
- @states.each { |name,state|
741
- # We've already retreived the source, and we don't
742
- # want to overwrite whatever it did. This is a bit
743
- # of a hack, but oh well, source is definitely special.
744
- next if name == :source
745
- state.is = :absent
746
- }
880
+ desc = server.list(path, self[:links], r, ignore)
881
+ if desc == ""
882
+ next
883
+ end
884
+
885
+ # Now create a new child for every file returned in the list.
886
+ result += desc.split("\n").collect { |line|
887
+ file, type = line.split("\t")
888
+ next if file == "/" # skip the listing object
889
+ name = file.sub(/^\//, '')
890
+
891
+ # This makes sure that the first source *always* wins
892
+ # for conflicting files.
893
+ next if found.include?(name)
894
+
895
+ # For directories, keep all of the sources, so that
896
+ # sourceselect still works as planned.
897
+ if type == "directory"
898
+ newsource = @parameters[:source].should.collect do |source|
899
+ source + file
900
+ end
901
+ else
902
+ newsource = source + file
903
+ end
904
+ args = {:source => newsource}
905
+ if type == file
906
+ args[:recurse] = nil
907
+ end
747
908
 
748
- return
749
- end
909
+ found << name
910
+ sourced << File.join(self[:path], name)
750
911
 
751
- states().each { |state|
752
- # We don't want to call 'describe()' twice, so only do a local
753
- # retrieve on the source.
754
- if state.name == :source
755
- state.retrieve(false)
756
- else
757
- state.retrieve
912
+ self.newchild(name, false, args)
913
+ }.reject {|c| c.nil? }
914
+
915
+ if self[:sourceselect] == :first
916
+ return [result, sourced]
758
917
  end
759
- }
918
+ end
919
+ return [result, sourced]
760
920
  end
761
921
 
762
- # Set the checksum, from another state. There are multiple states that
763
- # modify the contents of a file, and they need the ability to make sure
764
- # that the checksum value is in sync.
922
+ # Set the checksum, from another property. There are multiple
923
+ # properties that modify the contents of a file, and they need the
924
+ # ability to make sure that the checksum value is in sync.
765
925
  def setchecksum(sum = nil)
766
- if @states.include? :checksum
926
+ if @parameters.include? :checksum
767
927
  if sum
768
- @states[:checksum].checksum = sum
928
+ @parameters[:checksum].checksum = sum
769
929
  else
770
930
  # If they didn't pass in a sum, then tell checksum to
771
931
  # figure it out.
772
- @states[:checksum].retrieve
773
- @states[:checksum].checksum = @states[:checksum].is
932
+ @parameters[:checksum].retrieve
933
+ @parameters[:checksum].checksum = @parameters[:checksum].is
774
934
  end
775
935
  end
776
936
  end
777
937
 
778
- # Stat our file. Depending on the value of the 'links' attribute, we use
779
- # either 'stat' or 'lstat', and we expect the states to use the resulting
780
- # stat object accordingly (mostly by testing the 'ftype' value).
938
+ # Stat our file. Depending on the value of the 'links' attribute, we
939
+ # use either 'stat' or 'lstat', and we expect the properties to use the
940
+ # resulting stat object accordingly (mostly by testing the 'ftype'
941
+ # value).
781
942
  def stat(refresh = false)
782
943
  method = :stat
783
944
 
784
945
  # Files are the only types that support links
785
- if self.class.name == :file and self[:links] != :follow
946
+ if (self.class.name == :file and self[:links] != :follow) or self.class.name == :tidy
786
947
  method = :lstat
787
948
  end
788
949
  path = self[:path]
@@ -805,6 +966,17 @@ module Puppet
805
966
  return @stat
806
967
  end
807
968
 
969
+ # We have to hack this just a little bit, because otherwise we'll get
970
+ # an error when the target and the contents are created as properties on
971
+ # the far side.
972
+ def to_trans
973
+ obj = super
974
+ if obj[:target] == :notlink
975
+ obj.delete(:target)
976
+ end
977
+ obj
978
+ end
979
+
808
980
  def uri2obj(source)
809
981
  sourceobj = FileSource.new
810
982
  path = nil
@@ -817,7 +989,7 @@ module Puppet
817
989
  sourceobj.local = true
818
990
  end
819
991
  begin
820
- uri = URI.parse(source)
992
+ uri = URI.parse(URI.escape(source))
821
993
  rescue => detail
822
994
  self.fail "Could not understand source %s: %s" %
823
995
  [source, detail.to_s]
@@ -826,7 +998,7 @@ module Puppet
826
998
  case uri.scheme
827
999
  when "file":
828
1000
  unless defined? @@localfileserver
829
- @@localfileserver = Puppet::Server::FileServer.new(
1001
+ @@localfileserver = Puppet::Network::Handler.handler(:fileserver).new(
830
1002
  :Local => true,
831
1003
  :Mount => { "/" => "localhost" },
832
1004
  :Config => false
@@ -841,9 +1013,9 @@ module Puppet
841
1013
  args[:Port] = uri.port
842
1014
  end
843
1015
  # FIXME We should cache a copy of this server
844
- #sourceobj.server = Puppet::NetworkClient.new(args)
1016
+ #sourceobj.server = Puppet::Network::NetworkClient.new(args)
845
1017
  unless @clients.include?(source)
846
- @clients[source] = Puppet::Client::FileClient.new(args)
1018
+ @clients[source] = Puppet::Network::Client.file.new(args)
847
1019
  end
848
1020
  sourceobj.server = @clients[source]
849
1021
 
@@ -869,16 +1041,7 @@ module Puppet
869
1041
  def write(usetmp = true)
870
1042
  mode = self.should(:mode)
871
1043
 
872
- #if FileTest.exists?(self[:path])
873
- if s = stat(false)
874
- # this makes sure we have a copy for posterity
875
- @backed = self.handlebackup
876
-
877
- if s.ftype == "link" and self[:links] != :follow
878
- # Remove existing links, since we're writing out a file
879
- File.unlink(self[:path])
880
- end
881
- end
1044
+ remove_existing(:file)
882
1045
 
883
1046
  # The temporary file
884
1047
  path = nil
@@ -889,7 +1052,7 @@ module Puppet
889
1052
  end
890
1053
 
891
1054
  # As the correct user and group
892
- Puppet::Util.asuser(asuser(), self.should(:group)) do
1055
+ write_if_writable(File.dirname(path)) do
893
1056
  f = nil
894
1057
  # Open our file with the correct modes
895
1058
  if mode
@@ -923,10 +1086,68 @@ module Puppet
923
1086
  end
924
1087
  end
925
1088
 
1089
+ # make sure all of the modes are actually correct
1090
+ property_fix
1091
+
926
1092
  # And then update our checksum, so the next run doesn't find it.
927
1093
  # FIXME This is extra work, because it's going to read the whole
928
1094
  # file back in again.
929
1095
  self.setchecksum
1096
+
1097
+ end
1098
+
1099
+ # Run the block as the specified user if the dir is writeable, else
1100
+ # run it as root (or the current user).
1101
+ def write_if_writable(dir)
1102
+ yield
1103
+ # We're getting different behaviors from different versions of ruby, so...
1104
+ # asroot = true
1105
+ # Puppet::Util::SUIDManager.asuser(asuser(), self.should(:group)) do
1106
+ # if FileTest.writable?(dir)
1107
+ # asroot = false
1108
+ # yield
1109
+ # end
1110
+ # end
1111
+ #
1112
+ # if asroot
1113
+ # yield
1114
+ # end
1115
+ end
1116
+
1117
+ private
1118
+
1119
+ # Override the parent method, because we don't want to generate changes
1120
+ # when the file is missing and there is no 'ensure' state.
1121
+ def propertychanges
1122
+ unless self.stat
1123
+ found = false
1124
+ ([:ensure] + CREATORS).each do |prop|
1125
+ if @parameters.include?(prop)
1126
+ found = true
1127
+ break
1128
+ end
1129
+ end
1130
+ unless found
1131
+ return []
1132
+ end
1133
+ end
1134
+ super
1135
+ end
1136
+
1137
+ # There are some cases where all of the work does not get done on
1138
+ # file creation/modification, so we have to do some extra checking.
1139
+ def property_fix
1140
+ self.each do |thing|
1141
+ next unless thing.is_a? Puppet::Property
1142
+ next unless [:mode, :owner, :group].include?(thing.name)
1143
+
1144
+ # Make sure we get a new stat objct
1145
+ self.stat(true)
1146
+ thing.retrieve
1147
+ unless thing.insync?
1148
+ thing.sync
1149
+ end
1150
+ end
930
1151
  end
931
1152
  end # Puppet.type(:pfile)
932
1153
 
@@ -936,17 +1157,17 @@ module Puppet
936
1157
  attr_accessor :mount, :root, :server, :local
937
1158
  end
938
1159
 
939
- # We put all of the states in separate files, because there are so many
1160
+ # We put all of the properties in separate files, because there are so many
940
1161
  # of them. The order these are loaded is important, because it determines
941
- # the order they are in the state list.
1162
+ # the order they are in the property list.
942
1163
  require 'puppet/type/pfile/checksum'
943
1164
  require 'puppet/type/pfile/content' # can create the file
944
1165
  require 'puppet/type/pfile/source' # can create the file
945
- require 'puppet/type/pfile/target'
1166
+ require 'puppet/type/pfile/target' # creates a different type of file
946
1167
  require 'puppet/type/pfile/ensure' # can create the file
947
- require 'puppet/type/pfile/uid'
1168
+ require 'puppet/type/pfile/owner'
948
1169
  require 'puppet/type/pfile/group'
949
1170
  require 'puppet/type/pfile/mode'
950
1171
  require 'puppet/type/pfile/type'
951
1172
  end
952
- # $Id: pfile.rb 1355 2006-07-03 23:15:15Z luke $
1173
+ # $Id: pfile.rb 2436 2007-04-30 17:29:02Z luke $