bolt 2.38.0 → 3.0.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.

Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +17 -17
  3. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +25 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
  5. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +7 -3
  6. data/lib/bolt/analytics.rb +3 -2
  7. data/lib/bolt/applicator.rb +11 -1
  8. data/lib/bolt/bolt_option_parser.rb +3 -113
  9. data/lib/bolt/catalog.rb +10 -29
  10. data/lib/bolt/cli.rb +54 -155
  11. data/lib/bolt/config.rb +63 -269
  12. data/lib/bolt/config/options.rb +59 -97
  13. data/lib/bolt/config/transport/local.rb +1 -0
  14. data/lib/bolt/config/transport/options.rb +10 -2
  15. data/lib/bolt/config/transport/orch.rb +1 -0
  16. data/lib/bolt/config/transport/ssh.rb +0 -5
  17. data/lib/bolt/executor.rb +15 -5
  18. data/lib/bolt/inventory.rb +3 -2
  19. data/lib/bolt/inventory/group.rb +35 -12
  20. data/lib/bolt/inventory/inventory.rb +1 -1
  21. data/lib/bolt/logger.rb +115 -11
  22. data/lib/bolt/module.rb +10 -2
  23. data/lib/bolt/module_installer.rb +4 -2
  24. data/lib/bolt/module_installer/resolver.rb +65 -12
  25. data/lib/bolt/module_installer/specs/forge_spec.rb +8 -2
  26. data/lib/bolt/module_installer/specs/git_spec.rb +17 -2
  27. data/lib/bolt/outputter/human.rb +9 -5
  28. data/lib/bolt/outputter/json.rb +16 -16
  29. data/lib/bolt/outputter/rainbow.rb +3 -3
  30. data/lib/bolt/pal.rb +93 -14
  31. data/lib/bolt/pal/yaml_plan.rb +8 -2
  32. data/lib/bolt/pal/yaml_plan/evaluator.rb +7 -19
  33. data/lib/bolt/pal/yaml_plan/step.rb +3 -24
  34. data/lib/bolt/pal/yaml_plan/step/upload.rb +2 -2
  35. data/lib/bolt/pal/yaml_plan/transpiler.rb +6 -1
  36. data/lib/bolt/plugin.rb +3 -3
  37. data/lib/bolt/plugin/cache.rb +8 -8
  38. data/lib/bolt/plugin/module.rb +0 -23
  39. data/lib/bolt/plugin/puppet_connect_data.rb +77 -0
  40. data/lib/bolt/plugin/puppetdb.rb +1 -1
  41. data/lib/bolt/project.rb +54 -81
  42. data/lib/bolt/project_manager.rb +4 -3
  43. data/lib/bolt/project_manager/module_migrator.rb +6 -5
  44. data/lib/bolt/rerun.rb +1 -1
  45. data/lib/bolt/shell/bash.rb +1 -1
  46. data/lib/bolt/shell/bash/tmpdir.rb +4 -1
  47. data/lib/bolt/shell/powershell.rb +3 -4
  48. data/lib/bolt/shell/powershell/snippets.rb +9 -149
  49. data/lib/bolt/task.rb +1 -1
  50. data/lib/bolt/transport/docker/connection.rb +2 -2
  51. data/lib/bolt/transport/local.rb +1 -9
  52. data/lib/bolt/transport/orch/connection.rb +1 -1
  53. data/lib/bolt/transport/ssh.rb +1 -2
  54. data/lib/bolt/transport/ssh/connection.rb +1 -1
  55. data/lib/bolt/validator.rb +16 -15
  56. data/lib/bolt/version.rb +1 -1
  57. data/lib/bolt_server/config.rb +1 -1
  58. data/lib/bolt_server/schemas/partials/task.json +1 -1
  59. data/lib/bolt_server/transport_app.rb +3 -2
  60. data/libexec/bolt_catalog +1 -1
  61. data/modules/aggregate/plans/count.pp +21 -0
  62. data/modules/aggregate/plans/targets.pp +21 -0
  63. data/modules/puppet_connect/plans/test_input_data.pp +31 -0
  64. data/modules/puppetdb_fact/plans/init.pp +10 -0
  65. metadata +26 -17
  66. data/modules/aggregate/plans/nodes.pp +0 -36
@@ -53,31 +53,38 @@ module Bolt
53
53
  # Definitions used to validate config options.
54
54
  # https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
55
55
  OPTIONS = {
56
- "apply_settings" => {
56
+ "apply-settings" => {
57
57
  description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
58
58
  "plan function or the `bolt apply` command.",
59
59
  type: Hash,
60
60
  properties: {
61
- "show_diff" => {
62
- description: "Whether to log and report a contextual diff.",
61
+ "evaltrace" => {
62
+ description: "Whether each resource should log when it is being evaluated. This allows "\
63
+ "you to interactively see exactly what is being done.",
63
64
  type: [TrueClass, FalseClass],
64
65
  _example: true,
65
66
  _default: false
66
- }
67
- },
68
- _plugin: false,
69
- _deprecation: "This option will be removed in Bolt 3.0. Use `apply-settings` instead."
70
- },
71
- "apply-settings" => {
72
- description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
73
- "plan function or the `bolt apply` command.",
74
- type: Hash,
75
- properties: {
67
+ },
68
+ "log_level" => {
69
+ description: "The log level for logs in apply reports from Puppet. These can be seen "\
70
+ "in ApplyResults.",
71
+ type: String,
72
+ enum: %w[debug info notice warning err alert emerg crit],
73
+ _example: "debug",
74
+ _default: "notice"
75
+ },
76
76
  "show_diff" => {
77
77
  description: "Whether to log and report a contextual diff.",
78
78
  type: [TrueClass, FalseClass],
79
79
  _example: true,
80
80
  _default: false
81
+ },
82
+ "trace" => {
83
+ description: "Whether to print stack traces on some errors. Will print internal Ruby "\
84
+ "stack trace interleaved with Puppet function frames.",
85
+ type: [TrueClass, FalseClass],
86
+ _example: true,
87
+ _default: false
81
88
  }
82
89
  },
83
90
  _plugin: false
@@ -105,6 +112,17 @@ module Bolt
105
112
  _example: 50,
106
113
  _default: "100 or 1/7 the ulimit, whichever is lower."
107
114
  },
115
+ "disable-warnings" => {
116
+ description: "An array of IDs of warnings to suppress. Warnings with a matching ID will not be logged "\
117
+ "by Bolt. If you are upgrading Bolt to a new major version, you should re-enable all warnings "\
118
+ "until you have finished upgrading.",
119
+ type: Array,
120
+ items: {
121
+ type: String
122
+ },
123
+ _plugin: false,
124
+ _example: ["powershell_2"]
125
+ },
108
126
  "format" => {
109
127
  description: "The format to use when printing results.",
110
128
  type: String,
@@ -128,18 +146,6 @@ module Bolt
128
146
  _plugin: false,
129
147
  _example: {}
130
148
  },
131
- "inventoryfile" => {
132
- description: "The path to a structured data inventory file used to refer to groups of targets on the "\
133
- "command line and from plans. Read more about using inventory files in [Inventory "\
134
- "files](inventory_file_v2.md).",
135
- type: String,
136
- _plugin: false,
137
- _deprecation: "This option will be removed in Bolt 3.0. Use the `--inventoryfile` command-line option "\
138
- "to use a non-default inventory file or move the file contents to `inventory.yaml` in the "\
139
- "project directory.",
140
- _example: "~/.puppetlabs/bolt/inventory.yaml",
141
- _default: "project/inventory.yaml"
142
- },
143
149
  "plugin-cache" => {
144
150
  description: "This feature is experimental. Enable plugin caching and set the time-to-live.",
145
151
  type: Hash,
@@ -171,7 +177,7 @@ module Bolt
171
177
  "level" => {
172
178
  description: "The type of information to log.",
173
179
  type: String,
174
- enum: %w[trace debug error info notice warn fatal any],
180
+ enum: %w[trace debug error info warn fatal any],
175
181
  _default: "warn"
176
182
  }
177
183
  }
@@ -190,7 +196,7 @@ module Bolt
190
196
  "level" => {
191
197
  description: "The type of information to log.",
192
198
  type: String,
193
- enum: %w[trace debug error info notice warn fatal any],
199
+ enum: %w[trace debug error info warn fatal any],
194
200
  _default: "warn"
195
201
  }
196
202
  }
@@ -208,7 +214,7 @@ module Bolt
208
214
  },
209
215
  _plugin: false,
210
216
  _example: ["~/.puppetlabs/bolt/modules", "~/.puppetlabs/bolt/site-modules"],
211
- _default: ["project/modules", "project/site-modules", "project/site"]
217
+ _default: ["project/modules"]
212
218
  },
213
219
  "module-install" => {
214
220
  description: "Options that configure where Bolt downloads modules from. This option is only used when "\
@@ -260,6 +266,10 @@ module Bolt
260
266
  description: "The name of the module.",
261
267
  type: String
262
268
  },
269
+ "resolve" => {
270
+ description: "Whether to resolve the module's dependencies when installing modules.",
271
+ type: [TrueClass, FalseClass]
272
+ },
263
273
  "version_requirement" => {
264
274
  description: "The version requirement for the module. Accepts a specific version (1.2.3), version "\
265
275
  "shorthand (1.2.x), or a version range (>= 1.2.0).",
@@ -274,15 +284,24 @@ module Bolt
274
284
  description: "The URL to the public git repository.",
275
285
  type: String
276
286
  },
287
+ "name" => {
288
+ description: "The name of the module. Required when `resolve` is `false`.",
289
+ type: String
290
+ },
277
291
  "ref" => {
278
292
  description: "The git reference to check out. Can be either a branch, tag, or commit SHA.",
279
293
  type: String
294
+ },
295
+ "resolve" => {
296
+ description: "Whether to resolve the module's dependencies when installing modules.",
297
+ type: [TrueClass, FalseClass]
280
298
  }
281
299
  }
282
300
  }
283
301
  ]
284
302
  },
285
303
  _plugin: false,
304
+ _default: [],
286
305
  _example: [
287
306
  "puppetlabs-facts",
288
307
  { "name" => "puppetlabs-mysql" },
@@ -311,16 +330,6 @@ module Bolt
311
330
  _plugin: false,
312
331
  _example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy::*"]
313
332
  },
314
- "plugin_hooks" => {
315
- description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
316
- "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
317
- "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
318
- "and [`task`](using_plugins.md#task).",
319
- type: Hash,
320
- _plugin: true,
321
- _example: { "puppet_library" => { "plugin" => "puppet_agent", "version" => "6.15.0", "_run_as" => "root" } },
322
- _deprecation: "This option will be removed in Bolt 3.0. Use `plugin-hooks` instead."
323
- },
324
333
  "plugin-hooks" => {
325
334
  description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
326
335
  "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
@@ -398,40 +407,6 @@ module Bolt
398
407
  },
399
408
  _plugin: true
400
409
  },
401
- "puppetfile" => {
402
- description: "A map containing options for the `bolt puppetfile install` command and "\
403
- "`Install-BoltPuppetfile` cmdlet.",
404
- type: Hash,
405
- properties: {
406
- "forge" => {
407
- description: "A subsection that can have its own `proxy` setting to set an HTTP proxy for Forge "\
408
- "operations only, and a `baseurl` setting to specify a different Forge host.",
409
- type: Hash,
410
- properties: {
411
- "baseurl" => {
412
- description: "The URL to the Forge host.",
413
- type: String,
414
- format: "uri",
415
- _example: "https://forge.example.com"
416
- },
417
- "proxy" => {
418
- description: "The HTTP proxy to use for Forge operations.",
419
- type: String,
420
- format: "uri",
421
- _example: "https://my-forge-proxy.com:8080"
422
- }
423
- },
424
- _example: { "baseurl" => "https://forge.example.com", "proxy" => "https://my-forge-proxy.com:8080" }
425
- },
426
- "proxy" => {
427
- description: "The HTTP proxy to use for Git and Forge operations.",
428
- type: String,
429
- format: "uri",
430
- _example: "https://my-proxy.com:8080"
431
- }
432
- },
433
- _plugin: false
434
- },
435
410
  "save-rerun" => {
436
411
  description: "Whether to update `.rerun.json` in the Bolt project directory. If "\
437
412
  "your target names include passwords, set this value to `false` to avoid "\
@@ -475,8 +450,8 @@ module Bolt
475
450
 
476
451
  # Options that configure the inventory, specifically the default transport
477
452
  # used by targets and the transports themselves. These options are used in
478
- # bolt.yaml, under a 'config' key in inventory.yaml, and under the
479
- # 'inventory-config' key in bolt-defaults.yaml.
453
+ # bolt-defaults.yaml under 'inventory-config' and in inventory.yaml under
454
+ # 'config'.
480
455
  INVENTORY_OPTIONS = {
481
456
  "transport" => {
482
457
  description: "The default transport to use when the transport for a target is not "\
@@ -509,6 +484,7 @@ module Bolt
509
484
  "remote" => {
510
485
  description: "A map of configuration options for the remote transport.",
511
486
  type: Hash,
487
+ additionalProperties: true,
512
488
  _plugin: true,
513
489
  _example: { "run-on" => "proxy_target" }
514
490
  },
@@ -526,57 +502,45 @@ module Bolt
526
502
  }
527
503
  }.freeze
528
504
 
529
- # Options that are available in a bolt.yaml file
530
- BOLT_OPTIONS = %w[
531
- apply-settings
532
- apply_settings
533
- color
505
+ # Options that are available on the command line
506
+ # This only includes options where users can provide arbitrary
507
+ # values from the command-line, allowing the validator to check them
508
+ CLI_OPTIONS = %w[
534
509
  compile-concurrency
535
510
  concurrency
536
511
  format
537
- hiera-config
538
- inventoryfile
539
512
  log
540
513
  modulepath
541
- plugin-hooks
542
- plugin_hooks
543
- plugins
544
- puppetdb
545
- puppetfile
546
- save-rerun
547
- spinner
548
- trusted-external-command
514
+ transport
549
515
  ].freeze
550
516
 
551
517
  # Options that are available in a bolt-defaults.yaml file
552
- BOLT_DEFAULTS_OPTIONS = %w[
518
+ DEFAULTS_OPTIONS = %w[
553
519
  color
554
520
  compile-concurrency
555
521
  concurrency
522
+ disable-warnings
556
523
  format
557
524
  inventory-config
558
525
  log
559
526
  module-install
560
527
  plugin-cache
561
528
  plugin-hooks
562
- plugin_hooks
563
529
  plugins
564
530
  puppetdb
565
- puppetfile
566
531
  save-rerun
567
532
  spinner
568
533
  ].freeze
569
534
 
570
535
  # Options that are available in a bolt-project.yaml file
571
- BOLT_PROJECT_OPTIONS = %w[
536
+ PROJECT_OPTIONS = %w[
572
537
  apply-settings
573
- apply_settings
574
538
  color
575
539
  compile-concurrency
576
540
  concurrency
541
+ disable-warnings
577
542
  format
578
543
  hiera-config
579
- inventoryfile
580
544
  log
581
545
  modulepath
582
546
  module-install
@@ -585,10 +549,8 @@ module Bolt
585
549
  plans
586
550
  plugin-cache
587
551
  plugin-hooks
588
- plugin_hooks
589
552
  plugins
590
553
  puppetdb
591
- puppetfile
592
554
  save-rerun
593
555
  spinner
594
556
  tasks
@@ -17,6 +17,7 @@ module Bolt
17
17
  OPTIONS = WINDOWS_OPTIONS.dup.concat(RUN_AS_OPTIONS).sort.freeze
18
18
 
19
19
  DEFAULTS = {
20
+ 'bundled-ruby' => true,
20
21
  'cleanup' => true
21
22
  }.freeze
22
23
 
@@ -21,7 +21,7 @@ module Bolt
21
21
  type: [TrueClass, FalseClass],
22
22
  _plugin: false,
23
23
  _example: true,
24
- _default: false
24
+ _default: true
25
25
  },
26
26
  "cacert" => {
27
27
  type: String,
@@ -143,7 +143,8 @@ module Bolt
143
143
  "`task.py`) and the extension is case sensitive. When a target's name is `localhost`, "\
144
144
  "Ruby tasks run with the Bolt Ruby interpreter by default.",
145
145
  additionalProperties: {
146
- type: String
146
+ type: String,
147
+ _plugin: false
147
148
  },
148
149
  propertyNames: {
149
150
  pattern: "^.?[a-zA-Z0-9]+$"
@@ -252,6 +253,13 @@ module Bolt
252
253
  _plugin: true,
253
254
  _example: "jump.example.com"
254
255
  },
256
+ "read-timeout" => {
257
+ type: Integer,
258
+ description: "How long to wait in seconds when making requests to the Orchestrator.",
259
+ minimum: 1,
260
+ _plugin: true,
261
+ _example: 15
262
+ },
255
263
  "realm" => {
256
264
  type: String,
257
265
  description: "The Kerberos realm (Active Directory domain) to authenticate against.",
@@ -12,6 +12,7 @@ module Bolt
12
12
  host
13
13
  job-poll-interval
14
14
  job-poll-timeout
15
+ read-timeout
15
16
  service-url
16
17
  task-environment
17
18
  token-file
@@ -111,11 +111,6 @@ module Bolt
111
111
  @config['interpreters'] = normalize_interpreters(@config['interpreters'])
112
112
  end
113
113
 
114
- if @config['login-shell'] && !LOGIN_SHELLS.include?(@config['login-shell'])
115
- raise Bolt::ValidationError,
116
- "Unsupported login-shell #{@config['login-shell']}. Supported shells are #{LOGIN_SHELLS.join(', ')}"
117
- end
118
-
119
114
  if @config['login-shell'] == 'powershell'
120
115
  %w[tty run-as].each do |key|
121
116
  if @config[key]
data/lib/bolt/executor.rb CHANGED
@@ -100,6 +100,8 @@ module Bolt
100
100
  # that type of event, publish the event
101
101
  next unless types.nil? || types.include?(event[:type])
102
102
  @publisher.post(subscriber) do |sub|
103
+ # Wait for user to input to prompt before printing anything
104
+ sleep(0.1) while @prompting
103
105
  sub.handle_event(event)
104
106
  end
105
107
  end
@@ -119,11 +121,12 @@ module Bolt
119
121
  def queue_execute(targets)
120
122
  if @warn_concurrency && targets.length > @concurrency
121
123
  @warn_concurrency = false
122
- @logger.warn("The ulimit is low, which may cause file limit issues. Default concurrency has been set to "\
123
- "'#{@concurrency}' to mitigate those issues, which may cause Bolt to run slow. "\
124
- "Disable this warning by configuring ulimit using 'ulimit -n <limit>' in your shell "\
125
- "configuration, or by configuring Bolt's concurrency. "\
126
- "See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details.")
124
+ msg = "The ulimit is low, which may cause file limit issues. Default concurrency has been set to "\
125
+ "'#{@concurrency}' to mitigate those issues, which may cause Bolt to run slow. "\
126
+ "Disable this warning by configuring ulimit using 'ulimit -n <limit>' in your shell "\
127
+ "configuration, or by configuring Bolt's concurrency. "\
128
+ "See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
129
+ Bolt::Logger.warn("low_ulimit", msg)
127
130
  end
128
131
 
129
132
  targets.group_by(&:transport).flat_map do |protocol, protocol_targets|
@@ -258,7 +261,9 @@ module Bolt
258
261
 
259
262
  def with_node_logging(description, batch, log_level = :info)
260
263
  @logger.send(log_level, "#{description} on #{batch.map(&:safe_name)}")
264
+ publish_event(type: :start_spin)
261
265
  result = yield
266
+ publish_event(type: :stop_spin)
262
267
  @logger.send(log_level, result.to_json)
263
268
  result
264
269
  end
@@ -410,6 +415,7 @@ module Bolt
410
415
  subscribe(self, [:node_result])
411
416
  results = Array.new(skein.length)
412
417
  @in_parallel = true
418
+ publish_event(type: :stop_spin)
413
419
 
414
420
  until skein.empty?
415
421
  @thread_completed = false
@@ -417,6 +423,7 @@ module Bolt
417
423
 
418
424
  skein.each do |yarn|
419
425
  if yarn.alive?
426
+ publish_event(type: :stop_spin)
420
427
  r = yarn.resume
421
428
  else
422
429
  results[yarn.index] = yarn.value
@@ -428,6 +435,7 @@ module Bolt
428
435
  sleep(0.1) until @thread_completed || skein.empty?
429
436
  end
430
437
 
438
+ publish_event(type: :stop_spin)
431
439
  @in_parallel = false
432
440
  unsubscribe(self, [:node_result])
433
441
  results
@@ -469,6 +477,7 @@ module Bolt
469
477
  end
470
478
 
471
479
  def prompt(prompt, options)
480
+ @prompting = true
472
481
  unless $stdin.tty?
473
482
  raise Bolt::Error.new('STDIN is not a tty, unable to prompt', 'bolt/no-tty-error')
474
483
  end
@@ -480,6 +489,7 @@ module Bolt
480
489
  else
481
490
  $stdin.gets.to_s.chomp
482
491
  end
492
+ @prompting = false
483
493
 
484
494
  $stderr.puts if options[:sensitive]
485
495
 
@@ -55,7 +55,8 @@ module Bolt
55
55
  schema = {
56
56
  type: Hash,
57
57
  properties: OPTIONS.map { |opt| [opt, _ref: opt] }.to_h,
58
- definitions: DEFINITIONS
58
+ definitions: DEFINITIONS,
59
+ _plugin: true
59
60
  }
60
61
 
61
62
  schema[:definitions]['config'][:properties] = Bolt::Config.transport_definitions
@@ -96,7 +97,7 @@ module Bolt
96
97
 
97
98
  Bolt::Validator.new.tap do |validator|
98
99
  validator.validate(data, schema, source)
99
- validator.warnings.each { |warning| logger.warn(warning) }
100
+ validator.warnings.each { |warning| Bolt::Logger.warn(warning[:id], warning[:msg]) }
100
101
  end
101
102
 
102
103
  inventory = create_version(data, config.transport, config.transports, plugins)