openbolt 5.0.0.pre.rc2
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_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 +738 -0
data/lib/bolt/result.rb
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative '../bolt/error'
|
5
|
+
|
6
|
+
module Bolt
|
7
|
+
class Result
|
8
|
+
attr_reader :target, :value, :action, :object
|
9
|
+
|
10
|
+
def self.from_exception(target, exception, action: 'action', position: [])
|
11
|
+
details = create_details(position)
|
12
|
+
if exception.is_a?(Bolt::Error)
|
13
|
+
error = Bolt::Util.deep_merge({ 'details' => details }, exception.to_h)
|
14
|
+
else
|
15
|
+
details['class'] = exception.class.to_s
|
16
|
+
error = {
|
17
|
+
'kind' => 'puppetlabs.tasks/exception-error',
|
18
|
+
'issue_code' => 'EXCEPTION',
|
19
|
+
'msg' => exception.message,
|
20
|
+
'details' => details
|
21
|
+
}
|
22
|
+
error['details']['stack_trace'] = exception.backtrace.join('\n') if exception.backtrace
|
23
|
+
end
|
24
|
+
Result.new(target, error: error, action: action)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.create_details(position)
|
28
|
+
%w[file line].zip(position).to_h.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.for_lookup(target, key, value)
|
32
|
+
val = { 'value' => value }
|
33
|
+
new(target, value: val, action: 'lookup', object: key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.for_command(target, value, action, command, position)
|
37
|
+
details = create_details(position)
|
38
|
+
unless value['exit_code'] == 0
|
39
|
+
details['exit_code'] = value['exit_code']
|
40
|
+
value['_error'] = {
|
41
|
+
'kind' => 'puppetlabs.tasks/command-error',
|
42
|
+
'issue_code' => 'COMMAND_ERROR',
|
43
|
+
'msg' => "The command failed with exit code #{value['exit_code']}",
|
44
|
+
'details' => details
|
45
|
+
}
|
46
|
+
end
|
47
|
+
new(target, value: value, action: action, object: command)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.for_task(target, stdout, stderr, exit_code, task, position)
|
51
|
+
stdout.force_encoding('utf-8') unless stdout.encoding == Encoding::UTF_8
|
52
|
+
|
53
|
+
details = create_details(position)
|
54
|
+
value = if stdout.valid_encoding?
|
55
|
+
parse_hash(stdout) || { '_output' => stdout }
|
56
|
+
else
|
57
|
+
{ '_error' => { 'kind' => 'puppetlabs.tasks/task-error',
|
58
|
+
'issue_code' => 'TASK_ERROR',
|
59
|
+
'msg' => 'The task result contained invalid UTF-8 on stdout',
|
60
|
+
'details' => details } }
|
61
|
+
end
|
62
|
+
|
63
|
+
if exit_code != 0 && value['_error'].nil?
|
64
|
+
msg = if stdout.empty?
|
65
|
+
if stderr.empty?
|
66
|
+
"The task failed with exit code #{exit_code} and no output"
|
67
|
+
else
|
68
|
+
"The task failed with exit code #{exit_code} and no stdout, but stderr contained:\n#{stderr}"
|
69
|
+
end
|
70
|
+
else
|
71
|
+
"The task failed with exit code #{exit_code}"
|
72
|
+
end
|
73
|
+
details['exit_code'] = exit_code
|
74
|
+
value['_error'] = { 'kind' => 'puppetlabs.tasks/task-error',
|
75
|
+
'issue_code' => 'TASK_ERROR',
|
76
|
+
'msg' => msg,
|
77
|
+
'details' => details }
|
78
|
+
end
|
79
|
+
|
80
|
+
if value.key?('_error')
|
81
|
+
unless value['_error'].is_a?(Hash) && value['_error'].key?('msg')
|
82
|
+
details['original_error'] = value['_error']
|
83
|
+
value['_error'] = {
|
84
|
+
'msg' => "Invalid error returned from task #{task}: #{value['_error'].inspect}. Error "\
|
85
|
+
"must be an object with a msg key.",
|
86
|
+
'kind' => 'bolt/invalid-task-error',
|
87
|
+
'details' => details
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
value['_error']['kind'] ||= 'bolt/error'
|
92
|
+
value['_error']['details'] ||= details
|
93
|
+
end
|
94
|
+
|
95
|
+
if value.key?('_sensitive')
|
96
|
+
value['_sensitive'] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(value['_sensitive'])
|
97
|
+
end
|
98
|
+
|
99
|
+
new(target, value: value, action: 'task', object: task)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.parse_hash(string)
|
103
|
+
value = JSON.parse(string)
|
104
|
+
value if value.is_a? Hash
|
105
|
+
rescue JSON::ParserError
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.for_upload(target, source, destination)
|
110
|
+
new(target, message: "Uploaded '#{source}' to '#{target.host}:#{destination}'", action: 'upload', object: source)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.for_download(target, source, destination, download)
|
114
|
+
msg = "Downloaded '#{target.host}:#{source}' to '#{destination}'"
|
115
|
+
value = { 'path' => download }
|
116
|
+
|
117
|
+
new(target, value: value, message: msg, action: 'download', object: source)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Satisfies the Puppet datatypes API
|
121
|
+
def self.from_asserted_args(target, value)
|
122
|
+
new(target, value: value)
|
123
|
+
end
|
124
|
+
|
125
|
+
def self._pcore_init_from_hash
|
126
|
+
raise "Result shouldn't be instantiated from a pcore_init class method. How did this get called?"
|
127
|
+
end
|
128
|
+
|
129
|
+
def _pcore_init_from_hash(init_hash)
|
130
|
+
opts = init_hash.reject { |k, _v| k == 'target' }
|
131
|
+
initialize(init_hash['target'], **opts.transform_keys(&:to_sym))
|
132
|
+
end
|
133
|
+
|
134
|
+
def _pcore_init_hash
|
135
|
+
{ 'target' => @target,
|
136
|
+
'error' => @value['_error'],
|
137
|
+
'message' => @value['_output'],
|
138
|
+
'value' => @value,
|
139
|
+
'action' => @action,
|
140
|
+
'object' => @object }
|
141
|
+
end
|
142
|
+
|
143
|
+
def initialize(target, error: nil, message: nil, value: nil, action: 'action', object: nil)
|
144
|
+
@target = target
|
145
|
+
@value = value || {}
|
146
|
+
@action = action
|
147
|
+
@object = object
|
148
|
+
if error && !error.is_a?(Hash)
|
149
|
+
raise "TODO: how did we get a string error"
|
150
|
+
end
|
151
|
+
@value['_error'] = error if error
|
152
|
+
@value['_output'] = message if message
|
153
|
+
end
|
154
|
+
|
155
|
+
def message
|
156
|
+
@value['_output']
|
157
|
+
end
|
158
|
+
|
159
|
+
def message?
|
160
|
+
message && !message.strip.empty?
|
161
|
+
end
|
162
|
+
|
163
|
+
def generic_value
|
164
|
+
safe_value.reject { |k, _| %w[_error _output].include? k }
|
165
|
+
end
|
166
|
+
|
167
|
+
def eql?(other)
|
168
|
+
self.class == other.class &&
|
169
|
+
target == other.target &&
|
170
|
+
value == other.value
|
171
|
+
end
|
172
|
+
alias == eql?
|
173
|
+
|
174
|
+
def [](key)
|
175
|
+
value[key]
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_json(opts = nil)
|
179
|
+
to_data.to_json(opts)
|
180
|
+
end
|
181
|
+
|
182
|
+
def to_s
|
183
|
+
to_json
|
184
|
+
end
|
185
|
+
|
186
|
+
# This is the value with all non-UTF-8 characters removed, suitable for
|
187
|
+
# printing or converting to JSON. It *should* only be possible to have
|
188
|
+
# non-UTF-8 characters in stdout/stderr keys as they are not allowed from
|
189
|
+
# tasks but we scrub the whole thing just in case.
|
190
|
+
def safe_value
|
191
|
+
Bolt::Util.walk_vals(value) do |val|
|
192
|
+
if val.is_a?(String)
|
193
|
+
# Replace invalid bytes with hex codes, ie. \xDE\xAD\xBE\xEF
|
194
|
+
val.scrub { |c| c.bytes.map { |b| "\\x" + b.to_s(16).upcase }.join }
|
195
|
+
else
|
196
|
+
val
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def to_data
|
202
|
+
serialized_value = safe_value
|
203
|
+
|
204
|
+
if serialized_value.key?('_sensitive') &&
|
205
|
+
serialized_value['_sensitive'].is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
206
|
+
serialized_value['_sensitive'] = serialized_value['_sensitive'].to_s
|
207
|
+
end
|
208
|
+
|
209
|
+
{
|
210
|
+
"target" => @target.name,
|
211
|
+
"action" => action,
|
212
|
+
"object" => object,
|
213
|
+
"status" => status,
|
214
|
+
"value" => serialized_value
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
def status
|
219
|
+
ok? ? 'success' : 'failure'
|
220
|
+
end
|
221
|
+
|
222
|
+
def ok?
|
223
|
+
error_hash.nil?
|
224
|
+
end
|
225
|
+
alias ok ok?
|
226
|
+
alias success? ok?
|
227
|
+
|
228
|
+
# This allows access to errors outside puppet compilation
|
229
|
+
# it should be prefered over error in bolt code
|
230
|
+
def error_hash
|
231
|
+
value['_error']
|
232
|
+
end
|
233
|
+
|
234
|
+
# Warning: This will fail outside of a compilation.
|
235
|
+
# Use error_hash inside bolt.
|
236
|
+
# Is it crazy for this to behave differently outside a compiler?
|
237
|
+
def error
|
238
|
+
if error_hash
|
239
|
+
Puppet::DataTypes::Error.from_asserted_hash(error_hash)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def sensitive
|
244
|
+
value['_sensitive']
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bolt
|
4
|
+
class ResultSet
|
5
|
+
attr_accessor :elapsed_time
|
6
|
+
attr_reader :results
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# We only want want to include these when puppet is loaded
|
11
|
+
def self.include_iterable
|
12
|
+
include(Puppet::Pops::Types::Iterable)
|
13
|
+
include(Puppet::Pops::Types::IteratorProducer)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self._pcore_init_from_hash
|
17
|
+
raise "ResultSet shouldn't be instantiated from a pcore_init class method. How did this get called?"
|
18
|
+
end
|
19
|
+
|
20
|
+
def _pcore_init_from_hash(init_hash)
|
21
|
+
initialize(init_hash['results'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def _pcore_init_hash
|
25
|
+
{ 'results' => @results }
|
26
|
+
end
|
27
|
+
|
28
|
+
def iterator
|
29
|
+
if Object.const_defined?(:Puppet) && Puppet.const_defined?(:Pops) &&
|
30
|
+
self.class.included_modules.include?(Puppet::Pops::Types::Iterable)
|
31
|
+
Puppet::Pops::Types::Iterable.on(@results, Bolt::Result)
|
32
|
+
else
|
33
|
+
raise NotImplementedError, "iterator requires puppet code to be loaded."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(results)
|
38
|
+
@results = results
|
39
|
+
end
|
40
|
+
|
41
|
+
def each
|
42
|
+
@results.each { |r| yield r }
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def filter_set
|
47
|
+
filtered = @results.select { |r| yield r }
|
48
|
+
self.class.new(filtered)
|
49
|
+
end
|
50
|
+
|
51
|
+
def result_hash
|
52
|
+
@result_hash ||= @results.each_with_object({}) do |result, acc|
|
53
|
+
acc[result.target.name] = result
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def count
|
58
|
+
@results.size
|
59
|
+
end
|
60
|
+
alias length count
|
61
|
+
alias size count
|
62
|
+
|
63
|
+
def empty
|
64
|
+
@results.empty?
|
65
|
+
end
|
66
|
+
alias empty? empty
|
67
|
+
|
68
|
+
def targets
|
69
|
+
results.map(&:target)
|
70
|
+
end
|
71
|
+
|
72
|
+
def names
|
73
|
+
@results.map { |r| r.target.name }
|
74
|
+
end
|
75
|
+
|
76
|
+
def ok
|
77
|
+
@results.all?(&:ok?)
|
78
|
+
end
|
79
|
+
alias ok? ok
|
80
|
+
|
81
|
+
def error_set
|
82
|
+
filtered = @results.reject(&:ok?)
|
83
|
+
ResultSet.new(filtered)
|
84
|
+
end
|
85
|
+
|
86
|
+
def ok_set
|
87
|
+
filtered = @results.select(&:success?)
|
88
|
+
self.class.new(filtered)
|
89
|
+
end
|
90
|
+
|
91
|
+
def find(target_name)
|
92
|
+
result_hash[target_name]
|
93
|
+
end
|
94
|
+
|
95
|
+
def first
|
96
|
+
@results.first
|
97
|
+
end
|
98
|
+
|
99
|
+
def eql?(other)
|
100
|
+
self.class == other.class && @results == other.results
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_json(opts = nil)
|
104
|
+
to_data.to_json(opts)
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_data
|
108
|
+
@results.map(&:to_data)
|
109
|
+
end
|
110
|
+
alias to_a to_data
|
111
|
+
|
112
|
+
def to_s
|
113
|
+
to_json
|
114
|
+
end
|
115
|
+
|
116
|
+
def ==(other)
|
117
|
+
eql?(other)
|
118
|
+
end
|
119
|
+
|
120
|
+
def [](from, up_to = nil)
|
121
|
+
if up_to
|
122
|
+
@results[from..up_to]
|
123
|
+
else
|
124
|
+
@results[from]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bolt
|
4
|
+
class Shell
|
5
|
+
class Bash < Shell
|
6
|
+
class Tmpdir
|
7
|
+
def initialize(shell, path)
|
8
|
+
@shell = shell
|
9
|
+
@owner = shell.conn.user
|
10
|
+
@path = path
|
11
|
+
@logger = shell.logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
@path
|
16
|
+
end
|
17
|
+
|
18
|
+
def mkdirs(subdirs)
|
19
|
+
abs_subdirs = subdirs.map { |subdir| File.join(@path, subdir) }
|
20
|
+
result = @shell.execute(['mkdir', '-p'] + abs_subdirs)
|
21
|
+
if result.exit_code != 0
|
22
|
+
message = "Could not create subdirectories in '#{@path}': #{result.stderr.string}"
|
23
|
+
raise Bolt::Node::FileError.new(message, 'MKDIR_ERROR')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def chown(owner, force: false)
|
28
|
+
return if owner.nil? || (owner == @owner && !force)
|
29
|
+
|
30
|
+
result = @shell.execute(['id', '-g', owner])
|
31
|
+
if result.exit_code != 0
|
32
|
+
message = "Could not identify group of user #{owner}: #{result.stderr.string}"
|
33
|
+
raise Bolt::Node::FileError.new(message, 'ID_ERROR')
|
34
|
+
end
|
35
|
+
group = result.stdout.string.chomp
|
36
|
+
|
37
|
+
# Chown can only be run by root.
|
38
|
+
result = @shell.execute(['chown', '-R', "#{owner}:#{group}", @path], sudoable: true, run_as: 'root')
|
39
|
+
if result.exit_code != 0
|
40
|
+
message = "Could not change owner of '#{@path}' to #{owner}: #{result.stderr.string}"
|
41
|
+
raise Bolt::Node::FileError.new(message, 'CHOWN_ERROR')
|
42
|
+
end
|
43
|
+
|
44
|
+
# File ownership successfully changed, record the new owner.
|
45
|
+
@owner = owner
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete
|
49
|
+
result = @shell.execute(['rm', '-rf', @path], sudoable: true, run_as: @owner)
|
50
|
+
if result.exit_code != 0
|
51
|
+
Bolt::Logger.warn(
|
52
|
+
"fail_cleanup",
|
53
|
+
"Failed to clean up tmpdir '#{@path}': #{result.stderr.string}"
|
54
|
+
)
|
55
|
+
end
|
56
|
+
# For testing
|
57
|
+
result.stderr.string
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|