openbolt 5.0.0.pre.rc2 → 5.1.0
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 +4 -4
- data/Puppetfile +18 -12
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -3
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +2 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +1 -0
- data/lib/bolt/analytics.rb +1 -1
- data/lib/bolt/application.rb +17 -22
- data/lib/bolt/applicator.rb +4 -0
- data/lib/bolt/bolt_option_parser.rb +10 -8
- data/lib/bolt/cli.rb +7 -6
- data/lib/bolt/config/options.rb +59 -67
- data/lib/bolt/config/transport/base.rb +1 -0
- data/lib/bolt/config/transport/options.rb +59 -59
- data/lib/bolt/config.rb +8 -6
- data/lib/bolt/executor.rb +9 -24
- data/lib/bolt/fiber_executor.rb +3 -1
- data/lib/bolt/inventory/group.rb +3 -0
- data/lib/bolt/inventory/inventory.rb +2 -0
- data/lib/bolt/inventory/options.rb +7 -7
- data/lib/bolt/inventory/target.rb +3 -2
- data/lib/bolt/inventory.rb +1 -0
- data/lib/bolt/logger.rb +2 -0
- data/lib/bolt/module.rb +1 -0
- data/lib/bolt/module_installer/puppetfile.rb +4 -4
- data/lib/bolt/module_installer/resolver.rb +2 -2
- data/lib/bolt/module_installer/specs/forge_spec.rb +4 -4
- data/lib/bolt/module_installer/specs/git_spec.rb +6 -6
- data/lib/bolt/module_installer/specs/id/gitclone.rb +1 -0
- data/lib/bolt/module_installer/specs/id/github.rb +2 -1
- data/lib/bolt/module_installer/specs/id/gitlab.rb +2 -1
- data/lib/bolt/module_installer.rb +3 -1
- data/lib/bolt/outputter/human.rb +9 -4
- data/lib/bolt/outputter/rainbow.rb +1 -0
- data/lib/bolt/pal/yaml_plan/parameter.rb +2 -2
- data/lib/bolt/pal/yaml_plan/step/resources.rb +1 -1
- data/lib/bolt/pal.rb +4 -1
- data/lib/bolt/plan_creator.rb +5 -4
- data/lib/bolt/plugin/cache.rb +2 -0
- data/lib/bolt/plugin/module.rb +7 -0
- data/lib/bolt/plugin/puppet_connect_data.rb +1 -0
- data/lib/bolt/plugin/task.rb +3 -0
- data/lib/bolt/plugin.rb +4 -0
- data/lib/bolt/project.rb +3 -3
- data/lib/bolt/project_manager/config_migrator.rb +3 -3
- data/lib/bolt/project_manager/inventory_migrator.rb +1 -1
- data/lib/bolt/project_manager/module_migrator.rb +7 -6
- data/lib/bolt/project_manager.rb +11 -11
- data/lib/bolt/puppetdb/config.rb +4 -0
- data/lib/bolt/puppetdb/instance.rb +1 -0
- data/lib/bolt/rerun.rb +1 -0
- data/lib/bolt/resource_instance.rb +1 -1
- data/lib/bolt/result.rb +2 -1
- data/lib/bolt/shell/bash.rb +2 -1
- data/lib/bolt/shell/powershell.rb +4 -3
- data/lib/bolt/shell.rb +1 -1
- data/lib/bolt/task/run.rb +1 -0
- data/lib/bolt/task.rb +3 -0
- data/lib/bolt/transport/docker/connection.rb +2 -0
- data/lib/bolt/transport/jail/connection.rb +2 -0
- data/lib/bolt/transport/lxd/connection.rb +2 -0
- data/lib/bolt/transport/lxd.rb +1 -1
- data/lib/bolt/transport/podman/connection.rb +2 -0
- data/lib/bolt/transport/remote.rb +1 -0
- data/lib/bolt/transport/ssh/connection.rb +1 -1
- data/lib/bolt/transport/winrm/connection.rb +4 -3
- data/lib/bolt/util/format.rb +1 -0
- data/lib/bolt/util.rb +7 -4
- data/lib/bolt/validator.rb +1 -1
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs.rb +5 -0
- data/lib/bolt_spec/plans/mock_executor.rb +2 -4
- data/libexec/apply_catalog.rb +2 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +34 -51
- data/lib/bolt/config/transport/orch.rb +0 -41
- data/lib/bolt/transport/orch/connection.rb +0 -111
- data/lib/bolt/transport/orch.rb +0 -271
data/lib/bolt/transport/orch.rb
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'base64'
|
|
4
|
-
require 'find'
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'pathname'
|
|
7
|
-
require_relative '../../bolt/transport/base'
|
|
8
|
-
require_relative 'orch/connection'
|
|
9
|
-
|
|
10
|
-
module Bolt
|
|
11
|
-
module Transport
|
|
12
|
-
class Orch < Base
|
|
13
|
-
BOLT_COMMAND_TASK = Struct.new(:name).new('bolt_shim::command').freeze
|
|
14
|
-
BOLT_SCRIPT_TASK = Struct.new(:name).new('bolt_shim::script').freeze
|
|
15
|
-
BOLT_UPLOAD_TASK = Struct.new(:name).new('bolt_shim::upload').freeze
|
|
16
|
-
|
|
17
|
-
attr_writer :plan_context
|
|
18
|
-
|
|
19
|
-
def provided_features
|
|
20
|
-
['puppet-agent']
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def initialize(*args)
|
|
24
|
-
# lazy-load expensive gem code
|
|
25
|
-
require 'orchestrator_client'
|
|
26
|
-
|
|
27
|
-
@connections = {}
|
|
28
|
-
super
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def finish_plan(result)
|
|
32
|
-
if result.is_a? Bolt::PlanResult
|
|
33
|
-
@connections.each_value do |conn|
|
|
34
|
-
conn.finish_plan(result)
|
|
35
|
-
rescue StandardError => e
|
|
36
|
-
@logger.trace("Failed to finish plan on #{conn.key}: #{e.message}")
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# It's safe to create connections here for now because the
|
|
42
|
-
# batches/threads are per connection.
|
|
43
|
-
def get_connection(conn_opts)
|
|
44
|
-
key = Connection.get_key(conn_opts)
|
|
45
|
-
unless (conn = @connections[key])
|
|
46
|
-
conn = @connections[key] = Connection.new(conn_opts, @plan_context, logger)
|
|
47
|
-
end
|
|
48
|
-
conn
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def process_run_results(targets, results, task_name, position = [])
|
|
52
|
-
targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
|
|
53
|
-
results.map do |node_result|
|
|
54
|
-
target = targets_by_name[node_result['name']]
|
|
55
|
-
state = node_result['state']
|
|
56
|
-
result = node_result['result']
|
|
57
|
-
|
|
58
|
-
# If it's finished or already has a proper error simply pass it to the
|
|
59
|
-
# the result otherwise make sure an error is generated
|
|
60
|
-
if state == 'finished' || (result && result['_error'])
|
|
61
|
-
if result['_error']
|
|
62
|
-
unless result['_error'].is_a?(Hash)
|
|
63
|
-
result['_error'] = { 'kind' => 'puppetlabs.tasks/task-error',
|
|
64
|
-
'issue_code' => 'TASK_ERROR',
|
|
65
|
-
'msg' => result['_error'],
|
|
66
|
-
'details' => {} }
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
result['_error']['details'] ||= {}
|
|
70
|
-
unless result['_error']['details'].is_a?(Hash)
|
|
71
|
-
deets = result['_error']['details']
|
|
72
|
-
result['_error']['details'] = { 'msg' => deets }
|
|
73
|
-
end
|
|
74
|
-
file_line = %w[file line].zip(position).to_h.compact
|
|
75
|
-
result['_error']['details'].merge!(file_line) unless result['_error']['details']['file']
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
Bolt::Result.new(target, value: result, action: 'task', object: task_name)
|
|
79
|
-
elsif state == 'skipped'
|
|
80
|
-
details = %w[file line].zip(position).to_h.compact
|
|
81
|
-
Bolt::Result.new(
|
|
82
|
-
target,
|
|
83
|
-
value: { '_error' => {
|
|
84
|
-
'kind' => 'puppetlabs.tasks/skipped-node',
|
|
85
|
-
'msg' => "Target #{target.safe_name} was skipped",
|
|
86
|
-
'details' => details
|
|
87
|
-
} },
|
|
88
|
-
action: 'task', object: task_name
|
|
89
|
-
)
|
|
90
|
-
else
|
|
91
|
-
# Make a generic error with a unkown exit_code
|
|
92
|
-
Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name, position)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def batch_command(targets, command, options = {}, position = [], &callback)
|
|
98
|
-
if options[:env_vars] && !options[:env_vars].empty?
|
|
99
|
-
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
params = {
|
|
103
|
-
'command' => command
|
|
104
|
-
}
|
|
105
|
-
results = run_task_job(targets,
|
|
106
|
-
BOLT_COMMAND_TASK,
|
|
107
|
-
params,
|
|
108
|
-
options,
|
|
109
|
-
position,
|
|
110
|
-
&callback)
|
|
111
|
-
callback ||= proc {}
|
|
112
|
-
results.map! { |result| unwrap_bolt_result(result.target, result, 'command', command) }
|
|
113
|
-
results.each do |result|
|
|
114
|
-
callback.call(type: :node_result, result: result)
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def batch_script(targets, script, arguments, options = {}, position = [], &callback)
|
|
119
|
-
if options[:env_vars] && !options[:env_vars].empty?
|
|
120
|
-
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
content = File.open(script, &:read)
|
|
124
|
-
content = Base64.encode64(content)
|
|
125
|
-
params = {
|
|
126
|
-
'content' => content,
|
|
127
|
-
'arguments' => arguments,
|
|
128
|
-
'name' => Pathname(script).basename.to_s
|
|
129
|
-
}
|
|
130
|
-
callback ||= proc {}
|
|
131
|
-
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, position, &callback)
|
|
132
|
-
results.map! { |result| unwrap_bolt_result(result.target, result, 'script', script) }
|
|
133
|
-
results.each do |result|
|
|
134
|
-
callback.call(type: :node_result, result: result)
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def pack(directory)
|
|
139
|
-
# lazy-load expensive gem code
|
|
140
|
-
require 'minitar'
|
|
141
|
-
require 'zlib'
|
|
142
|
-
|
|
143
|
-
start_time = Time.now
|
|
144
|
-
io = StringIO.new
|
|
145
|
-
output = Minitar::Output.new(Zlib::GzipWriter.new(io))
|
|
146
|
-
Find.find(directory) do |file|
|
|
147
|
-
next unless File.file?(file)
|
|
148
|
-
|
|
149
|
-
tar_path = Pathname.new(file).relative_path_from(Pathname.new(directory))
|
|
150
|
-
@logger.trace("Packing #{file} to #{tar_path}")
|
|
151
|
-
stat = File.stat(file)
|
|
152
|
-
content = File.binread(file)
|
|
153
|
-
output.tar.add_file_simple(
|
|
154
|
-
tar_path.to_s,
|
|
155
|
-
data: content,
|
|
156
|
-
size: content.size,
|
|
157
|
-
mode: stat.mode & 0o777,
|
|
158
|
-
mtime: stat.mtime
|
|
159
|
-
)
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
duration = Time.now - start_time
|
|
163
|
-
@logger.trace("Packed upload in #{duration * 1000} ms")
|
|
164
|
-
|
|
165
|
-
output.close
|
|
166
|
-
io.string
|
|
167
|
-
ensure
|
|
168
|
-
# Closes both tar and sgz.
|
|
169
|
-
output&.close
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def batch_upload(targets, source, destination, options = {}, position = [], &callback)
|
|
173
|
-
stat = File.stat(source)
|
|
174
|
-
content = if stat.directory?
|
|
175
|
-
pack(source)
|
|
176
|
-
else
|
|
177
|
-
File.open(source, &:read)
|
|
178
|
-
end
|
|
179
|
-
content = Base64.encode64(content)
|
|
180
|
-
mode = File.stat(source).mode
|
|
181
|
-
params = {
|
|
182
|
-
'path' => destination,
|
|
183
|
-
'content' => content,
|
|
184
|
-
'mode' => mode,
|
|
185
|
-
'directory' => stat.directory?
|
|
186
|
-
}
|
|
187
|
-
callback ||= proc {}
|
|
188
|
-
results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, position, &callback)
|
|
189
|
-
results.map! do |result|
|
|
190
|
-
if result.error_hash
|
|
191
|
-
result
|
|
192
|
-
else
|
|
193
|
-
Bolt::Result.for_upload(result.target, source, destination)
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
results.each do |result|
|
|
197
|
-
callback&.call(type: :node_result, result: result)
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def batch_download(targets, *_args)
|
|
202
|
-
error = {
|
|
203
|
-
'kind' => 'bolt/not-supported-error',
|
|
204
|
-
'msg' => 'pcp transport does not support downloading files',
|
|
205
|
-
'details' => {}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
targets.map do |target|
|
|
209
|
-
Bolt::Result.new(target, error: error, action: 'download')
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def batches(targets)
|
|
214
|
-
targets.group_by { |target| Connection.get_key(target.options) }.values
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def run_task_job(targets, task, arguments, options, position)
|
|
218
|
-
targets.each do |target|
|
|
219
|
-
yield(type: :node_start, target: target) if block_given?
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
begin
|
|
223
|
-
# unpack any Sensitive data
|
|
224
|
-
arguments = unwrap_sensitive_args(arguments)
|
|
225
|
-
results = get_connection(targets.first.options).run_task(targets, task, arguments, options)
|
|
226
|
-
|
|
227
|
-
process_run_results(targets, results, task.name, position)
|
|
228
|
-
rescue OrchestratorClient::ApiError => e
|
|
229
|
-
targets.map do |target|
|
|
230
|
-
Bolt::Result.new(target, error: e.data)
|
|
231
|
-
end
|
|
232
|
-
rescue StandardError => e
|
|
233
|
-
targets.map do |target|
|
|
234
|
-
Bolt::Result.from_exception(target, e, action: 'task')
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
def batch_task(targets, task, arguments, options = {}, position = [], &callback)
|
|
240
|
-
callback ||= proc {}
|
|
241
|
-
results = run_task_job(targets, task, arguments, options, position, &callback)
|
|
242
|
-
results.each do |result|
|
|
243
|
-
callback.call(type: :node_result, result: result)
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def batch_task_with(_targets, _task, _target_mapping, _options = {}, _position = [])
|
|
248
|
-
raise NotImplementedError, "pcp transport does not support run_task_with()"
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
def batch_connected?(targets)
|
|
252
|
-
resp = get_connection(targets.first.options).query_inventory(targets)
|
|
253
|
-
resp['items'].all? { |node| node['connected'] }
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
# run_task generates a result that makes sense for a generic task which
|
|
257
|
-
# needs to be unwrapped to extract stdout/stderr/exitcode.
|
|
258
|
-
#
|
|
259
|
-
def unwrap_bolt_result(target, result, action, obj)
|
|
260
|
-
if result.error_hash
|
|
261
|
-
# something went wrong return the failure
|
|
262
|
-
return result
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
# If we get here, there's no error so we don't need the file or line
|
|
266
|
-
# number
|
|
267
|
-
Bolt::Result.for_command(target, result.value, action, obj, [])
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
end
|