openbolt 5.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Puppetfile +52 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +60 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +51 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +71 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +65 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +93 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +33 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +208 -0
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +62 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +57 -0
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +130 -0
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +31 -0
- data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +87 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +35 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +74 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +97 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +47 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +40 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +42 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +106 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +291 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +164 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +211 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +48 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +101 -0
- data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +131 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +59 -0
- data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +39 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +50 -0
- data/bolt-modules/boltlib/types/planresult.pp +18 -0
- data/bolt-modules/boltlib/types/targetspec.pp +7 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +42 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +20 -0
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
- data/bolt-modules/file/lib/puppet/functions/file/delete.rb +21 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +20 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +33 -0
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +24 -0
- data/bolt-modules/log/lib/puppet/functions/log/debug.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/error.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/fatal.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/info.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/trace.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/warn.rb +41 -0
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +36 -0
- data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +35 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +65 -0
- data/bolt-modules/system/lib/puppet/functions/system/env.rb +20 -0
- data/exe/bolt +17 -0
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +233 -0
- data/lib/bolt/application.rb +806 -0
- data/lib/bolt/applicator.rb +368 -0
- data/lib/bolt/apply_inventory.rb +93 -0
- data/lib/bolt/apply_result.rb +154 -0
- data/lib/bolt/apply_target.rb +90 -0
- data/lib/bolt/bolt_option_parser.rb +1226 -0
- data/lib/bolt/catalog/logging.rb +15 -0
- data/lib/bolt/catalog.rb +144 -0
- data/lib/bolt/cli.rb +949 -0
- data/lib/bolt/config/modulepath.rb +30 -0
- data/lib/bolt/config/options.rb +673 -0
- data/lib/bolt/config/transport/base.rb +133 -0
- data/lib/bolt/config/transport/docker.rb +34 -0
- data/lib/bolt/config/transport/jail.rb +33 -0
- data/lib/bolt/config/transport/local.rb +39 -0
- data/lib/bolt/config/transport/lxd.rb +34 -0
- data/lib/bolt/config/transport/options.rb +431 -0
- data/lib/bolt/config/transport/orch.rb +41 -0
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/config/transport/remote.rb +24 -0
- data/lib/bolt/config/transport/ssh.rb +138 -0
- data/lib/bolt/config/transport/winrm.rb +63 -0
- data/lib/bolt/config.rb +515 -0
- data/lib/bolt/container_result.rb +105 -0
- data/lib/bolt/error.rb +194 -0
- data/lib/bolt/executor.rb +539 -0
- data/lib/bolt/fiber_executor.rb +190 -0
- data/lib/bolt/inventory/group.rb +446 -0
- data/lib/bolt/inventory/inventory.rb +391 -0
- data/lib/bolt/inventory/options.rb +139 -0
- data/lib/bolt/inventory/target.rb +293 -0
- data/lib/bolt/inventory.rb +120 -0
- data/lib/bolt/logger.rb +252 -0
- data/lib/bolt/module.rb +54 -0
- data/lib/bolt/module_installer/installer.rb +44 -0
- data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
- data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
- data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
- data/lib/bolt/module_installer/puppetfile.rb +131 -0
- data/lib/bolt/module_installer/resolver.rb +129 -0
- data/lib/bolt/module_installer/specs/forge_spec.rb +91 -0
- data/lib/bolt/module_installer/specs/git_spec.rb +150 -0
- data/lib/bolt/module_installer/specs/id/base.rb +116 -0
- data/lib/bolt/module_installer/specs/id/gitclone.rb +120 -0
- data/lib/bolt/module_installer/specs/id/github.rb +90 -0
- data/lib/bolt/module_installer/specs/id/gitlab.rb +92 -0
- data/lib/bolt/module_installer/specs.rb +95 -0
- data/lib/bolt/module_installer.rb +208 -0
- data/lib/bolt/node/errors.rb +55 -0
- data/lib/bolt/node/output.rb +29 -0
- data/lib/bolt/outputter/human.rb +958 -0
- data/lib/bolt/outputter/json.rb +205 -0
- data/lib/bolt/outputter/logger.rb +76 -0
- data/lib/bolt/outputter/rainbow.rb +118 -0
- data/lib/bolt/outputter.rb +57 -0
- data/lib/bolt/pal/issues.rb +19 -0
- data/lib/bolt/pal/logging.rb +17 -0
- data/lib/bolt/pal/yaml_plan/evaluator.rb +83 -0
- data/lib/bolt/pal/yaml_plan/loader.rb +94 -0
- data/lib/bolt/pal/yaml_plan/parameter.rb +63 -0
- data/lib/bolt/pal/yaml_plan/step/command.rb +45 -0
- data/lib/bolt/pal/yaml_plan/step/download.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/eval.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step/plan.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/resources.rb +170 -0
- data/lib/bolt/pal/yaml_plan/step/script.rb +62 -0
- data/lib/bolt/pal/yaml_plan/step/task.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/upload.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step.rb +223 -0
- data/lib/bolt/pal/yaml_plan/transpiler.rb +90 -0
- data/lib/bolt/pal/yaml_plan.rb +172 -0
- data/lib/bolt/pal.rb +847 -0
- data/lib/bolt/plan_creator.rb +219 -0
- data/lib/bolt/plan_future.rb +86 -0
- data/lib/bolt/plan_result.rb +44 -0
- data/lib/bolt/plugin/cache.rb +76 -0
- data/lib/bolt/plugin/env_var.rb +54 -0
- data/lib/bolt/plugin/module.rb +276 -0
- data/lib/bolt/plugin/prompt.rb +36 -0
- data/lib/bolt/plugin/puppet_connect_data.rb +84 -0
- data/lib/bolt/plugin/puppetdb.rb +124 -0
- data/lib/bolt/plugin/task.rb +72 -0
- data/lib/bolt/plugin.rb +380 -0
- data/lib/bolt/project.rb +219 -0
- data/lib/bolt/project_manager/config_migrator.rb +113 -0
- data/lib/bolt/project_manager/inventory_migrator.rb +67 -0
- data/lib/bolt/project_manager/migrator.rb +39 -0
- data/lib/bolt/project_manager/module_migrator.rb +203 -0
- data/lib/bolt/project_manager.rb +221 -0
- data/lib/bolt/puppetdb/client.rb +153 -0
- data/lib/bolt/puppetdb/config.rb +176 -0
- data/lib/bolt/puppetdb/instance.rb +146 -0
- data/lib/bolt/puppetdb.rb +15 -0
- data/lib/bolt/r10k_log_proxy.rb +30 -0
- data/lib/bolt/rerun.rb +55 -0
- data/lib/bolt/resource_instance.rb +133 -0
- data/lib/bolt/result.rb +247 -0
- data/lib/bolt/result_set.rb +128 -0
- data/lib/bolt/shell/bash/tmpdir.rb +62 -0
- data/lib/bolt/shell/bash.rb +516 -0
- data/lib/bolt/shell/powershell/snippets.rb +181 -0
- data/lib/bolt/shell/powershell.rb +365 -0
- data/lib/bolt/shell.rb +105 -0
- data/lib/bolt/target.rb +174 -0
- data/lib/bolt/task/puppet_server.rb +27 -0
- data/lib/bolt/task/run.rb +55 -0
- data/lib/bolt/task.rb +163 -0
- data/lib/bolt/transport/base.rb +252 -0
- data/lib/bolt/transport/docker/connection.rb +150 -0
- data/lib/bolt/transport/docker.rb +23 -0
- data/lib/bolt/transport/jail/connection.rb +81 -0
- data/lib/bolt/transport/jail.rb +21 -0
- data/lib/bolt/transport/local/connection.rb +106 -0
- data/lib/bolt/transport/local.rb +20 -0
- data/lib/bolt/transport/lxd/connection.rb +115 -0
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/orch/connection.rb +111 -0
- data/lib/bolt/transport/orch.rb +271 -0
- data/lib/bolt/transport/podman/connection.rb +102 -0
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/remote.rb +41 -0
- data/lib/bolt/transport/simple.rb +54 -0
- data/lib/bolt/transport/ssh/connection.rb +321 -0
- data/lib/bolt/transport/ssh/exec_connection.rb +140 -0
- data/lib/bolt/transport/ssh.rb +48 -0
- data/lib/bolt/transport/winrm/connection.rb +378 -0
- data/lib/bolt/transport/winrm.rb +33 -0
- data/lib/bolt/util/format.rb +68 -0
- data/lib/bolt/util/puppet_log_level.rb +21 -0
- data/lib/bolt/util.rb +465 -0
- data/lib/bolt/validator.rb +227 -0
- data/lib/bolt/version.rb +5 -0
- data/lib/bolt.rb +8 -0
- data/lib/bolt_server/acl.rb +39 -0
- data/lib/bolt_server/base_config.rb +112 -0
- data/lib/bolt_server/config.rb +64 -0
- data/lib/bolt_server/file_cache.rb +200 -0
- data/lib/bolt_server/request_error.rb +11 -0
- data/lib/bolt_server/schemas/action-check_node_connections.json +14 -0
- data/lib/bolt_server/schemas/action-run_command.json +12 -0
- data/lib/bolt_server/schemas/action-run_script.json +47 -0
- data/lib/bolt_server/schemas/action-run_task.json +20 -0
- data/lib/bolt_server/schemas/action-upload_file.json +47 -0
- data/lib/bolt_server/schemas/partials/target-any.json +10 -0
- data/lib/bolt_server/schemas/partials/target-ssh.json +88 -0
- data/lib/bolt_server/schemas/partials/target-winrm.json +67 -0
- data/lib/bolt_server/schemas/partials/task.json +94 -0
- data/lib/bolt_server/schemas/transport-ssh.json +25 -0
- data/lib/bolt_server/schemas/transport-winrm.json +19 -0
- data/lib/bolt_server/transport_app.rb +554 -0
- data/lib/bolt_spec/bolt_context.rb +226 -0
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +51 -0
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +59 -0
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +57 -0
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +65 -0
- data/lib/bolt_spec/plans/action_stubs.rb +196 -0
- data/lib/bolt_spec/plans/mock_executor.rb +361 -0
- data/lib/bolt_spec/plans/publish_stub.rb +49 -0
- data/lib/bolt_spec/plans.rb +190 -0
- data/lib/bolt_spec/run.rb +246 -0
- data/lib/logging_extensions/logging.rb +13 -0
- data/libexec/apply_catalog.rb +130 -0
- data/libexec/bolt_catalog +68 -0
- data/libexec/custom_facts.rb +63 -0
- data/libexec/query_resources.rb +75 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/count.rb +21 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/nodes.rb +22 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/targets.rb +21 -0
- data/modules/aggregate/plans/count.pp +56 -0
- data/modules/aggregate/plans/targets.pp +56 -0
- data/modules/canary/lib/puppet/functions/canary/merge.rb +13 -0
- data/modules/canary/lib/puppet/functions/canary/random_split.rb +22 -0
- data/modules/canary/lib/puppet/functions/canary/skip.rb +25 -0
- data/modules/canary/plans/init.pp +100 -0
- data/modules/puppet_connect/plans/test_input_data.pp +94 -0
- data/modules/puppetdb_fact/plans/init.pp +20 -0
- data/resources/bolt_bash_completion.sh +214 -0
- metadata +735 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/container_result'
|
4
|
+
require 'bolt/error'
|
5
|
+
require 'bolt/util'
|
6
|
+
|
7
|
+
# Run a container and return its output to stdout and stderr.
|
8
|
+
#
|
9
|
+
# > **Note:** Not available in apply block
|
10
|
+
Puppet::Functions.create_function(:run_container) do
|
11
|
+
# Run a container.
|
12
|
+
# @param image The name of the image to run.
|
13
|
+
# @param options A hash of additional options.
|
14
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
15
|
+
# @option options [String] cmd A command to run in the container.
|
16
|
+
# @option options [Hash[String, Data]] env_vars Map of environment variables to set.
|
17
|
+
# @option options [Hash[Integer, Integer]] ports A map of container ports to
|
18
|
+
# publish. Keys are the host port, values are the corresponding container
|
19
|
+
# port.
|
20
|
+
# @option options [Boolean] rm Whether to remove the container once it exits.
|
21
|
+
# @option options [Hash[String, String]] volumes A map of absolute paths on
|
22
|
+
# the host to absolute paths on the remote to mount.
|
23
|
+
# @option options [String] workdir The working directory within the container.
|
24
|
+
# @return Output from the container.
|
25
|
+
# @example Run Nginx proxy manager
|
26
|
+
# run_container('jc21/nginx-proxy-manager', 'ports' => { 80 => 80, 81 => 81, 443 => 443 })
|
27
|
+
dispatch :run_container do
|
28
|
+
param 'String[1]', :image
|
29
|
+
optional_param 'Hash[String[1], Any]', :options
|
30
|
+
return_type 'ContainerResult'
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_container(image, options = {})
|
34
|
+
unless Puppet[:tasks]
|
35
|
+
raise Puppet::ParseErrorWithIssue
|
36
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_container')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Send Analytics Report
|
40
|
+
executor = Puppet.lookup(:bolt_executor)
|
41
|
+
executor.report_function_call(self.class.name)
|
42
|
+
|
43
|
+
options = options.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
44
|
+
validate_options(options)
|
45
|
+
|
46
|
+
if options.key?(:env_vars)
|
47
|
+
options[:env_vars] = options[:env_vars].transform_values do |val|
|
48
|
+
[Array, Hash].include?(val.class) ? val.to_json : val
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:ports]
|
53
|
+
ports = options[:ports].each_with_object([]) do |(host_port, container_port), acc|
|
54
|
+
acc << "-p"
|
55
|
+
acc << "#{host_port}:#{container_port}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if options[:volumes]
|
60
|
+
volumes = options[:volumes].each_with_object([]) do |(host_path, remote_path), acc|
|
61
|
+
begin
|
62
|
+
FileUtils.mkdir_p(host_path)
|
63
|
+
rescue StandardError => e
|
64
|
+
message = "Unable to create host volume directory #{host_path}: #{e.message}"
|
65
|
+
raise Bolt::Error.new(message, 'bolt/file-error')
|
66
|
+
end
|
67
|
+
acc << "-v"
|
68
|
+
acc << "#{host_path}:#{remote_path}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Run the container
|
73
|
+
# `docker run` will automatically pull the image if it isn't already downloaded
|
74
|
+
cmd = %w[run]
|
75
|
+
cmd += Bolt::Util.format_env_vars_for_cli(options[:env_vars]) if options[:env_vars]
|
76
|
+
cmd += volumes if volumes
|
77
|
+
cmd += ports if ports
|
78
|
+
cmd << "--rm" if options[:rm]
|
79
|
+
cmd += %W[-w #{options[:workdir]}] if options[:workdir]
|
80
|
+
cmd << image
|
81
|
+
cmd += Shellwords.shellsplit(options[:cmd]) if options[:cmd]
|
82
|
+
|
83
|
+
executor.publish_event(type: :container_start, image: image)
|
84
|
+
out, err, status = Bolt::Util.exec_docker(cmd)
|
85
|
+
|
86
|
+
o = out.is_a?(String) ? out.dup.force_encoding('utf-8') : out
|
87
|
+
e = err.is_a?(String) ? err.dup.force_encoding('utf-8') : err
|
88
|
+
|
89
|
+
unless status.exitstatus.zero?
|
90
|
+
result = Bolt::ContainerResult.from_exception(e,
|
91
|
+
status.exitstatus,
|
92
|
+
image,
|
93
|
+
position: Puppet::Pops::PuppetStack.top_of_stack)
|
94
|
+
executor.publish_event(type: :container_finish, result: result)
|
95
|
+
if options[:catch_errors]
|
96
|
+
return result
|
97
|
+
else
|
98
|
+
raise Bolt::ContainerFailure, result
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
value = { 'stdout' => o, 'stderr' => e, 'exit_code' => status.exitstatus }
|
103
|
+
result = Bolt::ContainerResult.new(value, object: image)
|
104
|
+
executor.publish_event(type: :container_finish, result: result)
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def validate_options(options)
|
109
|
+
if options.key?(:env_vars)
|
110
|
+
ev = options[:env_vars]
|
111
|
+
unless ev.is_a?(Hash)
|
112
|
+
msg = "Option 'env_vars' must be a hash. Received #{ev} which is a #{ev.class}"
|
113
|
+
raise Bolt::ValidationError, msg
|
114
|
+
end
|
115
|
+
|
116
|
+
if (bad_keys = ev.keys.reject { |k| k.is_a?(String) }).any?
|
117
|
+
msg = "Keys for option 'env_vars' must be strings: #{bad_keys.map(&:inspect).join(', ')}"
|
118
|
+
raise Bolt::ValidationError, msg
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
if options.key?(:volumes)
|
123
|
+
volumes = options[:volumes]
|
124
|
+
unless volumes.is_a?(Hash)
|
125
|
+
msg = "Option 'volumes' must be a hash. Received #{volumes} which is a #{volumes.class}"
|
126
|
+
raise Bolt::ValidationError, msg
|
127
|
+
end
|
128
|
+
|
129
|
+
if (bad_vs = volumes.reject { |k, v| k.is_a?(String) && v.is_a?(String) }).any?
|
130
|
+
msg = "Option 'volumes' only accepts strings for keys and values. "\
|
131
|
+
"Received: #{bad_vs.map(&:inspect).join(', ')}"
|
132
|
+
raise Bolt::ValidationError, msg
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
if options.key?(:cmd) && !options[:cmd].is_a?(String)
|
137
|
+
cmd = options[:cmd]
|
138
|
+
msg = "Option 'cmd' must be a string. Received #{cmd} which is a #{cmd.class}"
|
139
|
+
raise Bolt::ValidationError, msg
|
140
|
+
end
|
141
|
+
|
142
|
+
if options.key?(:workdir) && !options[:workdir].is_a?(String)
|
143
|
+
wd = options[:workdir]
|
144
|
+
msg = "Option 'workdir' must be a string. Received #{wd} which is a #{wd.class}"
|
145
|
+
raise Bolt::ValidationError, msg
|
146
|
+
end
|
147
|
+
|
148
|
+
if options.key?(:ports)
|
149
|
+
ports = options[:ports]
|
150
|
+
unless ports.is_a?(Hash)
|
151
|
+
msg = "Option 'ports' must be a hash. Received #{ports} which is a #{ports.class}"
|
152
|
+
raise Bolt::ValidationError, msg
|
153
|
+
end
|
154
|
+
|
155
|
+
if (bad_ps = ports.reject { |k, v| k.is_a?(Integer) && v.is_a?(Integer) }).any?
|
156
|
+
msg = "Option 'ports' only accepts integers for keys and values. "\
|
157
|
+
"Received: #{bad_ps.map(&:inspect).join(', ')}"
|
158
|
+
raise Bolt::ValidationError, msg
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/error'
|
4
|
+
|
5
|
+
# Runs the `plan` referenced by its name. A plan is autoloaded from `$MODULEROOT/plans`.
|
6
|
+
#
|
7
|
+
# > **Note:** Not available in apply block
|
8
|
+
Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction) do
|
9
|
+
# Run a plan
|
10
|
+
# @param plan_name The plan to run.
|
11
|
+
# @param args A hash of arguments to the plan. Can also include additional options.
|
12
|
+
# @option args [Boolean] _catch_errors Whether to catch raised errors.
|
13
|
+
# @option args [String] _run_as User to run as using privilege escalation.
|
14
|
+
# This option sets the [run-as user](privilege_escalation.md) for all
|
15
|
+
# targets whenever Bolt connects to a target. This is set for all functions
|
16
|
+
# in the called plan, including `run_plan()`.
|
17
|
+
# @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
|
18
|
+
# @example Run a plan
|
19
|
+
# run_plan('canary', 'command' => 'false', 'targets' => $targets, '_catch_errors' => true)
|
20
|
+
dispatch :run_plan do
|
21
|
+
scope_param
|
22
|
+
param 'String', :plan_name
|
23
|
+
optional_param 'Hash', :args
|
24
|
+
return_type 'Boltlib::PlanResult'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Run a plan, specifying `$nodes` or `$targets` as a positional argument.
|
28
|
+
#
|
29
|
+
# > **Note:** When running a plan with both a `$nodes` and `$targets` parameter, and using the second
|
30
|
+
# positional argument, the plan will fail.
|
31
|
+
#
|
32
|
+
# @param plan_name The plan to run.
|
33
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
34
|
+
# @param args A hash of arguments to the plan. Can also include additional options.
|
35
|
+
# @option args [Boolean] _catch_errors Whether to catch raised errors.
|
36
|
+
# @option args [String] _run_as User to run as using privilege escalation.
|
37
|
+
# This option sets the [run-as user](privilege_escalation.md) for all
|
38
|
+
# targets whenever Bolt connects to a target. This is set for all functions
|
39
|
+
# in the called plan, including `run_plan()`.
|
40
|
+
# @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
|
41
|
+
# @example Run a plan
|
42
|
+
# run_plan('canary', $targets, 'command' => 'false')
|
43
|
+
dispatch :run_plan_with_targetspec do
|
44
|
+
scope_param
|
45
|
+
param 'String', :plan_name
|
46
|
+
param 'Boltlib::TargetSpec', :targets
|
47
|
+
optional_param 'Hash', :args
|
48
|
+
return_type 'Boltlib::PlanResult'
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_plan_with_targetspec(scope, plan_name, targets, args = {})
|
52
|
+
run_inner_plan(scope, plan_name, targets, args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def run_plan(scope, plan_name, args = {})
|
56
|
+
run_inner_plan(scope, plan_name, nil, args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def run_inner_plan(scope, plan_name, targets, args = {})
|
60
|
+
unless Puppet[:tasks]
|
61
|
+
raise Puppet::ParseErrorWithIssue
|
62
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_plan')
|
63
|
+
end
|
64
|
+
|
65
|
+
executor = Puppet.lookup(:bolt_executor)
|
66
|
+
|
67
|
+
options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
|
68
|
+
options = options.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
69
|
+
|
70
|
+
# Bolt calls this function internally to trigger plans from the CLI. We
|
71
|
+
# don't want to count those invocations.
|
72
|
+
unless options[:bolt_api_call]
|
73
|
+
# Send Analytics Report
|
74
|
+
executor.report_function_call(self.class.name)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Send Analytics Report for bundled content, this should capture plans run from both CLI and Plans
|
78
|
+
executor.report_bundled_content('Plan', plan_name)
|
79
|
+
|
80
|
+
loaders = closure_scope.compiler.loaders
|
81
|
+
# The perspective of the environment is wanted here (for now) to not have to
|
82
|
+
# require modules to have dependencies defined in meta data.
|
83
|
+
loader = loaders.private_environment_loader
|
84
|
+
|
85
|
+
# TODO: Why would we not have a private_environment_loader?
|
86
|
+
unless loader && (func = loader.load(:plan, plan_name))
|
87
|
+
raise Bolt::Error.unknown_plan(plan_name)
|
88
|
+
end
|
89
|
+
|
90
|
+
if (run_as = options[:run_as])
|
91
|
+
old_run_as = executor.run_as
|
92
|
+
executor.run_as = run_as
|
93
|
+
end
|
94
|
+
|
95
|
+
closure = func.class.dispatcher.dispatchers[0]
|
96
|
+
if closure.model.is_a?(Bolt::PAL::YamlPlan)
|
97
|
+
executor.report_yaml_plan(closure.model.body)
|
98
|
+
end
|
99
|
+
|
100
|
+
# If a TargetSpec parameter is passed, ensure it is in inventory
|
101
|
+
inventory = Puppet.lookup(:bolt_inventory)
|
102
|
+
|
103
|
+
param_types = closure.parameters.each_with_object({}) do |param, param_acc|
|
104
|
+
param_acc[param.name] = extract_parameter_types(param.type_expr)&.flatten
|
105
|
+
end
|
106
|
+
|
107
|
+
targets_to_param(targets, params, param_types) if targets
|
108
|
+
|
109
|
+
if inventory.version > 1
|
110
|
+
params.each do |param, value|
|
111
|
+
# Note the safe lookup operator is needed to handle case where a parameter is passed to a
|
112
|
+
# plan that the plan is not expecting
|
113
|
+
if param_types[param]&.include?('TargetSpec') || param_types[param]&.include?('Boltlib::TargetSpec')
|
114
|
+
inventory.get_targets(value)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Wrap Sensitive parameters for plans that are run from the CLI, as it's impossible to pass
|
120
|
+
# a Sensitive value that way. We don't do this for plans run from the run_plan function, as
|
121
|
+
# it can receive Sensitive values as arguments.
|
122
|
+
# This should only happen after expanding target params, otherwise things will blow up if
|
123
|
+
# the targets are wrapped as Sensitive. Hopefully nobody does that, though...
|
124
|
+
if options[:bolt_api_call]
|
125
|
+
params = wrap_sensitive_parameters(params, closure.parameters)
|
126
|
+
end
|
127
|
+
|
128
|
+
# This can be anything as long as it's unique
|
129
|
+
plan_instance_id = SecureRandom.uuid
|
130
|
+
|
131
|
+
# Add the plan invocation ID to the plan_stack for the PlanFuture the plan is
|
132
|
+
# running in so that we know the PlanFuture is running in a new plan
|
133
|
+
# invocation. This can be nil in test cases and when `wait()` isn't
|
134
|
+
# supported.
|
135
|
+
current_future = executor.get_current_future(fiber: Fiber.current)
|
136
|
+
# Safe operator to make testing easier
|
137
|
+
current_future&.plan_stack&.unshift(plan_instance_id)
|
138
|
+
|
139
|
+
# wrap plan execution in logging messages
|
140
|
+
executor.log_plan(plan_name) do
|
141
|
+
result = nil
|
142
|
+
begin
|
143
|
+
# If the plan does not throw :return by calling the return function it's result is
|
144
|
+
# undef/nil
|
145
|
+
result = catch(:return) do
|
146
|
+
scope.with_global_scope do |global_scope|
|
147
|
+
executor.run_plan(global_scope, closure, params)
|
148
|
+
end
|
149
|
+
nil
|
150
|
+
end&.value
|
151
|
+
# Validate the result is a PlanResult
|
152
|
+
unless Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult').instance?(result)
|
153
|
+
raise Bolt::InvalidPlanResult.new(plan_name, result.to_s)
|
154
|
+
end
|
155
|
+
|
156
|
+
result
|
157
|
+
rescue Puppet::PreformattedError => e
|
158
|
+
if options[:catch_errors] && e.cause.is_a?(Bolt::Error)
|
159
|
+
result = e.cause.to_puppet_error
|
160
|
+
else
|
161
|
+
raise e
|
162
|
+
end
|
163
|
+
ensure
|
164
|
+
# Pop the plan invocation ID off of the plan_id stack for the Future.
|
165
|
+
current_future&.plan_stack&.shift
|
166
|
+
if run_as
|
167
|
+
executor.run_as = old_run_as
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
result
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Recursively examine the type_expr to build a list of types
|
176
|
+
def extract_parameter_types(type_expr)
|
177
|
+
# No type
|
178
|
+
if type_expr.nil?
|
179
|
+
[]
|
180
|
+
# Multiple types to extract (ex. Variant[TargetSpec, String])
|
181
|
+
elsif defined?(type_expr.keys)
|
182
|
+
type_expr.keys.flat_map { |param| extract_parameter_types(param) }
|
183
|
+
# Store cased value
|
184
|
+
elsif defined?(type_expr.cased_value)
|
185
|
+
[type_expr.cased_value]
|
186
|
+
# Type alias, able to resolve alias
|
187
|
+
elsif defined?(type_expr.resolved_type.name)
|
188
|
+
[type_expr.resolved_type.name]
|
189
|
+
# Nested type alias, recurse
|
190
|
+
elsif defined?(type_expr.type)
|
191
|
+
extract_parameter_types(type_expr.type)
|
192
|
+
# Array conatins alias types
|
193
|
+
elsif defined?(type_expr.types)
|
194
|
+
type_expr.types.flat_map { |param| extract_parameter_types(param) }
|
195
|
+
# Each element can be handled by a resolver above
|
196
|
+
elsif defined?(type_expr.element_type)
|
197
|
+
extract_parameter_types(type_expr.element_type)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# Wrap any Sensitive parameters in the Sensitive wrapper type, unless they are already
|
202
|
+
# wrapped as Sensitive. This will also raise a helpful warning if the type expression
|
203
|
+
# is a complex data type using Sensitive, as we don't handle those cases.
|
204
|
+
def wrap_sensitive_parameters(params, param_models)
|
205
|
+
models = param_models.each_with_object({}) { |param, acc| acc[param.name] = param }
|
206
|
+
|
207
|
+
params.each_with_object({}) do |(name, value), acc|
|
208
|
+
model = models[name]
|
209
|
+
|
210
|
+
# Parameters passed to a plan that the plan is not expecting don't have a model,
|
211
|
+
# so keep the parameter as-is.
|
212
|
+
if model.nil?
|
213
|
+
acc[name] = value
|
214
|
+
elsif sensitive_type?(model.type_expr)
|
215
|
+
acc[name] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(value)
|
216
|
+
else
|
217
|
+
if model.type_expr.to_s.include?('Sensitive')
|
218
|
+
# Include the location for regular plans. YAML plans don't have this info, so
|
219
|
+
# the location will be suppressed.
|
220
|
+
file = defined?(model.file) ? model.file : :default
|
221
|
+
line = defined?(model.line) ? model.line : :default
|
222
|
+
|
223
|
+
Puppet.warn_once(
|
224
|
+
'unsupported_sensitive_type',
|
225
|
+
name,
|
226
|
+
"Parameter '#{name}' is a complex type using Sensitive, unable to automatically wrap as Sensitive",
|
227
|
+
file,
|
228
|
+
line
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
acc[name] = value
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Whether the type is a supported Sensitive type. We only support wrapping parameterized
|
238
|
+
# and non-parameterized Sensitive types (e.g. Sensitive, Sensitive[String])
|
239
|
+
def sensitive_type?(type_expr)
|
240
|
+
# Parameterized Sensitive type (e.g. Sensitive[String])
|
241
|
+
# left_expr is defined whenever the type is parameterized. If this is a parameterized
|
242
|
+
# Sensitive type, then we check the cased_value, which is the stringified version of
|
243
|
+
# the left expression's type.
|
244
|
+
(defined?(type_expr.left_expr) && type_expr.left_expr.cased_value == 'Sensitive') ||
|
245
|
+
# Non-parameterized Sensitive type (Sensitive)
|
246
|
+
# cased_value is defined whenever the type is non-parameterized. If the type expression
|
247
|
+
# defines cased_value, then this is a simple type and we just need to check that it's
|
248
|
+
# Sensitive.
|
249
|
+
(defined?(type_expr.cased_value) && type_expr.cased_value == 'Sensitive') ||
|
250
|
+
# Sensitive type from YAML plans
|
251
|
+
# Type expressions from YAML plans are a different class than those from regular plans.
|
252
|
+
# As long as the type expression is PSensitiveType we can be sure that the type is
|
253
|
+
# either a parameterized or non-parameterized Sensitive type.
|
254
|
+
type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
|
255
|
+
end
|
256
|
+
|
257
|
+
def targets_to_param(targets, params, param_types)
|
258
|
+
nodes_param = param_types.include?('nodes')
|
259
|
+
targets_param = param_types['targets']&.any? { |p| p.match?(/TargetSpec/) }
|
260
|
+
|
261
|
+
# Both a 'TargetSpec $nodes' and 'TargetSpec $targets' parameter are present in the plan
|
262
|
+
if nodes_param && targets_param
|
263
|
+
raise ArgumentError,
|
264
|
+
"A plan with both a $nodes and $targets parameter cannot have either parameter specified " \
|
265
|
+
"as the second positional argument to run_plan()."
|
266
|
+
end
|
267
|
+
|
268
|
+
# Always populate a $nodes parameter over $targets
|
269
|
+
if nodes_param
|
270
|
+
if params['nodes']
|
271
|
+
raise ArgumentError,
|
272
|
+
"A plan's 'nodes' parameter can be specified as the second positional argument to " \
|
273
|
+
"run_plan(), but in that case 'nodes' must not be specified in the named arguments " \
|
274
|
+
"hash."
|
275
|
+
end
|
276
|
+
params['nodes'] = targets
|
277
|
+
# If there is only a $targets parameter, then populate it
|
278
|
+
elsif targets_param
|
279
|
+
if params['targets']
|
280
|
+
raise ArgumentError,
|
281
|
+
"A plan's 'targets' parameter can be specified as the second positional argument to " \
|
282
|
+
"run_plan(), but in that case 'targets' must not be specified in the named arguments " \
|
283
|
+
"hash."
|
284
|
+
end
|
285
|
+
params['targets'] = targets
|
286
|
+
# If a plan has neither parameter, just fall back to $nodes
|
287
|
+
else
|
288
|
+
params['nodes'] = targets
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Uploads the given script to the given set of targets and returns the result of having each target execute the script.
|
4
|
+
# This function does nothing if the list of targets is empty.
|
5
|
+
#
|
6
|
+
# > **Note:** Not available in apply block
|
7
|
+
Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFunction) do
|
8
|
+
# Run a script.
|
9
|
+
# @param script Path to a script to run on target. Can be an absolute path or a modulename/filename selector for a
|
10
|
+
# file in $MODULEROOT/files.
|
11
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
12
|
+
# @param options A hash of additional options.
|
13
|
+
# @option options [Array[String]] arguments An array of arguments to be passed to the script.
|
14
|
+
# Cannot be used with `pwsh_params`.
|
15
|
+
# @option options [Hash] pwsh_params Map of named parameters to pass to a PowerShell script.
|
16
|
+
# Cannot be used with `arguments`.
|
17
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
18
|
+
# @option options [String] _run_as User to run as using privilege escalation.
|
19
|
+
# @option options [Hash[String, Any]] _env_vars Map of environment variables to set.
|
20
|
+
# @return A list of results, one entry per target.
|
21
|
+
# @example Run a local script on Linux targets as 'root'
|
22
|
+
# run_script('/var/tmp/myscript', $targets, '_run_as' => 'root')
|
23
|
+
# @example Run a module-provided script with arguments
|
24
|
+
# run_script('iis/setup.ps1', $target, 'arguments' => ['/u', 'Administrator'])
|
25
|
+
# @example Pass named parameters to a PowerShell script
|
26
|
+
# run_script('iis/setup.ps1', $target, 'pwsh_params' => { 'User' => 'Administrator' })
|
27
|
+
dispatch :run_script do
|
28
|
+
scope_param
|
29
|
+
param 'String[1]', :script
|
30
|
+
param 'Boltlib::TargetSpec', :targets
|
31
|
+
optional_param 'Hash[String[1], Any]', :options
|
32
|
+
return_type 'ResultSet'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Run a script, logging the provided description.
|
36
|
+
# @param script Path to a script to run on target. Can be an absolute path or a modulename/filename selector for a
|
37
|
+
# file in $MODULEROOT/files.
|
38
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
39
|
+
# @param description A description to be output when calling this function.
|
40
|
+
# @param options A hash of additional options.
|
41
|
+
# @option options [Array[String]] arguments An array of arguments to be passed to the script.
|
42
|
+
# Cannot be used with `pwsh_params`.
|
43
|
+
# @option options [Hash] pwsh_params Map of named parameters to pass to a PowerShell script.
|
44
|
+
# Cannot be used with `arguments`.
|
45
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
46
|
+
# @option options [String] _run_as User to run as using privilege escalation.
|
47
|
+
# @option options [Hash[String, Any]] _env_vars Map of environment variables to set.
|
48
|
+
# @return A list of results, one entry per target.
|
49
|
+
# @example Run a script
|
50
|
+
# run_script('/var/tmp/myscript', $targets, 'Downloading my application')
|
51
|
+
dispatch :run_script_with_description do
|
52
|
+
scope_param
|
53
|
+
param 'String[1]', :script
|
54
|
+
param 'Boltlib::TargetSpec', :targets
|
55
|
+
param 'String', :description
|
56
|
+
optional_param 'Hash[String[1], Any]', :options
|
57
|
+
return_type 'ResultSet'
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_script(scope, script, targets, options = {})
|
61
|
+
run_script_with_description(scope, script, targets, nil, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_script_with_description(scope, script, targets, description = nil, options = {})
|
65
|
+
unless Puppet[:tasks]
|
66
|
+
raise Puppet::ParseErrorWithIssue
|
67
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_script')
|
68
|
+
end
|
69
|
+
|
70
|
+
if options.key?('arguments') && options.key?('pwsh_params')
|
71
|
+
raise Bolt::ValidationError, "Cannot specify both 'arguments' and 'pwsh_params'"
|
72
|
+
end
|
73
|
+
|
74
|
+
if options.key?('pwsh_params') && !options['pwsh_params'].is_a?(Hash)
|
75
|
+
raise Bolt::ValidationError, "Option 'pwsh_params' must be a hash"
|
76
|
+
end
|
77
|
+
|
78
|
+
if options.key?('arguments') && !options['arguments'].is_a?(Array)
|
79
|
+
raise Bolt::ValidationError, "Option 'arguments' must be an array"
|
80
|
+
end
|
81
|
+
|
82
|
+
arguments = options['arguments'] || []
|
83
|
+
pwsh_params = options['pwsh_params']
|
84
|
+
options = options.select { |opt| opt.start_with?('_') }.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
85
|
+
options[:description] = description if description
|
86
|
+
options[:pwsh_params] = pwsh_params if pwsh_params
|
87
|
+
|
88
|
+
# Ensure env_vars is a hash and that each hash value is transformed to JSON
|
89
|
+
# so we don't accidentally pass Ruby-style data to the target.
|
90
|
+
if options[:env_vars]
|
91
|
+
unless options[:env_vars].is_a?(Hash)
|
92
|
+
raise Bolt::ValidationError, "Option 'env_vars' must be a hash"
|
93
|
+
end
|
94
|
+
|
95
|
+
if (bad_keys = options[:env_vars].keys.reject { |k| k.is_a?(String) }).any?
|
96
|
+
raise Bolt::ValidationError,
|
97
|
+
"Keys for option 'env_vars' must be strings: #{bad_keys.map(&:inspect).join(', ')}"
|
98
|
+
end
|
99
|
+
|
100
|
+
options[:env_vars] = options[:env_vars].transform_values do |val|
|
101
|
+
[Array, Hash].include?(val.class) ? val.to_json : val
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
executor = Puppet.lookup(:bolt_executor)
|
106
|
+
inventory = Puppet.lookup(:bolt_inventory)
|
107
|
+
|
108
|
+
# Send Analytics Report
|
109
|
+
executor.report_function_call(self.class.name)
|
110
|
+
|
111
|
+
# Find the file path if it exists, otherwise return nil
|
112
|
+
found = Bolt::Util.find_file_from_scope(script, scope)
|
113
|
+
unless found && Puppet::FileSystem.exist?(found)
|
114
|
+
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
115
|
+
Puppet::Pops::Issues::NO_SUCH_FILE_OR_DIRECTORY, file: script
|
116
|
+
)
|
117
|
+
end
|
118
|
+
unless Puppet::FileSystem.file?(found)
|
119
|
+
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
120
|
+
Puppet::Pops::Issues::NOT_A_FILE, file: script
|
121
|
+
)
|
122
|
+
end
|
123
|
+
executor.report_file_source(self.class.name, script)
|
124
|
+
# Ensure that given targets are all Target instances)
|
125
|
+
targets = inventory.get_targets(targets)
|
126
|
+
|
127
|
+
if targets.empty?
|
128
|
+
Bolt::ResultSet.new([])
|
129
|
+
else
|
130
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
131
|
+
r = if executor.in_parallel?
|
132
|
+
executor.run_in_thread do
|
133
|
+
executor.run_script(targets, found, arguments, options, file_line)
|
134
|
+
end
|
135
|
+
else
|
136
|
+
executor.run_script(targets, found, arguments, options, file_line)
|
137
|
+
end
|
138
|
+
|
139
|
+
if !r.ok && !options[:catch_errors]
|
140
|
+
raise Bolt::RunFailure.new(r, 'run_script', script)
|
141
|
+
end
|
142
|
+
r
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|