puppet 3.6.2 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (751) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +2 -3
  3. data/Gemfile +14 -10
  4. data/README.md +1 -1
  5. data/ext/build_defaults.yaml +16 -1
  6. data/ext/debian/control +3 -2
  7. data/ext/debian/puppet-common.dirs +1 -0
  8. data/ext/debian/puppet-common.postinst +8 -8
  9. data/ext/debian/puppet-common.postrm +2 -1
  10. data/ext/project_data.yaml +16 -12
  11. data/ext/rack/example-passenger-vhost.conf +2 -2
  12. data/ext/redhat/puppet.spec.erb +6 -3
  13. data/ext/windows/service/daemon.rb +47 -41
  14. data/install.rb +1 -1
  15. data/lib/puppet.rb +34 -24
  16. data/lib/puppet/application.rb +34 -1
  17. data/lib/puppet/application/agent.rb +9 -8
  18. data/lib/puppet/application/apply.rb +14 -5
  19. data/lib/puppet/application/doc.rb +4 -11
  20. data/lib/puppet/application/master.rb +19 -17
  21. data/lib/puppet/application/queue.rb +1 -1
  22. data/lib/puppet/application/resource.rb +0 -1
  23. data/lib/puppet/configurer.rb +39 -2
  24. data/lib/puppet/configurer/downloader.rb +5 -10
  25. data/lib/puppet/configurer/downloader_factory.rb +34 -0
  26. data/lib/puppet/configurer/plugin_handler.rb +11 -17
  27. data/lib/puppet/defaults.rb +244 -119
  28. data/lib/puppet/environments.rb +8 -0
  29. data/lib/puppet/external/nagios/base.rb +1 -1
  30. data/lib/puppet/external/pson/pure/generator.rb +1 -8
  31. data/lib/puppet/face/ca.rb +7 -0
  32. data/lib/puppet/face/file/download.rb +5 -2
  33. data/lib/puppet/face/file/store.rb +1 -1
  34. data/lib/puppet/face/instrumentation_data.rb +2 -1
  35. data/lib/puppet/face/instrumentation_listener.rb +2 -1
  36. data/lib/puppet/face/instrumentation_probe.rb +2 -1
  37. data/lib/puppet/face/module/build.rb +2 -2
  38. data/lib/puppet/face/module/generate.rb +20 -12
  39. data/lib/puppet/face/module/install.rb +4 -3
  40. data/lib/puppet/face/module/uninstall.rb +7 -0
  41. data/lib/puppet/face/module/upgrade.rb +11 -3
  42. data/lib/puppet/face/node/clean.rb +1 -1
  43. data/lib/puppet/face/parser.rb +99 -7
  44. data/lib/puppet/feature/base.rb +18 -12
  45. data/lib/puppet/feature/cfacter.rb +14 -0
  46. data/lib/puppet/feature/pe_license.rb +4 -0
  47. data/lib/puppet/file_bucket/dipper.rb +19 -12
  48. data/lib/puppet/file_bucket/file.rb +73 -10
  49. data/lib/puppet/file_serving/configuration/parser.rb +3 -3
  50. data/lib/puppet/file_system.rb +1 -1
  51. data/lib/puppet/file_system/file19.rb +41 -0
  52. data/lib/puppet/file_system/file19windows.rb +0 -1
  53. data/lib/puppet/file_system/uniquefile.rb +190 -0
  54. data/lib/puppet/forge.rb +34 -7
  55. data/lib/puppet/forge/errors.rb +5 -6
  56. data/lib/puppet/forge/repository.rb +14 -2
  57. data/lib/puppet/functions.rb +19 -12
  58. data/lib/puppet/functions/assert_type.rb +27 -10
  59. data/lib/puppet/functions/each.rb +111 -0
  60. data/lib/puppet/functions/epp.rb +54 -0
  61. data/lib/puppet/functions/filter.rb +113 -0
  62. data/lib/puppet/functions/inline_epp.rb +88 -0
  63. data/lib/puppet/functions/map.rb +97 -0
  64. data/lib/puppet/functions/match.rb +102 -0
  65. data/lib/puppet/functions/reduce.rb +94 -0
  66. data/lib/puppet/functions/slice.rb +126 -0
  67. data/lib/puppet/functions/with.rb +23 -0
  68. data/lib/puppet/indirector/catalog/compiler.rb +4 -4
  69. data/lib/puppet/indirector/data_binding/hiera.rb +2 -45
  70. data/lib/puppet/indirector/facts/couch.rb +3 -1
  71. data/lib/puppet/indirector/facts/facter.rb +52 -65
  72. data/lib/puppet/indirector/file_bucket_file/file.rb +6 -3
  73. data/lib/puppet/indirector/hiera.rb +48 -0
  74. data/lib/puppet/indirector/indirection.rb +1 -1
  75. data/lib/puppet/indirector/request.rb +9 -3
  76. data/lib/puppet/indirector/resource/ral.rb +1 -1
  77. data/lib/puppet/indirector/rest.rb +7 -3
  78. data/lib/puppet/loaders.rb +0 -1
  79. data/lib/puppet/module.rb +2 -1
  80. data/lib/puppet/module_tool.rb +2 -0
  81. data/lib/puppet/module_tool/applications/application.rb +4 -5
  82. data/lib/puppet/module_tool/applications/builder.rb +64 -5
  83. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -2
  84. data/lib/puppet/module_tool/applications/unpacker.rb +14 -0
  85. data/lib/puppet/module_tool/applications/upgrader.rb +23 -13
  86. data/lib/puppet/module_tool/dependency.rb +12 -0
  87. data/lib/puppet/module_tool/errors/shared.rb +1 -1
  88. data/lib/puppet/module_tool/errors/upgrader.rb +20 -0
  89. data/lib/puppet/module_tool/installed_modules.rb +6 -1
  90. data/lib/puppet/module_tool/metadata.rb +53 -3
  91. data/lib/puppet/module_tool/modulefile.rb +1 -1
  92. data/lib/puppet/module_tool/skeleton/templates/generator/Gemfile +7 -0
  93. data/lib/puppet/module_tool/skeleton/templates/generator/manifests/init.pp.erb +1 -1
  94. data/lib/puppet/module_tool/skeleton/templates/generator/spec/spec_helper.rb +1 -17
  95. data/lib/puppet/module_tool/tar/mini.rb +20 -2
  96. data/lib/puppet/network/http.rb +5 -0
  97. data/lib/puppet/network/http/api/v1.rb +2 -2
  98. data/lib/puppet/network/http/api/v2/environments.rb +15 -1
  99. data/lib/puppet/network/http/connection.rb +54 -68
  100. data/lib/puppet/network/http/factory.rb +44 -0
  101. data/lib/puppet/network/http/handler.rb +12 -6
  102. data/lib/puppet/network/http/nocache_pool.rb +21 -0
  103. data/lib/puppet/network/http/pool.rb +120 -0
  104. data/lib/puppet/network/http/rack/rest.rb +3 -1
  105. data/lib/puppet/network/http/session.rb +17 -0
  106. data/lib/puppet/network/http/site.rb +39 -0
  107. data/lib/puppet/network/http/webrick/rest.rb +3 -1
  108. data/lib/puppet/network/http_pool.rb +3 -4
  109. data/lib/puppet/node.rb +19 -6
  110. data/lib/puppet/node/environment.rb +34 -8
  111. data/lib/puppet/parser/ast/collection.rb +4 -0
  112. data/lib/puppet/parser/ast/collexpr.rb +1 -1
  113. data/lib/puppet/parser/ast/node.rb +5 -0
  114. data/lib/puppet/parser/ast/pops_bridge.rb +49 -6
  115. data/lib/puppet/parser/compiler.rb +66 -38
  116. data/lib/puppet/parser/e4_parser_adapter.rb +2 -2
  117. data/lib/puppet/parser/files.rb +76 -33
  118. data/lib/puppet/parser/functions.rb +1 -7
  119. data/lib/puppet/parser/functions/assert_type.rb +31 -0
  120. data/lib/puppet/parser/functions/contain.rb +15 -5
  121. data/lib/puppet/parser/functions/create_resources.rb +5 -1
  122. data/lib/puppet/parser/functions/digest.rb +5 -0
  123. data/lib/puppet/parser/functions/each.rb +46 -107
  124. data/lib/puppet/parser/functions/epp.rb +13 -9
  125. data/lib/puppet/parser/functions/file.rb +20 -12
  126. data/lib/puppet/parser/functions/filter.rb +32 -88
  127. data/lib/puppet/parser/functions/include.rb +12 -24
  128. data/lib/puppet/parser/functions/inline_epp.rb +9 -12
  129. data/lib/puppet/parser/functions/lookup.rb +1 -1
  130. data/lib/puppet/parser/functions/map.rb +30 -83
  131. data/lib/puppet/parser/functions/match.rb +28 -0
  132. data/lib/puppet/parser/functions/reduce.rb +69 -98
  133. data/lib/puppet/parser/functions/require.rb +13 -5
  134. data/lib/puppet/parser/functions/search.rb +6 -1
  135. data/lib/puppet/parser/functions/slice.rb +35 -103
  136. data/lib/puppet/parser/functions/template.rb +12 -5
  137. data/lib/puppet/parser/functions/with.rb +21 -0
  138. data/lib/puppet/parser/lexer.rb +1 -1
  139. data/lib/puppet/parser/parser_factory.rb +21 -33
  140. data/lib/puppet/parser/resource.rb +2 -3
  141. data/lib/puppet/parser/scope.rb +85 -15
  142. data/lib/puppet/pops.rb +9 -11
  143. data/lib/puppet/pops/adapters.rb +2 -1
  144. data/lib/puppet/pops/binder/bindings_checker.rb +4 -4
  145. data/lib/puppet/pops/binder/bindings_factory.rb +6 -6
  146. data/lib/puppet/pops/binder/bindings_label_provider.rb +1 -1
  147. data/lib/puppet/pops/binder/bindings_loader.rb +2 -2
  148. data/lib/puppet/pops/binder/bindings_model.rb +58 -191
  149. data/lib/puppet/pops/binder/bindings_model_dumper.rb +1 -1
  150. data/lib/puppet/pops/binder/bindings_model_meta.rb +215 -0
  151. data/lib/puppet/pops/binder/injector.rb +9 -9
  152. data/lib/puppet/pops/binder/key_factory.rb +2 -2
  153. data/lib/puppet/pops/binder/lookup.rb +14 -6
  154. data/lib/puppet/pops/binder/producers.rb +9 -12
  155. data/lib/puppet/pops/evaluator/access_operator.rb +35 -29
  156. data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +175 -0
  157. data/lib/puppet/pops/evaluator/callable_signature.rb +1 -2
  158. data/lib/puppet/pops/evaluator/closure.rb +151 -35
  159. data/lib/puppet/pops/evaluator/compare_operator.rb +26 -22
  160. data/lib/puppet/pops/evaluator/epp_evaluator.rb +16 -15
  161. data/lib/puppet/pops/evaluator/evaluator_impl.rb +277 -229
  162. data/lib/puppet/pops/evaluator/relationship_operator.rb +3 -2
  163. data/lib/puppet/pops/evaluator/runtime3_support.rb +86 -53
  164. data/lib/puppet/pops/functions/dispatch.rb +9 -4
  165. data/lib/puppet/pops/functions/dispatcher.rb +2 -169
  166. data/lib/puppet/pops/issue_reporter.rb +14 -6
  167. data/lib/puppet/pops/issues.rb +96 -21
  168. data/lib/puppet/pops/loader/base_loader.rb +3 -3
  169. data/lib/puppet/pops/loader/loader.rb +1 -1
  170. data/lib/puppet/pops/loader/loader_paths.rb +2 -21
  171. data/lib/puppet/pops/loader/ruby_function_instantiator.rb +1 -1
  172. data/lib/puppet/pops/loader/static_loader.rb +12 -2
  173. data/lib/puppet/pops/model/ast_transformer.rb +4 -24
  174. data/lib/puppet/pops/model/factory.rb +72 -10
  175. data/lib/puppet/pops/model/model.rb +82 -574
  176. data/lib/puppet/pops/model/model_label_provider.rb +4 -2
  177. data/lib/puppet/pops/model/model_meta.rb +576 -0
  178. data/lib/puppet/pops/model/model_tree_dumper.rb +27 -5
  179. data/lib/puppet/pops/parser/egrammar.ra +209 -221
  180. data/lib/puppet/pops/parser/eparser.rb +1459 -1431
  181. data/lib/puppet/pops/parser/evaluating_parser.rb +15 -75
  182. data/lib/puppet/pops/parser/lexer2.rb +14 -10
  183. data/lib/puppet/pops/parser/lexer_support.rb +6 -0
  184. data/lib/puppet/pops/parser/locator.rb +1 -1
  185. data/lib/puppet/pops/parser/parser_support.rb +31 -49
  186. data/lib/puppet/pops/patterns.rb +10 -10
  187. data/lib/puppet/pops/semantic_error.rb +1 -1
  188. data/lib/puppet/pops/types/class_loader.rb +24 -13
  189. data/lib/puppet/pops/types/type_calculator.rb +188 -87
  190. data/lib/puppet/pops/types/type_factory.rb +79 -53
  191. data/lib/puppet/pops/types/type_parser.rb +22 -16
  192. data/lib/puppet/pops/types/types.rb +283 -392
  193. data/lib/puppet/pops/types/types_meta.rb +223 -0
  194. data/lib/puppet/pops/utils.rb +16 -14
  195. data/lib/puppet/pops/validation/checker4_0.rb +264 -18
  196. data/lib/puppet/pops/validation/validator_factory_4_0.rb +0 -1
  197. data/lib/puppet/pops/visitor.rb +0 -103
  198. data/lib/puppet/provider/exec.rb +10 -1
  199. data/lib/puppet/provider/file/windows.rb +3 -4
  200. data/lib/puppet/provider/group/windows_adsi.rb +10 -10
  201. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -4
  202. data/lib/puppet/provider/package/apt.rb +5 -1
  203. data/lib/puppet/provider/package/gem.rb +7 -3
  204. data/lib/puppet/provider/package/openbsd.rb +84 -7
  205. data/lib/puppet/provider/package/pacman.rb +29 -4
  206. data/lib/puppet/provider/package/rpm.rb +5 -7
  207. data/lib/puppet/provider/package/sun.rb +5 -1
  208. data/lib/puppet/provider/package/windows.rb +6 -1
  209. data/lib/puppet/provider/package/windows/exe_package.rb +1 -1
  210. data/lib/puppet/provider/package/windows/msi_package.rb +1 -1
  211. data/lib/puppet/provider/package/windows/package.rb +13 -1
  212. data/lib/puppet/provider/package/yum.rb +7 -3
  213. data/lib/puppet/provider/package/zypper.rb +5 -1
  214. data/lib/puppet/provider/parsedfile.rb +17 -1
  215. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +6 -12
  216. data/lib/puppet/provider/service/freebsd.rb +12 -12
  217. data/lib/puppet/provider/service/init.rb +5 -0
  218. data/lib/puppet/provider/service/launchd.rb +0 -3
  219. data/lib/puppet/provider/service/openbsd.rb +8 -7
  220. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +2 -2
  221. data/lib/puppet/provider/sshkey/parsed.rb +5 -0
  222. data/lib/puppet/provider/user/user_role_add.rb +5 -4
  223. data/lib/puppet/provider/user/windows_adsi.rb +8 -8
  224. data/lib/puppet/provider/zone/solaris.rb +1 -1
  225. data/lib/puppet/reference/metaparameter.rb +8 -6
  226. data/lib/puppet/reports/store.rb +4 -9
  227. data/lib/puppet/resource.rb +75 -11
  228. data/lib/puppet/resource/catalog.rb +9 -7
  229. data/lib/puppet/resource/type.rb +27 -0
  230. data/lib/puppet/settings.rb +61 -41
  231. data/lib/puppet/settings/base_setting.rb +9 -3
  232. data/lib/puppet/settings/environment_conf.rb +32 -4
  233. data/lib/puppet/settings/file_setting.rb +9 -1
  234. data/lib/puppet/settings/priority_setting.rb +5 -5
  235. data/lib/puppet/ssl.rb +1 -0
  236. data/lib/puppet/ssl/certificate_authority.rb +15 -6
  237. data/lib/puppet/ssl/certificate_authority/autosign_command.rb +2 -1
  238. data/lib/puppet/ssl/host.rb +3 -2
  239. data/lib/puppet/ssl/inventory.rb +11 -6
  240. data/lib/puppet/ssl/validator/default_validator.rb +1 -0
  241. data/lib/puppet/ssl/validator/no_validator.rb +3 -0
  242. data/lib/puppet/transaction.rb +29 -0
  243. data/lib/puppet/transaction/resource_harness.rb +16 -3
  244. data/lib/puppet/type.rb +71 -49
  245. data/lib/puppet/type/exec.rb +36 -8
  246. data/lib/puppet/type/file.rb +56 -16
  247. data/lib/puppet/type/file/content.rb +3 -3
  248. data/lib/puppet/type/file/mode.rb +12 -3
  249. data/lib/puppet/type/file/source.rb +4 -1
  250. data/lib/puppet/type/group.rb +1 -1
  251. data/lib/puppet/type/mount.rb +1 -3
  252. data/lib/puppet/type/resources.rb +59 -35
  253. data/lib/puppet/type/ssh_authorized_key.rb +54 -16
  254. data/lib/puppet/type/sshkey.rb +1 -1
  255. data/lib/puppet/type/user.rb +17 -11
  256. data/lib/puppet/type/yumrepo.rb +59 -8
  257. data/lib/puppet/type/zone.rb +3 -6
  258. data/lib/puppet/util.rb +64 -55
  259. data/lib/puppet/util/autoload.rb +2 -2
  260. data/lib/puppet/util/colors.rb +61 -19
  261. data/lib/puppet/util/command_line.rb +21 -4
  262. data/lib/puppet/util/execution.rb +41 -29
  263. data/lib/puppet/util/feature.rb +15 -4
  264. data/lib/puppet/util/filetype.rb +6 -2
  265. data/lib/puppet/util/http_proxy.rb +29 -2
  266. data/lib/puppet/util/lockfile.rb +1 -1
  267. data/lib/puppet/util/log/destinations.rb +7 -3
  268. data/lib/puppet/util/logging.rb +44 -14
  269. data/lib/puppet/util/pidlock.rb +11 -5
  270. data/lib/puppet/util/posix.rb +21 -31
  271. data/lib/puppet/util/profiler.rb +17 -9
  272. data/lib/puppet/util/profiler/aggregate.rb +85 -0
  273. data/lib/puppet/util/profiler/around_profiler.rb +67 -0
  274. data/lib/puppet/util/profiler/logging.rb +12 -11
  275. data/lib/puppet/util/profiler/wall_clock.rb +7 -6
  276. data/lib/puppet/util/rdoc.rb +8 -1
  277. data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +1 -1
  278. data/lib/puppet/util/suidmanager.rb +1 -8
  279. data/lib/puppet/util/windows.rb +14 -3
  280. data/lib/puppet/util/windows/access_control_list.rb +4 -4
  281. data/lib/puppet/util/{adsi.rb → windows/adsi.rb} +99 -37
  282. data/lib/puppet/util/windows/api_types.rb +255 -0
  283. data/lib/puppet/util/windows/com.rb +224 -0
  284. data/lib/puppet/util/windows/error.rb +72 -5
  285. data/lib/puppet/util/windows/file.rb +254 -132
  286. data/lib/puppet/util/windows/process.rb +293 -177
  287. data/lib/puppet/util/windows/registry.rb +12 -2
  288. data/lib/puppet/util/windows/root_certs.rb +16 -9
  289. data/lib/puppet/util/windows/security.rb +501 -232
  290. data/lib/puppet/util/windows/sid.rb +80 -36
  291. data/lib/puppet/util/windows/string.rb +2 -0
  292. data/lib/puppet/util/windows/taskscheduler.rb +1241 -0
  293. data/lib/puppet/util/windows/user.rb +241 -57
  294. data/lib/puppet/vendor.rb +3 -1
  295. data/lib/puppet/vendor/load_pathspec.rb +1 -0
  296. data/lib/puppet/vendor/load_rgen.rb +1 -0
  297. data/lib/puppet/vendor/pathspec/CHANGELOG.md +2 -0
  298. data/lib/puppet/vendor/pathspec/LICENSE +201 -0
  299. data/lib/puppet/vendor/pathspec/PUPPET_README.md +6 -0
  300. data/lib/puppet/vendor/pathspec/README.md +53 -0
  301. data/lib/puppet/vendor/pathspec/lib/pathspec.rb +121 -0
  302. data/lib/puppet/vendor/pathspec/lib/pathspec/gitignorespec.rb +275 -0
  303. data/lib/puppet/vendor/pathspec/lib/pathspec/regexspec.rb +17 -0
  304. data/lib/puppet/vendor/pathspec/lib/pathspec/spec.rb +14 -0
  305. data/lib/puppet/vendor/require_vendored.rb +2 -0
  306. data/lib/puppet/vendor/rgen/CHANGELOG +197 -0
  307. data/lib/puppet/vendor/rgen/MIT-LICENSE +20 -0
  308. data/lib/puppet/vendor/rgen/PUPPET_README.md +6 -0
  309. data/lib/puppet/vendor/rgen/README.rdoc +78 -0
  310. data/lib/puppet/vendor/rgen/Rakefile +41 -0
  311. data/lib/puppet/vendor/rgen/TODO +41 -0
  312. data/lib/puppet/vendor/rgen/anounce.txt +61 -0
  313. data/lib/puppet/vendor/rgen/design_rationale.txt +71 -0
  314. data/lib/puppet/vendor/rgen/lib/ea_support/ea_support.rb +54 -0
  315. data/lib/puppet/vendor/rgen/lib/ea_support/id_store.rb +32 -0
  316. data/lib/puppet/vendor/rgen/lib/ea_support/uml13_ea_metamodel.rb +562 -0
  317. data/lib/puppet/vendor/rgen/lib/ea_support/uml13_ea_metamodel_ext.rb +45 -0
  318. data/lib/puppet/vendor/rgen/lib/ea_support/uml13_ea_metamodel_generator.rb +43 -0
  319. data/lib/puppet/vendor/rgen/lib/ea_support/uml13_ea_to_uml13.rb +103 -0
  320. data/lib/puppet/vendor/rgen/lib/ea_support/uml13_to_uml13_ea.rb +89 -0
  321. data/lib/puppet/vendor/rgen/lib/metamodels/uml13_metamodel.rb +559 -0
  322. data/lib/puppet/vendor/rgen/lib/metamodels/uml13_metamodel_ext.rb +26 -0
  323. data/lib/puppet/vendor/rgen/lib/mmgen/metamodel_generator.rb +20 -0
  324. data/lib/puppet/vendor/rgen/lib/mmgen/mm_ext/ecore_mmgen_ext.rb +91 -0
  325. data/lib/puppet/vendor/rgen/lib/mmgen/mmgen.rb +28 -0
  326. data/lib/puppet/vendor/rgen/lib/mmgen/templates/annotations.tpl +37 -0
  327. data/lib/puppet/vendor/rgen/lib/mmgen/templates/metamodel_generator.tpl +172 -0
  328. data/lib/puppet/vendor/rgen/lib/rgen/array_extensions.rb +45 -0
  329. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ecore.rb +218 -0
  330. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ecore_builder_methods.rb +81 -0
  331. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ecore_ext.rb +69 -0
  332. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ecore_interface.rb +47 -0
  333. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ecore_to_ruby.rb +167 -0
  334. data/lib/puppet/vendor/rgen/lib/rgen/ecore/ruby_to_ecore.rb +91 -0
  335. data/lib/puppet/vendor/rgen/lib/rgen/environment.rb +129 -0
  336. data/lib/puppet/vendor/rgen/lib/rgen/fragment/dump_file_cache.rb +63 -0
  337. data/lib/puppet/vendor/rgen/lib/rgen/fragment/fragmented_model.rb +140 -0
  338. data/lib/puppet/vendor/rgen/lib/rgen/fragment/model_fragment.rb +289 -0
  339. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/abstract_instantiator.rb +66 -0
  340. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/abstract_xml_instantiator.rb +66 -0
  341. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
  342. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/ecore_xml_instantiator.rb +169 -0
  343. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/json_instantiator.rb +126 -0
  344. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/json_parser.rb +331 -0
  345. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/json_parser.y +94 -0
  346. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/nodebased_xml_instantiator.rb +137 -0
  347. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/qualified_name_resolver.rb +97 -0
  348. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/reference_resolver.rb +128 -0
  349. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/resolution_helper.rb +47 -0
  350. data/lib/puppet/vendor/rgen/lib/rgen/instantiator/xmi11_instantiator.rb +168 -0
  351. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder.rb +224 -0
  352. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/builder_extensions.rb +556 -0
  353. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/builder_runtime.rb +174 -0
  354. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/constant_order_helper.rb +89 -0
  355. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/data_types.rb +77 -0
  356. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
  357. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/intermediate/feature.rb +168 -0
  358. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
  359. data/lib/puppet/vendor/rgen/lib/rgen/metamodel_builder/module_extension.rb +42 -0
  360. data/lib/puppet/vendor/rgen/lib/rgen/model_builder.rb +32 -0
  361. data/lib/puppet/vendor/rgen/lib/rgen/model_builder/builder_context.rb +334 -0
  362. data/lib/puppet/vendor/rgen/lib/rgen/model_builder/model_serializer.rb +225 -0
  363. data/lib/puppet/vendor/rgen/lib/rgen/model_builder/reference_resolver.rb +156 -0
  364. data/lib/puppet/vendor/rgen/lib/rgen/serializer/json_serializer.rb +121 -0
  365. data/lib/puppet/vendor/rgen/lib/rgen/serializer/opposite_reference_filter.rb +18 -0
  366. data/lib/puppet/vendor/rgen/lib/rgen/serializer/qualified_name_provider.rb +47 -0
  367. data/lib/puppet/vendor/rgen/lib/rgen/serializer/xmi11_serializer.rb +116 -0
  368. data/lib/puppet/vendor/rgen/lib/rgen/serializer/xmi20_serializer.rb +71 -0
  369. data/lib/puppet/vendor/rgen/lib/rgen/serializer/xml_serializer.rb +98 -0
  370. data/lib/puppet/vendor/rgen/lib/rgen/template_language.rb +297 -0
  371. data/lib/puppet/vendor/rgen/lib/rgen/template_language/directory_template_container.rb +83 -0
  372. data/lib/puppet/vendor/rgen/lib/rgen/template_language/output_handler.rb +87 -0
  373. data/lib/puppet/vendor/rgen/lib/rgen/template_language/template_container.rb +234 -0
  374. data/lib/puppet/vendor/rgen/lib/rgen/template_language/template_helper.rb +26 -0
  375. data/lib/puppet/vendor/rgen/lib/rgen/transformer.rb +475 -0
  376. data/lib/puppet/vendor/rgen/lib/rgen/util/auto_class_creator.rb +61 -0
  377. data/lib/puppet/vendor/rgen/lib/rgen/util/cached_glob.rb +67 -0
  378. data/lib/puppet/vendor/rgen/lib/rgen/util/file_cache_map.rb +124 -0
  379. data/lib/puppet/vendor/rgen/lib/rgen/util/file_change_detector.rb +84 -0
  380. data/lib/puppet/vendor/rgen/lib/rgen/util/method_delegation.rb +114 -0
  381. data/lib/puppet/vendor/rgen/lib/rgen/util/model_comparator.rb +68 -0
  382. data/lib/puppet/vendor/rgen/lib/rgen/util/model_comparator_base.rb +142 -0
  383. data/lib/puppet/vendor/rgen/lib/rgen/util/model_dumper.rb +29 -0
  384. data/lib/puppet/vendor/rgen/lib/rgen/util/name_helper.rb +42 -0
  385. data/lib/puppet/vendor/rgen/lib/rgen/util/pattern_matcher.rb +329 -0
  386. data/lib/puppet/vendor/rgen/lib/transformers/ecore_to_uml13.rb +79 -0
  387. data/lib/puppet/vendor/rgen/lib/transformers/uml13_to_ecore.rb +127 -0
  388. data/lib/puppet/vendor/rgen/test/array_extensions_test.rb +64 -0
  389. data/lib/puppet/vendor/rgen/test/ea_instantiator_test.rb +35 -0
  390. data/lib/puppet/vendor/rgen/test/ea_serializer_test.rb +23 -0
  391. data/lib/puppet/vendor/rgen/test/ecore_self_test.rb +54 -0
  392. data/lib/puppet/vendor/rgen/test/environment_test.rb +90 -0
  393. data/lib/puppet/vendor/rgen/test/json_test.rb +171 -0
  394. data/lib/puppet/vendor/rgen/test/metamodel_builder_test.rb +1482 -0
  395. data/lib/puppet/vendor/rgen/test/metamodel_from_ecore_test.rb +57 -0
  396. data/lib/puppet/vendor/rgen/test/metamodel_order_test.rb +131 -0
  397. data/lib/puppet/vendor/rgen/test/metamodel_roundtrip_test.rb +98 -0
  398. data/lib/puppet/vendor/rgen/test/metamodel_roundtrip_test/TestModel.rb +70 -0
  399. data/lib/puppet/vendor/rgen/test/metamodel_roundtrip_test/houseMetamodel.ecore +42 -0
  400. data/lib/puppet/vendor/rgen/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +44 -0
  401. data/lib/puppet/vendor/rgen/test/metamodel_roundtrip_test/using_builtin_types.ecore +9 -0
  402. data/lib/puppet/vendor/rgen/test/method_delegation_test.rb +178 -0
  403. data/lib/puppet/vendor/rgen/test/model_builder/builder_context_test.rb +59 -0
  404. data/lib/puppet/vendor/rgen/test/model_builder/builder_test.rb +242 -0
  405. data/lib/puppet/vendor/rgen/test/model_builder/ecore_original.rb +163 -0
  406. data/lib/puppet/vendor/rgen/test/model_builder/ecore_original_regenerated.rb +163 -0
  407. data/lib/puppet/vendor/rgen/test/model_builder/reference_resolver_test.rb +156 -0
  408. data/lib/puppet/vendor/rgen/test/model_builder/serializer_test.rb +94 -0
  409. data/lib/puppet/vendor/rgen/test/model_builder/statemachine_metamodel.rb +42 -0
  410. data/lib/puppet/vendor/rgen/test/model_builder/test_model/statemachine1.rb +23 -0
  411. data/lib/puppet/vendor/rgen/test/model_builder_test.rb +6 -0
  412. data/lib/puppet/vendor/rgen/test/model_fragment_test.rb +30 -0
  413. data/lib/puppet/vendor/rgen/test/output_handler_test.rb +58 -0
  414. data/lib/puppet/vendor/rgen/test/qualified_name_provider_test.rb +48 -0
  415. data/lib/puppet/vendor/rgen/test/qualified_name_resolver_test.rb +102 -0
  416. data/lib/puppet/vendor/rgen/test/reference_resolver_test.rb +117 -0
  417. data/lib/puppet/vendor/rgen/test/rgen_test.rb +26 -0
  418. data/lib/puppet/vendor/rgen/test/template_language_test.rb +163 -0
  419. data/lib/puppet/vendor/rgen/test/template_language_test/expected_result1.txt +29 -0
  420. data/lib/puppet/vendor/rgen/test/template_language_test/expected_result2.txt +9 -0
  421. data/lib/puppet/vendor/rgen/test/template_language_test/expected_result3.txt +4 -0
  422. data/lib/puppet/vendor/rgen/test/template_language_test/indentStringTestDefaultIndent.out +1 -0
  423. data/lib/puppet/vendor/rgen/test/template_language_test/indentStringTestTabIndent.out +1 -0
  424. data/lib/puppet/vendor/rgen/test/template_language_test/templates/callback_indent_test/a.tpl +12 -0
  425. data/lib/puppet/vendor/rgen/test/template_language_test/templates/callback_indent_test/b.tpl +5 -0
  426. data/lib/puppet/vendor/rgen/test/template_language_test/templates/code/array.tpl +11 -0
  427. data/lib/puppet/vendor/rgen/test/template_language_test/templates/content/author.tpl +7 -0
  428. data/lib/puppet/vendor/rgen/test/template_language_test/templates/content/chapter.tpl +5 -0
  429. data/lib/puppet/vendor/rgen/test/template_language_test/templates/define_local_test/local.tpl +8 -0
  430. data/lib/puppet/vendor/rgen/test/template_language_test/templates/define_local_test/test.tpl +8 -0
  431. data/lib/puppet/vendor/rgen/test/template_language_test/templates/evaluate_test/test.tpl +7 -0
  432. data/lib/puppet/vendor/rgen/test/template_language_test/templates/indent_string_test.tpl +12 -0
  433. data/lib/puppet/vendor/rgen/test/template_language_test/templates/index/c/cmod.tpl +1 -0
  434. data/lib/puppet/vendor/rgen/test/template_language_test/templates/index/chapter.tpl +3 -0
  435. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_backslash_r_test.tpl +5 -0
  436. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_indent_test/no_indent.tpl +3 -0
  437. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_indent_test/sub1/no_indent.tpl +3 -0
  438. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_indent_test/test.tpl +24 -0
  439. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_indent_test/test2.tpl +13 -0
  440. data/lib/puppet/vendor/rgen/test/template_language_test/templates/no_indent_test/test3.tpl +10 -0
  441. data/lib/puppet/vendor/rgen/test/template_language_test/templates/null_context_test.tpl +17 -0
  442. data/lib/puppet/vendor/rgen/test/template_language_test/templates/root.tpl +31 -0
  443. data/lib/puppet/vendor/rgen/test/template_language_test/templates/template_resolution_test/sub1.tpl +9 -0
  444. data/lib/puppet/vendor/rgen/test/template_language_test/templates/template_resolution_test/sub1/sub1.tpl +3 -0
  445. data/lib/puppet/vendor/rgen/test/template_language_test/templates/template_resolution_test/test.tpl +4 -0
  446. data/lib/puppet/vendor/rgen/test/template_language_test/testout.txt +29 -0
  447. data/lib/puppet/vendor/rgen/test/testmodel/class_model_checker.rb +119 -0
  448. data/lib/puppet/vendor/rgen/test/testmodel/ea_testmodel.eap +0 -0
  449. data/lib/puppet/vendor/rgen/test/testmodel/ea_testmodel.xml +1029 -0
  450. data/lib/puppet/vendor/rgen/test/testmodel/ea_testmodel_partial.xml +317 -0
  451. data/lib/puppet/vendor/rgen/test/testmodel/ecore_model_checker.rb +101 -0
  452. data/lib/puppet/vendor/rgen/test/testmodel/manual_testmodel.xml +22 -0
  453. data/lib/puppet/vendor/rgen/test/testmodel/object_model_checker.rb +67 -0
  454. data/lib/puppet/vendor/rgen/test/transformer_test.rb +254 -0
  455. data/lib/puppet/vendor/rgen/test/util/file_cache_map_test.rb +99 -0
  456. data/lib/puppet/vendor/rgen/test/util/pattern_matcher_test.rb +97 -0
  457. data/lib/puppet/vendor/rgen/test/util_test.rb +5 -0
  458. data/lib/puppet/vendor/rgen/test/xml_instantiator_test.rb +160 -0
  459. data/lib/puppet/vendor/rgen/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
  460. data/lib/puppet/vendor/rgen/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
  461. data/lib/puppet/vendor/rgen/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
  462. data/lib/puppet/vendor/rgen/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
  463. data/lib/puppet/vendor/safe_yaml/PUPPET_README.md +6 -0
  464. data/lib/puppet/vendor/semantic/PUPPET_README.md +6 -0
  465. data/lib/puppet/version.rb +1 -1
  466. data/spec/fixtures/integration/node/environment/sitedir2/00_a.pp +2 -0
  467. data/spec/fixtures/integration/node/environment/sitedir2/02_folder/01_b.pp +6 -0
  468. data/spec/fixtures/integration/node/environment/sitedir2/03_c.pp +1 -0
  469. data/spec/fixtures/integration/node/environment/sitedir2/04_include.pp +2 -0
  470. data/spec/fixtures/releases/jamtur01-apache/manifests/vhost.pp +1 -1
  471. data/spec/fixtures/unit/indirector/hiera/global.yaml +10 -0
  472. data/spec/fixtures/unit/indirector/hiera/invalid.yaml +1 -0
  473. data/spec/fixtures/unit/parser/functions/create_resources/foo/manifests/init.pp +3 -0
  474. data/spec/fixtures/unit/parser/functions/create_resources/foo/manifests/wrongdefine.pp +3 -0
  475. data/spec/fixtures/unit/parser/lexer/argumentdefaults.pp +2 -2
  476. data/spec/fixtures/unit/parser/lexer/casestatement.pp +14 -14
  477. data/spec/fixtures/unit/parser/lexer/classheirarchy.pp +3 -3
  478. data/spec/fixtures/unit/parser/lexer/classincludes.pp +3 -3
  479. data/spec/fixtures/unit/parser/lexer/classpathtest.pp +1 -1
  480. data/spec/fixtures/unit/parser/lexer/collection_override.pp +1 -1
  481. data/spec/fixtures/unit/parser/lexer/componentrequire.pp +2 -2
  482. data/spec/fixtures/unit/parser/lexer/deepclassheirarchy.pp +5 -5
  483. data/spec/fixtures/unit/parser/lexer/defineoverrides.pp +2 -2
  484. data/spec/fixtures/unit/parser/lexer/filecreate.pp +2 -2
  485. data/spec/fixtures/unit/parser/lexer/ifexpression.pp +1 -1
  486. data/spec/fixtures/unit/parser/lexer/implicititeration.pp +4 -4
  487. data/spec/fixtures/unit/parser/lexer/multipleinstances.pp +3 -3
  488. data/spec/fixtures/unit/parser/lexer/multisubs.pp +2 -2
  489. data/spec/fixtures/unit/parser/lexer/namevartest.pp +2 -2
  490. data/spec/fixtures/unit/parser/lexer/simpledefaults.pp +1 -1
  491. data/spec/fixtures/unit/pops/parser/lexer/argumentdefaults.pp +1 -1
  492. data/spec/fixtures/unit/pops/parser/lexer/casestatement.pp +14 -14
  493. data/spec/fixtures/unit/pops/parser/lexer/classheirarchy.pp +3 -3
  494. data/spec/fixtures/unit/pops/parser/lexer/classincludes.pp +3 -3
  495. data/spec/fixtures/unit/pops/parser/lexer/classpathtest.pp +1 -1
  496. data/spec/fixtures/unit/pops/parser/lexer/collection_override.pp +1 -1
  497. data/spec/fixtures/unit/pops/parser/lexer/componentrequire.pp +2 -2
  498. data/spec/fixtures/unit/pops/parser/lexer/deepclassheirarchy.pp +5 -5
  499. data/spec/fixtures/unit/pops/parser/lexer/defineoverrides.pp +2 -2
  500. data/spec/fixtures/unit/pops/parser/lexer/filecreate.pp +2 -2
  501. data/spec/fixtures/unit/pops/parser/lexer/ifexpression.pp +1 -1
  502. data/spec/fixtures/unit/pops/parser/lexer/implicititeration.pp +4 -4
  503. data/spec/fixtures/unit/pops/parser/lexer/multipleinstances.pp +3 -3
  504. data/spec/fixtures/unit/pops/parser/lexer/multisubs.pp +2 -2
  505. data/spec/fixtures/unit/pops/parser/lexer/namevartest.pp +2 -2
  506. data/spec/fixtures/unit/pops/parser/lexer/simpledefaults.pp +1 -1
  507. data/spec/fixtures/unit/provider/package/gem/gem-list-single-package +4 -0
  508. data/spec/fixtures/unit/type/user/authorized_keys +1 -1
  509. data/spec/integration/agent/logging_spec.rb +4 -0
  510. data/spec/integration/application/doc_spec.rb +4 -3
  511. data/spec/integration/configurer_spec.rb +0 -14
  512. data/spec/integration/defaults_spec.rb +26 -0
  513. data/spec/integration/environments/default_manifest_spec.rb +274 -0
  514. data/spec/integration/faces/documentation_spec.rb +0 -4
  515. data/spec/integration/file_bucket/file_spec.rb +21 -0
  516. data/spec/integration/indirector/catalog/compiler_spec.rb +0 -2
  517. data/spec/integration/indirector/catalog/queue_spec.rb +0 -2
  518. data/spec/integration/indirector/facts/facter_spec.rb +1 -1
  519. data/spec/integration/indirector/file_content/file_server_spec.rb +2 -2
  520. data/spec/integration/node/environment_spec.rb +24 -8
  521. data/spec/integration/parser/catalog_spec.rb +10 -10
  522. data/spec/integration/parser/class_spec.rb +37 -0
  523. data/spec/integration/parser/collector_spec.rb +234 -75
  524. data/spec/integration/parser/compiler_spec.rb +385 -401
  525. data/spec/integration/parser/conditionals_spec.rb +117 -0
  526. data/spec/integration/parser/future_compiler_spec.rb +359 -8
  527. data/spec/integration/parser/node_spec.rb +185 -0
  528. data/spec/integration/parser/resource_expressions_spec.rb +286 -0
  529. data/spec/integration/parser/ruby_manifest_spec.rb +0 -4
  530. data/spec/integration/parser/scope_spec.rb +94 -151
  531. data/spec/integration/provider/cron/crontab_spec.rb +137 -148
  532. data/spec/integration/ssl/certificate_authority_spec.rb +26 -0
  533. data/spec/integration/ssl/certificate_request_spec.rb +0 -6
  534. data/spec/integration/ssl/certificate_revocation_list_spec.rb +0 -2
  535. data/spec/integration/ssl/host_spec.rb +0 -2
  536. data/spec/integration/transaction_spec.rb +16 -0
  537. data/spec/integration/type/file_spec.rb +14 -13
  538. data/spec/integration/type/nagios_spec.rb +6 -15
  539. data/spec/integration/type/sshkey_spec.rb +22 -0
  540. data/spec/integration/type/tidy_spec.rb +3 -0
  541. data/spec/integration/type/user_spec.rb +8 -3
  542. data/spec/integration/util/autoload_spec.rb +6 -6
  543. data/spec/integration/util/rdoc/parser_spec.rb +7 -0
  544. data/spec/integration/util/windows/process_spec.rb +12 -0
  545. data/spec/integration/util/windows/security_spec.rb +36 -35
  546. data/spec/integration/util/windows/user_spec.rb +75 -9
  547. data/spec/integration/util_spec.rb +2 -2
  548. data/spec/lib/matchers/resource.rb +1 -0
  549. data/spec/lib/puppet_spec/compiler.rb +15 -2
  550. data/spec/lib/puppet_spec/files.rb +10 -0
  551. data/spec/lib/puppet_spec/language.rb +74 -0
  552. data/spec/lib/puppet_spec/matchers.rb +59 -32
  553. data/spec/lib/puppet_spec/module_tool/stub_source.rb +3 -0
  554. data/spec/shared_behaviours/hiera_indirections.rb +99 -0
  555. data/spec/shared_behaviours/iterative_functions.rb +69 -0
  556. data/spec/unit/application/apply_spec.rb +4 -2
  557. data/spec/unit/application/doc_spec.rb +17 -13
  558. data/spec/unit/application/master_spec.rb +35 -27
  559. data/spec/unit/application/resource_spec.rb +0 -5
  560. data/spec/unit/configurer/downloader_factory_spec.rb +96 -0
  561. data/spec/unit/configurer/downloader_spec.rb +3 -24
  562. data/spec/unit/configurer/plugin_handler_spec.rb +22 -22
  563. data/spec/unit/configurer_spec.rb +0 -4
  564. data/spec/unit/defaults_spec.rb +30 -0
  565. data/spec/unit/face/config_spec.rb +2 -1
  566. data/spec/unit/face/module/build_spec.rb +2 -2
  567. data/spec/unit/face/module/install_spec.rb +8 -8
  568. data/spec/unit/face/parser_spec.rb +71 -33
  569. data/spec/unit/file_bucket/file_spec.rb +2 -2
  570. data/spec/unit/file_system/uniquefile_spec.rb +184 -0
  571. data/spec/unit/forge/errors_spec.rb +4 -6
  572. data/spec/unit/forge/module_release_spec.rb +178 -89
  573. data/spec/unit/forge/repository_spec.rb +110 -2
  574. data/spec/unit/forge_spec.rb +39 -3
  575. data/spec/unit/functions/assert_type_spec.rb +22 -3
  576. data/spec/unit/{parser/methods → functions}/each_spec.rb +21 -1
  577. data/spec/unit/{parser/functions → functions}/epp_spec.rb +61 -9
  578. data/spec/unit/{parser/methods → functions}/filter_spec.rb +34 -38
  579. data/spec/unit/{parser/functions → functions}/inline_epp_spec.rb +18 -3
  580. data/spec/unit/functions/map_spec.rb +169 -0
  581. data/spec/unit/functions/match_spec.rb +57 -0
  582. data/spec/unit/{parser/methods → functions}/reduce_spec.rb +23 -5
  583. data/spec/unit/{parser/methods → functions}/slice_spec.rb +34 -21
  584. data/spec/unit/functions/with_spec.rb +35 -0
  585. data/spec/unit/functions4_spec.rb +7 -8
  586. data/spec/unit/indirector/catalog/compiler_spec.rb +0 -2
  587. data/spec/unit/indirector/catalog/static_compiler_spec.rb +11 -0
  588. data/spec/unit/indirector/data_binding/hiera_spec.rb +1 -96
  589. data/spec/unit/indirector/facts/facter_spec.rb +69 -102
  590. data/spec/unit/indirector/hiera_spec.rb +17 -0
  591. data/spec/unit/indirector/request_spec.rb +2 -4
  592. data/spec/unit/indirector/resource/ral_spec.rb +5 -0
  593. data/spec/unit/indirector/resource_type/parser_spec.rb +17 -12
  594. data/spec/unit/indirector/rest_spec.rb +36 -6
  595. data/spec/unit/interface/face_collection_spec.rb +2 -2
  596. data/spec/unit/module_tool/applications/builder_spec.rb +364 -14
  597. data/spec/unit/module_tool/applications/uninstaller_spec.rb +22 -0
  598. data/spec/unit/module_tool/applications/unpacker_spec.rb +40 -0
  599. data/spec/unit/module_tool/applications/upgrader_spec.rb +22 -0
  600. data/spec/unit/module_tool/installed_modules_spec.rb +49 -0
  601. data/spec/unit/module_tool/metadata_spec.rb +72 -4
  602. data/spec/unit/module_tool/tar/mini_spec.rb +2 -1
  603. data/spec/unit/network/authentication_spec.rb +4 -0
  604. data/spec/unit/network/http/api/v2/environments_spec.rb +24 -3
  605. data/spec/unit/network/http/connection_spec.rb +127 -92
  606. data/spec/unit/network/http/factory_spec.rb +82 -0
  607. data/spec/unit/network/http/handler_spec.rb +23 -13
  608. data/spec/unit/network/http/nocache_pool_spec.rb +43 -0
  609. data/spec/unit/network/http/pool_spec.rb +269 -0
  610. data/spec/unit/network/http/rack/rest_spec.rb +1 -1
  611. data/spec/unit/network/http/session_spec.rb +43 -0
  612. data/spec/unit/network/http/site_spec.rb +90 -0
  613. data/spec/unit/network/http/webrick_spec.rb +1 -1
  614. data/spec/unit/network/http_pool_spec.rb +9 -6
  615. data/spec/unit/network/http_spec.rb +10 -0
  616. data/spec/unit/node/environment_spec.rb +54 -0
  617. data/spec/unit/node_spec.rb +3 -5
  618. data/spec/unit/parser/compiler_spec.rb +9 -2
  619. data/spec/unit/parser/files_spec.rb +19 -0
  620. data/spec/unit/parser/functions/contain_spec.rb +51 -0
  621. data/spec/unit/parser/functions/create_resources_spec.rb +8 -1
  622. data/spec/unit/parser/functions/digest_spec.rb +31 -0
  623. data/spec/unit/parser/functions/file_spec.rb +48 -5
  624. data/spec/unit/parser/functions/include_spec.rb +15 -1
  625. data/spec/unit/parser/functions/realize_spec.rb +43 -35
  626. data/spec/unit/parser/functions/require_spec.rb +19 -5
  627. data/spec/unit/parser/functions/search_spec.rb +5 -0
  628. data/spec/unit/parser/functions/shared.rb +82 -0
  629. data/spec/unit/parser/functions_spec.rb +1 -1
  630. data/spec/unit/parser/lexer_spec.rb +10 -1
  631. data/spec/unit/parser/type_loader_spec.rb +0 -1
  632. data/spec/unit/pops/benchmark_spec.rb +1 -1
  633. data/spec/unit/pops/binder/bindings_composer_spec.rb +24 -22
  634. data/spec/unit/pops/binder/injector_spec.rb +8 -6
  635. data/spec/unit/pops/evaluator/access_ops_spec.rb +3 -3
  636. data/spec/unit/pops/evaluator/comparison_ops_spec.rb +7 -4
  637. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +250 -30
  638. data/spec/unit/pops/evaluator/logical_ops_spec.rb +2 -2
  639. data/spec/unit/pops/evaluator/variables_spec.rb +0 -105
  640. data/spec/unit/pops/issues_spec.rb +170 -0
  641. data/spec/unit/pops/loaders/dependency_loader_spec.rb +17 -0
  642. data/spec/unit/pops/loaders/loader_paths_spec.rb +4 -15
  643. data/spec/unit/pops/loaders/loaders_spec.rb +31 -11
  644. data/spec/unit/pops/loaders/module_loaders_spec.rb +0 -29
  645. data/spec/unit/pops/loaders/static_loader_spec.rb +6 -0
  646. data/spec/unit/pops/parser/epp_parser_spec.rb +38 -9
  647. data/spec/unit/pops/parser/evaluating_parser_spec.rb +0 -1
  648. data/spec/unit/pops/parser/lexer2_spec.rb +21 -4
  649. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +5 -0
  650. data/spec/unit/pops/parser/parse_calls_spec.rb +6 -3
  651. data/spec/unit/pops/parser/parse_conditionals_spec.rb +12 -5
  652. data/spec/unit/pops/parser/parse_containers_spec.rb +62 -7
  653. data/spec/unit/pops/parser/parse_resource_spec.rb +155 -73
  654. data/spec/unit/pops/parser/parser_spec.rb +16 -0
  655. data/spec/unit/pops/parser/parsing_typed_parameters_spec.rb +72 -0
  656. data/spec/unit/pops/transformer/transform_calls_spec.rb +1 -1
  657. data/spec/unit/pops/types/type_calculator_spec.rb +254 -57
  658. data/spec/unit/pops/types/type_factory_spec.rb +8 -3
  659. data/spec/unit/pops/types/type_parser_spec.rb +26 -5
  660. data/spec/unit/pops/validator/validator_spec.rb +143 -27
  661. data/spec/unit/provider/exec/posix_spec.rb +22 -14
  662. data/spec/unit/provider/exec/shell_spec.rb +2 -2
  663. data/spec/unit/provider/file/windows_spec.rb +7 -7
  664. data/spec/unit/provider/group/windows_adsi_spec.rb +17 -17
  665. data/spec/unit/provider/package/gem_spec.rb +10 -0
  666. data/spec/unit/provider/package/openbsd_spec.rb +66 -9
  667. data/spec/unit/provider/package/pacman_spec.rb +90 -71
  668. data/spec/unit/provider/package/windows/package_spec.rb +21 -6
  669. data/spec/unit/provider/package/yum_spec.rb +1 -0
  670. data/spec/unit/provider/parsedfile_spec.rb +1 -1
  671. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +9 -9
  672. data/spec/unit/provider/service/openbsd_spec.rb +26 -2
  673. data/spec/unit/provider/service/upstart_spec.rb +12 -1
  674. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +6 -0
  675. data/spec/unit/provider/user/user_role_add_spec.rb +23 -1
  676. data/spec/unit/provider/user/windows_adsi_spec.rb +17 -17
  677. data/spec/unit/reports/store_spec.rb +0 -16
  678. data/spec/unit/resource/catalog_spec.rb +0 -5
  679. data/spec/unit/resource_spec.rb +2 -2
  680. data/spec/unit/settings/autosign_setting_spec.rb +2 -2
  681. data/spec/unit/settings/environment_conf_spec.rb +77 -10
  682. data/spec/unit/settings/file_setting_spec.rb +5 -4
  683. data/spec/unit/settings/priority_setting_spec.rb +4 -4
  684. data/spec/unit/settings_spec.rb +41 -3
  685. data/spec/unit/ssl/certificate_authority_spec.rb +25 -2
  686. data/spec/unit/ssl/inventory_spec.rb +13 -0
  687. data/spec/unit/ssl/validator_spec.rb +0 -1
  688. data/spec/unit/transaction/resource_harness_spec.rb +64 -0
  689. data/spec/unit/transaction_spec.rb +98 -47
  690. data/spec/unit/type/cron_spec.rb +3 -3
  691. data/spec/unit/type/exec_spec.rb +9 -0
  692. data/spec/unit/type/file/content_spec.rb +54 -71
  693. data/spec/unit/type/file/mode_spec.rb +26 -1
  694. data/spec/unit/type/file/source_spec.rb +26 -4
  695. data/spec/unit/type/file_spec.rb +3 -3
  696. data/spec/unit/type/nagios_spec.rb +12 -3
  697. data/spec/unit/type/resources_spec.rb +64 -30
  698. data/spec/unit/type/user_spec.rb +1 -1
  699. data/spec/unit/type/yumrepo_spec.rb +136 -0
  700. data/spec/unit/type/zone_spec.rb +44 -1
  701. data/spec/unit/type_spec.rb +20 -0
  702. data/spec/unit/util/colors_spec.rb +14 -8
  703. data/spec/unit/util/command_line_spec.rb +11 -7
  704. data/spec/unit/util/execution_spec.rb +35 -42
  705. data/spec/unit/util/feature_spec.rb +12 -0
  706. data/spec/unit/util/http_proxy_spec.rb +43 -1
  707. data/spec/unit/util/log/destinations_spec.rb +45 -1
  708. data/spec/unit/util/logging_spec.rb +38 -0
  709. data/spec/unit/util/pidlock_spec.rb +37 -1
  710. data/spec/unit/util/profiler/aggregate_spec.rb +59 -0
  711. data/spec/unit/util/profiler/around_profiler_spec.rb +61 -0
  712. data/spec/unit/util/profiler/logging_spec.rb +18 -29
  713. data/spec/unit/util/profiler/wall_clock_spec.rb +1 -1
  714. data/spec/unit/util/profiler_spec.rb +55 -0
  715. data/spec/unit/util/queue_spec.rb +0 -1
  716. data/spec/unit/util/rdoc/parser_spec.rb +14 -6
  717. data/spec/unit/util/tagging_spec.rb +1 -1
  718. data/spec/unit/util/windows/access_control_entry_spec.rb +1 -1
  719. data/spec/unit/util/{adsi_spec.rb → windows/adsi_spec.rb} +111 -108
  720. data/spec/unit/util/windows/api_types_spec.rb +28 -0
  721. data/spec/unit/util/windows/registry_spec.rb +7 -6
  722. data/spec/unit/util/windows/sid_spec.rb +3 -6
  723. data/spec/unit/util/windows/string_spec.rb +4 -0
  724. data/spec/unit/util/zaml_spec.rb +5 -1
  725. data/tasks/benchmark.rake +40 -5
  726. data/tasks/parser.rake +16 -2
  727. data/tasks/yard.rake +1 -1
  728. metadata +296 -68
  729. data/lib/puppet/file_system/tempfile.rb +0 -20
  730. data/lib/puppet/parser/e_parser_adapter.rb +0 -119
  731. data/lib/puppet/parser/functions/collect.rb +0 -15
  732. data/lib/puppet/parser/functions/select.rb +0 -15
  733. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +0 -109
  734. data/lib/puppet/pops/parser/lexer.rb +0 -753
  735. data/lib/puppet/pops/parser/makefile +0 -6
  736. data/lib/puppet/pops/validation/checker3_1.rb +0 -558
  737. data/lib/puppet/pops/validation/validator_factory_3_1.rb +0 -31
  738. data/lib/puppet/util/profiler/none.rb +0 -8
  739. data/spec/unit/face/certificate_request_spec.rb +0 -7
  740. data/spec/unit/face/certificate_revocation_list_spec.rb +0 -7
  741. data/spec/unit/face/key_spec.rb +0 -7
  742. data/spec/unit/face/report_spec.rb +0 -7
  743. data/spec/unit/face/resource_spec.rb +0 -7
  744. data/spec/unit/face/resource_type_spec.rb +0 -7
  745. data/spec/unit/file_system/tempfile_spec.rb +0 -48
  746. data/spec/unit/parser/eparser_adapter_spec.rb +0 -407
  747. data/spec/unit/parser/methods/map_spec.rb +0 -184
  748. data/spec/unit/parser/methods/shared.rb +0 -45
  749. data/spec/unit/pops/parser/lexer_spec.rb +0 -840
  750. data/spec/unit/pops/transformer/transform_resource_spec.rb +0 -185
  751. data/spec/unit/util/profiler/none_spec.rb +0 -12
@@ -2,14 +2,8 @@ require 'puppet/util/windows'
2
2
 
3
3
  module Puppet::Util::Windows
4
4
  module SID
5
- require 'windows/security'
6
- include ::Windows::Security
7
-
8
- require 'windows/memory'
9
- include ::Windows::Memory
10
-
11
- require 'windows/msvcrt/string'
12
- include ::Windows::MSVCRT::String
5
+ require 'ffi'
6
+ extend FFI::Library
13
7
 
14
8
  # missing from Windows::Error
15
9
  ERROR_NONE_MAPPED = 1332
@@ -24,6 +18,7 @@ module Puppet::Util::Windows
24
18
 
25
19
  sid ? sid.to_s : nil
26
20
  end
21
+ module_function :name_to_sid
27
22
 
28
23
  # Convert an account name, e.g. 'Administrators' into a SID object,
29
24
  # e.g. 'S-1-5-32-544'. The name can be specified as 'Administrators',
@@ -40,6 +35,7 @@ module Puppet::Util::Windows
40
35
  rescue
41
36
  nil
42
37
  end
38
+ module_function :name_to_sid_object
43
39
 
44
40
  # Converts an octet string array of bytes to a SID object,
45
41
  # e.g. [1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0] is the representation for
@@ -52,6 +48,7 @@ module Puppet::Util::Windows
52
48
 
53
49
  Win32::Security::SID.new(bytes.pack('C*'))
54
50
  end
51
+ module_function :octet_string_to_sid_object
55
52
 
56
53
  # Convert a SID string, e.g. "S-1-5-32-544" to a name,
57
54
  # e.g. 'BUILTIN\Administrators'. Returns nil if an account
@@ -67,52 +64,99 @@ module Puppet::Util::Windows
67
64
  rescue
68
65
  nil
69
66
  end
67
+ module_function :sid_to_name
68
+
69
+ # http://stackoverflow.com/a/1792930 - 68 bytes, 184 characters in a string
70
+ MAXIMUM_SID_STRING_LENGTH = 184
70
71
 
71
72
  # Convert a SID pointer to a SID string, e.g. "S-1-5-32-544".
72
73
  def sid_ptr_to_string(psid)
73
- sid_buf = 0.chr * 256
74
- str_ptr = 0.chr * 4
74
+ if ! psid.instance_of?(FFI::Pointer) || IsValidSid(psid) == FFI::WIN32_FALSE
75
+ raise Puppet::Util::Windows::Error.new("Invalid SID")
76
+ end
75
77
 
76
- raise Puppet::Util::Windows::Error.new("Invalid SID") unless IsValidSid(psid)
78
+ sid_string = nil
79
+ FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr|
80
+ if ConvertSidToStringSidW(psid, buffer_ptr) == FFI::WIN32_FALSE
81
+ raise Puppet::Util::Windows::Error.new("Failed to convert binary SID")
82
+ end
77
83
 
78
- raise Puppet::Util::Windows::Error.new("Failed to convert binary SID") unless ConvertSidToStringSid(psid, str_ptr)
84
+ buffer_ptr.read_win32_local_pointer do |wide_string_ptr|
85
+ if wide_string_ptr.null?
86
+ raise Puppet::Error.new("ConvertSidToStringSidW failed to allocate buffer for sid")
87
+ end
79
88
 
80
- begin
81
- strncpy(sid_buf, str_ptr.unpack('L')[0], sid_buf.size - 1)
82
- sid_buf[sid_buf.size - 1] = 0.chr
83
- return sid_buf.strip
84
- ensure
85
- LocalFree(str_ptr.unpack('L')[0])
89
+ sid_string = wide_string_ptr.read_arbitrary_wide_string_up_to(MAXIMUM_SID_STRING_LENGTH)
90
+ end
86
91
  end
92
+
93
+ sid_string
87
94
  end
95
+ module_function :sid_ptr_to_string
88
96
 
89
97
  # Convert a SID string, e.g. "S-1-5-32-544" to a pointer (containing the
90
98
  # address of the binary SID structure). The returned value can be used in
91
99
  # Win32 APIs that expect a PSID, e.g. IsValidSid. The account for this
92
100
  # SID may or may not exist.
93
- def string_to_sid_ptr(string, &block)
94
- sid_buf = 0.chr * 80
95
- string_addr = [string].pack('p*').unpack('L')[0]
96
-
97
- raise Puppet::Util::Windows::Error.new("Failed to convert string SID: #{string}") unless ConvertStringSidToSid(string_addr, sid_buf)
98
-
99
- sid_ptr = sid_buf.unpack('L')[0]
100
- begin
101
- yield sid_ptr
102
- ensure
103
- LocalFree(sid_ptr)
101
+ def string_to_sid_ptr(string_sid, &block)
102
+ FFI::MemoryPointer.from_string_to_wide_string(string_sid) do |lpcwstr|
103
+ FFI::MemoryPointer.new(:pointer, 1) do |sid_ptr_ptr|
104
+
105
+ if ConvertStringSidToSidW(lpcwstr, sid_ptr_ptr) == FFI::WIN32_FALSE
106
+ raise Puppet::Util::Windows::Error.new("Failed to convert string SID: #{string_sid}")
107
+ end
108
+
109
+ sid_ptr_ptr.read_win32_local_pointer do |sid_ptr|
110
+ yield sid_ptr
111
+ end
112
+ end
104
113
  end
114
+
115
+ # yielded sid_ptr has already had LocalFree called, nothing to return
116
+ nil
105
117
  end
118
+ module_function :string_to_sid_ptr
106
119
 
107
120
  # Return true if the string is a valid SID, e.g. "S-1-5-32-544", false otherwise.
108
- def valid_sid?(string)
109
- string_to_sid_ptr(string) { |ptr| true }
110
- rescue Puppet::Util::Windows::Error => e
111
- if e.code == ERROR_INVALID_SID_STRUCTURE
112
- false
113
- else
114
- raise
121
+ def valid_sid?(string_sid)
122
+ valid = false
123
+
124
+ begin
125
+ string_to_sid_ptr(string_sid) { |ptr| valid = ! ptr.nil? && ! ptr.null? }
126
+ rescue Puppet::Util::Windows::Error => e
127
+ raise if e.code != ERROR_INVALID_SID_STRUCTURE
115
128
  end
129
+
130
+ valid
116
131
  end
132
+ module_function :valid_sid?
133
+
134
+ ffi_convention :stdcall
135
+
136
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa379151(v=vs.85).aspx
137
+ # BOOL WINAPI IsValidSid(
138
+ # _In_ PSID pSid
139
+ # );
140
+ ffi_lib :advapi32
141
+ attach_function_private :IsValidSid,
142
+ [:pointer], :win32_bool
143
+
144
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa376399(v=vs.85).aspx
145
+ # BOOL ConvertSidToStringSid(
146
+ # _In_ PSID Sid,
147
+ # _Out_ LPTSTR *StringSid
148
+ # );
149
+ ffi_lib :advapi32
150
+ attach_function_private :ConvertSidToStringSidW,
151
+ [:pointer, :pointer], :win32_bool
152
+
153
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa376402(v=vs.85).aspx
154
+ # BOOL WINAPI ConvertStringSidToSid(
155
+ # _In_ LPCTSTR StringSid,
156
+ # _Out_ PSID *Sid
157
+ # );
158
+ ffi_lib :advapi32
159
+ attach_function_private :ConvertStringSidToSidW,
160
+ [:lpcwstr, :pointer], :win32_bool
117
161
  end
118
162
  end
@@ -2,6 +2,8 @@ require 'puppet/util/windows'
2
2
 
3
3
  module Puppet::Util::Windows::String
4
4
  def wide_string(str)
5
+ # if given a nil string, assume caller wants to pass a nil pointer to win32
6
+ return nil if str.nil?
5
7
  # ruby (< 2.1) does not respect multibyte terminators, so it is possible
6
8
  # for a string to contain a single trailing null byte, followed by garbage
7
9
  # causing buffer overruns.
@@ -0,0 +1,1241 @@
1
+ require 'puppet/util/windows'
2
+
3
+ # The Win32 module serves as a namespace only
4
+ module Win32
5
+ # The TaskScheduler class encapsulates taskscheduler settings and behavior
6
+ class TaskScheduler
7
+ include Puppet::Util::Windows::String
8
+
9
+ require 'ffi'
10
+ extend FFI::Library
11
+
12
+ # The error class raised if any task scheduler specific calls fail.
13
+ class Error < Puppet::Util::Windows::Error; end
14
+
15
+ private
16
+
17
+ class << self
18
+ attr_accessor :com_initialized
19
+ end
20
+
21
+ # :stopdoc:
22
+ TASK_TIME_TRIGGER_ONCE = :TASK_TIME_TRIGGER_ONCE
23
+ TASK_TIME_TRIGGER_DAILY = :TASK_TIME_TRIGGER_DAILY
24
+ TASK_TIME_TRIGGER_WEEKLY = :TASK_TIME_TRIGGER_WEEKLY
25
+ TASK_TIME_TRIGGER_MONTHLYDATE = :TASK_TIME_TRIGGER_MONTHLYDATE
26
+ TASK_TIME_TRIGGER_MONTHLYDOW = :TASK_TIME_TRIGGER_MONTHLYDOW
27
+ TASK_EVENT_TRIGGER_ON_IDLE = :TASK_EVENT_TRIGGER_ON_IDLE
28
+ TASK_EVENT_TRIGGER_AT_SYSTEMSTART = :TASK_EVENT_TRIGGER_AT_SYSTEMSTART
29
+ TASK_EVENT_TRIGGER_AT_LOGON = :TASK_EVENT_TRIGGER_AT_LOGON
30
+
31
+ TASK_SUNDAY = 0x1
32
+ TASK_MONDAY = 0x2
33
+ TASK_TUESDAY = 0x4
34
+ TASK_WEDNESDAY = 0x8
35
+ TASK_THURSDAY = 0x10
36
+ TASK_FRIDAY = 0x20
37
+ TASK_SATURDAY = 0x40
38
+ TASK_FIRST_WEEK = 1
39
+ TASK_SECOND_WEEK = 2
40
+ TASK_THIRD_WEEK = 3
41
+ TASK_FOURTH_WEEK = 4
42
+ TASK_LAST_WEEK = 5
43
+ TASK_JANUARY = 0x1
44
+ TASK_FEBRUARY = 0x2
45
+ TASK_MARCH = 0x4
46
+ TASK_APRIL = 0x8
47
+ TASK_MAY = 0x10
48
+ TASK_JUNE = 0x20
49
+ TASK_JULY = 0x40
50
+ TASK_AUGUST = 0x80
51
+ TASK_SEPTEMBER = 0x100
52
+ TASK_OCTOBER = 0x200
53
+ TASK_NOVEMBER = 0x400
54
+ TASK_DECEMBER = 0x800
55
+
56
+ TASK_FLAG_INTERACTIVE = 0x1
57
+ TASK_FLAG_DELETE_WHEN_DONE = 0x2
58
+ TASK_FLAG_DISABLED = 0x4
59
+ TASK_FLAG_START_ONLY_IF_IDLE = 0x10
60
+ TASK_FLAG_KILL_ON_IDLE_END = 0x20
61
+ TASK_FLAG_DONT_START_IF_ON_BATTERIES = 0x40
62
+ TASK_FLAG_KILL_IF_GOING_ON_BATTERIES = 0x80
63
+ TASK_FLAG_RUN_ONLY_IF_DOCKED = 0x100
64
+ TASK_FLAG_HIDDEN = 0x200
65
+ TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = 0x400
66
+ TASK_FLAG_RESTART_ON_IDLE_RESUME = 0x800
67
+ TASK_FLAG_SYSTEM_REQUIRED = 0x1000
68
+ TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x2000
69
+ TASK_TRIGGER_FLAG_HAS_END_DATE = 0x1
70
+ TASK_TRIGGER_FLAG_KILL_AT_DURATION_END = 0x2
71
+ TASK_TRIGGER_FLAG_DISABLED = 0x4
72
+
73
+ TASK_MAX_RUN_TIMES = 1440
74
+ TASKS_TO_RETRIEVE = 5
75
+
76
+ # COM
77
+
78
+ CLSID_CTask = FFI::WIN32::GUID['148BD520-A2AB-11CE-B11F-00AA00530503']
79
+ IID_ITask = FFI::WIN32::GUID['148BD524-A2AB-11CE-B11F-00AA00530503']
80
+ IID_IPersistFile = FFI::WIN32::GUID['0000010b-0000-0000-C000-000000000046']
81
+
82
+ SCHED_S_TASK_READY = 0x00041300
83
+ SCHED_S_TASK_RUNNING = 0x00041301
84
+ SCHED_S_TASK_HAS_NOT_RUN = 0x00041303
85
+ SCHED_S_TASK_NOT_SCHEDULED = 0x00041305
86
+ # HRESULT error codes
87
+ # http://blogs.msdn.com/b/eldar/archive/2007/04/03/a-lot-of-hresult-codes.aspx
88
+ # in Ruby, an 0x8XXXXXXX style HRESULT can be resolved to 2s complement
89
+ # by using "0x8XXXXXXX".to_i(16) - - 0x100000000
90
+ SCHED_E_ACCOUNT_INFORMATION_NOT_SET = -2147216625 # 0x8004130F
91
+ SCHED_E_NO_SECURITY_SERVICES = -2147216622 # 0x80041312
92
+ # No mapping between account names and security IDs was done.
93
+ ERROR_NONE_MAPPED = -2147023564 # 0x80070534 WIN32 Error CODE 1332 (0x534)
94
+
95
+ public
96
+
97
+ # :startdoc:
98
+
99
+ # Shorthand constants
100
+ IDLE = Puppet::Util::Windows::Process::IDLE_PRIORITY_CLASS
101
+ NORMAL = Puppet::Util::Windows::Process::NORMAL_PRIORITY_CLASS
102
+ HIGH = Puppet::Util::Windows::Process::HIGH_PRIORITY_CLASS
103
+ REALTIME = Puppet::Util::Windows::Process::REALTIME_PRIORITY_CLASS
104
+ BELOW_NORMAL = Puppet::Util::Windows::Process::BELOW_NORMAL_PRIORITY_CLASS
105
+ ABOVE_NORMAL = Puppet::Util::Windows::Process::ABOVE_NORMAL_PRIORITY_CLASS
106
+
107
+ ONCE = TASK_TIME_TRIGGER_ONCE
108
+ DAILY = TASK_TIME_TRIGGER_DAILY
109
+ WEEKLY = TASK_TIME_TRIGGER_WEEKLY
110
+ MONTHLYDATE = TASK_TIME_TRIGGER_MONTHLYDATE
111
+ MONTHLYDOW = TASK_TIME_TRIGGER_MONTHLYDOW
112
+
113
+ ON_IDLE = TASK_EVENT_TRIGGER_ON_IDLE
114
+ AT_SYSTEMSTART = TASK_EVENT_TRIGGER_AT_SYSTEMSTART
115
+ AT_LOGON = TASK_EVENT_TRIGGER_AT_LOGON
116
+ FIRST_WEEK = TASK_FIRST_WEEK
117
+ SECOND_WEEK = TASK_SECOND_WEEK
118
+ THIRD_WEEK = TASK_THIRD_WEEK
119
+ FOURTH_WEEK = TASK_FOURTH_WEEK
120
+ LAST_WEEK = TASK_LAST_WEEK
121
+ SUNDAY = TASK_SUNDAY
122
+ MONDAY = TASK_MONDAY
123
+ TUESDAY = TASK_TUESDAY
124
+ WEDNESDAY = TASK_WEDNESDAY
125
+ THURSDAY = TASK_THURSDAY
126
+ FRIDAY = TASK_FRIDAY
127
+ SATURDAY = TASK_SATURDAY
128
+ JANUARY = TASK_JANUARY
129
+ FEBRUARY = TASK_FEBRUARY
130
+ MARCH = TASK_MARCH
131
+ APRIL = TASK_APRIL
132
+ MAY = TASK_MAY
133
+ JUNE = TASK_JUNE
134
+ JULY = TASK_JULY
135
+ AUGUST = TASK_AUGUST
136
+ SEPTEMBER = TASK_SEPTEMBER
137
+ OCTOBER = TASK_OCTOBER
138
+ NOVEMBER = TASK_NOVEMBER
139
+ DECEMBER = TASK_DECEMBER
140
+
141
+ INTERACTIVE = TASK_FLAG_INTERACTIVE
142
+ DELETE_WHEN_DONE = TASK_FLAG_DELETE_WHEN_DONE
143
+ DISABLED = TASK_FLAG_DISABLED
144
+ START_ONLY_IF_IDLE = TASK_FLAG_START_ONLY_IF_IDLE
145
+ KILL_ON_IDLE_END = TASK_FLAG_KILL_ON_IDLE_END
146
+ DONT_START_IF_ON_BATTERIES = TASK_FLAG_DONT_START_IF_ON_BATTERIES
147
+ KILL_IF_GOING_ON_BATTERIES = TASK_FLAG_KILL_IF_GOING_ON_BATTERIES
148
+ RUN_ONLY_IF_DOCKED = TASK_FLAG_RUN_ONLY_IF_DOCKED
149
+ HIDDEN = TASK_FLAG_HIDDEN
150
+ RUN_IF_CONNECTED_TO_INTERNET = TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET
151
+ RESTART_ON_IDLE_RESUME = TASK_FLAG_RESTART_ON_IDLE_RESUME
152
+ SYSTEM_REQUIRED = TASK_FLAG_SYSTEM_REQUIRED
153
+ RUN_ONLY_IF_LOGGED_ON = TASK_FLAG_RUN_ONLY_IF_LOGGED_ON
154
+
155
+ FLAG_HAS_END_DATE = TASK_TRIGGER_FLAG_HAS_END_DATE
156
+ FLAG_KILL_AT_DURATION_END = TASK_TRIGGER_FLAG_KILL_AT_DURATION_END
157
+ FLAG_DISABLED = TASK_TRIGGER_FLAG_DISABLED
158
+
159
+ MAX_RUN_TIMES = TASK_MAX_RUN_TIMES
160
+
161
+ # Returns a new TaskScheduler object. If a work_item (and possibly the
162
+ # the trigger) are passed as arguments then a new work item is created and
163
+ # associated with that trigger, although you can still activate other tasks
164
+ # with the same handle.
165
+ #
166
+ # This is really just a bit of convenience. Passing arguments to the
167
+ # constructor is the same as calling TaskScheduler.new plus
168
+ # TaskScheduler#new_work_item.
169
+ #
170
+ def initialize(work_item=nil, trigger=nil)
171
+ @pITS = nil
172
+ @pITask = nil
173
+
174
+ if ! self.class.com_initialized
175
+ Puppet::Util::Windows::COM.InitializeCom()
176
+ self.class.com_initialized = true
177
+ end
178
+
179
+ @pITS = COM::TaskScheduler.new
180
+ at_exit do
181
+ begin
182
+ @pITS.Release if @pITS && !@pITS.null?
183
+ @pITS = nil
184
+ rescue
185
+ end
186
+ end
187
+
188
+ if work_item
189
+ if trigger
190
+ raise TypeError unless trigger.is_a?(Hash)
191
+ new_work_item(work_item, trigger)
192
+ end
193
+ end
194
+ end
195
+
196
+ # Returns an array of scheduled task names.
197
+ #
198
+ def enum
199
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
200
+ array = []
201
+
202
+ @pITS.UseInstance(COM::EnumWorkItems, :Enum) do |pIEnum|
203
+ FFI::MemoryPointer.new(:pointer) do |names_array_ptr_ptr|
204
+ FFI::MemoryPointer.new(:win32_ulong) do |fetched_count_ptr|
205
+ # awkward usage, if number requested is available, returns S_OK (0), or if less were returned returns S_FALSE (1)
206
+ while (pIEnum.Next(TASKS_TO_RETRIEVE, names_array_ptr_ptr, fetched_count_ptr) >= Puppet::Util::Windows::COM::S_OK)
207
+ count = fetched_count_ptr.read_win32_ulong
208
+ break if count == 0
209
+
210
+ names_array_ptr_ptr.read_com_memory_pointer do |names_array_ptr|
211
+ # iterate over the array of pointers
212
+ name_ptr_ptr = FFI::Pointer.new(:pointer, names_array_ptr)
213
+ for i in 0 ... count
214
+ name_ptr_ptr[i].read_com_memory_pointer do |name_ptr|
215
+ array << name_ptr.read_arbitrary_wide_string_up_to(256)
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ array
225
+ end
226
+
227
+ alias :tasks :enum
228
+
229
+ # Activate the specified task.
230
+ #
231
+ def activate(task)
232
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
233
+ raise TypeError unless task.is_a?(String)
234
+
235
+ FFI::MemoryPointer.new(:pointer) do |ptr|
236
+ @pITS.Activate(wide_string(task), IID_ITask, ptr)
237
+
238
+ reset_current_task
239
+ @pITask = COM::Task.new(ptr.read_pointer)
240
+ end
241
+
242
+ @pITask
243
+ end
244
+
245
+ # Delete the specified task name.
246
+ #
247
+ def delete(task)
248
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
249
+ raise TypeError unless task.is_a?(String)
250
+
251
+ @pITS.Delete(wide_string(task))
252
+
253
+ true
254
+ end
255
+
256
+ # Execute the current task.
257
+ #
258
+ def run
259
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
260
+
261
+ @pITask.Run
262
+ end
263
+
264
+ # Saves the current task. Tasks must be saved before they can be activated.
265
+ # The .job file itself is typically stored in the C:\WINDOWS\Tasks folder.
266
+ #
267
+ # If +file+ (an absolute path) is specified then the job is saved to that
268
+ # file instead. A '.job' extension is recommended but not enforced.
269
+ #
270
+ def save(file = nil)
271
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
272
+
273
+ reset = true
274
+
275
+ begin
276
+ @pITask.QueryInstance(COM::PersistFile) do |pIPersistFile|
277
+ pIPersistFile.Save(wide_string(file), 1)
278
+ end
279
+ rescue
280
+ reset = false
281
+ ensure
282
+ reset_current_task if reset
283
+ end
284
+ end
285
+
286
+ # Terminate the current task.
287
+ #
288
+ def terminate
289
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
290
+
291
+ @pITask.Terminate
292
+ end
293
+
294
+ # Set the host on which the various TaskScheduler methods will execute.
295
+ #
296
+ def machine=(host)
297
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
298
+ raise TypeError unless host.is_a?(String)
299
+
300
+ @pITS.SetTargetComputer(wide_string(host))
301
+
302
+ host
303
+ end
304
+
305
+ alias :host= :machine=
306
+
307
+ # Sets the +user+ and +password+ for the given task. If the user and
308
+ # password are set properly then true is returned.
309
+ #
310
+ # In some cases the job may be created, but the account information was
311
+ # bad. In this case the task is created but a warning is generated and
312
+ # false is returned.
313
+ #
314
+ def set_account_information(user, password)
315
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
316
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
317
+
318
+ bool = false
319
+
320
+ begin
321
+ if (user.nil? || user=="") && (password.nil? || password=="")
322
+ @pITask.SetAccountInformation(wide_string(""), FFI::Pointer::NULL)
323
+ else
324
+ user = wide_string(user)
325
+ password = wide_string(password)
326
+ @pITask.SetAccountInformation(user, password)
327
+ end
328
+
329
+ bool = true
330
+ rescue Puppet::Util::Windows::Error => e
331
+ raise e unless e.code == SCHED_E_ACCOUNT_INFORMATION_NOT_SET
332
+
333
+ warn 'job created, but password was invalid'
334
+ end
335
+
336
+ bool
337
+ end
338
+
339
+ # Returns the user associated with the task or nil if no user has yet
340
+ # been associated with the task.
341
+ #
342
+ def account_information
343
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
344
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
345
+
346
+ # default under certain failures
347
+ user = nil
348
+
349
+ begin
350
+ FFI::MemoryPointer.new(:pointer) do |ptr|
351
+ @pITask.GetAccountInformation(ptr)
352
+ ptr.read_com_memory_pointer do |str_ptr|
353
+ user = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
354
+ end
355
+ end
356
+ rescue Puppet::Util::Windows::Error => e
357
+ raise e unless e.code == SCHED_E_ACCOUNT_INFORMATION_NOT_SET ||
358
+ e.code == SCHED_E_NO_SECURITY_SERVICES ||
359
+ e.code == ERROR_NONE_MAPPED
360
+ end
361
+
362
+ user
363
+ end
364
+
365
+ # Returns the name of the application associated with the task.
366
+ #
367
+ def application_name
368
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
369
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
370
+
371
+ app = nil
372
+
373
+ FFI::MemoryPointer.new(:pointer) do |ptr|
374
+ @pITask.GetApplicationName(ptr)
375
+
376
+ ptr.read_com_memory_pointer do |str_ptr|
377
+ app = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
378
+ end
379
+ end
380
+
381
+ app
382
+ end
383
+
384
+ # Sets the application name associated with the task.
385
+ #
386
+ def application_name=(app)
387
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
388
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
389
+ raise TypeError unless app.is_a?(String)
390
+
391
+ @pITask.SetApplicationName(wide_string(app))
392
+
393
+ app
394
+ end
395
+
396
+ # Returns the command line parameters for the task.
397
+ #
398
+ def parameters
399
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
400
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
401
+
402
+ param = nil
403
+
404
+ FFI::MemoryPointer.new(:pointer) do |ptr|
405
+ @pITask.GetParameters(ptr)
406
+
407
+ ptr.read_com_memory_pointer do |str_ptr|
408
+ param = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
409
+ end
410
+ end
411
+
412
+ param
413
+ end
414
+
415
+ # Sets the parameters for the task. These parameters are passed as command
416
+ # line arguments to the application the task will run. To clear the command
417
+ # line parameters set it to an empty string.
418
+ #
419
+ def parameters=(param)
420
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
421
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
422
+ raise TypeError unless param.is_a?(String)
423
+
424
+ @pITask.SetParameters(wide_string(param))
425
+
426
+ param
427
+ end
428
+
429
+ # Returns the working directory for the task.
430
+ #
431
+ def working_directory
432
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
433
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
434
+
435
+ dir = nil
436
+
437
+ FFI::MemoryPointer.new(:pointer) do |ptr|
438
+ @pITask.GetWorkingDirectory(ptr)
439
+
440
+ ptr.read_com_memory_pointer do |str_ptr|
441
+ dir = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
442
+ end
443
+ end
444
+
445
+ dir
446
+ end
447
+
448
+ # Sets the working directory for the task.
449
+ #
450
+ def working_directory=(dir)
451
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
452
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
453
+ raise TypeError unless dir.is_a?(String)
454
+
455
+ @pITask.SetWorkingDirectory(wide_string(dir))
456
+
457
+ dir
458
+ end
459
+
460
+ # Returns the task's priority level. Possible values are 'idle',
461
+ # 'normal', 'high', 'realtime', 'below_normal', 'above_normal',
462
+ # and 'unknown'.
463
+ #
464
+ def priority
465
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
466
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
467
+
468
+ FFI::MemoryPointer.new(:dword, 1) do |ptr|
469
+ @pITask.GetPriority(ptr)
470
+
471
+ pri = ptr.read_dword
472
+ if (pri & IDLE) != 0
473
+ priority = 'idle'
474
+ elsif (pri & NORMAL) != 0
475
+ priority = 'normal'
476
+ elsif (pri & HIGH) != 0
477
+ priority = 'high'
478
+ elsif (pri & REALTIME) != 0
479
+ priority = 'realtime'
480
+ elsif (pri & BELOW_NORMAL) != 0
481
+ priority = 'below_normal'
482
+ elsif (pri & ABOVE_NORMAL) != 0
483
+ priority = 'above_normal'
484
+ else
485
+ priority = 'unknown'
486
+ end
487
+ end
488
+
489
+ priority
490
+ end
491
+
492
+ # Sets the priority of the task. The +priority+ should be a numeric
493
+ # priority constant value.
494
+ #
495
+ def priority=(priority)
496
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
497
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
498
+ raise TypeError unless priority.is_a?(Numeric)
499
+
500
+ @pITask.SetPriority(priority)
501
+
502
+ priority
503
+ end
504
+
505
+ # Creates a new work item (scheduled job) with the given +trigger+. The
506
+ # trigger variable is a hash of options that define when the scheduled
507
+ # job should run.
508
+ #
509
+ def new_work_item(task, trigger)
510
+ raise TypeError unless trigger.is_a?(Hash)
511
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
512
+
513
+ # I'm working around github issue #1 here.
514
+ enum.each{ |name|
515
+ if name.downcase == task.downcase + '.job'
516
+ raise Error.new("task '#{task}' already exists")
517
+ end
518
+ }
519
+
520
+ FFI::MemoryPointer.new(:pointer) do |ptr|
521
+ @pITS.NewWorkItem(wide_string(task), CLSID_CTask, IID_ITask, ptr)
522
+
523
+ reset_current_task
524
+ @pITask = COM::Task.new(ptr.read_pointer)
525
+
526
+ FFI::MemoryPointer.new(:word, 1) do |trigger_index_ptr|
527
+ # Without the 'enum.include?' check above the code segfaults here if the
528
+ # task already exists. This should probably be handled properly instead
529
+ # of simply avoiding the issue.
530
+
531
+ @pITask.UseInstance(COM::TaskTrigger, :CreateTrigger, trigger_index_ptr) do |pITaskTrigger|
532
+ populate_trigger(pITaskTrigger, trigger)
533
+ end
534
+ end
535
+ end
536
+
537
+ @pITask
538
+ end
539
+
540
+ alias :new_task :new_work_item
541
+
542
+ # Returns the number of triggers associated with the active task.
543
+ #
544
+ def trigger_count
545
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
546
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
547
+
548
+ count = 0
549
+
550
+ FFI::MemoryPointer.new(:word, 1) do |ptr|
551
+ @pITask.GetTriggerCount(ptr)
552
+ count = ptr.read_word
553
+ end
554
+
555
+ count
556
+ end
557
+
558
+ # Returns a string that describes the current trigger at the specified
559
+ # index for the active task.
560
+ #
561
+ # Example: "At 7:14 AM every day, starting 4/11/2009"
562
+ #
563
+ def trigger_string(index)
564
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
565
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
566
+ raise TypeError unless index.is_a?(Numeric)
567
+
568
+ FFI::MemoryPointer.new(:pointer) do |ptr|
569
+ @pITask.GetTriggerString(index, ptr)
570
+
571
+ ptr.read_com_memory_pointer do |str_ptr|
572
+ trigger = str_ptr.read_arbitrary_wide_string_up_to(256)
573
+ end
574
+ end
575
+
576
+ trigger
577
+ end
578
+
579
+ # Deletes the trigger at the specified index.
580
+ #
581
+ def delete_trigger(index)
582
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
583
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
584
+
585
+ @pITask.DeleteTrigger(index)
586
+ index
587
+ end
588
+
589
+ # Returns a hash that describes the trigger at the given index for the
590
+ # current task.
591
+ #
592
+ def trigger(index)
593
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
594
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
595
+
596
+ trigger = {}
597
+
598
+ @pITask.UseInstance(COM::TaskTrigger, :GetTrigger, index) do |pITaskTrigger|
599
+ FFI::MemoryPointer.new(COM::TASK_TRIGGER.size) do |task_trigger_ptr|
600
+ pITaskTrigger.GetTrigger(task_trigger_ptr)
601
+ trigger = populate_hash_from_trigger(COM::TASK_TRIGGER.new(task_trigger_ptr))
602
+ end
603
+ end
604
+
605
+ trigger
606
+ end
607
+
608
+ # Sets the trigger for the currently active task.
609
+ #
610
+ def trigger=(trigger)
611
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
612
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
613
+ raise TypeError unless trigger.is_a?(Hash)
614
+
615
+ FFI::MemoryPointer.new(:word, 1) do |trigger_index_ptr|
616
+ # Without the 'enum.include?' check above the code segfaults here if the
617
+ # task already exists. This should probably be handled properly instead
618
+ # of simply avoiding the issue.
619
+
620
+ @pITask.UseInstance(COM::TaskTrigger, :CreateTrigger, trigger_index_ptr) do |pITaskTrigger|
621
+ populate_trigger(pITaskTrigger, trigger)
622
+ end
623
+ end
624
+
625
+ trigger
626
+ end
627
+
628
+ # Adds a trigger at the specified index.
629
+ #
630
+ def add_trigger(index, trigger)
631
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
632
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
633
+ raise TypeError unless trigger.is_a?(Hash)
634
+
635
+ @pITask.UseInstance(COM::TaskTrigger, :GetTrigger, index) do |pITaskTrigger|
636
+ populate_trigger(pITaskTrigger, trigger)
637
+ end
638
+ end
639
+
640
+ # Returns the flags (integer) that modify the behavior of the work item. You
641
+ # must OR the return value to determine the flags yourself.
642
+ #
643
+ def flags
644
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
645
+
646
+ flags = 0
647
+
648
+ FFI::MemoryPointer.new(:dword, 1) do |ptr|
649
+ @pITask.GetFlags(ptr)
650
+ flags = ptr.read_dword
651
+ end
652
+
653
+ flags
654
+ end
655
+
656
+ # Sets an OR'd value of flags that modify the behavior of the work item.
657
+ #
658
+ def flags=(flags)
659
+ raise Error.new('No current task scheduler. ITaskScheduler is NULL.') if @pITS.nil?
660
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
661
+
662
+ @pITask.SetFlags(flags)
663
+ flags
664
+ end
665
+
666
+ # Returns the status of the currently active task. Possible values are
667
+ # 'ready', 'running', 'not scheduled' or 'unknown'.
668
+ #
669
+ def status
670
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
671
+
672
+ st = nil
673
+
674
+ FFI::MemoryPointer.new(:hresult, 1) do |ptr|
675
+ @pITask.GetStatus(ptr)
676
+ st = ptr.read_hresult
677
+ end
678
+
679
+ case st
680
+ when SCHED_S_TASK_READY
681
+ status = 'ready'
682
+ when SCHED_S_TASK_RUNNING
683
+ status = 'running'
684
+ when SCHED_S_TASK_NOT_SCHEDULED
685
+ status = 'not scheduled'
686
+ else
687
+ status = 'unknown'
688
+ end
689
+
690
+ status
691
+ end
692
+
693
+ # Returns the exit code from the last scheduled run.
694
+ #
695
+ def exit_code
696
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
697
+
698
+ status = 0
699
+
700
+ begin
701
+ FFI::MemoryPointer.new(:dword, 1) do |ptr|
702
+ @pITask.GetExitCode(ptr)
703
+ status = ptr.read_dword
704
+ end
705
+ rescue Puppet::Util::Windows::Error => e
706
+ raise e unless e.code == SCHED_S_TASK_HAS_NOT_RUN
707
+ end
708
+
709
+ status
710
+ end
711
+
712
+ # Returns the comment associated with the task, if any.
713
+ #
714
+ def comment
715
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
716
+
717
+ comment = nil
718
+
719
+ FFI::MemoryPointer.new(:pointer) do |ptr|
720
+ @pITask.GetComment(ptr)
721
+
722
+ ptr.read_com_memory_pointer do |str_ptr|
723
+ comment = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
724
+ end
725
+ end
726
+
727
+ comment
728
+ end
729
+
730
+ # Sets the comment for the task.
731
+ #
732
+ def comment=(comment)
733
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
734
+ raise TypeError unless comment.is_a?(String)
735
+
736
+ @pITask.SetComment(wide_string(comment))
737
+ comment
738
+ end
739
+
740
+ # Returns the name of the user who created the task.
741
+ #
742
+ def creator
743
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
744
+
745
+ creator = nil
746
+
747
+ FFI::MemoryPointer.new(:pointer) do |ptr|
748
+ @pITask.GetCreator(ptr)
749
+
750
+ ptr.read_com_memory_pointer do |str_ptr|
751
+ creator = str_ptr.read_arbitrary_wide_string_up_to(256) if ! str_ptr.null?
752
+ end
753
+ end
754
+
755
+ creator
756
+ end
757
+
758
+ # Sets the creator for the task.
759
+ #
760
+ def creator=(creator)
761
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
762
+ raise TypeError unless creator.is_a?(String)
763
+
764
+ @pITask.SetCreator(wide_string(creator))
765
+ creator
766
+ end
767
+
768
+ # Returns a Time object that indicates the next time the task will run.
769
+ #
770
+ def next_run_time
771
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
772
+
773
+ time = nil
774
+
775
+ FFI::MemoryPointer.new(WIN32::SYSTEMTIME.size) do |ptr|
776
+ @pITask.GetNextRunTime(ptr)
777
+ time = WIN32::SYSTEMTIME.new(ptr).to_local_time
778
+ end
779
+
780
+ time
781
+ end
782
+
783
+ # Returns a Time object indicating the most recent time the task ran or
784
+ # nil if the task has never run.
785
+ #
786
+ def most_recent_run_time
787
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
788
+
789
+ time = nil
790
+
791
+ begin
792
+ FFI::MemoryPointer.new(WIN32::SYSTEMTIME.size) do |ptr|
793
+ @pITask.GetMostRecentRunTime(ptr)
794
+ time = WIN32::SYSTEMTIME.new(ptr).to_local_time
795
+ end
796
+ rescue Puppet::Util::Windows::Error => e
797
+ raise e unless e.code == SCHED_S_TASK_HAS_NOT_RUN
798
+ end
799
+
800
+ time
801
+ end
802
+
803
+ # Returns the maximum length of time, in milliseconds, that the task
804
+ # will run before terminating.
805
+ #
806
+ def max_run_time
807
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
808
+
809
+ max_run_time = nil
810
+
811
+ FFI::MemoryPointer.new(:dword, 1) do |ptr|
812
+ @pITask.GetMaxRunTime(ptr)
813
+ max_run_time = ptr.read_dword
814
+ end
815
+
816
+ max_run_time
817
+ end
818
+
819
+ # Sets the maximum length of time, in milliseconds, that the task can run
820
+ # before terminating. Returns the value you specified if successful.
821
+ #
822
+ def max_run_time=(max_run_time)
823
+ raise Error.new('No currently active task. ITask is NULL.') if @pITask.nil?
824
+ raise TypeError unless max_run_time.is_a?(Numeric)
825
+
826
+ @pITask.SetMaxRunTime(max_run_time)
827
+ max_run_time
828
+ end
829
+
830
+ # Returns whether or not the scheduled task exists.
831
+ def exists?(job_name)
832
+ bool = false
833
+ Dir.foreach('C:/Windows/Tasks'){ |file|
834
+ if File.basename(file, '.job') == job_name
835
+ bool = true
836
+ break
837
+ end
838
+ }
839
+ bool
840
+ end
841
+
842
+ private
843
+
844
+ # :stopdoc:
845
+
846
+ # Used for the new_work_item method
847
+ ValidTriggerKeys = [
848
+ 'end_day',
849
+ 'end_month',
850
+ 'end_year',
851
+ 'flags',
852
+ 'minutes_duration',
853
+ 'minutes_interval',
854
+ 'random_minutes_interval',
855
+ 'start_day',
856
+ 'start_hour',
857
+ 'start_minute',
858
+ 'start_month',
859
+ 'start_year',
860
+ 'trigger_type',
861
+ 'type'
862
+ ]
863
+
864
+ ValidTypeKeys = [
865
+ 'days_interval',
866
+ 'weeks_interval',
867
+ 'days_of_week',
868
+ 'months',
869
+ 'days',
870
+ 'weeks'
871
+ ]
872
+
873
+ # Private method that validates keys, and converts all keys to lowercase
874
+ # strings.
875
+ #
876
+ def transform_and_validate(hash)
877
+ new_hash = {}
878
+
879
+ hash.each{ |key, value|
880
+ key = key.to_s.downcase
881
+ if key == 'type'
882
+ new_type_hash = {}
883
+ raise ArgumentError unless value.is_a?(Hash)
884
+ value.each{ |subkey, subvalue|
885
+ subkey = subkey.to_s.downcase
886
+ if ValidTypeKeys.include?(subkey)
887
+ new_type_hash[subkey] = subvalue
888
+ else
889
+ raise ArgumentError, "Invalid type key '#{subkey}'"
890
+ end
891
+ }
892
+ new_hash[key] = new_type_hash
893
+ else
894
+ if ValidTriggerKeys.include?(key)
895
+ new_hash[key] = value
896
+ else
897
+ raise ArgumentError, "Invalid key '#{key}'"
898
+ end
899
+ end
900
+ }
901
+
902
+ new_hash
903
+ end
904
+
905
+ private
906
+
907
+ def reset_current_task
908
+ # Ensure that COM reference is decremented properly
909
+ @pITask.Release if @pITask && ! @pITask.null?
910
+ @pITask = nil
911
+ end
912
+
913
+ def populate_trigger(task_trigger, trigger)
914
+ raise TypeError unless task_trigger.is_a?(COM::TaskTrigger)
915
+ trigger = transform_and_validate(trigger)
916
+
917
+ FFI::MemoryPointer.new(COM::TASK_TRIGGER.size) do |trigger_ptr|
918
+ FFI::MemoryPointer.new(COM::TRIGGER_TYPE_UNION.size) do |trigger_type_union_ptr|
919
+ trigger_type_union = COM::TRIGGER_TYPE_UNION.new(trigger_type_union_ptr)
920
+
921
+ tmp = trigger['type'].is_a?(Hash) ? trigger['type'] : nil
922
+ case trigger['trigger_type']
923
+ when :TASK_TIME_TRIGGER_DAILY
924
+ if tmp && tmp['days_interval']
925
+ trigger_type_union[:Daily][:DaysInterval] = tmp['days_interval']
926
+ end
927
+ when :TASK_TIME_TRIGGER_WEEKLY
928
+ if tmp && tmp['weeks_interval'] && tmp['days_of_week']
929
+ trigger_type_union[:Weekly][:WeeksInterval] = tmp['weeks_interval']
930
+ trigger_type_union[:Weekly][:rgfDaysOfTheWeek] = tmp['days_of_week']
931
+ end
932
+ when :TASK_TIME_TRIGGER_MONTHLYDATE
933
+ if tmp && tmp['months'] && tmp['days']
934
+ trigger_type_union[:MonthlyDate][:rgfDays] = tmp['days']
935
+ trigger_type_union[:MonthlyDate][:rgfMonths] = tmp['months']
936
+ end
937
+ when :TASK_TIME_TRIGGER_MONTHLYDOW
938
+ if tmp && tmp['weeks'] && tmp['days_of_week'] && tmp['months']
939
+ trigger_type_union[:MonthlyDOW][:wWhichWeek] = tmp['weeks']
940
+ trigger_type_union[:MonthlyDOW][:rgfDaysOfTheWeek] = tmp['days_of_week']
941
+ trigger_type_union[:MonthlyDOW][:rgfMonths] = tmp['months']
942
+ end
943
+ when :TASK_TIME_TRIGGER_ONCE
944
+ # Do nothing. The Type member of the TASK_TRIGGER struct is ignored.
945
+ else
946
+ raise Error.new("Unknown trigger type #{trigger['trigger_type']}")
947
+ end
948
+
949
+ trigger_struct = COM::TASK_TRIGGER.new(trigger_ptr)
950
+ trigger_struct[:cbTriggerSize] = COM::TASK_TRIGGER.size
951
+ trigger_struct[:wBeginYear] = trigger['start_year'] || 0
952
+ trigger_struct[:wBeginMonth] = trigger['start_month'] || 0
953
+ trigger_struct[:wBeginDay] = trigger['start_day'] || 0
954
+ trigger_struct[:wEndYear] = trigger['end_year'] || 0
955
+ trigger_struct[:wEndMonth] = trigger['end_month'] || 0
956
+ trigger_struct[:wEndDay] = trigger['end_day'] || 0
957
+ trigger_struct[:wStartHour] = trigger['start_hour'] || 0
958
+ trigger_struct[:wStartMinute] = trigger['start_minute'] || 0
959
+ trigger_struct[:MinutesDuration] = trigger['minutes_duration'] || 0
960
+ trigger_struct[:MinutesInterval] = trigger['minutes_interval'] || 0
961
+ trigger_struct[:rgFlags] = trigger['flags'] || 0
962
+ trigger_struct[:TriggerType] = trigger['trigger_type'] || :TASK_TIME_TRIGGER_ONCE
963
+ trigger_struct[:Type] = trigger_type_union
964
+ trigger_struct[:wRandomMinutesInterval] = trigger['random_minutes_interval']
965
+
966
+ task_trigger.SetTrigger(trigger_struct)
967
+ end
968
+ end
969
+ end
970
+
971
+ def populate_hash_from_trigger(task_trigger)
972
+ raise TypeError unless task_trigger.is_a?(COM::TASK_TRIGGER)
973
+
974
+ trigger = {
975
+ 'start_year' => task_trigger[:wBeginYear],
976
+ 'start_month' => task_trigger[:wBeginMonth],
977
+ 'start_day' => task_trigger[:wBeginDay],
978
+ 'end_year' => task_trigger[:wEndYear],
979
+ 'end_month' => task_trigger[:wEndMonth],
980
+ 'end_day' => task_trigger[:wEndDay],
981
+ 'start_hour' => task_trigger[:wStartHour],
982
+ 'start_minute' => task_trigger[:wStartMinute],
983
+ 'minutes_duration' => task_trigger[:MinutesDuration],
984
+ 'minutes_interval' => task_trigger[:MinutesInterval],
985
+ 'flags' => task_trigger[:rgFlags],
986
+ 'trigger_type' => task_trigger[:TriggerType],
987
+ 'random_minutes_interval' => task_trigger[:wRandomMinutesInterval]
988
+ }
989
+
990
+ case task_trigger[:TriggerType]
991
+ when :TASK_TIME_TRIGGER_DAILY
992
+ trigger['type'] = { 'days_interval' => task_trigger[:Type][:Daily][:DaysInterval] }
993
+ when :TASK_TIME_TRIGGER_WEEKLY
994
+ trigger['type'] = {
995
+ 'weeks_interval' => task_trigger[:Type][:Weekly][:WeeksInterval],
996
+ 'days_of_week' => task_trigger[:Type][:Weekly][:rgfDaysOfTheWeek]
997
+ }
998
+ when :TASK_TIME_TRIGGER_MONTHLYDATE
999
+ trigger['type'] = {
1000
+ 'days' => task_trigger[:Type][:MonthlyDate][:rgfDays],
1001
+ 'months' => task_trigger[:Type][:MonthlyDate][:rgfMonths]
1002
+ }
1003
+ when :TASK_TIME_TRIGGER_MONTHLYDOW
1004
+ trigger['type'] = {
1005
+ 'weeks' => task_trigger[:Type][:MonthlyDOW][:wWhichWeek],
1006
+ 'days_of_week' => task_trigger[:Type][:MonthlyDOW][:rgfDaysOfTheWeek],
1007
+ 'months' => task_trigger[:Type][:MonthlyDOW][:rgfMonths]
1008
+ }
1009
+ when :TASK_TIME_TRIGGER_ONCE
1010
+ trigger['type'] = { 'once' => nil }
1011
+ else
1012
+ raise Error.new("Unknown trigger type #{task_trigger[:TriggerType]}")
1013
+ end
1014
+
1015
+ trigger
1016
+ end
1017
+
1018
+ module COM
1019
+ extend FFI::Library
1020
+ private
1021
+
1022
+ com = Puppet::Util::Windows::COM
1023
+
1024
+ public
1025
+
1026
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381811(v=vs.85).aspx
1027
+ ITaskScheduler = com::Interface[com::IUnknown,
1028
+ FFI::WIN32::GUID['148BD527-A2AB-11CE-B11F-00AA00530503'],
1029
+
1030
+ SetTargetComputer: [[:lpcwstr], :hresult],
1031
+ # LPWSTR *
1032
+ GetTargetComputer: [[:pointer], :hresult],
1033
+ # IEnumWorkItems **
1034
+ Enum: [[:pointer], :hresult],
1035
+ # LPCWSTR, REFIID, IUnknown **
1036
+ Activate: [[:lpcwstr, :pointer, :pointer], :hresult],
1037
+ Delete: [[:lpcwstr], :hresult],
1038
+ # LPCWSTR, REFCLSID, REFIID, IUnknown **
1039
+ NewWorkItem: [[:lpcwstr, :pointer, :pointer, :pointer], :hresult],
1040
+ # LPCWSTR, IScheduledWorkItem *
1041
+ AddWorkItem: [[:lpcwstr, :pointer], :hresult],
1042
+ # LPCWSTR, REFIID
1043
+ IsOfType: [[:lpcwstr, :pointer], :hresult]
1044
+ ]
1045
+
1046
+ TaskScheduler = com::Factory[ITaskScheduler,
1047
+ FFI::WIN32::GUID['148BD52A-A2AB-11CE-B11F-00AA00530503']]
1048
+
1049
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa380706(v=vs.85).aspx
1050
+ IEnumWorkItems = com::Interface[com::IUnknown,
1051
+ FFI::WIN32::GUID['148BD528-A2AB-11CE-B11F-00AA00530503'],
1052
+
1053
+ # ULONG, LPWSTR **, ULONG *
1054
+ Next: [[:win32_ulong, :pointer, :pointer], :hresult],
1055
+ Skip: [[:win32_ulong], :hresult],
1056
+ Reset: [[], :hresult],
1057
+ # IEnumWorkItems ** ppEnumWorkItems
1058
+ Clone: [[:pointer], :hresult]
1059
+ ]
1060
+
1061
+ EnumWorkItems = com::Instance[IEnumWorkItems]
1062
+
1063
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381216(v=vs.85).aspx
1064
+ IScheduledWorkItem = com::Interface[com::IUnknown,
1065
+ FFI::WIN32::GUID['a6b952f0-a4b1-11d0-997d-00aa006887ec'],
1066
+
1067
+ # WORD *, ITaskTrigger **
1068
+ CreateTrigger: [[:pointer, :pointer], :hresult],
1069
+ DeleteTrigger: [[:word], :hresult],
1070
+ # WORD *
1071
+ GetTriggerCount: [[:pointer], :hresult],
1072
+ # WORD, ITaskTrigger **
1073
+ GetTrigger: [[:word, :pointer], :hresult],
1074
+ # WORD, LPWSTR *
1075
+ GetTriggerString: [[:word, :pointer], :hresult],
1076
+ # LPSYSTEMTIME, LPSYSTEMTIME, WORD *, LPSYSTEMTIME *
1077
+ GetRunTimes: [[:pointer, :pointer, :pointer, :pointer], :hresult],
1078
+ # SYSTEMTIME *
1079
+ GetNextRunTime: [[:pointer], :hresult],
1080
+ SetIdleWait: [[:word, :word], :hresult],
1081
+ # WORD *, WORD *
1082
+ GetIdleWait: [[:pointer, :pointer], :hresult],
1083
+ Run: [[], :hresult],
1084
+ Terminate: [[], :hresult],
1085
+ EditWorkItem: [[:hwnd, :dword], :hresult],
1086
+ # SYSTEMTIME *
1087
+ GetMostRecentRunTime: [[:pointer], :hresult],
1088
+ # HRESULT *
1089
+ GetStatus: [[:pointer], :hresult],
1090
+ GetExitCode: [[:pdword], :hresult],
1091
+ SetComment: [[:lpcwstr], :hresult],
1092
+ # LPWSTR *
1093
+ GetComment: [[:pointer], :hresult],
1094
+ SetCreator: [[:lpcwstr], :hresult],
1095
+ # LPWSTR *
1096
+ GetCreator: [[:pointer], :hresult],
1097
+ # WORD, BYTE[]
1098
+ SetWorkItemData: [[:word, :buffer_in], :hresult],
1099
+ # WORD *, BYTE **
1100
+ GetWorkItemData: [[:pointer, :pointer], :hresult],
1101
+ SetErrorRetryCount: [[:word], :hresult],
1102
+ # WORD *
1103
+ GetErrorRetryCount: [[:pointer], :hresult],
1104
+ SetErrorRetryInterval: [[:word], :hresult],
1105
+ # WORD *
1106
+ GetErrorRetryInterval: [[:pointer], :hresult],
1107
+ SetFlags: [[:dword], :hresult],
1108
+ # WORD *
1109
+ GetFlags: [[:pointer], :hresult],
1110
+ SetAccountInformation: [[:lpcwstr, :lpcwstr], :hresult],
1111
+ # LPWSTR *
1112
+ GetAccountInformation: [[:pointer], :hresult]
1113
+ ]
1114
+
1115
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381311(v=vs.85).aspx
1116
+ ITask = com::Interface[IScheduledWorkItem,
1117
+ FFI::WIN32::GUID['148BD524-A2AB-11CE-B11F-00AA00530503'],
1118
+
1119
+ SetApplicationName: [[:lpcwstr], :hresult],
1120
+ # LPWSTR *
1121
+ GetApplicationName: [[:pointer], :hresult],
1122
+ SetParameters: [[:lpcwstr], :hresult],
1123
+ # LPWSTR *
1124
+ GetParameters: [[:pointer], :hresult],
1125
+ SetWorkingDirectory: [[:lpcwstr], :hresult],
1126
+ # LPWSTR *
1127
+ GetWorkingDirectory: [[:pointer], :hresult],
1128
+ SetPriority: [[:dword], :hresult],
1129
+ # DWORD *
1130
+ GetPriority: [[:pointer], :hresult],
1131
+ SetTaskFlags: [[:dword], :hresult],
1132
+ # DWORD *
1133
+ GetTaskFlags: [[:pointer], :hresult],
1134
+ SetMaxRunTime: [[:dword], :hresult],
1135
+ # DWORD *
1136
+ GetMaxRunTime: [[:pointer], :hresult]
1137
+ ]
1138
+
1139
+ Task = com::Instance[ITask]
1140
+
1141
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms688695(v=vs.85).aspx
1142
+ IPersist = com::Interface[com::IUnknown,
1143
+ FFI::WIN32::GUID['0000010c-0000-0000-c000-000000000046'],
1144
+ # CLSID *
1145
+ GetClassID: [[:pointer], :hresult]
1146
+ ]
1147
+
1148
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms687223(v=vs.85).aspx
1149
+ IPersistFile = com::Interface[IPersist,
1150
+ FFI::WIN32::GUID['0000010b-0000-0000-C000-000000000046'],
1151
+
1152
+ IsDirty: [[], :hresult],
1153
+ Load: [[:lpcolestr, :dword], :hresult],
1154
+ Save: [[:lpcolestr, :win32_bool], :hresult],
1155
+ SaveCompleted: [[:lpcolestr], :hresult],
1156
+ # LPOLESTR *
1157
+ GetCurFile: [[:pointer], :hresult]
1158
+ ]
1159
+
1160
+ PersistFile = com::Instance[IPersistFile]
1161
+
1162
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381864(v=vs.85).aspx
1163
+ ITaskTrigger = com::Interface[com::IUnknown,
1164
+ FFI::WIN32::GUID['148BD52B-A2AB-11CE-B11F-00AA00530503'],
1165
+
1166
+ SetTrigger: [[:pointer], :hresult],
1167
+ GetTrigger: [[:pointer], :hresult],
1168
+ GetTriggerString: [[:pointer], :hresult]
1169
+ ]
1170
+
1171
+ TaskTrigger = com::Instance[ITaskTrigger]
1172
+
1173
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa383620(v=vs.85).aspx
1174
+ # The TASK_TRIGGER_TYPE field of the TASK_TRIGGER structure determines
1175
+ # which member of the TRIGGER_TYPE_UNION field to use.
1176
+ TASK_TRIGGER_TYPE = enum(
1177
+ :TASK_TIME_TRIGGER_ONCE, 0, # Ignore the Type field
1178
+ :TASK_TIME_TRIGGER_DAILY, 1,
1179
+ :TASK_TIME_TRIGGER_WEEKLY, 2,
1180
+ :TASK_TIME_TRIGGER_MONTHLYDATE, 3,
1181
+ :TASK_TIME_TRIGGER_MONTHLYDOW, 4,
1182
+ :TASK_EVENT_TRIGGER_ON_IDLE, 5, # Ignore the Type field
1183
+ :TASK_EVENT_TRIGGER_AT_SYSTEMSTART, 6, # Ignore the Type field
1184
+ :TASK_EVENT_TRIGGER_AT_LOGON, 7 # Ignore the Type field
1185
+ )
1186
+
1187
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa446857(v=vs.85).aspx
1188
+ class DAILY < FFI::Struct
1189
+ layout :DaysInterval, :word
1190
+ end
1191
+
1192
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa384014(v=vs.85).aspx
1193
+ class WEEKLY < FFI::Struct
1194
+ layout :WeeksInterval, :word,
1195
+ :rgfDaysOfTheWeek, :word
1196
+ end
1197
+
1198
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381918(v=vs.85).aspx
1199
+ class MONTHLYDATE < FFI::Struct
1200
+ layout :rgfDays, :dword,
1201
+ :rgfMonths, :word
1202
+ end
1203
+
1204
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa381918(v=vs.85).aspx
1205
+ class MONTHLYDOW < FFI::Struct
1206
+ layout :wWhichWeek, :word,
1207
+ :rgfDaysOfTheWeek, :word,
1208
+ :rgfMonths, :word
1209
+ end
1210
+
1211
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa384002(v=vs.85).aspx
1212
+ class TRIGGER_TYPE_UNION < FFI::Union
1213
+ layout :Daily, DAILY,
1214
+ :Weekly, WEEKLY,
1215
+ :MonthlyDate, MONTHLYDATE,
1216
+ :MonthlyDOW, MONTHLYDOW
1217
+ end
1218
+
1219
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa383618(v=vs.85).aspx
1220
+ class TASK_TRIGGER < FFI::Struct
1221
+ layout :cbTriggerSize, :word, # Structure size.
1222
+ :Reserved1, :word, # Reserved. Must be zero.
1223
+ :wBeginYear, :word, # Trigger beginning date year.
1224
+ :wBeginMonth, :word, # Trigger beginning date month.
1225
+ :wBeginDay, :word, # Trigger beginning date day.
1226
+ :wEndYear, :word, # Optional trigger ending date year.
1227
+ :wEndMonth, :word, # Optional trigger ending date month.
1228
+ :wEndDay, :word, # Optional trigger ending date day.
1229
+ :wStartHour, :word, # Run bracket start time hour.
1230
+ :wStartMinute, :word, # Run bracket start time minute.
1231
+ :MinutesDuration, :dword, # Duration of run bracket.
1232
+ :MinutesInterval, :dword, # Run bracket repetition interval.
1233
+ :rgFlags, :dword, # Trigger flags.
1234
+ :TriggerType, TASK_TRIGGER_TYPE, # Trigger type.
1235
+ :Type, TRIGGER_TYPE_UNION, # Trigger data.
1236
+ :Reserved2, :word, # Reserved. Must be zero.
1237
+ :wRandomMinutesInterval, :word # Maximum number of random minutes after start time
1238
+ end
1239
+ end
1240
+ end
1241
+ end