bolt 3.29.0 → 3.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b5a8936e9789e8d1a722b5cc76cedf594a8f09709352b95ed6e423f0d7ddc6e
4
- data.tar.gz: ef052d1f831ba328d6949a1f33ec617f933f2f28e862d23264ed1dfd9b43b0a6
3
+ metadata.gz: 80dd0d96ead6ae1cddc50bfd8381ea7cdce56a521afa475108589066dcd75f39
4
+ data.tar.gz: bee19d728cf36384d22e1c69eff95e05c58bc08b9186c6542ca3bc07effcb8d6
5
5
  SHA512:
6
- metadata.gz: f1eeec5f42a0f82a751d5eaa834a42e66d26080a0250e680d4c6328e7fb3a2048f13093d65dc6a7d55220963d8178cbaee7744643f17dd82af44d92b3187c3a6
7
- data.tar.gz: 6cd501114d6efc60a26df945e528b03a610018c287a9e03b722f15da5a37680655df1dc953702922e0c306376adcb9e536b30f6aedb1b24a4efe9e97fc3da504
6
+ metadata.gz: a3a05e9ee13b0e24f951268f0d27d5e6ba5d26df4f21f96f0f1f2c6fe37df5db83bab32114d5ebc2cfebe806ee0fde992c1e8a69d254f960ce7e1a79f31300fb
7
+ data.tar.gz: 5b3a8b35ddde08c7c89c1b97421b987e37cfdc973cb08a5ae1dcc36cbbefd6c4b3d81db058406d490958fc0718b8cec23d9536b68f2e5af023990e0f43506b78
@@ -6,7 +6,7 @@ Puppet::Functions.create_function(:'ctrl::do_until') do
6
6
  # @param block The code block to repeat.
7
7
  # @option options [Numeric] limit The number of times to repeat the block.
8
8
  # @option options [Numeric] interval The number of seconds to wait before repeating the block.
9
- # @return [nil]
9
+ # @return The value of the code block's last iteration
10
10
  # @example Run a task until it succeeds
11
11
  # ctrl::do_until() || {
12
12
  # run_task('test', $target, '_catch_errors' => true).ok()
@@ -284,6 +284,9 @@ module Bolt
284
284
  'catalog' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(catalog),
285
285
  'plugins' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(plugins),
286
286
  'apply_settings' => @apply_settings,
287
+ # This should just be boltlib and modules dirs shipped with bolt packages
288
+ # The apply_catalog task uses them to load core types if they exist
289
+ 'bolt_builtin_content' => @modulepath - @plugin_dirs,
287
290
  '_task' => catalog_apply_task.name,
288
291
  '_noop' => options[:noop]
289
292
  }
@@ -11,7 +11,9 @@ module Bolt
11
11
  cleanup
12
12
  interpreters
13
13
  remote
14
+ shell-command
14
15
  tmpdir
16
+ tty
15
17
  ].concat(RUN_AS_OPTIONS).sort.freeze
16
18
 
17
19
  DEFAULTS = {
@@ -332,7 +332,7 @@ module Bolt
332
332
  },
333
333
  "shell-command" => {
334
334
  type: String,
335
- description: "A shell command to wrap any Docker exec commands in, such as `bash -lc`.",
335
+ description: "A shell command to wrap any exec commands in, such as `bash -lc`.",
336
336
  _plugin: true,
337
337
  _example: "bash -lc"
338
338
  },
@@ -14,6 +14,10 @@ module Bolt
14
14
  EXTENDED_TARGET_REGEX = /[[:space:],]+(?=[^\]}]*(?:[\[{]|$))/.freeze
15
15
  TARGET_REGEX = /[[:space:],]+/.freeze
16
16
 
17
+ # Pattern which looks for indicators that glob-based target name matching
18
+ # should be used.
19
+ GLOB_MATCH_REGEX = /[*?\[\]{}]/.freeze
20
+
17
21
  class WildcardError < Bolt::Error
18
22
  def initialize(target)
19
23
  super("Found 0 targets matching wildcard pattern #{target}", 'bolt.inventory/wildcard-error')
@@ -119,19 +123,36 @@ module Bolt
119
123
  if ext_glob
120
124
  File.fnmatch(wildcard, target_name, File::FNM_CASEFOLD | File::FNM_EXTGLOB)
121
125
  else
122
- regexp = Regexp.new("^#{Regexp.escape(wildcard).gsub('\*', '.*?')}$", Regexp::IGNORECASE)
123
- target_name =~ regexp
126
+ File.fnmatch(wildcard, target_name, File::FNM_CASEFOLD)
124
127
  end
125
128
  end
126
129
 
127
130
  # If target is a group name, expand it to the members of that group.
128
131
  # Else match against groups and targets in inventory by name or alias.
129
- # If a wildcard string, error if no matches are found.
132
+ # Attempt exact matches for groups, targets, and aliases first for speed.
133
+ # If no exact match and the string contains wildcard characters, then check
134
+ # and see if the target string might be a URI, if it parses as a URI with
135
+ # a scheme then return as-is, otherwise look for a wildcard match and
136
+ # error if no matches are found.
130
137
  # Else fall back to [target] if no matches are found.
131
138
  def resolve_name(target, ext_glob: false)
132
139
  if (group = group_lookup[target])
133
140
  group.all_targets.to_a
134
- else
141
+ elsif @targets.key?(target)
142
+ [target]
143
+ elsif (real_target = groups.target_aliases[target])
144
+ [real_target]
145
+ elsif GLOB_MATCH_REGEX.match?(target)
146
+ # URIs and glob wildcards have some overlapping characters. If the target
147
+ # being resolved parses as a valid target URI and has a scheme defined then
148
+ # return it as-is and do not try to do further wildcard matching:
149
+ uri = begin
150
+ Bolt::Inventory::Target.parse_uri(target)
151
+ rescue Bolt::ParseError
152
+ nil
153
+ end
154
+ return [target] if uri&.scheme
155
+
135
156
  targets = []
136
157
 
137
158
  # Find groups that match the glob
@@ -148,12 +169,11 @@ module Bolt
148
169
  .select { |tgt_alias, _| match_wildcard?(target, tgt_alias, ext_glob: ext_glob) }
149
170
  .values
150
171
 
151
- if targets.empty?
152
- raise(WildcardError, target) if target.include?('*')
153
- [target]
154
- else
155
- targets.uniq
156
- end
172
+ raise(WildcardError, target) if targets.empty?
173
+
174
+ targets.uniq
175
+ else # rubocop:disable Lint/DuplicateBranch
176
+ [target]
157
177
  end
158
178
  end
159
179
  private :resolve_name
@@ -34,7 +34,7 @@ module Bolt
34
34
  @name = @uri
35
35
  @safe_name = @uri_obj.omit(:password).to_str.sub(%r{^//}, '')
36
36
  end
37
-
37
+ # handle special localhost target
38
38
  if @name == 'localhost'
39
39
  default = { 'config' => { 'transport' => 'local' } }
40
40
  target_data = Bolt::Util.deep_merge(default, target_data)
@@ -53,6 +53,8 @@ module Bolt
53
53
  @inventory = inventory
54
54
 
55
55
  validate
56
+ # after setting config, apply local defaults when using bundled ruby
57
+ set_local_defaults if transport_config['bundled-ruby']
56
58
  end
57
59
 
58
60
  def set_local_defaults
data/lib/bolt/target.rb CHANGED
@@ -80,10 +80,6 @@ module Bolt
80
80
  inventory_target.resources
81
81
  end
82
82
 
83
- def set_local_defaults
84
- inventory_target.set_local_defaults
85
- end
86
-
87
83
  # rubocop:disable Naming/AccessorMethodName
88
84
  def set_resource(resource)
89
85
  inventory_target.set_resource(resource)
@@ -11,10 +11,6 @@ module Bolt
11
11
  end
12
12
 
13
13
  def with_connection(target)
14
- if target.transport_config['bundled-ruby']
15
- target.set_local_defaults
16
- end
17
-
18
14
  yield Connection.new(target)
19
15
  end
20
16
  end
@@ -57,12 +57,24 @@ module Bolt
57
57
  end
58
58
 
59
59
  def execute(command)
60
- lxc_command = %w[lxc exec]
60
+ lxc_command = %W[lxc exec #{container_id}]
61
+ lxc_command += ['--mode', target.options['tty'].to_s.empty? ? 'non-interactive' : 'interactive']
61
62
  lxc_command += @env_vars if @env_vars
62
- lxc_command += %W[#{container_id} -- sh -c #{Shellwords.shellescape(command)}]
63
+ lxc_command << '--'
64
+
65
+ if target.options['shell-command'].to_s.empty?
66
+ lxc_command += Shellwords.split(command)
67
+ else
68
+ lxc_command += Shellwords.split(target.options['shell-command'])
69
+ lxc_command << command
70
+ end
63
71
 
64
72
  @logger.trace { "Executing: #{lxc_command.join(' ')}" }
65
- Open3.popen3(lxc_command.join(' '))
73
+
74
+ Open3.popen3(*lxc_command)
75
+ rescue StandardError
76
+ @logger.trace { "Command aborted" }
77
+ raise
66
78
  end
67
79
 
68
80
  private def execute_local_command(command)
data/lib/bolt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '3.29.0'
4
+ VERSION = '3.30.0'
5
5
  end
@@ -52,6 +52,19 @@ begin
52
52
  $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
53
53
  end
54
54
 
55
+ # In the case we are applying on a bolt runner and using bundled-ruby over local transport
56
+ # we will want to load code shipped with bolt. This is last on the load path and therefore
57
+ # explicitly packaged plugins should take precedence
58
+ args['bolt_builtin_content'].each do |builtin_dir|
59
+ next unless Dir.exist?(builtin_dir)
60
+ Dir.foreach(builtin_dir) do |dir|
61
+ unless ['.', '..'].include? dir
62
+ full_path = File.join(builtin_dir, dir, 'lib')
63
+ $LOAD_PATH << full_path unless $LOAD_PATH.include?(full_path)
64
+ end
65
+ end
66
+ end
67
+
55
68
  if (conn_info = args['_target'])
56
69
  unless (type = conn_info['remote-transport'])
57
70
  puts "Cannot execute a catalog for a remote target without knowing it's the remote-transport type."
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bolt
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.29.0
4
+ version: 3.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-17 00:00:00.000000000 Z
11
+ date: 2024-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -366,58 +366,82 @@ dependencies:
366
366
  name: octokit
367
367
  requirement: !ruby/object:Gem::Requirement
368
368
  requirements:
369
- - - "~>"
369
+ - - ">="
370
370
  - !ruby/object:Gem::Version
371
371
  version: '4.0'
372
+ - - "<"
373
+ - !ruby/object:Gem::Version
374
+ version: '9'
372
375
  type: :development
373
376
  prerelease: false
374
377
  version_requirements: !ruby/object:Gem::Requirement
375
378
  requirements:
376
- - - "~>"
379
+ - - ">="
377
380
  - !ruby/object:Gem::Version
378
381
  version: '4.0'
382
+ - - "<"
383
+ - !ruby/object:Gem::Version
384
+ version: '9'
379
385
  - !ruby/object:Gem::Dependency
380
386
  name: puppetlabs_spec_helper
381
387
  requirement: !ruby/object:Gem::Requirement
382
388
  requirements:
383
- - - "~>"
389
+ - - ">="
384
390
  - !ruby/object:Gem::Version
385
391
  version: '5.0'
392
+ - - "<"
393
+ - !ruby/object:Gem::Version
394
+ version: '8'
386
395
  type: :development
387
396
  prerelease: false
388
397
  version_requirements: !ruby/object:Gem::Requirement
389
398
  requirements:
390
- - - "~>"
399
+ - - ">="
391
400
  - !ruby/object:Gem::Version
392
401
  version: '5.0'
402
+ - - "<"
403
+ - !ruby/object:Gem::Version
404
+ version: '8'
393
405
  - !ruby/object:Gem::Dependency
394
406
  name: rake
395
407
  requirement: !ruby/object:Gem::Requirement
396
408
  requirements:
397
- - - "~>"
409
+ - - ">="
398
410
  - !ruby/object:Gem::Version
399
411
  version: '12.0'
412
+ - - "<"
413
+ - !ruby/object:Gem::Version
414
+ version: '14'
400
415
  type: :development
401
416
  prerelease: false
402
417
  version_requirements: !ruby/object:Gem::Requirement
403
418
  requirements:
404
- - - "~>"
419
+ - - ">="
405
420
  - !ruby/object:Gem::Version
406
421
  version: '12.0'
422
+ - - "<"
423
+ - !ruby/object:Gem::Version
424
+ version: '14'
407
425
  - !ruby/object:Gem::Dependency
408
426
  name: rspec
409
427
  requirement: !ruby/object:Gem::Requirement
410
428
  requirements:
411
- - - "~>"
429
+ - - ">="
412
430
  - !ruby/object:Gem::Version
413
431
  version: '3.0'
432
+ - - "<"
433
+ - !ruby/object:Gem::Version
434
+ version: '4'
414
435
  type: :development
415
436
  prerelease: false
416
437
  version_requirements: !ruby/object:Gem::Requirement
417
438
  requirements:
418
- - - "~>"
439
+ - - ">="
419
440
  - !ruby/object:Gem::Version
420
441
  version: '3.0'
442
+ - - "<"
443
+ - !ruby/object:Gem::Version
444
+ version: '4'
421
445
  description: Execute commands remotely over SSH and WinRM
422
446
  email:
423
447
  - puppet@puppet.com