bolt 2.33.1 → 2.37.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +1 -1
  3. data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +1 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -3
  5. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +17 -6
  6. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +56 -0
  7. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +24 -6
  8. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -8
  9. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +21 -1
  10. data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +18 -1
  11. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +24 -6
  12. data/lib/bolt/analytics.rb +27 -8
  13. data/lib/bolt/apply_result.rb +3 -3
  14. data/lib/bolt/bolt_option_parser.rb +48 -16
  15. data/lib/bolt/cli.rb +95 -227
  16. data/lib/bolt/config.rb +145 -54
  17. data/lib/bolt/config/options.rb +76 -10
  18. data/lib/bolt/config/transport/base.rb +10 -19
  19. data/lib/bolt/config/transport/local.rb +0 -7
  20. data/lib/bolt/config/transport/options.rb +1 -1
  21. data/lib/bolt/config/transport/ssh.rb +8 -14
  22. data/lib/bolt/config/validator.rb +231 -0
  23. data/lib/bolt/error.rb +33 -3
  24. data/lib/bolt/executor.rb +92 -6
  25. data/lib/bolt/inventory/group.rb +2 -1
  26. data/lib/bolt/module_installer.rb +1 -1
  27. data/lib/bolt/module_installer/specs/forge_spec.rb +5 -4
  28. data/lib/bolt/module_installer/specs/git_spec.rb +4 -3
  29. data/lib/bolt/outputter/human.rb +21 -9
  30. data/lib/bolt/outputter/rainbow.rb +1 -1
  31. data/lib/bolt/pal.rb +19 -7
  32. data/lib/bolt/pal/yaml_plan.rb +7 -0
  33. data/lib/bolt/plan_creator.rb +160 -0
  34. data/lib/bolt/plugin.rb +42 -13
  35. data/lib/bolt/plugin/cache.rb +76 -0
  36. data/lib/bolt/plugin/module.rb +4 -4
  37. data/lib/bolt/project.rb +46 -40
  38. data/lib/bolt/project_manager.rb +199 -0
  39. data/lib/bolt/{project_migrator/config.rb → project_manager/config_migrator.rb} +43 -5
  40. data/lib/bolt/{project_migrator/inventory.rb → project_manager/inventory_migrator.rb} +5 -5
  41. data/lib/bolt/{project_migrator/base.rb → project_manager/migrator.rb} +2 -2
  42. data/lib/bolt/{project_migrator/modules.rb → project_manager/module_migrator.rb} +3 -3
  43. data/lib/bolt/puppetdb/client.rb +3 -2
  44. data/lib/bolt/puppetdb/config.rb +9 -8
  45. data/lib/bolt/rerun.rb +1 -5
  46. data/lib/bolt/shell/bash.rb +8 -2
  47. data/lib/bolt/shell/powershell.rb +17 -1
  48. data/lib/bolt/task/run.rb +1 -1
  49. data/lib/bolt/transport/orch.rb +0 -5
  50. data/lib/bolt/transport/orch/connection.rb +10 -3
  51. data/lib/bolt/transport/remote.rb +1 -1
  52. data/lib/bolt/transport/ssh/exec_connection.rb +6 -2
  53. data/lib/bolt/util.rb +41 -7
  54. data/lib/bolt/version.rb +1 -1
  55. data/lib/bolt/yarn.rb +23 -0
  56. data/lib/bolt_server/base_config.rb +3 -1
  57. data/lib/bolt_server/config.rb +3 -1
  58. data/lib/bolt_server/file_cache.rb +2 -0
  59. data/lib/bolt_server/plugin.rb +13 -0
  60. data/lib/bolt_server/plugin/puppet_connect_data.rb +37 -0
  61. data/lib/bolt_server/schemas/connect-data.json +22 -0
  62. data/lib/bolt_server/schemas/partials/task.json +2 -2
  63. data/lib/bolt_server/transport_app.rb +72 -13
  64. data/lib/bolt_spec/plans/mock_executor.rb +4 -1
  65. data/libexec/apply_catalog.rb +1 -1
  66. data/libexec/custom_facts.rb +1 -1
  67. data/libexec/query_resources.rb +1 -1
  68. metadata +15 -13
  69. data/lib/bolt/project_migrator.rb +0 -80
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf27b6c8b1a7e3cfb2eb61617bd7ab4927161c577df4915d959182fd8bce7eaf
4
- data.tar.gz: '05578a39ce18d1d63bf9455c8890e1e328bdcb3f52dacc3d6d5047251bca833e'
3
+ metadata.gz: 2cbd90e42181c76bad4eee913ee67369202296852cfa5153a1f5490def4e77d3
4
+ data.tar.gz: 87ac43d10edeebefaa31f581f49cbcf9f729e25f5d7efec583e09dcf04f97be6
5
5
  SHA512:
6
- metadata.gz: 11b3fad81f576fa435b570b15ee7cbab14b7c099b4b179770eb20dbc7f2a2db9b2d2de6c4a52eb09021a9794d13c4da704eb3a2ed362cfd50ab1946e7ef5998d
7
- data.tar.gz: 300b9fa2214a66d239218b7a8c12518a97c2cf2fafd401c860a3ff9cdd439355608b30d72d5a82f157eea842a25a7c5bc9d484dd9f616837ebfe4beff26c0795
6
+ metadata.gz: 392f0d453c49a536852692e873e5c5f55807294fa0bd914593722c26d39459e494b83453a3b995319b04b8f2e6f3a1f04f7661400841192bdffc56df47e4170e
7
+ data.tar.gz: 750cd8e9c29008e8bb4dfc7350d52a268c01d91fa088e9007ff241648e31a90e76d9cabfef9f1db5675d33f6b82b2898a54f758bc21c17c18d888919d0441807
data/Puppetfile CHANGED
@@ -7,7 +7,7 @@ moduledir File.join(File.dirname(__FILE__), 'modules')
7
7
  # Core modules used by 'apply'
8
8
  mod 'puppetlabs-service', '1.3.0'
9
9
  mod 'puppetlabs-puppet_agent', '4.2.0'
10
- mod 'puppetlabs-facts', '1.1.0'
10
+ mod 'puppetlabs-facts', '1.2.0'
11
11
 
12
12
  # Core types and providers for Puppet 6
13
13
  mod 'puppetlabs-augeas_core', '1.1.1'
@@ -12,6 +12,7 @@ Puppet::DataTypes.create_type('ApplyResult') do
12
12
  message => Callable[[], Optional[String]],
13
13
  action => Callable[[], String],
14
14
  to_data => Callable[[], Hash],
15
+ value => Callable[[], Hash]
15
16
  }
16
17
  PUPPET
17
18
 
@@ -44,9 +44,7 @@ Puppet::Functions.create_function(:catch_errors) do
44
44
  yield
45
45
  rescue Puppet::PreformattedError => e
46
46
  if e.cause.is_a?(Bolt::Error)
47
- if error_types.nil?
48
- e.cause.to_puppet_error
49
- elsif error_types.include?(e.cause.to_h['kind'])
47
+ if error_types.nil? || error_types.include?(e.cause.to_h['kind'])
50
48
  e.cause.to_puppet_error
51
49
  else
52
50
  raise e
@@ -110,14 +110,25 @@ Puppet::Functions.create_function(:download_file, Puppet::Functions::InternalFun
110
110
  targets = inventory.get_targets(targets)
111
111
  if targets.empty?
112
112
  call_function('debug', "Simulating file download of '#{source}' - no targets given - no action taken")
113
- r = Bolt::ResultSet.new([])
113
+ Bolt::ResultSet.new([])
114
114
  else
115
- r = executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
116
- end
115
+ r = if executor.in_parallel
116
+ require 'concurrent'
117
+ require 'fiber'
118
+ future = Concurrent::Future.execute do
119
+ executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
120
+ end
121
+
122
+ Fiber.yield('unfinished') while future.incomplete?
123
+ future.value || future.reason
124
+ else
125
+ executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
126
+ end
117
127
 
118
- if !r.ok && !options[:catch_errors]
119
- raise Bolt::RunFailure.new(r, 'download_file', source)
128
+ if !r.ok && !options[:catch_errors]
129
+ raise Bolt::RunFailure.new(r, 'download_file', source)
130
+ end
131
+ r
120
132
  end
121
- r
122
133
  end
123
134
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/yarn'
4
+
5
+ # Map a code block onto an array, where each array element executes in parallel.
6
+ # This function is experimental.
7
+ #
8
+ # > **Note:** Not available in apply block.
9
+ Puppet::Functions.create_function(:parallelize, Puppet::Functions::InternalFunction) do
10
+ # Map a block onto an array, where each array element executes in parallel.
11
+ # This function is experimental.
12
+ # @param data The array to apply the block to.
13
+ # @return [Array] An array of PlanResult objects. Each input from the input
14
+ # array returns a corresponding PlanResult object.
15
+ # @example Execute two tasks on multiple targets. Once the task finishes on one
16
+ # target, that target can move to the next step without waiting for the task
17
+ # to finish on the second target.
18
+ # $targets = get_targets(["host1", "host2"])
19
+ # $result = parallelize ($targets) |$t| {
20
+ # run_task('a', $t)
21
+ # run_task('b', $t)
22
+ # }
23
+ dispatch :parallelize do
24
+ scope_param
25
+ param 'Array[Any]', :data
26
+ block_param 'Callable[Any]', :block
27
+ return_type 'Array[Boltlib::PlanResult]'
28
+ end
29
+
30
+ def parallelize(scope, data, &block)
31
+ unless Puppet[:tasks]
32
+ raise Puppet::ParseErrorWithIssue
33
+ .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'parallelize')
34
+ end
35
+
36
+ executor = Puppet.lookup(:bolt_executor)
37
+ executor.report_function_call(self.class.name)
38
+
39
+ skein = data.each_with_index.map do |object, index|
40
+ executor.create_yarn(scope, block, object, index)
41
+ end
42
+
43
+ result = executor.round_robin(skein)
44
+
45
+ failed_indices = result.each_index.select do |i|
46
+ result[i].is_a?(Bolt::Error)
47
+ end
48
+
49
+ # TODO: Inner catch errors block?
50
+ if failed_indices.any?
51
+ raise Bolt::ParallelFailure.new(result, failed_indices)
52
+ end
53
+
54
+ result
55
+ end
56
+ end
@@ -67,14 +67,32 @@ Puppet::Functions.create_function(:run_command) do
67
67
 
68
68
  if targets.empty?
69
69
  call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
70
- r = Bolt::ResultSet.new([])
70
+ Bolt::ResultSet.new([])
71
71
  else
72
- r = executor.run_command(targets, command, options, Puppet::Pops::PuppetStack.top_of_stack)
73
- end
72
+ r = if executor.in_parallel
73
+ require 'concurrent'
74
+ require 'fiber'
75
+ future = Concurrent::Future.execute do
76
+ executor.run_command(targets,
77
+ command,
78
+ options,
79
+ Puppet::Pops::PuppetStack.top_of_stack)
80
+ end
81
+
82
+ Fiber.yield('unfinished') while future.incomplete?
83
+ future.value || future.reason
84
+ else
85
+ executor.run_command(targets,
86
+ command,
87
+ options,
88
+ Puppet::Pops::PuppetStack.top_of_stack)
89
+ end
90
+
91
+ if !r.ok && !options[:catch_errors]
92
+ raise Bolt::RunFailure.new(r, 'run_command', command)
93
+ end
74
94
 
75
- if !r.ok && !options[:catch_errors]
76
- raise Bolt::RunFailure.new(r, 'run_command', command)
95
+ r
77
96
  end
78
- r
79
97
  end
80
98
  end
@@ -84,15 +84,34 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
84
84
  # Ensure that given targets are all Target instances)
85
85
  targets = inventory.get_targets(targets)
86
86
 
87
- r = if targets.empty?
88
- Bolt::ResultSet.new([])
89
- else
90
- executor.run_script(targets, found, arguments, options, Puppet::Pops::PuppetStack.top_of_stack)
91
- end
87
+ if targets.empty?
88
+ Bolt::ResultSet.new([])
89
+ else
90
+ r = if executor.in_parallel
91
+ require 'concurrent'
92
+ require 'fiber'
93
+ future = Concurrent::Future.execute do
94
+ executor.run_script(targets,
95
+ found,
96
+ arguments,
97
+ options,
98
+ Puppet::Pops::PuppetStack.top_of_stack)
99
+ end
92
100
 
93
- if !r.ok && !options[:catch_errors]
94
- raise Bolt::RunFailure.new(r, 'run_script', script)
101
+ Fiber.yield('unfinished') while future.incomplete?
102
+ future.value || future.reason
103
+ else
104
+ executor.run_script(targets,
105
+ found,
106
+ arguments,
107
+ options,
108
+ Puppet::Pops::PuppetStack.top_of_stack)
109
+ end
110
+
111
+ if !r.ok && !options[:catch_errors]
112
+ raise Bolt::RunFailure.new(r, 'run_script', script)
113
+ end
114
+ r
95
115
  end
96
- r
97
116
  end
98
117
  end
@@ -133,7 +133,27 @@ Puppet::Functions.create_function(:run_task) do
133
133
  if targets.empty?
134
134
  Bolt::ResultSet.new([])
135
135
  else
136
- result = executor.run_task(targets, task, params, options, Puppet::Pops::PuppetStack.top_of_stack)
136
+ result = if executor.in_parallel
137
+ require 'concurrent'
138
+ require 'fiber'
139
+ future = Concurrent::Future.execute do
140
+ executor.run_task(targets,
141
+ task,
142
+ params,
143
+ options,
144
+ Puppet::Pops::PuppetStack.top_of_stack)
145
+ end
146
+
147
+ Fiber.yield('unfinished') while future.incomplete?
148
+ future.value || future.reason
149
+ else
150
+ executor.run_task(targets,
151
+ task,
152
+ params,
153
+ options,
154
+ Puppet::Pops::PuppetStack.top_of_stack)
155
+ end
156
+
137
157
  if !result.ok && !options[:catch_errors]
138
158
  raise Bolt::RunFailure.new(result, 'run_task', task_name)
139
159
  end
@@ -180,7 +180,24 @@ Puppet::Functions.create_function(:run_task_with) do
180
180
  else
181
181
  # Combine the results from the task run with any failing results that were
182
182
  # generated earlier when creating the target mapping
183
- task_result = executor.run_task_with(target_mapping, task, options, Puppet::Pops::PuppetStack.top_of_stack)
183
+ task_result = if executor.in_parallel
184
+ require 'concurrent'
185
+ require 'fiber'
186
+ future = Concurrent::Future.execute do
187
+ executor.run_task_with(target_mapping,
188
+ task,
189
+ options,
190
+ Puppet::Pops::PuppetStack.top_of_stack)
191
+ end
192
+
193
+ Fiber.yield('unfinished') while future.incomplete?
194
+ future.value || future.reason
195
+ else
196
+ executor.run_task_with(target_mapping,
197
+ task,
198
+ options,
199
+ Puppet::Pops::PuppetStack.top_of_stack)
200
+ end
184
201
  result = Bolt::ResultSet.new(task_result.results + error_set)
185
202
 
186
203
  if !result.ok && !options[:catch_errors]
@@ -81,14 +81,32 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
81
81
  targets = inventory.get_targets(targets)
82
82
  if targets.empty?
83
83
  call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
84
- r = Bolt::ResultSet.new([])
84
+ Bolt::ResultSet.new([])
85
85
  else
86
- r = executor.upload_file(targets, found, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
87
- end
86
+ r = if executor.in_parallel
87
+ require 'concurrent'
88
+ require 'fiber'
89
+ future = Concurrent::Future.execute do
90
+ executor.upload_file(targets,
91
+ found,
92
+ destination,
93
+ options,
94
+ Puppet::Pops::PuppetStack.top_of_stack)
95
+ end
88
96
 
89
- if !r.ok && !options[:catch_errors]
90
- raise Bolt::RunFailure.new(r, 'upload_file', source)
97
+ Fiber.yield('unfinished') while future.incomplete?
98
+ future.value || future.reason
99
+ else
100
+ executor.upload_file(targets,
101
+ found,
102
+ destination,
103
+ options,
104
+ Puppet::Pops::PuppetStack.top_of_stack)
105
+ end
106
+ if !r.ok && !options[:catch_errors]
107
+ raise Bolt::RunFailure.new(r, 'upload_file', source)
108
+ end
109
+ r
91
110
  end
92
- r
93
111
  end
94
112
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'bolt/util'
4
4
  require 'bolt/version'
5
+ require 'find'
5
6
  require 'json'
6
7
  require 'logging'
7
8
  require 'securerandom'
@@ -23,14 +24,16 @@ module Bolt
23
24
  plan_steps: :cd8,
24
25
  return_type: :cd9,
25
26
  inventory_version: :cd10,
26
- boltdir_type: :cd11
27
+ boltdir_type: :cd11,
28
+ puppet_plan_count: :cd12,
29
+ yaml_plan_count: :cd13
27
30
  }.freeze
28
31
 
29
32
  def self.build_client
30
33
  logger = Bolt::Logger.logger(self)
31
34
  begin
32
- config_file = config_path(logger)
33
- config = load_config(config_file, logger)
35
+ config_file = config_path
36
+ config = load_config(config_file)
34
37
  rescue ArgumentError
35
38
  config = { 'disabled' => true }
36
39
  end
@@ -51,7 +54,7 @@ module Bolt
51
54
  NoopClient.new
52
55
  end
53
56
 
54
- def self.config_path(logger)
57
+ def self.config_path
55
58
  path = File.expand_path(File.join('~', '.puppetlabs', 'etc', 'bolt', 'analytics.yaml'))
56
59
  old_path = File.expand_path(File.join('~', '.puppetlabs', 'bolt', 'analytics.yaml'))
57
60
 
@@ -59,7 +62,7 @@ module Bolt
59
62
  if File.exist?(old_path)
60
63
  message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading "\
61
64
  "analytics configuration from '#{path}'."
62
- logger.warn(message)
65
+ Bolt::Logger.warn_once('duplicate_analytics', message)
63
66
  end
64
67
 
65
68
  path
@@ -70,12 +73,12 @@ module Bolt
70
73
  end
71
74
  end
72
75
 
73
- def self.load_config(filename, logger)
76
+ def self.load_config(filename)
74
77
  if File.exist?(filename)
75
78
  Bolt::Util.read_optional_yaml_hash(filename, 'analytics')
76
79
  else
77
80
  unless ENV['BOLT_DISABLE_ANALYTICS']
78
- logger.warn <<~ANALYTICS
81
+ Bolt::Logger.warn_once('analytics_opt_out', <<~ANALYTICS)
79
82
  Bolt collects data about how you use it. You can opt out of providing this data.
80
83
 
81
84
  To disable analytics data collection, add this line to ~/.puppetlabs/etc/bolt/analytics.yaml :
@@ -134,11 +137,23 @@ module Bolt
134
137
  end
135
138
 
136
139
  def report_bundled_content(mode, name)
137
- if bundled_content[mode.split(' ').first]&.include?(name)
140
+ if bundled_content[mode.split.first]&.include?(name)
138
141
  event('Bundled Content', mode, label: name)
139
142
  end
140
143
  end
141
144
 
145
+ def plan_counts(plans_path)
146
+ pp_count, yaml_count = if File.exist?(plans_path)
147
+ %w[pp yaml].map do |extension|
148
+ Find.find(plans_path.to_s).grep(/.*\.#{extension}/).length
149
+ end
150
+ else
151
+ [0, 0]
152
+ end
153
+
154
+ { puppet_plan_count: pp_count, yaml_plan_count: yaml_count }
155
+ end
156
+
142
157
  def event(category, action, label: nil, value: nil, **kwargs)
143
158
  custom_dimensions = Bolt::Util.walk_keys(kwargs) do |k|
144
159
  CUSTOM_DIMENSIONS[k] || raise("Unknown analytics key '#{k}'")
@@ -224,6 +239,10 @@ module Bolt
224
239
 
225
240
  def report_bundled_content(mode, name); end
226
241
 
242
+ def plan_counts(_)
243
+ {}
244
+ end
245
+
227
246
  def event(category, action, **_kwargs)
228
247
  @logger.trace "Skipping submission of '#{category} #{action}' event because analytics is disabled"
229
248
  end
@@ -96,9 +96,9 @@ module Bolt
96
96
  @target = target
97
97
  @value = {}
98
98
  @action = 'apply'
99
- value['report'] = report if report
100
- value['_error'] = error if error
101
- value['_output'] = metrics_message if metrics_message
99
+ @value['report'] = report if report
100
+ @value['_error'] = error if error
101
+ @value['_output'] = metrics_message if metrics_message
102
102
  end
103
103
 
104
104
  def event_metrics
@@ -6,14 +6,15 @@ require 'optparse'
6
6
 
7
7
  module Bolt
8
8
  class BoltOptionParser < OptionParser
9
+ PROJECT_PATHS = %w[project configfile boltdir].freeze
9
10
  OPTIONS = { inventory: %w[targets query rerun description],
10
11
  authentication: %w[user password password-prompt private-key host-key-check ssl ssl-verify],
11
12
  escalation: %w[run-as sudo-password sudo-password-prompt sudo-executable],
12
13
  run_context: %w[concurrency inventoryfile save-rerun cleanup],
13
- global_config_setters: %w[modulepath project configfile],
14
+ global_config_setters: PROJECT_PATHS + %w[modulepath],
14
15
  transports: %w[transport connect-timeout tty native-ssh ssh-command copy-command],
15
16
  display: %w[format color verbose trace],
16
- global: %w[help version debug log-level] }.freeze
17
+ global: %w[help version debug log-level clear-cache] }.freeze
17
18
 
18
19
  ACTION_OPTS = OPTIONS.values.flatten.freeze
19
20
 
@@ -46,7 +47,8 @@ module Bolt
46
47
  when 'inventory'
47
48
  case action
48
49
  when 'show'
49
- { flags: OPTIONS[:inventory] + OPTIONS[:global] + %w[format inventoryfile boltdir configfile detail],
50
+ { flags: OPTIONS[:inventory] + OPTIONS[:global] +
51
+ PROJECT_PATHS + %w[format inventoryfile detail],
50
52
  banner: INVENTORY_SHOW_HELP }
51
53
  else
52
54
  { flags: OPTIONS[:global],
@@ -55,7 +57,7 @@ module Bolt
55
57
  when 'group'
56
58
  case action
57
59
  when 'show'
58
- { flags: OPTIONS[:global] + %w[format inventoryfile boltdir configfile],
60
+ { flags: OPTIONS[:global] + PROJECT_PATHS + %w[format inventoryfile],
59
61
  banner: GROUP_SHOW_HELP }
60
62
  else
61
63
  { flags: OPTIONS[:global],
@@ -67,13 +69,13 @@ module Bolt
67
69
  when 'module'
68
70
  case action
69
71
  when 'add'
70
- { flags: OPTIONS[:global] + %w[configfile project],
72
+ { flags: OPTIONS[:global] + PROJECT_PATHS,
71
73
  banner: MODULE_ADD_HELP }
72
74
  when 'generate-types'
73
75
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
74
76
  banner: MODULE_GENERATETYPES_HELP }
75
77
  when 'install'
76
- { flags: OPTIONS[:global] + %w[configfile force project resolve],
78
+ { flags: OPTIONS[:global] + PROJECT_PATHS + %w[force resolve],
77
79
  banner: MODULE_INSTALL_HELP }
78
80
  when 'show'
79
81
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
@@ -88,7 +90,7 @@ module Bolt
88
90
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
89
91
  banner: PLAN_CONVERT_HELP }
90
92
  when 'new'
91
- { flags: OPTIONS[:global] + %w[configfile project],
93
+ { flags: OPTIONS[:global] + PROJECT_PATHS + %w[pp],
92
94
  banner: PLAN_NEW_HELP }
93
95
  when 'run'
94
96
  { flags: ACTION_OPTS + %w[params compile-concurrency tmpdir hiera-config],
@@ -106,7 +108,7 @@ module Bolt
106
108
  { flags: OPTIONS[:global] + %w[modules],
107
109
  banner: PROJECT_INIT_HELP }
108
110
  when 'migrate'
109
- { flags: OPTIONS[:global] + %w[inventoryfile project configfile],
111
+ { flags: OPTIONS[:global] + PROJECT_PATHS + %w[inventoryfile],
110
112
  banner: PROJECT_MIGRATE_HELP }
111
113
  else
112
114
  { flags: OPTIONS[:global],
@@ -793,7 +795,10 @@ module Bolt
793
795
  @options[:noop] = true
794
796
  end
795
797
  define('--description DESCRIPTION',
796
- 'Description to use for the job') do |description|
798
+ 'Deprecated. Description to use for the job') do |description|
799
+ msg = "Command line option '--description' is deprecated, and will be "\
800
+ "removed in Bolt 3.0."
801
+ @deprecations << { type: 'Using --description', msg: msg }
797
802
  @options[:description] = description
798
803
  end
799
804
  define('--params PARAMETERS',
@@ -873,13 +878,25 @@ module Bolt
873
878
  File.expand_path(moduledir)
874
879
  end
875
880
  end
876
- define('--project PATH', '--boltdir PATH',
877
- 'Specify what project to load config from (default: autodiscovered from current working dir)') do |path|
881
+ define('--boltdir PATH',
882
+ 'Deprecated. Specify what project to load config from (default:',
883
+ 'autodiscovered from current working dir)') do |path|
884
+ msg = "Command line option '--boltdir' is deprecated, use '--project' instead."
885
+ @deprecations << { type: 'Using --boltdir', msg: msg }
878
886
  @options[:boltdir] = path
879
887
  end
888
+ define('--project PATH',
889
+ 'Path to load the Bolt project from (default: autodiscovered from current dir)') do |path|
890
+ @options[:project] = path
891
+ end
880
892
  define('--configfile PATH',
881
- 'Specify where to load config from (default: ~/.puppetlabs/bolt/bolt.yaml).',
882
- 'Directory containing bolt.yaml will be used as the project directory.') do |path|
893
+ 'Deprecated. Specify where to load config from (default:',
894
+ '~/.puppetlabs/bolt/bolt.yaml). Directory containing bolt.yaml will be',
895
+ 'used as the project directory.') do |path|
896
+ msg = "Command line option '--configfile' is deprecated, and " \
897
+ "will be removed in Bolt 3.0. Use '--project' and provide the "\
898
+ "directory path instead."
899
+ @deprecations << { type: 'Using --configfile', msg: msg }
883
900
  @options[:configfile] = path
884
901
  end
885
902
  define('--hiera-config PATH',
@@ -891,12 +908,18 @@ module Bolt
891
908
  if ENV.include?(Bolt::Inventory::ENVIRONMENT_VAR)
892
909
  raise Bolt::CLIError, "Cannot pass inventory file when #{Bolt::Inventory::ENVIRONMENT_VAR} is set"
893
910
  end
894
- @options[:inventoryfile] = Pathname.new(File.expand_path(path))
911
+ @options[:inventoryfile] = File.expand_path(path)
895
912
  end
896
913
  define('--puppetfile PATH',
897
- 'Specify a Puppetfile to use when installing modules. (default: ~/.puppetlabs/bolt/Puppetfile)',
914
+ 'Deprecated. Specify a Puppetfile to use when installing modules.',
915
+ ' (default: ~/.puppetlabs/bolt/Puppetfile)',
898
916
  'Modules are installed in the current project.') do |path|
899
- @options[:puppetfile_path] = Pathname.new(File.expand_path(path))
917
+ command = Bolt::Util.powershell? ? 'Update-BoltProject' : 'bolt project migrate'
918
+ msg = "Command line option '--puppetfile' is deprecated, and will be removed "\
919
+ "in Bolt 3.0. You can migrate to using the new module management "\
920
+ "workflow using '#{command}'."
921
+ @deprecations << { type: 'Using --puppetfile', msg: msg }
922
+ @options[:puppetfile_path] = File.expand_path(path)
900
923
  end
901
924
  define('--[no-]save-rerun', 'Whether to update the rerun file after this command.') do |save|
902
925
  @options[:'save-rerun'] = save
@@ -945,6 +968,11 @@ module Bolt
945
968
  @options[:resolve] = resolve
946
969
  end
947
970
 
971
+ separator "\nPLAN OPTIONS"
972
+ define('--pp', 'Create a new Puppet language plan.') do |_|
973
+ @options[:puppet] = true
974
+ end
975
+
948
976
  separator "\nDISPLAY OPTIONS"
949
977
  define('--filter FILTER', 'Filter tasks and plans by a matching substring') do |filter|
950
978
  unless /^[a-z0-9_:]+$/.match(filter)
@@ -997,6 +1025,10 @@ module Bolt
997
1025
  "trace, debug, info, warn, error, fatal, any.") do |level|
998
1026
  @options[:log] = { 'console' => { 'level' => level } }
999
1027
  end
1028
+ define('--clear-cache',
1029
+ "Clear plugin cache before executing") do |_|
1030
+ @options[:clear_cache] = true
1031
+ end
1000
1032
  define('--plugin PLUGIN', 'Select the plugin to use') do |plug|
1001
1033
  @options[:plugin] = plug
1002
1034
  end