bolt 2.20.0 → 2.24.1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +3 -1
  3. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +6 -0
  4. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +12 -6
  5. data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
  6. data/bolt-modules/out/lib/puppet/functions/out/message.rb +1 -1
  7. data/exe/bolt +1 -0
  8. data/guides/inventory.txt +19 -0
  9. data/guides/project.txt +22 -0
  10. data/lib/bolt/analytics.rb +5 -5
  11. data/lib/bolt/applicator.rb +4 -3
  12. data/lib/bolt/bolt_option_parser.rb +75 -25
  13. data/lib/bolt/catalog.rb +9 -1
  14. data/lib/bolt/cli.rb +226 -73
  15. data/lib/bolt/config.rb +7 -0
  16. data/lib/bolt/config/options.rb +4 -4
  17. data/lib/bolt/executor.rb +16 -8
  18. data/lib/bolt/inventory/group.rb +3 -3
  19. data/lib/bolt/logger.rb +3 -4
  20. data/lib/bolt/module.rb +2 -1
  21. data/lib/bolt/outputter.rb +56 -0
  22. data/lib/bolt/outputter/human.rb +10 -9
  23. data/lib/bolt/outputter/json.rb +11 -4
  24. data/lib/bolt/outputter/logger.rb +2 -2
  25. data/lib/bolt/outputter/rainbow.rb +15 -0
  26. data/lib/bolt/pal.rb +5 -9
  27. data/lib/bolt/pal/yaml_plan/evaluator.rb +4 -0
  28. data/lib/bolt/pal/yaml_plan/step.rb +14 -1
  29. data/lib/bolt/pal/yaml_plan/step/message.rb +30 -0
  30. data/lib/bolt/pal/yaml_plan/transpiler.rb +11 -3
  31. data/lib/bolt/plugin/prompt.rb +3 -3
  32. data/lib/bolt/project.rb +6 -4
  33. data/lib/bolt/project_migrate.rb +138 -0
  34. data/lib/bolt/shell/bash.rb +7 -7
  35. data/lib/bolt/transport/docker/connection.rb +9 -9
  36. data/lib/bolt/transport/local/connection.rb +2 -2
  37. data/lib/bolt/transport/orch.rb +3 -3
  38. data/lib/bolt/transport/ssh/connection.rb +5 -5
  39. data/lib/bolt/transport/ssh/exec_connection.rb +4 -4
  40. data/lib/bolt/transport/winrm/connection.rb +17 -8
  41. data/lib/bolt/util.rb +1 -1
  42. data/lib/bolt/util/puppet_log_level.rb +4 -3
  43. data/lib/bolt/version.rb +1 -1
  44. data/lib/bolt_server/base_config.rb +1 -1
  45. data/lib/bolt_server/pe/pal.rb +1 -1
  46. data/lib/bolt_server/transport_app.rb +76 -0
  47. data/lib/bolt_spec/plans.rb +1 -1
  48. data/lib/bolt_spec/plans/action_stubs.rb +1 -1
  49. data/libexec/apply_catalog.rb +2 -2
  50. data/libexec/bolt_catalog +1 -1
  51. data/libexec/custom_facts.rb +1 -1
  52. data/libexec/query_resources.rb +1 -1
  53. data/modules/secure_env_vars/plans/init.pp +20 -0
  54. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a72c179da8e6e3fd3d8f883366e88f98026de00eee08ae2410515b2103a3810d
4
- data.tar.gz: 968edc1c0c30a370ed06b1c9bd5498ccaaaa5e15f3c47307cad1e68f2af5dafb
3
+ metadata.gz: 4a424969e4d64b199e77f75c0d67f2f8d668124dea01c8feaec98f7c8d6acd8a
4
+ data.tar.gz: c877c94c963b4dcca169b8bad3cf85fe547c1ca9a6050c9554fcc0685cb324b5
5
5
  SHA512:
6
- metadata.gz: a906282180c5df824978979d8e12da5cbe2f835ccef2ae65f2e2fc892bcfa1514a4f8f76418b866fe9cbfe8ce8f8f28b66306055b7acc67de6a7a2e13bb7edbf
7
- data.tar.gz: ee4c33740e8e29ad4b3026e5b75b3f0d29556c92e9277bc34101c5f8acfe80db599389c8544aab5946c6c444502a49ddb515da0a854b5796b0aae54fc0875ffc
6
+ metadata.gz: 7720901d8ad877de79b073b3d2d845e78845366bd3e556b4e9c7f4c3be7907e4f9bbf95de06a2583fa2b8d773494855bc3ff1d03fbd3a05217afa969caa1b703
7
+ data.tar.gz: f9f4ffb0512f5be6962497bec3f64f69e58f79862fb0337c7d7d67d8964a124afc01ea99cec2f39c12952943e06006d8bc99bb2651e592b909f599791d2b0b4d
data/Puppetfile CHANGED
@@ -5,7 +5,7 @@ forge "http://forge.puppetlabs.com"
5
5
  moduledir File.join(File.dirname(__FILE__), 'modules')
6
6
 
7
7
  # Core modules used by 'apply'
8
- mod 'puppetlabs-service', '1.2.0'
8
+ mod 'puppetlabs-service', '1.3.0'
9
9
  mod 'puppetlabs-puppet_agent', '3.2.0'
10
10
  mod 'puppetlabs-facts', '1.0.0'
11
11
 
@@ -28,6 +28,7 @@ mod 'puppetlabs-python_task_helper', '0.4.3'
28
28
  mod 'puppetlabs-reboot', '3.0.0'
29
29
  mod 'puppetlabs-ruby_task_helper', '0.5.1'
30
30
  mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
31
+ mod 'puppetlabs-stdlib', '6.3.0'
31
32
 
32
33
  # Plugin modules
33
34
  mod 'puppetlabs-aws_inventory', '0.5.0'
@@ -42,3 +43,4 @@ mod 'puppetlabs-yaml', '0.2.0'
42
43
  mod 'canary', local: true
43
44
  mod 'aggregate', local: true
44
45
  mod 'puppetdb_fact', local: true
46
+ mod 'secure_env_vars', local: true
@@ -11,6 +11,9 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
11
11
  # @param args A hash of arguments to the plan. Can also include additional options.
12
12
  # @option args [Boolean] _catch_errors Whether to catch raised errors.
13
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()`.
14
17
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
15
18
  # @example Run a plan
16
19
  # run_plan('canary', 'command' => 'false', 'targets' => $targets, '_catch_errors' => true)
@@ -31,6 +34,9 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
31
34
  # @param args A hash of arguments to the plan. Can also include additional options.
32
35
  # @option args [Boolean] _catch_errors Whether to catch raised errors.
33
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()`.
34
40
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
35
41
  # @example Run a plan
36
42
  # run_plan('canary', $targets, 'command' => 'false')
@@ -4,30 +4,36 @@
4
4
  Puppet::Functions.create_function(:'ctrl::do_until') do
5
5
  # @param options A hash of additional options.
6
6
  # @option options [Numeric] limit The number of times to repeat the block.
7
+ # @option options [Numeric] interval The number of seconds to wait before repeating the block.
7
8
  # @example Run a task until it succeeds
8
9
  # ctrl::do_until() || {
9
- # run_task('test', $target, _catch_errors => true).ok()
10
+ # run_task('test', $target, '_catch_errors' => true).ok()
10
11
  # }
11
- #
12
12
  # @example Run a task until it succeeds or fails 10 times
13
13
  # ctrl::do_until('limit' => 10) || {
14
- # run_task('test', $target, _catch_errors => true).ok()
14
+ # run_task('test', $target, '_catch_errors' => true).ok()
15
+ # }
16
+ # @example Run a task and wait 10 seconds before running it again
17
+ # ctrl::do_until('interval' => 10) || {
18
+ # run_task('test', $target, '_catch_errors' => true).ok()
15
19
  # }
16
- #
17
20
  dispatch :do_until do
18
21
  optional_param 'Hash[String[1], Any]', :options
19
22
  block_param
20
23
  end
21
24
 
22
- def do_until(options = { 'limit' => 0 })
25
+ def do_until(options = {})
23
26
  # Send Analytics Report
24
27
  Puppet.lookup(:bolt_executor) {}&.report_function_call(self.class.name)
25
28
 
26
- limit = options['limit']
29
+ limit = options['limit'] || 0
30
+ interval = options['interval']
31
+
27
32
  i = 0
28
33
  until (x = yield)
29
34
  i += 1
30
35
  break if limit != 0 && i >= limit
36
+ Kernel.sleep(interval) if interval
31
37
  end
32
38
  x
33
39
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ # Returns an array containing all of the filenames except for "." and ".." in the given directory.
6
+ Puppet::Functions.create_function(:'dir::children', Puppet::Functions::InternalFunction) do
7
+ # @param dirname Absolute path or Puppet module name.
8
+ # @return Array of files in the given directory.
9
+ # @example List filenames from an absolute path.
10
+ # dir::children('/home/user/subdir/')
11
+ # @example List filenames from a Puppet file path.
12
+ # dir::children('puppet_agent')
13
+ dispatch :children do
14
+ scope_param
15
+ required_param 'String', :dirname
16
+ return_type 'Array'
17
+ end
18
+
19
+ def children(scope, dirname)
20
+ # Send Analytics Report
21
+ Puppet.lookup(:bolt_executor) {}&.report_function_call(self.class.name)
22
+ modname, subpath = dirname.split(File::SEPARATOR, 2)
23
+ mod_path = scope.compiler.environment.module(modname)&.path
24
+
25
+ full_mod_path = File.join(mod_path, subpath || '') if mod_path
26
+
27
+ # Expand relative to the project directory if path is relative
28
+ project = Puppet.lookup(:bolt_project_data)
29
+ pathname = Pathname.new(dirname)
30
+ full_dir = pathname.absolute? ? dirname : File.expand_path(File.join(project.path, dirname))
31
+
32
+ # Sort for testability
33
+ Dir.children(full_mod_path || full_dir).sort
34
+ end
35
+ end
@@ -12,7 +12,7 @@ Puppet::Functions.create_function(:'out::message') do
12
12
  # @example Print a message
13
13
  # out::message('Something went wrong')
14
14
  dispatch :output_message do
15
- param 'String', :message
15
+ param 'Any', :message
16
16
  return_type 'Undef'
17
17
  end
18
18
 
data/exe/bolt CHANGED
@@ -4,6 +4,7 @@
4
4
  require 'bolt'
5
5
  require 'bolt/cli'
6
6
 
7
+ Thread.current[:name] ||= 'main'
7
8
  cli = Bolt::CLI.new(ARGV)
8
9
  begin
9
10
  opts = cli.parse
@@ -0,0 +1,19 @@
1
+ TOPIC
2
+ inventory
3
+
4
+ DESCRIPTION
5
+ The inventory describes the targets that you run Bolt commands on, along
6
+ with any data and configuration for the targets. Targets in an inventory can
7
+ belong to one or more groups, allowing you to share data and configuration
8
+ across multiple targets and to specify multiple targets for your Bolt
9
+ commands without the need to list each target individually.
10
+
11
+ In most cases, Bolt loads the inventory from an inventory file in your Bolt
12
+ project. The inventory file is a YAML file named 'inventory.yaml'. Because
13
+ Bolt loads the inventory file from a Bolt project, you must have an existing
14
+ project configuration file named 'bolt-project.yaml' alongside the inventory
15
+ file.
16
+
17
+ DOCUMENTATION
18
+ https://pup.pt/bolt-inventory
19
+ https://pup.pt/bolt-inventory-reference
@@ -0,0 +1,22 @@
1
+ TOPIC
2
+ project
3
+
4
+ DESCRIPTION
5
+ A Bolt project is a directory that serves as the launching point for Bolt
6
+ and allows you to create a shareable orchestration application. Projects
7
+ typically include a project configuration file, an inventory file, and any
8
+ content you use in your project workflow, such as tasks and plans.
9
+
10
+ When you run Bolt, it runs in the context of a project. If the directory you
11
+ run Bolt from is not a project, Bolt attempts to find a project by
12
+ traversing the parent directories. If Bolt is unable to find a project, it
13
+ runs from the default project, located at '~/.puppetlabs/bolt'.
14
+
15
+ A directory is only considered a Bolt project when it has a project
16
+ configuration file named 'bolt-project.yaml'. Bolt doesn't load project data
17
+ and content, including inventory files, unless the data and content are part
18
+ of a project.
19
+
20
+ DOCUMENTATION
21
+ https://pup.pt/bolt-projects
22
+ https://pup.pt/bolt-project-reference
@@ -72,7 +72,7 @@ module Bolt
72
72
 
73
73
  def self.load_config(filename, logger)
74
74
  if File.exist?(filename)
75
- YAML.load_file(filename)
75
+ Bolt::Util.read_optional_yaml_hash(filename, 'analytics')
76
76
  else
77
77
  unless ENV['BOLT_DISABLE_ANALYTICS']
78
78
  logger.warn <<~ANALYTICS
@@ -161,9 +161,9 @@ module Bolt
161
161
  # Handle analytics submission in the background to avoid blocking the
162
162
  # app or polluting the log with errors
163
163
  Concurrent::Future.execute(executor: @executor) do
164
- @logger.debug "Submitting analytics: #{JSON.pretty_generate(params)}"
164
+ @logger.trace "Submitting analytics: #{JSON.pretty_generate(params)}"
165
165
  @http.post(TRACKING_URL, params)
166
- @logger.debug "Completed analytics submission"
166
+ @logger.trace "Completed analytics submission"
167
167
  end
168
168
  end
169
169
 
@@ -215,13 +215,13 @@ module Bolt
215
215
  end
216
216
 
217
217
  def screen_view(screen, **_kwargs)
218
- @logger.debug "Skipping submission of '#{screen}' screenview because analytics is disabled"
218
+ @logger.trace "Skipping submission of '#{screen}' screenview because analytics is disabled"
219
219
  end
220
220
 
221
221
  def report_bundled_content(mode, name); end
222
222
 
223
223
  def event(category, action, **_kwargs)
224
- @logger.debug "Skipping submission of '#{category} #{action}' event because analytics is disabled"
224
+ @logger.trace "Skipping submission of '#{category} #{action}' event because analytics is disabled"
225
225
  end
226
226
 
227
227
  def finish; end
@@ -27,7 +27,7 @@ module Bolt
27
27
  @hiera_config = hiera_config ? validate_hiera_config(hiera_config) : nil
28
28
  @apply_settings = apply_settings || {}
29
29
 
30
- @pool = Concurrent::ThreadPoolExecutor.new(max_threads: max_compiles)
30
+ @pool = Concurrent::ThreadPoolExecutor.new(name: 'apply', max_threads: max_compiles)
31
31
  @logger = Logging.logger[self]
32
32
  end
33
33
 
@@ -217,6 +217,7 @@ module Bolt
217
217
  r = @executor.log_action(description, targets) do
218
218
  futures = targets.map do |target|
219
219
  Concurrent::Future.execute(executor: @pool) do
220
+ Thread.current[:name] ||= Thread.current.name
220
221
  @executor.with_node_logging("Compiling manifest block", [target]) do
221
222
  compile(target, scope)
222
223
  end
@@ -300,7 +301,7 @@ module Bolt
300
301
 
301
302
  files.each do |file|
302
303
  tar_path = Pathname.new(file).relative_path_from(parent)
303
- @logger.debug("Packing plugin #{file} to #{tar_path}")
304
+ @logger.trace("Packing plugin #{file} to #{tar_path}")
304
305
  stat = File.stat(file)
305
306
  content = File.binread(file)
306
307
  output.tar.add_file_simple(
@@ -314,7 +315,7 @@ module Bolt
314
315
  end
315
316
 
316
317
  duration = Time.now - start_time
317
- @logger.debug("Packed plugins in #{duration * 1000} ms")
318
+ @logger.trace("Packed plugins in #{duration * 1000} ms")
318
319
 
319
320
  output.close
320
321
  Base64.encode64(sio.string)
@@ -25,7 +25,7 @@ module Bolt
25
25
  when 'command'
26
26
  case action
27
27
  when 'run'
28
- { flags: ACTION_OPTS,
28
+ { flags: ACTION_OPTS + %w[env-var],
29
29
  banner: COMMAND_RUN_HELP }
30
30
  else
31
31
  { flags: OPTIONS[:global],
@@ -61,11 +61,17 @@ module Bolt
61
61
  { flags: OPTIONS[:global],
62
62
  banner: GROUP_HELP }
63
63
  end
64
+ when 'guide'
65
+ { flags: OPTIONS[:global] + %w[format],
66
+ banner: GUIDE_HELP }
64
67
  when 'plan'
65
68
  case action
66
69
  when 'convert'
67
70
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
68
71
  banner: PLAN_CONVERT_HELP }
72
+ when 'new'
73
+ { flags: OPTIONS[:global] + %w[configfile project],
74
+ banner: PLAN_NEW_HELP }
69
75
  when 'run'
70
76
  { flags: ACTION_OPTS + %w[params compile-concurrency tmpdir hiera-config],
71
77
  banner: PLAN_RUN_HELP }
@@ -82,7 +88,7 @@ module Bolt
82
88
  { flags: OPTIONS[:global] + %w[modules],
83
89
  banner: PROJECT_INIT_HELP }
84
90
  when 'migrate'
85
- { flags: OPTIONS[:global] + %w[inventoryfile boltdir configfile],
91
+ { flags: OPTIONS[:global] + %w[inventoryfile project configfile],
86
92
  banner: PROJECT_MIGRATE_HELP }
87
93
  else
88
94
  { flags: OPTIONS[:global],
@@ -106,7 +112,7 @@ module Bolt
106
112
  when 'script'
107
113
  case action
108
114
  when 'run'
109
- { flags: ACTION_OPTS + %w[tmpdir],
115
+ { flags: ACTION_OPTS + %w[tmpdir env-var],
110
116
  banner: SCRIPT_RUN_HELP }
111
117
  else
112
118
  { flags: OPTIONS[:global],
@@ -159,15 +165,19 @@ module Bolt
159
165
  SUBCOMMANDS
160
166
  apply Apply Puppet manifest code
161
167
  command Run a command remotely
162
- file Upload a local file or directory
168
+ file Copy files between the controller and targets
163
169
  group Show the list of groups in the inventory
170
+ guide View guides for Bolt concepts and features
164
171
  inventory Show the list of targets an action would run on
165
- plan Convert, show, and run Bolt plans
172
+ plan Convert, create, show, and run Bolt plans
166
173
  project Create and migrate Bolt projects
167
174
  puppetfile Install and list modules and generate type references
168
175
  script Upload a local script and run it remotely
169
176
  secret Create encryption keys and encrypt and decrypt values
170
177
  task Show and run Bolt tasks
178
+
179
+ GUIDES
180
+ For a list of guides on Bolt's concepts and features, run 'bolt guide'.
171
181
  HELP
172
182
 
173
183
  APPLY_HELP = <<~HELP
@@ -286,6 +296,26 @@ module Bolt
286
296
  Show the list of groups in the inventory.
287
297
  HELP
288
298
 
299
+ GUIDE_HELP = <<~HELP
300
+ NAME
301
+ guide
302
+
303
+ USAGE
304
+ bolt guide [topic] [options]
305
+
306
+ DESCRIPTION
307
+ View guides for Bolt's concepts and features.
308
+
309
+ Omitting a topic will display a list of available guides,
310
+ while providing a topic will display the relevant guide.
311
+
312
+ EXAMPLES
313
+ View a list of available guides
314
+ bolt guide
315
+ View the 'project' guide page
316
+ bolt guide project
317
+ HELP
318
+
289
319
  INVENTORY_HELP = <<~HELP
290
320
  NAME
291
321
  inventory
@@ -319,10 +349,11 @@ module Bolt
319
349
  bolt plan <action> [parameters] [options]
320
350
 
321
351
  DESCRIPTION
322
- Convert, show, and run Bolt plans.
352
+ Convert, create, show, and run Bolt plans.
323
353
 
324
354
  ACTIONS
325
355
  convert Convert a YAML plan to a Bolt plan
356
+ new Create a new plan in the current project
326
357
  run Run a plan on the specified targets
327
358
  show Show available plans and plan documentation
328
359
  HELP
@@ -345,6 +376,20 @@ module Bolt
345
376
  bolt plan convert path/to/plan/myplan.yaml
346
377
  HELP
347
378
 
379
+ PLAN_NEW_HELP = <<~HELP
380
+ NAME
381
+ new
382
+
383
+ USAGE
384
+ bolt plan new <plan> [options]
385
+
386
+ DESCRIPTION
387
+ Create a new plan in the current project.
388
+
389
+ EXAMPLES
390
+ bolt plan new myproject::myplan
391
+ HELP
392
+
348
393
  PLAN_RUN_HELP = <<~HELP
349
394
  NAME
350
395
  run
@@ -402,19 +447,18 @@ module Bolt
402
447
  init
403
448
 
404
449
  USAGE
405
- bolt project init [directory] [options]
450
+ bolt project init [name] [options]
406
451
 
407
452
  DESCRIPTION
408
- Create a new Bolt project.
453
+ Create a new Bolt project in the current working directory.
409
454
 
410
- Specify a directory to create a Bolt project in. Defaults to the
411
- curent working directory.
455
+ Specify a name for the Bolt project. Defaults to the basename of the current working directory.
412
456
 
413
457
  EXAMPLES
414
- Create a new Bolt project in the current working directory.
458
+ Create a new Bolt project using the directory as the project name.
415
459
  bolt project init
416
- Create a new Bolt project at a specified path.
417
- bolt project init ~/path/to/project
460
+ Create a new Bolt project with a specified name.
461
+ bolt project init myproject
418
462
  Create a new Bolt project with existing modules.
419
463
  bolt project init --modules puppetlabs-apt,puppetlabs-ntp
420
464
  HELP
@@ -427,10 +471,7 @@ module Bolt
427
471
  bolt project migrate [options]
428
472
 
429
473
  DESCRIPTION
430
- Migrate a Bolt project to the latest version.
431
-
432
- Loads a Bolt project's inventory file and migrates it to the latest version. The
433
- inventory file is modified in place and will not preserve comments or formatting.
474
+ Migrate a Bolt project to use current best practices and the latest version of configuration files.
434
475
  HELP
435
476
 
436
477
  PUPPETFILE_HELP = <<~HELP
@@ -676,9 +717,9 @@ module Bolt
676
717
  @options[:password] = password
677
718
  end
678
719
  define('--password-prompt', 'Prompt for user to input password') do |_password|
679
- STDERR.print "Please enter your password: "
680
- @options[:password] = STDIN.noecho(&:gets).chomp
681
- STDERR.puts
720
+ $stderr.print "Please enter your password: "
721
+ @options[:password] = $stdin.noecho(&:gets).chomp
722
+ $stderr.puts
682
723
  end
683
724
  define('--private-key KEY', 'Path to private ssh key to authenticate with') do |key|
684
725
  @options[:'private-key'] = File.expand_path(key)
@@ -702,9 +743,9 @@ module Bolt
702
743
  @options[:'sudo-password'] = password
703
744
  end
704
745
  define('--sudo-password-prompt', 'Prompt for user to input escalation password') do |_password|
705
- STDERR.print "Please enter your privilege escalation password: "
706
- @options[:'sudo-password'] = STDIN.noecho(&:gets).chomp
707
- STDERR.puts
746
+ $stderr.print "Please enter your privilege escalation password: "
747
+ @options[:'sudo-password'] = $stdin.noecho(&:gets).chomp
748
+ $stderr.puts
708
749
  end
709
750
  define('--sudo-executable EXEC', "Specify an executable for running as another user.",
710
751
  "This option is experimental.") do |exec|
@@ -761,6 +802,15 @@ module Bolt
761
802
  @options[:'save-rerun'] = save
762
803
  end
763
804
 
805
+ separator "\nREMOTE ENVIRONMENT OPTIONS"
806
+ define('--env-var ENVIRONMENT_VARIABLES', 'Environment variables to set on the target') do |envvar|
807
+ unless envvar.include?('=')
808
+ raise Bolt::CLIError, "Environment variables must be specified using 'myenvvar=key' format"
809
+ end
810
+ @options[:env_vars] ||= {}
811
+ @options[:env_vars].store(*envvar.split('=', 2))
812
+ end
813
+
764
814
  separator "\nTRANSPORT OPTIONS"
765
815
  define('--transport TRANSPORT', TRANSPORTS.keys.map(&:to_s),
766
816
  "Specify a default transport: #{TRANSPORTS.keys.join(', ')}") do |t|
@@ -837,7 +887,7 @@ module Bolt
837
887
  end
838
888
  define('--log-level LEVEL',
839
889
  "Set the log level for the console. Available options are",
840
- "debug, info, notice, warn, error, fatal, any.") do |level|
890
+ "trace, debug, info, warn, error, fatal, any.") do |level|
841
891
  @options[:log] = { 'console' => { 'level' => level } }
842
892
  end
843
893
  define('--plugin PLUGIN', 'Select the plugin to use') do |plug|
@@ -878,7 +928,7 @@ module Bolt
878
928
  file = value.sub(/^@/, '')
879
929
  read_arg_file(file)
880
930
  elsif value == '-'
881
- STDIN.read
931
+ $stdin.read
882
932
  else
883
933
  value
884
934
  end