bolt 2.42.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +21 -19
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -5
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +7 -3
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +3 -2
- data/lib/bolt/analytics.rb +3 -2
- data/lib/bolt/applicator.rb +11 -1
- data/lib/bolt/apply_result.rb +1 -1
- data/lib/bolt/bolt_option_parser.rb +9 -116
- data/lib/bolt/catalog.rb +10 -29
- data/lib/bolt/cli.rb +90 -154
- data/lib/bolt/config.rb +66 -239
- data/lib/bolt/config/options.rb +79 -102
- data/lib/bolt/config/transport/local.rb +1 -0
- data/lib/bolt/config/transport/lxd.rb +21 -0
- data/lib/bolt/config/transport/options.rb +9 -2
- data/lib/bolt/config/transport/orch.rb +1 -0
- data/lib/bolt/executor.rb +23 -6
- data/lib/bolt/inventory.rb +1 -1
- data/lib/bolt/inventory/group.rb +7 -4
- data/lib/bolt/logger.rb +123 -11
- data/lib/bolt/module_installer.rb +6 -4
- data/lib/bolt/module_installer/puppetfile.rb +2 -2
- data/lib/bolt/module_installer/resolver.rb +59 -14
- data/lib/bolt/module_installer/specs/forge_spec.rb +10 -4
- data/lib/bolt/module_installer/specs/git_spec.rb +19 -4
- data/lib/bolt/outputter/human.rb +56 -17
- data/lib/bolt/outputter/json.rb +16 -16
- data/lib/bolt/outputter/rainbow.rb +3 -3
- data/lib/bolt/pal.rb +95 -15
- data/lib/bolt/pal/yaml_plan.rb +9 -4
- data/lib/bolt/pal/yaml_plan/evaluator.rb +5 -153
- data/lib/bolt/pal/yaml_plan/step.rb +91 -52
- data/lib/bolt/pal/yaml_plan/step/command.rb +16 -16
- data/lib/bolt/pal/yaml_plan/step/download.rb +15 -16
- data/lib/bolt/pal/yaml_plan/step/eval.rb +11 -11
- data/lib/bolt/pal/yaml_plan/step/message.rb +13 -4
- data/lib/bolt/pal/yaml_plan/step/plan.rb +19 -15
- data/lib/bolt/pal/yaml_plan/step/resources.rb +82 -21
- data/lib/bolt/pal/yaml_plan/step/script.rb +32 -17
- data/lib/bolt/pal/yaml_plan/step/task.rb +19 -16
- data/lib/bolt/pal/yaml_plan/step/upload.rb +16 -17
- data/lib/bolt/pal/yaml_plan/transpiler.rb +2 -1
- data/lib/bolt/plan_creator.rb +1 -1
- data/lib/bolt/plugin.rb +2 -2
- data/lib/bolt/plugin/cache.rb +7 -7
- data/lib/bolt/plugin/module.rb +0 -23
- data/lib/bolt/plugin/puppet_connect_data.rb +77 -0
- data/lib/bolt/plugin/puppetdb.rb +1 -1
- data/lib/bolt/project.rb +54 -81
- data/lib/bolt/project_manager.rb +5 -4
- data/lib/bolt/project_manager/module_migrator.rb +7 -6
- data/lib/bolt/rerun.rb +1 -1
- data/lib/bolt/result.rb +6 -1
- data/lib/bolt/shell.rb +16 -0
- data/lib/bolt/shell/bash.rb +57 -25
- data/lib/bolt/shell/bash/tmpdir.rb +6 -3
- data/lib/bolt/shell/powershell.rb +33 -10
- data/lib/bolt/shell/powershell/snippets.rb +37 -150
- data/lib/bolt/task.rb +2 -2
- data/lib/bolt/transport/base.rb +0 -9
- data/lib/bolt/transport/docker.rb +1 -125
- data/lib/bolt/transport/docker/connection.rb +86 -161
- data/lib/bolt/transport/local.rb +1 -9
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/lxd/connection.rb +99 -0
- data/lib/bolt/transport/orch/connection.rb +1 -1
- data/lib/bolt/transport/ssh.rb +1 -2
- data/lib/bolt/transport/ssh/connection.rb +2 -2
- data/lib/bolt/transport/winrm/connection.rb +1 -1
- data/lib/bolt/validator.rb +2 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/config.rb +1 -1
- data/lib/bolt_server/transport_app.rb +61 -32
- data/lib/bolt_spec/bolt_context.rb +9 -4
- data/lib/bolt_spec/plans.rb +1 -109
- data/lib/bolt_spec/plans/action_stubs.rb +1 -1
- data/lib/bolt_spec/plans/mock_executor.rb +4 -0
- data/libexec/bolt_catalog +1 -1
- data/modules/aggregate/plans/count.pp +21 -0
- data/modules/aggregate/plans/targets.pp +21 -0
- data/modules/puppet_connect/plans/test_input_data.pp +67 -0
- data/modules/puppetdb_fact/plans/init.pp +10 -0
- metadata +13 -9
- data/modules/aggregate/plans/nodes.pp +0 -36
data/lib/bolt/catalog.rb
CHANGED
@@ -76,31 +76,27 @@ module Bolt
|
|
76
76
|
# is the only way to log a message that will make it back to Bolt
|
77
77
|
# to be printed.
|
78
78
|
target = request['target']
|
79
|
-
plan_vars = shadow_vars('plan', request['plan_vars'], target['facts'])
|
80
|
-
target_vars = shadow_vars('target', target['variables'], target['facts'])
|
81
79
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
# these variables are moved before the variable they reference, Puppet will
|
87
|
-
# be unable to deserialize the data and raise an error.
|
88
|
-
topscope_vars = target_vars.reject { |k, _v| plan_vars.key?(k) }.merge(plan_vars)
|
80
|
+
variables = {
|
81
|
+
variables: request['plan_vars'],
|
82
|
+
target_variables: target['variables']
|
83
|
+
}
|
89
84
|
|
90
|
-
env_conf = {
|
91
|
-
|
92
|
-
|
85
|
+
env_conf = {
|
86
|
+
modulepath: request['modulepath'],
|
87
|
+
facts: target['facts']
|
88
|
+
}
|
93
89
|
|
94
90
|
puppet_settings = {
|
95
91
|
node_name_value: target['name'],
|
96
|
-
hiera_config:
|
92
|
+
hiera_config: request['hiera_config']
|
97
93
|
}
|
98
94
|
|
99
95
|
with_puppet_settings(puppet_settings) do
|
100
96
|
Puppet::Pal.in_tmp_environment('bolt_catalog', **env_conf) do |pal|
|
101
97
|
Puppet.override(puppet_overrides) do
|
102
98
|
Puppet.lookup(:pal_current_node).trusted_data = target['trusted']
|
103
|
-
pal.with_catalog_compiler do |compiler|
|
99
|
+
pal.with_catalog_compiler(**variables) do |compiler|
|
104
100
|
options = request['puppet_config'] || {}
|
105
101
|
# Configure language strictness in the CatalogCompiler. We want Bolt to be able
|
106
102
|
# to compile most Puppet 4+ manifests, so we default to allowing deprecated functions.
|
@@ -119,21 +115,6 @@ module Bolt
|
|
119
115
|
end
|
120
116
|
end
|
121
117
|
|
122
|
-
# Warn and remove variables that will be shadowed by facts of the same
|
123
|
-
# name, which are set in scope earlier.
|
124
|
-
def shadow_vars(type, vars, facts)
|
125
|
-
collisions, valid = vars.partition do |k, _|
|
126
|
-
facts.include?(k)
|
127
|
-
end
|
128
|
-
if collisions.any?
|
129
|
-
names = collisions.map { |k, _| "$#{k}" }.join(', ')
|
130
|
-
plural = collisions.length == 1 ? '' : 's'
|
131
|
-
Puppet.warning("#{type.capitalize} variable#{plural} #{names} will be overridden by fact#{plural} " \
|
132
|
-
"of the same name in the apply block")
|
133
|
-
end
|
134
|
-
valid.to_h
|
135
|
-
end
|
136
|
-
|
137
118
|
def build_program(code)
|
138
119
|
ast = Puppet::Pops::Serialization::FromDataConverter.convert(code)
|
139
120
|
|
data/lib/bolt/cli.rb
CHANGED
@@ -33,19 +33,18 @@ module Bolt
|
|
33
33
|
|
34
34
|
class CLI
|
35
35
|
COMMANDS = {
|
36
|
-
'command'
|
37
|
-
'script'
|
38
|
-
'task'
|
39
|
-
'plan'
|
40
|
-
'file'
|
41
|
-
'
|
42
|
-
'
|
43
|
-
'
|
44
|
-
'
|
45
|
-
'
|
46
|
-
'
|
47
|
-
'
|
48
|
-
'guide' => %w[]
|
36
|
+
'command' => %w[run],
|
37
|
+
'script' => %w[run],
|
38
|
+
'task' => %w[show run],
|
39
|
+
'plan' => %w[show run convert new],
|
40
|
+
'file' => %w[download upload],
|
41
|
+
'secret' => %w[encrypt decrypt createkeys],
|
42
|
+
'inventory' => %w[show],
|
43
|
+
'group' => %w[show],
|
44
|
+
'project' => %w[init migrate],
|
45
|
+
'module' => %w[add generate-types install show],
|
46
|
+
'apply' => %w[],
|
47
|
+
'guide' => %w[]
|
49
48
|
}.freeze
|
50
49
|
|
51
50
|
attr_reader :config, :options
|
@@ -147,10 +146,6 @@ module Bolt
|
|
147
146
|
end
|
148
147
|
|
149
148
|
validate(options)
|
150
|
-
|
151
|
-
# Deprecation warnings can't be issued until after config is loaded, so
|
152
|
-
# store them for later.
|
153
|
-
@parser_deprecations = parser.deprecations
|
154
149
|
rescue Bolt::Error => e
|
155
150
|
fatal_error(e)
|
156
151
|
raise e
|
@@ -159,25 +154,19 @@ module Bolt
|
|
159
154
|
# Loads the project and configuration. All errors that are raised here are not
|
160
155
|
# handled by the outputter, as it relies on config being loaded.
|
161
156
|
def load_config
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
Bolt::
|
157
|
+
project = if ENV['BOLT_PROJECT']
|
158
|
+
Bolt::Project.create_project(ENV['BOLT_PROJECT'], 'environment')
|
159
|
+
elsif options[:project]
|
160
|
+
dir = Pathname.new(options[:project])
|
161
|
+
if (dir + Bolt::Project::BOLTDIR_NAME).directory?
|
162
|
+
Bolt::Project.create_project(dir + Bolt::Project::BOLTDIR_NAME)
|
163
|
+
else
|
164
|
+
Bolt::Project.create_project(dir)
|
165
|
+
end
|
167
166
|
else
|
168
|
-
|
169
|
-
project = if cli_flag
|
170
|
-
dir = Pathname.new(cli_flag)
|
171
|
-
if (dir + Bolt::Project::BOLTDIR_NAME).directory?
|
172
|
-
Bolt::Project.create_project(dir + Bolt::Project::BOLTDIR_NAME)
|
173
|
-
else
|
174
|
-
Bolt::Project.create_project(dir)
|
175
|
-
end
|
176
|
-
else
|
177
|
-
Bolt::Project.find_boltdir(Dir.pwd)
|
178
|
-
end
|
179
|
-
Bolt::Config.from_project(project, options)
|
167
|
+
Bolt::Project.find_boltdir(Dir.pwd)
|
180
168
|
end
|
169
|
+
@config = Bolt::Config.from_project(project, options)
|
181
170
|
rescue Bolt::Error => e
|
182
171
|
fatal_error(e)
|
183
172
|
raise e
|
@@ -185,20 +174,17 @@ module Bolt
|
|
185
174
|
|
186
175
|
# Completes the setup process by configuring Bolt and log messages
|
187
176
|
def finalize_setup
|
188
|
-
Bolt::Logger.configure(config.log, config.color)
|
177
|
+
Bolt::Logger.configure(config.log, config.color, config.disable_warnings)
|
178
|
+
Bolt::Logger.stream = config.stream
|
189
179
|
Bolt::Logger.analytics = analytics
|
180
|
+
Bolt::Logger.flush_queue
|
190
181
|
|
191
182
|
# Logger must be configured before checking path case and project file, otherwise logs will not display
|
192
183
|
config.check_path_case('modulepath', config.modulepath)
|
193
184
|
config.project.check_deprecated_file
|
194
185
|
|
195
|
-
|
196
|
-
|
197
|
-
@parser_deprecations.each { |dep| Bolt::Logger.deprecation_warning(dep[:type], dep[:msg]) }
|
198
|
-
config.deprecations.each { |dep| Bolt::Logger.deprecation_warning(dep[:type], dep[:msg]) }
|
199
|
-
|
200
|
-
if options[:clear_cache] && File.exist?(config.project.cache_file)
|
201
|
-
FileUtils.rm(config.project.cache_file)
|
186
|
+
if options[:clear_cache] && File.exist?(config.project.plugin_cache_file)
|
187
|
+
FileUtils.rm(config.project.plugin_cache_file)
|
202
188
|
end
|
203
189
|
|
204
190
|
warn_inventory_overrides_cli(options)
|
@@ -218,9 +204,8 @@ module Bolt
|
|
218
204
|
|
219
205
|
return unless !stdout.empty? && stdout.to_i < 3
|
220
206
|
|
221
|
-
msg = "Detected PowerShell 2 on controller. PowerShell 2 is
|
222
|
-
|
223
|
-
Bolt::Logger.deprecation_warning("PowerShell 2 controller", msg)
|
207
|
+
msg = "Detected PowerShell 2 on controller. PowerShell 2 is unsupported."
|
208
|
+
Bolt::Logger.deprecation_warning("powershell_2_controller", msg)
|
224
209
|
end
|
225
210
|
end
|
226
211
|
|
@@ -228,7 +213,7 @@ module Bolt
|
|
228
213
|
target_opts = options.keys.select { |opt| %i[query rerun targets].include?(opt) }
|
229
214
|
target_string = "'--targets', '--rerun', or '--query'"
|
230
215
|
if target_opts.length > 1
|
231
|
-
raise Bolt::CLIError, "Only one targeting option #{target_string}
|
216
|
+
raise Bolt::CLIError, "Only one targeting option #{target_string} can be specified"
|
232
217
|
elsif target_opts.empty? && options[:subcommand] != 'plan'
|
233
218
|
raise Bolt::CLIError, "Command requires a targeting option: #{target_string}"
|
234
219
|
end
|
@@ -265,11 +250,14 @@ module Bolt
|
|
265
250
|
end
|
266
251
|
end
|
267
252
|
|
268
|
-
if %w[task plan].include?(options[:subcommand]) && options[:action] == 'run'
|
253
|
+
if %w[task plan script].include?(options[:subcommand]) && options[:action] == 'run'
|
269
254
|
if options[:object].nil?
|
270
255
|
raise Bolt::CLIError, "Must specify a #{options[:subcommand]} to run"
|
271
256
|
end
|
272
|
-
|
257
|
+
end
|
258
|
+
|
259
|
+
# This may mean that we parsed a parameter as the object
|
260
|
+
if %w[task plan].include?(options[:subcommand]) && options[:action] == 'run'
|
273
261
|
unless options[:object] =~ /\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\Z/
|
274
262
|
raise Bolt::CLIError,
|
275
263
|
"Invalid #{options[:subcommand]} '#{options[:object]}'"
|
@@ -314,26 +302,18 @@ module Bolt
|
|
314
302
|
"Unknown argument(s) #{options[:leftovers].join(', ')}"
|
315
303
|
end
|
316
304
|
|
317
|
-
if options.slice(:boltdir, :configfile, :project).length > 1
|
318
|
-
raise Bolt::CLIError, "Only one of '--boltdir', '--project', or '--configfile' may be specified"
|
319
|
-
end
|
320
|
-
|
321
305
|
if options[:noop] &&
|
322
306
|
!(options[:subcommand] == 'task' && options[:action] == 'run') && options[:subcommand] != 'apply'
|
323
307
|
raise Bolt::CLIError,
|
324
|
-
"Option '--noop'
|
308
|
+
"Option '--noop' can only be specified when running a task or applying manifest code"
|
325
309
|
end
|
326
310
|
|
327
311
|
if options[:env_vars]
|
328
312
|
unless %w[command script].include?(options[:subcommand]) && options[:action] == 'run'
|
329
313
|
raise Bolt::CLIError,
|
330
|
-
"Option '--env-var'
|
314
|
+
"Option '--env-var' can only be specified when running a command or script"
|
331
315
|
end
|
332
316
|
end
|
333
|
-
|
334
|
-
if options.key?(:debug) && options.key?(:log)
|
335
|
-
raise Bolt::CLIError, "Only one of '--debug' or '--log-level' may be specified"
|
336
|
-
end
|
337
317
|
end
|
338
318
|
|
339
319
|
def handle_parser_errors
|
@@ -376,7 +356,10 @@ module Bolt
|
|
376
356
|
conflicting_options = Set.new(opts.keys.map(&:to_s)).intersection(inventory_cli_opts)
|
377
357
|
|
378
358
|
if inventory_source && conflicting_options.any?
|
379
|
-
|
359
|
+
Bolt::Logger.warn(
|
360
|
+
"cli_overrides",
|
361
|
+
"CLI arguments #{conflicting_options.to_a} might be overridden by Inventory: #{inventory_source}"
|
362
|
+
)
|
380
363
|
end
|
381
364
|
end
|
382
365
|
|
@@ -393,7 +376,7 @@ module Bolt
|
|
393
376
|
# Initialize inventory and targets. Errors here are better to catch early.
|
394
377
|
# options[:target_args] will contain a string/array version of the targetting options this is passed to plans
|
395
378
|
# options[:targets] will contain a resolved set of Target objects
|
396
|
-
unless %w[guide module project
|
379
|
+
unless %w[guide module project secret].include?(options[:subcommand]) ||
|
397
380
|
%w[convert new show].include?(options[:action])
|
398
381
|
update_targets(options)
|
399
382
|
end
|
@@ -448,15 +431,12 @@ module Bolt
|
|
448
431
|
list_modules
|
449
432
|
end
|
450
433
|
return 0
|
451
|
-
when 'show-modules'
|
452
|
-
list_modules
|
453
|
-
return 0
|
454
434
|
when 'convert'
|
455
435
|
pal.convert_plan(options[:object])
|
456
436
|
return 0
|
457
437
|
end
|
458
438
|
|
459
|
-
message = 'There
|
439
|
+
message = 'There might be processes left executing on some nodes.'
|
460
440
|
|
461
441
|
if %w[task plan].include?(options[:subcommand]) && options[:task_options] && !options[:params_parsed] && pal
|
462
442
|
options[:task_options] = pal.parse_params(options[:subcommand], options[:object], options[:task_options])
|
@@ -500,17 +480,6 @@ module Bolt
|
|
500
480
|
when 'generate-types'
|
501
481
|
code = generate_types
|
502
482
|
end
|
503
|
-
when 'puppetfile'
|
504
|
-
case options[:action]
|
505
|
-
when 'generate-types'
|
506
|
-
code = generate_types
|
507
|
-
when 'install'
|
508
|
-
code = install_puppetfile(
|
509
|
-
config.puppetfile_config,
|
510
|
-
config.puppetfile,
|
511
|
-
config.modulepath.first
|
512
|
-
)
|
513
|
-
end
|
514
483
|
when 'secret'
|
515
484
|
code = Bolt::Secret.execute(plugins, outputter, options)
|
516
485
|
when 'apply'
|
@@ -528,7 +497,6 @@ module Bolt
|
|
528
497
|
|
529
498
|
elapsed_time = Benchmark.realtime do
|
530
499
|
executor_opts = {}
|
531
|
-
executor_opts[:description] = options[:description] if options.key?(:description)
|
532
500
|
executor_opts[:env_vars] = options[:env_vars] if options.key?(:env_vars)
|
533
501
|
executor.subscribe(outputter)
|
534
502
|
executor.subscribe(log_outputter)
|
@@ -537,19 +505,14 @@ module Bolt
|
|
537
505
|
when 'command'
|
538
506
|
executor.run_command(targets, options[:object], executor_opts)
|
539
507
|
when 'script'
|
540
|
-
|
541
|
-
|
542
|
-
executor.run_script(targets, script, options[:leftovers], executor_opts)
|
508
|
+
script_path = find_file(options[:object])
|
509
|
+
executor.run_script(targets, script_path, options[:leftovers], executor_opts)
|
543
510
|
when 'task'
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
inventory,
|
550
|
-
options[:description])
|
551
|
-
end
|
552
|
-
r
|
511
|
+
pal.run_task(options[:object],
|
512
|
+
targets,
|
513
|
+
options[:task_options],
|
514
|
+
executor,
|
515
|
+
inventory)
|
553
516
|
when 'file'
|
554
517
|
src = options[:object]
|
555
518
|
dest = options[:leftovers].first
|
@@ -610,7 +573,7 @@ module Bolt
|
|
610
573
|
end
|
611
574
|
|
612
575
|
def list_plans
|
613
|
-
plans = filter_content(pal.
|
576
|
+
plans = filter_content(pal.list_plans_with_cache(filter_content: true), options[:filter])
|
614
577
|
outputter.print_plans(plans, pal.user_modulepath)
|
615
578
|
end
|
616
579
|
|
@@ -650,7 +613,7 @@ module Bolt
|
|
650
613
|
if plan_arguments['nodes'] || plan_arguments['targets']
|
651
614
|
key = plan_arguments.include?('nodes') ? 'nodes' : 'targets'
|
652
615
|
raise Bolt::CLIError,
|
653
|
-
"A plan's '#{key}' parameter
|
616
|
+
"A plan's '#{key}' parameter can be specified using the --#{key} option, but in that " \
|
654
617
|
"case it must not be specified as a separate #{key}=<value> parameter nor included " \
|
655
618
|
"in the JSON data passed in the --params option"
|
656
619
|
end
|
@@ -662,7 +625,7 @@ module Bolt
|
|
662
625
|
if node_param && target_param
|
663
626
|
msg = "Plan parameters include both 'nodes' and 'targets' with type 'TargetSpec', " \
|
664
627
|
"neither will populated with the value for --nodes or --targets."
|
665
|
-
|
628
|
+
Bolt::Logger.warn("nodes_targets_parameters", msg)
|
666
629
|
elsif node_param
|
667
630
|
plan_arguments['nodes'] = nodes.join(',')
|
668
631
|
elsif target_param
|
@@ -672,7 +635,6 @@ module Bolt
|
|
672
635
|
|
673
636
|
plan_context = { plan_name: plan_name,
|
674
637
|
params: plan_arguments }
|
675
|
-
plan_context[:description] = options[:description] if options[:description]
|
676
638
|
|
677
639
|
executor = Bolt::Executor.new(config.concurrency, analytics, options[:noop], config.modified_concurrency)
|
678
640
|
if %w[human rainbow].include?(options.fetch(:format, 'human'))
|
@@ -684,9 +646,7 @@ module Bolt
|
|
684
646
|
|
685
647
|
executor.subscribe(log_outputter)
|
686
648
|
executor.start_plan(plan_context)
|
687
|
-
result =
|
688
|
-
pal.run_plan(plan_name, plan_arguments, executor, inventory, puppetdb_client)
|
689
|
-
end
|
649
|
+
result = pal.run_plan(plan_name, plan_arguments, executor, inventory, puppetdb_client)
|
690
650
|
|
691
651
|
# If a non-bolt exception bubbles up the plan won't get finished
|
692
652
|
executor.finish_plan(result)
|
@@ -709,7 +669,7 @@ module Bolt
|
|
709
669
|
"about defining and declaring classes and types in the Puppet documentation at "\
|
710
670
|
"https://puppet.com/docs/puppet/latest/lang_classes.html and "\
|
711
671
|
"https://puppet.com/docs/puppet/latest/lang_defined_types.html"
|
712
|
-
|
672
|
+
Bolt::Logger.warn("empty_manifest", message)
|
713
673
|
end
|
714
674
|
|
715
675
|
executor = Bolt::Executor.new(config.concurrency, analytics, noop, config.modified_concurrency)
|
@@ -738,14 +698,12 @@ module Bolt
|
|
738
698
|
end
|
739
699
|
|
740
700
|
def list_modules
|
741
|
-
assert_puppetfile_or_module_command(config.project.modules)
|
742
701
|
outputter.print_module_list(pal.list_modules)
|
743
702
|
end
|
744
703
|
|
745
704
|
def generate_types
|
746
|
-
assert_puppetfile_or_module_command(config.project.modules)
|
747
705
|
# generate_types will surface a nice error with helpful message if it fails
|
748
|
-
pal.generate_types
|
706
|
+
pal.generate_types(cache: true)
|
749
707
|
0
|
750
708
|
end
|
751
709
|
|
@@ -753,19 +711,19 @@ module Bolt
|
|
753
711
|
#
|
754
712
|
def install_project_modules(project, config, force, resolve)
|
755
713
|
assert_project_file(project)
|
756
|
-
assert_puppetfile_or_module_command(project.modules)
|
757
714
|
|
758
|
-
|
759
|
-
outputter.print_message
|
760
|
-
|
715
|
+
if project.modules.empty? && resolve != false
|
716
|
+
outputter.print_message(
|
717
|
+
"Project configuration file #{project.project_file} does not "\
|
718
|
+
"specify any module dependencies. Nothing to do."
|
719
|
+
)
|
761
720
|
return 0
|
762
721
|
end
|
763
722
|
|
764
|
-
modules = project.modules || []
|
765
723
|
installer = Bolt::ModuleInstaller.new(outputter, pal)
|
766
724
|
|
767
725
|
ok = outputter.spin do
|
768
|
-
installer.install(modules,
|
726
|
+
installer.install(project.modules,
|
769
727
|
project.puppetfile,
|
770
728
|
project.managed_moduledir,
|
771
729
|
config,
|
@@ -780,14 +738,12 @@ module Bolt
|
|
780
738
|
#
|
781
739
|
def add_project_module(name, project, config)
|
782
740
|
assert_project_file(project)
|
783
|
-
assert_puppetfile_or_module_command(project.modules)
|
784
741
|
|
785
|
-
modules = project.modules || []
|
786
742
|
installer = Bolt::ModuleInstaller.new(outputter, pal)
|
787
743
|
|
788
744
|
ok = outputter.spin do
|
789
745
|
installer.add(name,
|
790
|
-
modules,
|
746
|
+
project.modules,
|
791
747
|
project.puppetfile,
|
792
748
|
project.managed_moduledir,
|
793
749
|
project.project_file,
|
@@ -818,8 +774,6 @@ module Bolt
|
|
818
774
|
# Loads a Puppetfile and installs its modules.
|
819
775
|
#
|
820
776
|
def install_puppetfile(puppetfile_config, puppetfile, moduledir)
|
821
|
-
assert_puppetfile_or_module_command(config.project.modules)
|
822
|
-
|
823
777
|
outputter.print_message("Installing modules from Puppetfile")
|
824
778
|
installer = Bolt::ModuleInstaller.new(outputter, pal)
|
825
779
|
ok = outputter.spin do
|
@@ -829,47 +783,6 @@ module Bolt
|
|
829
783
|
ok ? 0 : 1
|
830
784
|
end
|
831
785
|
|
832
|
-
# Raises an error if the 'puppetfile install' command is deprecated due to
|
833
|
-
# modules being configured.
|
834
|
-
#
|
835
|
-
def assert_puppetfile_or_module_command(modules)
|
836
|
-
if Bolt::Util.powershell?
|
837
|
-
case options[:action]
|
838
|
-
when 'generate-types'
|
839
|
-
old_command = 'Register-BoltPuppetfileTypes'
|
840
|
-
new_command = 'Register-BoltModuleTypes'
|
841
|
-
when 'install'
|
842
|
-
old_command = 'Install-BoltPuppetfile'
|
843
|
-
new_command = 'Install-BoltModule'
|
844
|
-
when 'show', 'show-modules'
|
845
|
-
old_command = 'Get-BoltPuppetfileModules'
|
846
|
-
new_command = 'Get-BoltModule'
|
847
|
-
end
|
848
|
-
else
|
849
|
-
old_command = "bolt puppetfile #{options[:action]}"
|
850
|
-
new_command = if options[:action] == 'show-modules'
|
851
|
-
'bolt module show'
|
852
|
-
else
|
853
|
-
"bolt module #{options[:action]}"
|
854
|
-
end
|
855
|
-
end
|
856
|
-
|
857
|
-
if modules && options[:subcommand] == 'puppetfile'
|
858
|
-
raise Bolt::CLIError,
|
859
|
-
"Unable to use command '#{old_command}' when 'modules' is configured in "\
|
860
|
-
"bolt-project.yaml. Use '#{new_command}' instead."
|
861
|
-
elsif modules.nil? && options[:subcommand] == 'puppetfile'
|
862
|
-
msg = "Command '#{old_command}' is deprecated and will be removed in Bolt 3.0. Update your project to use "\
|
863
|
-
"the module management feature. For more information, see https://pup.pt/bolt-module-migrate."
|
864
|
-
Bolt::Logger.deprecation_warning('puppetfile command', msg)
|
865
|
-
elsif modules.nil? && options[:subcommand] == 'module'
|
866
|
-
msg = "Unable to use command '#{new_command}' when 'modules' is not configured in "\
|
867
|
-
"bolt-project.yaml. "
|
868
|
-
msg += "Use '#{old_command}' instead." if options[:action] != 'add'
|
869
|
-
raise Bolt::CLIError, msg
|
870
|
-
end
|
871
|
-
end
|
872
|
-
|
873
786
|
def pal
|
874
787
|
@pal ||= Bolt::PAL.new(Bolt::Config::Modulepath.new(config.modulepath),
|
875
788
|
config.hiera_config,
|
@@ -930,6 +843,28 @@ module Bolt
|
|
930
843
|
Bolt::Util.validate_file(type, path, allow_dir)
|
931
844
|
end
|
932
845
|
|
846
|
+
# Returns the path to a file. If the path is an absolute or relative to
|
847
|
+
# a file, and the file exists, returns the path as-is. Otherwise, checks if
|
848
|
+
# the path is a Puppet file path and looks for the file in a module's files
|
849
|
+
# directory.
|
850
|
+
#
|
851
|
+
def find_file(path)
|
852
|
+
unless File.exist?(path) || Pathname.new(path).absolute?
|
853
|
+
modulepath = Bolt::Config::Modulepath.new(config.modulepath)
|
854
|
+
modules = Bolt::Module.discover(modulepath.full_modulepath, config.project)
|
855
|
+
mod, file = path.split(File::SEPARATOR, 2)
|
856
|
+
|
857
|
+
if modules[mod]
|
858
|
+
@logger.debug("Did not find file at #{File.expand_path(path)}, checking in module '#{mod}'")
|
859
|
+
path = File.join(modules[mod].path, 'files', file)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
Bolt::Util.validate_file('script', path)
|
864
|
+
|
865
|
+
path
|
866
|
+
end
|
867
|
+
|
933
868
|
def rerun
|
934
869
|
@rerun ||= Bolt::Rerun.new(config.rerunfile, config.save_rerun)
|
935
870
|
end
|
@@ -958,7 +893,7 @@ module Bolt
|
|
958
893
|
# If the bundled content directory is empty, Bolt is likely installed as a gem.
|
959
894
|
if ENV['BOLT_GEM'].nil? && incomplete_install?
|
960
895
|
msg = <<~MSG.chomp
|
961
|
-
Bolt
|
896
|
+
Bolt might be installed as a gem. To use Bolt reliably and with all of its
|
962
897
|
dependencies, uninstall the 'bolt' gem and install Bolt as a package:
|
963
898
|
https://puppet.com/docs/bolt/latest/bolt_installing.html
|
964
899
|
|
@@ -966,7 +901,7 @@ module Bolt
|
|
966
901
|
set the BOLT_GEM environment variable.
|
967
902
|
MSG
|
968
903
|
|
969
|
-
|
904
|
+
Bolt::Logger.warn("gem_install", msg)
|
970
905
|
end
|
971
906
|
|
972
907
|
# We only need to enumerate bundled content when running a task or plan
|
@@ -989,7 +924,8 @@ module Bolt
|
|
989
924
|
# Gem installs include the aggregate, canary, and puppetdb_fact modules, while
|
990
925
|
# package installs include modules listed in the Bolt repo Puppetfile
|
991
926
|
def incomplete_install?
|
992
|
-
|
927
|
+
builtin_module_list = %w[aggregate canary puppetdb_fact secure_env_vars puppet_connect]
|
928
|
+
(Dir.children(Bolt::Config::Modulepath::MODULES_PATH) - builtin_module_list).empty?
|
993
929
|
end
|
994
930
|
|
995
931
|
# Mimicks the output from Outputter::Human#fatal_error. This should be used to print
|