puppet 3.0.0.rc5 → 3.0.0.rc7

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 (398) hide show
  1. data/LICENSE +1 -1
  2. data/README_DEVELOPER.md +209 -1
  3. data/README_HIERA.md +148 -0
  4. data/Rakefile +25 -27
  5. data/bin/extlookup2hiera +56 -0
  6. data/conf/auth.conf +34 -34
  7. data/examples/hiera/README.md +91 -0
  8. data/examples/hiera/etc/hiera.yaml +15 -0
  9. data/examples/hiera/etc/hieradb/common.yaml +3 -0
  10. data/examples/hiera/etc/hieradb/dc1.yaml +6 -0
  11. data/examples/hiera/etc/hieradb/development.yaml +2 -0
  12. data/examples/hiera/etc/puppet.conf +3 -0
  13. data/examples/hiera/modules/data/manifests/common.pp +3 -0
  14. data/examples/hiera/modules/ntp/manifests/config.pp +5 -0
  15. data/examples/hiera/modules/ntp/manifests/data.pp +3 -0
  16. data/examples/hiera/modules/ntp/templates/ntp.conf.erb +3 -0
  17. data/examples/hiera/modules/users/manifests/common.pp +3 -0
  18. data/examples/hiera/modules/users/manifests/dc1.pp +3 -0
  19. data/examples/hiera/modules/users/manifests/development.pp +3 -0
  20. data/examples/hiera/site.pp +3 -0
  21. data/ext/build_defaults.yaml +23 -0
  22. data/ext/debian/README.Debian +8 -0
  23. data/ext/debian/README.source +2 -0
  24. data/ext/debian/TODO.Debian +1 -0
  25. data/ext/debian/changelog.erb +1104 -0
  26. data/ext/debian/compat +1 -0
  27. data/ext/debian/control +143 -0
  28. data/ext/debian/copyright +361 -0
  29. data/ext/debian/docs +1 -0
  30. data/ext/debian/fileserver.conf +17 -0
  31. data/ext/debian/puppet-common.dirs +8 -0
  32. data/ext/debian/puppet-common.install +4 -0
  33. data/ext/debian/puppet-common.lintian-overrides +5 -0
  34. data/ext/debian/puppet-common.manpages +2 -0
  35. data/ext/debian/puppet-common.postinst +35 -0
  36. data/ext/debian/puppet-common.postrm +32 -0
  37. data/ext/debian/puppet-el.dirs +1 -0
  38. data/ext/debian/puppet-el.emacsen-install +25 -0
  39. data/ext/debian/puppet-el.emacsen-remove +11 -0
  40. data/ext/debian/puppet-el.emacsen-startup +9 -0
  41. data/ext/debian/puppet-el.install +1 -0
  42. data/ext/debian/puppet-testsuite.install +2 -0
  43. data/ext/debian/puppet-testsuite.lintian-overrides +4 -0
  44. data/ext/debian/puppet.conf +14 -0
  45. data/ext/debian/puppet.default +7 -0
  46. data/ext/debian/puppet.init +118 -0
  47. data/ext/debian/puppet.lintian-overrides +3 -0
  48. data/ext/debian/puppet.logrotate +11 -0
  49. data/ext/debian/puppet.manpages +32 -0
  50. data/ext/debian/puppet.postinst +20 -0
  51. data/ext/debian/puppet.postrm +20 -0
  52. data/ext/debian/puppet.preinst +20 -0
  53. data/ext/debian/puppetmaster-common.install +2 -0
  54. data/ext/debian/puppetmaster-common.manpages +2 -0
  55. data/ext/debian/puppetmaster-common.puppetqd.default +27 -0
  56. data/ext/debian/puppetmaster-common.puppetqd.init +84 -0
  57. data/ext/debian/puppetmaster-passenger.dirs +4 -0
  58. data/ext/debian/puppetmaster-passenger.postinst +66 -0
  59. data/ext/debian/puppetmaster-passenger.postrm +33 -0
  60. data/ext/debian/puppetmaster.README.debian +16 -0
  61. data/ext/debian/puppetmaster.default +38 -0
  62. data/ext/debian/puppetmaster.init +158 -0
  63. data/ext/debian/puppetmaster.lintian-overrides +3 -0
  64. data/ext/debian/puppetmaster.postinst +20 -0
  65. data/ext/debian/puppetmaster.postrm +5 -0
  66. data/ext/debian/puppetmaster.preinst +22 -0
  67. data/ext/debian/rules +128 -0
  68. data/ext/debian/source/format +1 -0
  69. data/ext/debian/source/options +1 -0
  70. data/ext/debian/vim-puppet.README.Debian +13 -0
  71. data/ext/debian/vim-puppet.dirs +3 -0
  72. data/ext/debian/vim-puppet.yaml +5 -0
  73. data/ext/debian/watch +2 -0
  74. data/ext/emacs/puppet-mode.el +1 -0
  75. data/ext/envpuppet +4 -0
  76. data/ext/envpuppet.bat +3 -2
  77. data/{conf → ext}/freebsd/puppetd +0 -0
  78. data/{conf → ext}/freebsd/puppetmasterd +0 -0
  79. data/{conf → ext}/gentoo/conf.d/puppet +0 -0
  80. data/{conf → ext}/gentoo/conf.d/puppetmaster +0 -0
  81. data/{conf → ext}/gentoo/init.d/puppet +0 -0
  82. data/{conf → ext}/gentoo/init.d/puppetmaster +0 -0
  83. data/{conf → ext}/gentoo/puppet/fileserver.conf +0 -0
  84. data/{conf → ext}/gentoo/puppet/puppet.conf +0 -0
  85. data/ext/ips/puppet-agent +49 -0
  86. data/ext/ips/puppet-master +44 -0
  87. data/ext/ips/puppet.conf +29 -0
  88. data/ext/ips/puppet.p5m.erb +12 -0
  89. data/ext/ips/puppetagent.xml +46 -0
  90. data/ext/ips/puppetmaster.xml +42 -0
  91. data/ext/ips/rules +19 -0
  92. data/ext/ips/transforms +34 -0
  93. data/{conf → ext}/osx/PackageInfo.plist +0 -0
  94. data/{conf → ext}/osx/createpackage.sh +1 -1
  95. data/ext/osx/file_mapping.yaml +33 -0
  96. data/ext/osx/preflight.erb +37 -0
  97. data/{tasks/rake/templates → ext/osx}/prototype.plist.erb +0 -0
  98. data/ext/packaging/README-Solaris.md +117 -0
  99. data/ext/packaging/README.md +89 -0
  100. data/ext/packaging/tasks/00_utils.rb +236 -0
  101. data/ext/packaging/tasks/10_setupvars.rake +62 -0
  102. data/ext/packaging/tasks/apple.rake +201 -0
  103. data/ext/packaging/tasks/clean.rake +5 -0
  104. data/ext/packaging/tasks/deb.rake +105 -0
  105. data/ext/packaging/tasks/gem.rake +52 -0
  106. data/ext/packaging/tasks/ips.rake +78 -0
  107. data/ext/packaging/tasks/mock.rake +88 -0
  108. data/ext/packaging/tasks/release.rake +20 -0
  109. data/ext/packaging/tasks/rpm.rake +39 -0
  110. data/ext/packaging/tasks/ship.rake +34 -0
  111. data/ext/packaging/tasks/sign.rake +76 -0
  112. data/ext/packaging/tasks/tar.rake +20 -0
  113. data/ext/project_data.yaml +25 -0
  114. data/ext/rack/files/apache2.conf +2 -1
  115. data/{conf → ext}/redhat/client.init +0 -0
  116. data/{conf → ext}/redhat/client.sysconfig +0 -0
  117. data/{conf → ext}/redhat/fileserver.conf +0 -0
  118. data/{conf → ext}/redhat/logrotate +0 -0
  119. data/{conf → ext}/redhat/puppet.conf +0 -0
  120. data/{conf/redhat/puppet.spec → ext/redhat/puppet.spec.erb} +140 -33
  121. data/{conf → ext}/redhat/queue.init +0 -0
  122. data/{conf → ext}/redhat/rundir-perms.patch +0 -0
  123. data/{conf → ext}/redhat/server.init +0 -0
  124. data/{conf → ext}/redhat/server.sysconfig +0 -0
  125. data/{conf → ext}/solaris/pkginfo +0 -0
  126. data/{conf → ext}/solaris/smf/puppetd.xml +0 -0
  127. data/{conf → ext}/solaris/smf/puppetmasterd.xml +0 -0
  128. data/{conf → ext}/solaris/smf/svc-puppetd +0 -0
  129. data/{conf → ext}/solaris/smf/svc-puppetmasterd +0 -0
  130. data/{conf → ext}/suse/client.init +0 -0
  131. data/{conf → ext}/suse/fileserver.conf +0 -0
  132. data/{conf → ext}/suse/logrotate +0 -0
  133. data/{conf → ext}/suse/puppet.conf +0 -0
  134. data/{conf → ext}/suse/puppet.spec +1 -1
  135. data/{conf → ext}/suse/server.init +0 -0
  136. data/ext/systemd/puppetagent.service +13 -0
  137. data/ext/systemd/puppetmaster.service +13 -0
  138. data/{conf → ext}/windows/eventlog/Rakefile +0 -0
  139. data/{conf → ext}/windows/eventlog/puppetres.dll +0 -0
  140. data/{conf → ext}/windows/eventlog/puppetres.mc +0 -0
  141. data/ext/windows/service/daemon.bat +6 -0
  142. data/ext/windows/service/daemon.rb +90 -0
  143. data/install.rb +22 -32
  144. data/lib/hiera/backend/puppet_backend.rb +102 -0
  145. data/lib/hiera/scope.rb +42 -0
  146. data/lib/hiera_puppet.rb +89 -0
  147. data/lib/puppet.rb +1 -1
  148. data/lib/puppet/agent.rb +2 -2
  149. data/lib/puppet/agent/locker.rb +12 -9
  150. data/lib/puppet/application.rb +10 -8
  151. data/lib/puppet/application/agent.rb +12 -8
  152. data/lib/puppet/application/apply.rb +2 -2
  153. data/lib/puppet/application/cert.rb +6 -6
  154. data/lib/puppet/application/certificate.rb +1 -4
  155. data/lib/puppet/application/describe.rb +1 -1
  156. data/lib/puppet/application/device.rb +5 -2
  157. data/lib/puppet/application/doc.rb +1 -1
  158. data/lib/puppet/application/face_base.rb +3 -13
  159. data/lib/puppet/application/filebucket.rb +1 -1
  160. data/lib/puppet/application/inspect.rb +1 -1
  161. data/lib/puppet/application/kick.rb +4 -2
  162. data/lib/puppet/application/master.rb +2 -2
  163. data/lib/puppet/application/queue.rb +3 -1
  164. data/lib/puppet/application/resource.rb +1 -1
  165. data/lib/puppet/configurer.rb +11 -7
  166. data/lib/puppet/configurer/downloader.rb +1 -4
  167. data/lib/puppet/daemon.rb +4 -4
  168. data/lib/puppet/defaults.rb +64 -60
  169. data/lib/puppet/external/dot.rb +1 -1
  170. data/lib/puppet/external/pson/common.rb +15 -0
  171. data/lib/puppet/external/pson/pure.rb +0 -62
  172. data/lib/puppet/external/pson/pure/generator.rb +1 -1
  173. data/lib/puppet/external/pson/pure/parser.rb +2 -2
  174. data/lib/puppet/face/ca.rb +19 -14
  175. data/lib/puppet/face/config.rb +2 -2
  176. data/lib/puppet/face/facts.rb +1 -1
  177. data/lib/puppet/face/help/action.erb +0 -1
  178. data/lib/puppet/face/help/face.erb +0 -1
  179. data/lib/puppet/face/help/man.erb +3 -6
  180. data/lib/puppet/face/module/install.rb +1 -1
  181. data/lib/puppet/face/module/list.rb +1 -1
  182. data/lib/puppet/face/module/uninstall.rb +1 -1
  183. data/lib/puppet/face/node.rb +1 -1
  184. data/lib/puppet/face/node/clean.rb +30 -25
  185. data/lib/puppet/feature/base.rb +0 -3
  186. data/lib/puppet/feature/rails.rb +2 -1
  187. data/lib/puppet/file_serving/terminus_selector.rb +1 -1
  188. data/lib/puppet/indirector/catalog/active_record.rb +5 -0
  189. data/lib/puppet/indirector/catalog/static_compiler.rb +2 -3
  190. data/lib/puppet/indirector/certificate/disabled_ca.rb +22 -0
  191. data/lib/puppet/indirector/certificate_request/disabled_ca.rb +22 -0
  192. data/lib/puppet/indirector/certificate_revocation_list/disabled_ca.rb +22 -0
  193. data/lib/puppet/indirector/face.rb +3 -3
  194. data/lib/puppet/indirector/facts/active_record.rb +5 -0
  195. data/lib/puppet/indirector/facts/facter.rb +1 -4
  196. data/lib/puppet/indirector/facts/inventory_active_record.rb +6 -0
  197. data/lib/puppet/indirector/file_bucket_file/file.rb +2 -1
  198. data/lib/puppet/indirector/indirection.rb +2 -2
  199. data/lib/puppet/indirector/key/disabled_ca.rb +22 -0
  200. data/lib/puppet/indirector/node/active_record.rb +5 -0
  201. data/lib/puppet/indirector/request.rb +4 -0
  202. data/lib/puppet/indirector/resource/active_record.rb +5 -0
  203. data/lib/puppet/network/authentication.rb +30 -0
  204. data/lib/puppet/network/http.rb +0 -13
  205. data/lib/puppet/network/http/connection.rb +10 -2
  206. data/lib/puppet/network/http/handler.rb +8 -0
  207. data/lib/puppet/network/http/mongrel/rest.rb +5 -0
  208. data/lib/puppet/network/http/rack/rest.rb +7 -0
  209. data/lib/puppet/network/http/webrick.rb +3 -6
  210. data/lib/puppet/network/http/webrick/rest.rb +4 -0
  211. data/lib/puppet/network/server.rb +9 -33
  212. data/lib/puppet/node.rb +1 -1
  213. data/lib/puppet/node/facts.rb +0 -1
  214. data/lib/puppet/parser/compiler.rb +1 -1
  215. data/lib/puppet/parser/functions.rb +12 -1
  216. data/lib/puppet/parser/functions/hiera.rb +8 -0
  217. data/lib/puppet/parser/functions/hiera_array.rb +8 -0
  218. data/lib/puppet/parser/functions/hiera_hash.rb +8 -0
  219. data/lib/puppet/parser/functions/hiera_include.rb +11 -0
  220. data/lib/puppet/parser/functions/shellquote.rb +21 -29
  221. data/lib/puppet/parser/lexer.rb +2 -1
  222. data/lib/puppet/parser/scope.rb +8 -0
  223. data/lib/puppet/provider/exec/windows.rb +1 -1
  224. data/lib/puppet/provider/group/groupadd.rb +2 -3
  225. data/lib/puppet/provider/package/pkg.rb +37 -10
  226. data/lib/puppet/provider/service/daemontools.rb +1 -1
  227. data/lib/puppet/provider/service/launchd.rb +1 -1
  228. data/lib/puppet/provider/service/redhat.rb +1 -1
  229. data/lib/puppet/provider/service/runit.rb +1 -1
  230. data/lib/puppet/provider/user/useradd.rb +8 -3
  231. data/lib/puppet/provider/user/windows_adsi.rb +11 -0
  232. data/lib/puppet/provider/zfs/zfs.rb +29 -2
  233. data/lib/puppet/provider/zone/solaris.rb +144 -39
  234. data/lib/puppet/provider/zpool/zpool.rb +7 -10
  235. data/lib/puppet/settings.rb +50 -86
  236. data/lib/puppet/settings/duration_setting.rb +34 -0
  237. data/lib/puppet/settings/terminus_setting.rb +16 -0
  238. data/lib/puppet/ssl/base.rb +49 -9
  239. data/lib/puppet/ssl/certificate.rb +13 -9
  240. data/lib/puppet/ssl/certificate_authority.rb +4 -0
  241. data/lib/puppet/ssl/certificate_authority/interface.rb +10 -17
  242. data/lib/puppet/ssl/certificate_factory.rb +4 -21
  243. data/lib/puppet/ssl/certificate_request.rb +1 -10
  244. data/lib/puppet/ssl/certificate_revocation_list.rb +1 -3
  245. data/lib/puppet/ssl/digest.rb +20 -0
  246. data/lib/puppet/ssl/host.rb +31 -6
  247. data/lib/puppet/test/test_helper.rb +1 -1
  248. data/lib/puppet/transaction/report.rb +2 -1
  249. data/lib/puppet/type.rb +1 -1
  250. data/lib/puppet/type/augeas.rb +1 -1
  251. data/lib/puppet/type/cron.rb +1 -1
  252. data/lib/puppet/type/exec.rb +7 -8
  253. data/lib/puppet/type/file.rb +1 -1
  254. data/lib/puppet/type/file/content.rb +2 -2
  255. data/lib/puppet/type/file/ensure.rb +1 -1
  256. data/lib/puppet/type/file/mode.rb +1 -1
  257. data/lib/puppet/type/file/selcontext.rb +6 -2
  258. data/lib/puppet/type/file/source.rb +1 -1
  259. data/lib/puppet/type/schedule.rb +1 -1
  260. data/lib/puppet/type/scheduled_task.rb +1 -1
  261. data/lib/puppet/type/tidy.rb +1 -1
  262. data/lib/puppet/type/zone.rb +126 -253
  263. data/lib/puppet/util.rb +10 -23
  264. data/lib/puppet/util/adsi.rb +22 -14
  265. data/lib/puppet/util/log/destinations.rb +7 -0
  266. data/lib/puppet/util/log/rate_limited_logger.rb +40 -0
  267. data/lib/puppet/util/metric.rb +2 -2
  268. data/lib/puppet/util/monkey_patches.rb +8 -0
  269. data/lib/puppet/util/platform.rb +7 -0
  270. data/lib/puppet/util/selinux.rb +31 -36
  271. data/lib/puppet/util/windows/error.rb +1 -1
  272. data/lib/puppet/util/windows/process.rb +3 -3
  273. data/lib/puppet/util/windows/security.rb +7 -7
  274. data/lib/puppet/util/windows/user.rb +65 -2
  275. data/lib/puppet/util/zaml.rb +90 -46
  276. data/lib/puppet/version.rb +1 -1
  277. data/spec/fixtures/hiera.yaml +9 -0
  278. data/spec/fixtures/manifests/site.pp +0 -0
  279. data/spec/integration/defaults_spec.rb +25 -11
  280. data/spec/integration/faces/ca_spec.rb +11 -16
  281. data/spec/integration/network/server/webrick_spec.rb +14 -27
  282. data/spec/integration/node_spec.rb +4 -1
  283. data/spec/integration/parser/functions/require_spec.rb +3 -3
  284. data/spec/integration/parser/undef_param_spec.rb +88 -0
  285. data/spec/integration/provider/mount_spec.rb +4 -1
  286. data/spec/integration/ssl/certificate_authority_spec.rb +18 -0
  287. data/spec/lib/puppet_spec/files.rb +3 -3
  288. data/spec/lib/puppet_spec/settings.rb +0 -1
  289. data/spec/shared_contexts/platform.rb +8 -0
  290. data/spec/spec_helper.rb +6 -0
  291. data/spec/unit/agent/locker_spec.rb +8 -2
  292. data/spec/unit/application/agent_spec.rb +29 -7
  293. data/spec/unit/application/apply_spec.rb +1 -1
  294. data/spec/unit/application/device_spec.rb +18 -1
  295. data/spec/unit/application/face_base_spec.rb +16 -2
  296. data/spec/unit/application/kick_spec.rb +8 -0
  297. data/spec/unit/application/queue_spec.rb +5 -0
  298. data/spec/unit/application_spec.rb +13 -23
  299. data/spec/unit/configurer/downloader_spec.rb +2 -11
  300. data/spec/unit/configurer_spec.rb +6 -0
  301. data/spec/unit/face/node_spec.rb +1 -1
  302. data/spec/unit/hiera/backend/puppet_backend_spec.rb +140 -0
  303. data/spec/unit/hiera/scope_spec.rb +62 -0
  304. data/spec/unit/hiera_puppet_spec.rb +111 -0
  305. data/spec/unit/indirector/catalog/active_record_spec.rb +4 -0
  306. data/spec/unit/indirector/catalog/static_compiler_spec.rb +194 -0
  307. data/spec/unit/indirector/certificate/disabled_ca_spec.rb +33 -0
  308. data/spec/unit/indirector/certificate_request/disabled_ca_spec.rb +33 -0
  309. data/spec/unit/indirector/certificate_revocation_list/disabled_ca_spec.rb +33 -0
  310. data/spec/unit/indirector/facts/active_record_spec.rb +37 -26
  311. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -0
  312. data/spec/unit/indirector/hiera_spec.rb +2 -1
  313. data/spec/unit/indirector/key/disabled_ca_spec.rb +33 -0
  314. data/spec/unit/indirector/node/active_record_spec.rb +7 -0
  315. data/spec/unit/indirector/request_spec.rb +22 -0
  316. data/spec/unit/indirector/resource/active_record_spec.rb +5 -0
  317. data/spec/unit/module_tool/application_spec.rb +1 -1
  318. data/spec/unit/network/authentication_spec.rb +86 -0
  319. data/spec/unit/network/http/connection_spec.rb +21 -0
  320. data/spec/unit/network/http/handler_spec.rb +12 -0
  321. data/spec/unit/network/http/rack/rest_spec.rb +7 -0
  322. data/spec/unit/network/http/webrick_spec.rb +11 -26
  323. data/spec/unit/network/server_spec.rb +79 -192
  324. data/spec/unit/node/facts_spec.rb +2 -2
  325. data/spec/unit/parser/ast/vardef_spec.rb +4 -4
  326. data/spec/unit/parser/files_spec.rb +3 -0
  327. data/spec/unit/parser/functions/defined_spec.rb +5 -5
  328. data/spec/unit/parser/functions/fqdn_rand_spec.rb +1 -1
  329. data/spec/unit/parser/functions/hiera_array_spec.rb +23 -0
  330. data/spec/unit/parser/functions/hiera_hash_spec.rb +19 -0
  331. data/spec/unit/parser/functions/hiera_include_spec.rb +19 -0
  332. data/spec/unit/parser/functions/hiera_spec.rb +21 -0
  333. data/spec/unit/parser/functions/include_spec.rb +3 -3
  334. data/spec/unit/parser/functions/realize_spec.rb +3 -3
  335. data/spec/unit/parser/functions/require_spec.rb +5 -5
  336. data/spec/unit/parser/functions/shellquote_spec.rb +0 -4
  337. data/spec/unit/parser/functions_spec.rb +6 -10
  338. data/spec/unit/parser/lexer_spec.rb +13 -0
  339. data/spec/unit/parser/scope_spec.rb +16 -1
  340. data/spec/unit/provider/exec/posix_spec.rb +7 -6
  341. data/spec/unit/provider/group/groupadd_spec.rb +36 -30
  342. data/spec/unit/provider/package/pkg_spec.rb +16 -2
  343. data/spec/unit/provider/service/redhat_spec.rb +2 -2
  344. data/spec/unit/provider/sshkey/parsed_spec.rb +4 -0
  345. data/spec/unit/provider/user/user_role_add_spec.rb +125 -126
  346. data/spec/unit/provider/user/useradd_spec.rb +147 -118
  347. data/spec/unit/provider/user/windows_adsi_spec.rb +22 -0
  348. data/spec/unit/provider/zone/solaris_spec.rb +126 -7
  349. data/spec/unit/provider/zpool/zpool_spec.rb +4 -3
  350. data/spec/unit/puppet_spec.rb +7 -0
  351. data/spec/unit/settings/duration_setting_spec.rb +45 -0
  352. data/spec/unit/settings/terminus_setting_spec.rb +28 -0
  353. data/spec/unit/settings_spec.rb +21 -23
  354. data/spec/unit/ssl/base_spec.rb +68 -19
  355. data/spec/unit/ssl/certificate_authority/interface_spec.rb +19 -30
  356. data/spec/unit/ssl/certificate_authority_spec.rb +3 -2
  357. data/spec/unit/ssl/certificate_factory_spec.rb +15 -6
  358. data/spec/unit/ssl/certificate_request_spec.rb +80 -113
  359. data/spec/unit/ssl/certificate_revocation_list_spec.rb +1 -1
  360. data/spec/unit/ssl/certificate_spec.rb +26 -2
  361. data/spec/unit/ssl/digest_spec.rb +35 -0
  362. data/spec/unit/ssl/host_spec.rb +73 -27
  363. data/spec/unit/ssl/key_spec.rb +0 -4
  364. data/spec/unit/type/exec_spec.rb +1 -1
  365. data/spec/unit/type/file_spec.rb +2 -1
  366. data/spec/unit/type/scheduled_task_spec.rb +2 -2
  367. data/spec/unit/type/zone_spec.rb +52 -10
  368. data/spec/unit/util/adsi_spec.rb +19 -0
  369. data/spec/unit/util/checksums_spec.rb +2 -3
  370. data/spec/unit/util/execution_spec.rb +1 -1
  371. data/spec/unit/util/log/destinations_spec.rb +1 -0
  372. data/spec/unit/util/log/rate_limited_logger_spec.rb +51 -0
  373. data/spec/unit/util/logging_spec.rb +6 -6
  374. data/spec/unit/util/selinux_spec.rb +24 -32
  375. data/spec/unit/util/zaml_spec.rb +94 -6
  376. data/spec/unit/util_spec.rb +17 -0
  377. data/spec/watchr.rb +2 -6
  378. data/tasks/{rake/manpages.rake → manpages.rake} +0 -0
  379. data/tasks/{rake/parser.rake → parser.rake} +0 -0
  380. metadata +1003 -119
  381. data/CHANGELOG +0 -9233
  382. data/conf/osx/preflight +0 -24
  383. data/lib/puppet/network/http/mongrel.rb +0 -35
  384. data/lib/puppet/util/config_timeout.rb +0 -24
  385. data/spec/unit/network/http/mongrel/rest_spec.rb +0 -257
  386. data/spec/unit/network/http/mongrel_spec.rb +0 -91
  387. data/spec/unit/network/http_spec.rb +0 -31
  388. data/spec/unit/util/config_timeout_spec.rb +0 -57
  389. data/tasks/rake/apple.rake +0 -176
  390. data/tasks/rake/changelog.rake +0 -15
  391. data/tasks/rake/ci.rake +0 -22
  392. data/tasks/rake/dailybuild.rake +0 -9
  393. data/tasks/rake/gem.rake +0 -63
  394. data/tasks/rake/git_workflow.rake +0 -134
  395. data/tasks/rake/metrics.rake +0 -14
  396. data/tasks/rake/sign.rake +0 -14
  397. data/tasks/rake/testbranch.rake +0 -16
  398. data/tasks/rake/yard.rake +0 -11
@@ -363,30 +363,17 @@ module Util
363
363
  # will recognize as links to the line numbers in the trace)
364
364
  def self.pretty_backtrace(backtrace = caller(1))
365
365
  backtrace.collect do |line|
366
- file_path, line_num = line.split(":")
367
- file_path = expand_symlinks(File.expand_path(file_path))
368
-
369
- file_path + ":" + line_num
370
- end .join("\n")
371
-
372
- end
373
-
374
- # utility method that takes a path as input, checks each component of the path to see if it is a symlink, and expands
375
- # it if it is. returns the expanded path.
376
- def self.expand_symlinks(file_path)
377
- file_path.split("/").inject do |full_path, next_dir|
378
- next_path = full_path + "/" + next_dir
379
- if File.symlink?(next_path) then
380
- link = File.readlink(next_path)
381
- next_path =
382
- case link
383
- when /^\// then link
384
- else
385
- File.expand_path(full_path + "/" + link)
386
- end
366
+ _, path, rest = /^(.*):(\d+.*)$/.match(line).to_a
367
+ # If the path doesn't exist - like in one test, and like could happen in
368
+ # the world - we should just tolerate it and carry on. --daniel 2012-09-05
369
+ # Also, if we don't match, just include the whole line.
370
+ if path
371
+ path = Pathname(path).realpath rescue path
372
+ "#{path}:#{rest}"
373
+ else
374
+ line
387
375
  end
388
- next_path
389
- end
376
+ end.join("\n")
390
377
  end
391
378
 
392
379
  # Replace a file, securely. This takes a block, and passes it the file
@@ -45,8 +45,12 @@ module Puppet::Util::ADSI
45
45
  "#{computer_uri}/#{resource_name},#{resource_type}"
46
46
  end
47
47
 
48
+ def wmi_connection
49
+ connect(wmi_resource_uri)
50
+ end
51
+
48
52
  def execquery(query)
49
- connect(wmi_resource_uri).execquery(query)
53
+ wmi_connection.execquery(query)
50
54
  end
51
55
 
52
56
  def sid_for_account(name)
@@ -85,19 +89,7 @@ module Puppet::Util::ADSI
85
89
  end
86
90
 
87
91
  def self.logon(name, password)
88
- fLOGON32_LOGON_NETWORK = 3
89
- fLOGON32_PROVIDER_DEFAULT = 0
90
-
91
- logon_user = Win32API.new("advapi32", "LogonUser", ['P', 'P', 'P', 'L', 'L', 'P'], 'L')
92
- close_handle = Win32API.new("kernel32", "CloseHandle", ['P'], 'V')
93
-
94
- token = ' ' * 4
95
- if logon_user.call(name, "", password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token) != 0
96
- close_handle.call(token.unpack('L')[0])
97
- true
98
- else
99
- false
100
- end
92
+ Puppet::Util::Windows::User.password_is?(name, password)
101
93
  end
102
94
 
103
95
  def [](attribute)
@@ -200,6 +192,22 @@ module Puppet::Util::ADSI
200
192
  end
201
193
  end
202
194
 
195
+ class UserProfile
196
+ def self.delete(sid)
197
+ begin
198
+ Puppet::Util::ADSI.wmi_connection.Delete("Win32_UserProfile.SID='#{sid}'")
199
+ rescue => e
200
+ # http://social.technet.microsoft.com/Forums/en/ITCG/thread/0f190051-ac96-4bf1-a47f-6b864bfacee5
201
+ # Prior to Vista SP1, there's no builtin way to programmatically
202
+ # delete user profiles (except for delprof.exe). So try to delete
203
+ # but warn if we fail
204
+ raise e unless e.message.include?('80041010')
205
+
206
+ Puppet.warning "Cannot delete user profile for '#{sid}' prior to Vista SP1"
207
+ end
208
+ end
209
+ end
210
+
203
211
  class Group
204
212
  extend Enumerable
205
213
 
@@ -76,6 +76,13 @@ Puppet::Util::Log.newdesttype :file do
76
76
  # create the log file, if it doesn't already exist
77
77
  file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
78
78
 
79
+ # Give ownership to the user and group puppet will run as
80
+ begin
81
+ FileUtils.chown(Puppet[:user], Puppet[:group], path) unless Puppet::Util::Platform.windows?
82
+ rescue ArgumentError, Errno::EPERM
83
+ Puppet.err "Unable to set ownership of log file"
84
+ end
85
+
79
86
  @file = file
80
87
 
81
88
  @autoflush = Puppet[:autoflush]
@@ -0,0 +1,40 @@
1
+ require 'puppet/util/logging'
2
+
3
+ # Logging utility class that limits the frequency of identical log messages
4
+ class Puppet::Util::Log::RateLimitedLogger
5
+ include Puppet::Util::Logging
6
+
7
+ def initialize(interval)
8
+ raise ArgumentError, "Logging rate-limit interval must be an integer" unless interval.is_a?(Integer)
9
+ @interval = interval
10
+ @log_record = {}
11
+ end
12
+
13
+ # Override the logging entry point to rate-limit it
14
+ def send_log(level, message)
15
+ Puppet::Util::Log.create({:level => level, :message => message}) if should_log?(level, message)
16
+ end
17
+
18
+ private
19
+
20
+ def should_log?(level, message)
21
+ # Initialize separate records for different levels, and only when needed
22
+ record = (@log_record[level] ||= {})
23
+ last_log = record[message]
24
+
25
+ # Skip logging if the time interval since the last logging hasn't elapsed yet
26
+ return false if last_log and within_interval?(last_log)
27
+
28
+ # Purge stale entries; do this after the interval check to reduce passes through the cache
29
+ record.delete_if { |key, time| !within_interval?(time) }
30
+
31
+ # Reset the beginning of the interval to the current time
32
+ record[message] = Time.now
33
+
34
+ true
35
+ end
36
+
37
+ def within_interval?(time)
38
+ time + @interval > Time.now
39
+ end
40
+ end
@@ -46,9 +46,9 @@ class Puppet::Util::Metric
46
46
 
47
47
  begin
48
48
  if Puppet.features.rrd_legacy? && ! Puppet.features.rrd?
49
- @rrd.create( Puppet[:rrdinterval].to_i, start, args)
49
+ @rrd.create( Puppet[:rrdinterval], start, args)
50
50
  else
51
- RRD.create( self.path, '-s', Puppet[:rrdinterval].to_i.to_s, '-b', start.to_i.to_s, *args)
51
+ RRD.create( self.path, '-s', Puppet[:rrdinterval].to_s, '-b', start.to_i.to_s, *args)
52
52
  end
53
53
  rescue => detail
54
54
  raise "Could not create RRD file #{path}: #{detail}"
@@ -81,6 +81,14 @@ if RUBY_VERSION == '1.8.1' || RUBY_VERSION == '1.8.2'
81
81
  }
82
82
  end
83
83
 
84
+ class Fixnum
85
+ # Returns the int itself. This method is intended for compatibility to
86
+ # character constant in Ruby 1.9. 1.8.5 is missing it; add it.
87
+ def ord
88
+ self
89
+ end unless method_defined? 'ord'
90
+ end
91
+
84
92
  class Array
85
93
  # Ruby < 1.8.7 doesn't have this method but we use it in tests
86
94
  def combination(num)
@@ -10,6 +10,13 @@ module Puppet
10
10
  !!File::ALT_SEPARATOR
11
11
  end
12
12
  module_function :windows?
13
+
14
+ def default_paths
15
+ return [] if windows?
16
+
17
+ %w{/usr/sbin /sbin}
18
+ end
19
+ module_function :default_paths
13
20
  end
14
21
  end
15
22
  end
@@ -136,6 +136,21 @@ module Puppet::Util::SELinux
136
136
  nil
137
137
  end
138
138
 
139
+ ########################################################################
140
+ # Internal helper methods from here on in, kids. Don't fiddle.
141
+ private
142
+
143
+ # Check filesystem a path resides on for SELinux support against
144
+ # whitelist of known-good filesystems.
145
+ # Returns true if the filesystem can support SELinux labels and
146
+ # false if not.
147
+ def selinux_label_support?(file)
148
+ fstype = find_fs(file)
149
+ return false if fstype.nil?
150
+ filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs']
151
+ filesystems.include?(fstype)
152
+ end
153
+
139
154
  # Internal helper function to read and parse /proc/mounts
140
155
  def read_mounts
141
156
  mounts = ""
@@ -171,46 +186,26 @@ module Puppet::Util::SELinux
171
186
  mntpoint
172
187
  end
173
188
 
174
- def realpath(path)
175
- path, rest = Pathname.new(path), []
176
- path, rest = path.dirname, [path.basename] + rest while ! path.exist?
177
- File.join( path.realpath, *rest )
178
- end
179
-
180
- def parent_directory(path)
181
- Pathname.new(path).dirname.to_s
182
- end
183
-
184
- # Internal helper function to return which type of filesystem a
185
- # given file path resides on
189
+ # Internal helper function to return which type of filesystem a given file
190
+ # path resides on
186
191
  def find_fs(path)
187
- unless mnts = read_mounts
188
- return nil
192
+ return nil unless mounts = read_mounts
193
+
194
+ # cleanpath eliminates useless parts of the path (like '.', or '..', or
195
+ # multiple slashes), without touching the filesystem, and without
196
+ # following symbolic links. This gives the right (logical) tree to follow
197
+ # while we try and figure out what file-system the target lives on.
198
+ path = Pathname(path).cleanpath
199
+ unless path.absolute?
200
+ raise Puppet::DevError, "got a relative path in SELinux find_fs: #{path}"
189
201
  end
190
202
 
191
- # For a given file:
192
- # Check if the filename is in the data structure;
193
- # return the fstype if it is.
194
- # Just in case: return something if you're down to "/" or ""
195
- # Remove the last slash and everything after it,
196
- # and repeat with that as the file for the next loop through.
197
- path = realpath(path)
198
- while not path.empty?
199
- return mnts[path] if mnts.has_key?(path)
200
- path = parent_directory(path)
203
+ # Now, walk up the tree until we find a match for that path in the hash.
204
+ path.ascend do |segment|
205
+ return mounts[segment.to_s] if mounts.has_key?(segment.to_s)
201
206
  end
202
- mnts['/']
203
- end
204
207
 
205
- # Check filesystem a path resides on for SELinux support against
206
- # whitelist of known-good filesystems.
207
- # Returns true if the filesystem can support SELinux labels and
208
- # false if not.
209
- def selinux_label_support?(file)
210
- fstype = find_fs(file)
211
- return false if fstype.nil?
212
- filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs']
213
- filesystems.include?(fstype)
208
+ # Should never be reached...
209
+ return mounts['/']
214
210
  end
215
-
216
211
  end
@@ -3,7 +3,7 @@ require 'puppet/util/windows'
3
3
  # represents an error resulting from a Win32 error code
4
4
  class Puppet::Util::Windows::Error < Puppet::Error
5
5
  require 'windows/error'
6
- include Windows::Error
6
+ include ::Windows::Error
7
7
 
8
8
  attr_reader :code
9
9
 
@@ -1,9 +1,9 @@
1
1
  require 'puppet/util/windows'
2
2
 
3
3
  module Puppet::Util::Windows::Process
4
- extend Windows::Process
5
- extend Windows::Handle
6
- extend Windows::Synchronize
4
+ extend ::Windows::Process
5
+ extend ::Windows::Handle
6
+ extend ::Windows::Synchronize
7
7
 
8
8
  def execute(command, arguments, stdin, stdout, stderr)
9
9
  Process.create( :command_line => command, :startup_info => {:stdin => stdin, :stdout => stdout, :stderr => stderr}, :close_handles => false )
@@ -72,13 +72,13 @@ require 'windows/memory'
72
72
  require 'windows/volume'
73
73
 
74
74
  module Puppet::Util::Windows::Security
75
- include Windows::File
76
- include Windows::Handle
77
- include Windows::Security
78
- include Windows::Process
79
- include Windows::Memory
80
- include Windows::MSVCRT::Buffer
81
- include Windows::Volume
75
+ include ::Windows::File
76
+ include ::Windows::Handle
77
+ include ::Windows::Security
78
+ include ::Windows::Process
79
+ include ::Windows::Memory
80
+ include ::Windows::MSVCRT::Buffer
81
+ include ::Windows::Volume
82
82
 
83
83
  extend Puppet::Util::Windows::Security
84
84
 
@@ -4,8 +4,8 @@ require 'win32/security'
4
4
  require 'facter'
5
5
 
6
6
  module Puppet::Util::Windows::User
7
- include Windows::Security
8
- extend Windows::Security
7
+ include ::Windows::Security
8
+ extend ::Windows::Security
9
9
 
10
10
  def admin?
11
11
  majversion = Facter.value(:kernelmajversion)
@@ -40,4 +40,67 @@ module Puppet::Util::Windows::User
40
40
  member.unpack('L')[0] == 1
41
41
  end
42
42
  module_function :check_token_membership
43
+
44
+ def password_is?(name, password)
45
+ logon_user(name, password)
46
+ true
47
+ rescue Puppet::Util::Windows::Error => e
48
+ false
49
+ end
50
+ module_function :password_is?
51
+
52
+ def logon_user(name, password, &block)
53
+ fLOGON32_LOGON_NETWORK = 3
54
+ fLOGON32_PROVIDER_DEFAULT = 0
55
+
56
+ logon_user = Win32API.new("advapi32", "LogonUser", ['P', 'P', 'P', 'L', 'L', 'P'], 'L')
57
+ close_handle = Win32API.new("kernel32", "CloseHandle", ['P'], 'V')
58
+
59
+ token = 0.chr * 4
60
+ if logon_user.call(name, ".", password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token) == 0
61
+ raise Puppet::Util::Windows::Error.new("Failed to logon user #{name.inspect}")
62
+ end
63
+
64
+ begin
65
+ yield token.unpack('L')[0] if block_given?
66
+ ensure
67
+ close_handle.call(token.unpack('L')[0])
68
+ end
69
+ end
70
+ module_function :logon_user
71
+
72
+ def load_profile(user, password)
73
+ logon_user(user, password) do |token|
74
+ # Set up the PROFILEINFO structure that will be used to load the
75
+ # new user's profile
76
+ # typedef struct _PROFILEINFO {
77
+ # DWORD dwSize;
78
+ # DWORD dwFlags;
79
+ # LPTSTR lpUserName;
80
+ # LPTSTR lpProfilePath;
81
+ # LPTSTR lpDefaultPath;
82
+ # LPTSTR lpServerName;
83
+ # LPTSTR lpPolicyPath;
84
+ # HANDLE hProfile;
85
+ # } PROFILEINFO, *LPPROFILEINFO;
86
+ fPI_NOUI = 1
87
+ profile = 0.chr * 4
88
+ pi = [4 * 8, fPI_NOUI, user, nil, nil, nil, nil, profile].pack('LLPPPPPP')
89
+
90
+ load_user_profile = Win32API.new('userenv', 'LoadUserProfile', ['L', 'P'], 'L')
91
+ unload_user_profile = Win32API.new('userenv', 'UnloadUserProfile', ['L', 'P'], 'L')
92
+
93
+ # Load the profile. Since it doesn't exist, it will be created
94
+ if load_user_profile.call(token, pi) == 0
95
+ raise Puppet::Util::Windows::Error.new("Failed to load user profile #{user.inspect}")
96
+ end
97
+
98
+ Puppet.debug("Loaded profile for #{user}")
99
+
100
+ if unload_user_profile.call(token, pi.unpack('LLLLLLLL').last) == 0
101
+ raise Puppet::Util::Windows::Error.new("Failed to unload user profile #{user.inspect}")
102
+ end
103
+ end
104
+ end
105
+ module_function :load_profile
43
106
  end
@@ -18,13 +18,35 @@
18
18
  #
19
19
  # http://github.com/hallettj/zaml
20
20
  #
21
- # Authors: Markus Roberts, Jesse Hallett, Ian McIntosh, Igal Koshevoy, Simon Chiang
21
+ # ## License (from upstream)
22
22
  #
23
+ # Copyright (c) 2008-2009 ZAML contributers
24
+ #
25
+ # This program is dual-licensed under the GNU General Public License
26
+ # version 3 or later and under the Apache License, version 2.0.
27
+ #
28
+ # This program is free software: you can redistribute it and/or modify it
29
+ # under the terms of the GNU General Public License as published by the
30
+ # Free Software Foundation, either version 3 of the License, or (at your
31
+ # option) any later version; or under the terms of the Apache License,
32
+ # Version 2.0.
33
+ #
34
+ # This program is distributed in the hope that it will be useful, but
35
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
36
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37
+ # General Public License and the Apache License for more details.
38
+ #
39
+ # You should have received a copy of the GNU General Public License
40
+ # along with this program. If not, see
41
+ # <http://www.gnu.org/licenses/>.
42
+ #
43
+ # You may obtain a copy of the Apache License at
44
+ # <https://www.apache.org/licenses/LICENSE-2.0.html>.
23
45
 
24
46
  require 'yaml'
25
47
 
26
48
  class ZAML
27
- VERSION = "0.1.1"
49
+ VERSION = "0.1.3"
28
50
  #
29
51
  # Class Methods
30
52
  #
@@ -33,6 +55,7 @@ class ZAML
33
55
  stuff.to_zaml(z)
34
56
  where << z.to_s
35
57
  end
58
+
36
59
  #
37
60
  # Instance Methods
38
61
  #
@@ -44,12 +67,14 @@ class ZAML
44
67
  @next_free_label_number = 0
45
68
  emit('--- ')
46
69
  end
70
+
47
71
  def nested(tail=' ')
48
72
  old_indent = @indent
49
73
  @indent = "#{@indent || "\n"}#{tail}"
50
74
  yield
51
75
  @indent = old_indent
52
76
  end
77
+
53
78
  class Label
54
79
  #
55
80
  # YAML only wants objects in the datastream once; if the same object
@@ -68,51 +93,69 @@ class ZAML
68
93
  # it can be handled).
69
94
  #
70
95
  attr_accessor :this_label_number
96
+
71
97
  def initialize(obj,indent)
72
98
  @indent = indent
73
99
  @this_label_number = nil
74
100
  @obj = obj # prevent garbage collection so that object id isn't reused
75
101
  end
102
+
76
103
  def to_s
77
104
  @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : ''
78
105
  end
106
+
79
107
  def reference
80
108
  @reference ||= '*id%03d' % @this_label_number
81
109
  end
82
110
  end
111
+
83
112
  def label_for(obj)
84
113
  @previously_emitted_object[obj.object_id]
85
114
  end
115
+
86
116
  def new_label_for(obj)
87
117
  label = Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ')
88
118
  @previously_emitted_object[obj.object_id] = label
89
119
  label
90
120
  end
121
+
91
122
  def first_time_only(obj)
92
123
  if label = label_for(obj)
93
124
  label.this_label_number ||= (@next_free_label_number += 1)
94
125
  emit(label.reference)
95
126
  else
96
- if @structured_key_prefix and not obj.is_a? String
127
+ with_structured_prefix(obj) do
128
+ emit(new_label_for(obj))
129
+ yield
130
+ end
131
+ end
132
+ end
133
+
134
+ def with_structured_prefix(obj)
135
+ if @structured_key_prefix
136
+ unless obj.is_a?(String) and obj !~ /\n/
97
137
  emit(@structured_key_prefix)
98
138
  @structured_key_prefix = nil
99
139
  end
100
- emit(new_label_for(obj))
101
- yield
102
140
  end
141
+ yield
103
142
  end
143
+
104
144
  def emit(s)
105
145
  @result << s
106
146
  @recent_nl = false unless s.kind_of?(Label)
107
147
  end
108
- def nl(s='')
148
+
149
+ def nl(s = nil)
109
150
  emit(@indent || "\n") unless @recent_nl
110
- emit(s)
151
+ emit(s) if s
111
152
  @recent_nl = true
112
153
  end
154
+
113
155
  def to_s
114
156
  @result.join
115
157
  end
158
+
116
159
  def prefix_structured_keys(x)
117
160
  @structured_key_prefix = x
118
161
  yield
@@ -228,23 +271,13 @@ class Exception
228
271
  end
229
272
 
230
273
  class String
231
- ZAML_ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \x08 \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f }
232
- def escaped_for_zaml
233
- # JJM (Note the trailing dots to construct a multi-line method chain.) This
234
- # code is meant to escape all bytes which are not ASCII-8BIT printable
235
- # characters. Multi-byte unicode characters are handled just fine because
236
- # each byte of the character results in an escaped string emitted to the
237
- # YAML stream. When the YAML is de-serialized back into a String the bytes
238
- # will be reconstructed properly into the unicode character.
239
- self.to_ascii8bit.gsub( /\x5C/n, "\\\\\\" ). # Demi-kludge for Maglev/rubinius; the regexp should be /\\/ but parsetree chokes on that.
240
- gsub( /"/n, "\\\"" ).
241
- gsub( /([\x00-\x1F])/n ) { |x| ZAML_ESCAPES[ x.unpack("C")[0] ] }
242
- end
274
+ ZAML_ESCAPES = {
275
+ "\a" => "\\a", "\e" => "\\e", "\f" => "\\f", "\n" => "\\n",
276
+ "\r" => "\\r", "\t" => "\\t", "\v" => "\\v"
277
+ }
278
+
243
279
  def to_zaml(z)
244
- z.first_time_only(self) {
245
- hex_num = '0x[a-f\d]+'
246
- float = '\d+\.?\d*'
247
- num = "[-+]?(?:#{float}|#{hex_num})"
280
+ z.with_structured_prefix(self) do
248
281
  case
249
282
  when self == ''
250
283
  z.emit('""')
@@ -258,39 +291,50 @@ class String
258
291
  | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
259
292
  | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
260
293
  )*\z/mnx
261
-
294
+ # Emit the binary tag, then recurse. Ruby splits BASE64 output at the 60
295
+ # character mark when packing strings, and we can wind up a multi-line
296
+ # string here. We could reimplement the multi-line string logic,
297
+ # but why would we - this does just as well for producing solid output.
262
298
  z.emit("!binary ")
263
- z.emit([self].pack("m*"))
264
- when (
265
- (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or
266
- (self =~ /\A\n* /) or
267
- (self =~ /[\s:]$/) or
268
- (self =~ /^[>|][-+\d]*\s/i) or
269
- (self[-1..-1] =~ /\s/) or
270
- (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or
271
- (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/)
272
- )
273
- z.emit("\"#{escaped_for_zaml}\"")
274
- when self =~ /\n/
299
+ [self].pack("m*").to_zaml(z)
300
+
301
+ # Only legal UTF-8 characters can make it this far, so we are safe
302
+ # against emitting something dubious. That means we don't need to mess
303
+ # about, just emit them directly. --daniel 2012-07-14
304
+ when ((self =~ /\A[a-zA-Z\/][-\[\]_\/.:a-zA-Z0-9]*\z/) and
305
+ (self !~ /^(?:true|false|yes|no|on|null|off)$/i))
306
+ # simple string literal, safe to emit unquoted.
307
+ z.emit(self)
308
+ when (self =~ /\n/ and self !~ /\A\s/ and self !~ /\s\z/)
309
+ # embedded newline, split line-wise in quoted string block form.
275
310
  if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end
276
- z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } }
311
+ z.nested { split("\n",-1).each { |line| z.nl; z.emit(line) } }
277
312
  else
278
- z.emit(self)
313
+ # ...though we still have to escape unsafe characters.
314
+ escaped = gsub(/[\\"\x00-\x1F]/) do |c|
315
+ ZAML_ESCAPES[c] || "\\x#{c[0].ord.to_s(16)}"
316
+ end
317
+ z.emit("\"#{escaped}\"")
279
318
  end
280
- }
319
+ end
281
320
  end
282
321
 
283
322
  # Return a guranteed ASCII-8BIT encoding for Ruby 1.9 This is a helper
284
323
  # method for other methods that perform regular expressions against byte
285
324
  # sequences deliberately rather than dealing with characters.
286
325
  # The method may or may not return a new instance.
287
- def to_ascii8bit
288
- if self.respond_to?(:encoding) and self.encoding.name != "ASCII-8BIT" then
289
- str = self.dup
290
- str.force_encoding("ASCII-8BIT")
291
- return str
292
- else
293
- return self
326
+ if String.method_defined?(:encoding)
327
+ ASCII_ENCODING = Encoding.find("ASCII-8BIT")
328
+ def to_ascii8bit
329
+ if self.encoding == ASCII_ENCODING
330
+ self
331
+ else
332
+ self.dup.force_encoding(ASCII_ENCODING)
333
+ end
334
+ end
335
+ else
336
+ def to_ascii8bit
337
+ self
294
338
  end
295
339
  end
296
340
  end