bolt 2.32.0 → 2.33.1
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.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +5 -5
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +6 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -1
- data/guides/logging.txt +18 -0
- data/lib/bolt/config/transport/options.rb +1 -1
- data/lib/bolt/error.rb +4 -0
- data/lib/bolt/executor.rb +12 -12
- data/lib/bolt/module_installer.rb +1 -0
- data/lib/bolt/pal.rb +30 -24
- data/lib/bolt/pal/yaml_plan.rb +4 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +23 -1
- data/lib/bolt/pal/yaml_plan/loader.rb +14 -9
- data/lib/bolt/result.rb +23 -11
- data/lib/bolt/shell/bash.rb +11 -6
- data/lib/bolt/shell/powershell.rb +11 -6
- data/lib/bolt/transport/base.rb +18 -18
- data/lib/bolt/transport/docker.rb +23 -6
- data/lib/bolt/transport/orch.rb +23 -14
- data/lib/bolt/transport/remote.rb +2 -2
- data/lib/bolt/transport/simple.rb +6 -6
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -1
- data/lib/bolt_spec/plans/mock_executor.rb +5 -5
- metadata +3 -3
- data/modules/secure_env_vars/plans/init.pp +0 -20
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: cf27b6c8b1a7e3cfb2eb61617bd7ab4927161c577df4915d959182fd8bce7eaf
         | 
| 4 | 
            +
              data.tar.gz: '05578a39ce18d1d63bf9455c8890e1e328bdcb3f52dacc3d6d5047251bca833e'
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 11b3fad81f576fa435b570b15ee7cbab14b7c099b4b179770eb20dbc7f2a2db9b2d2de6c4a52eb09021a9794d13c4da704eb3a2ed362cfd50ab1946e7ef5998d
         | 
| 7 | 
            +
              data.tar.gz: 300b9fa2214a66d239218b7a8c12518a97c2cf2fafd401c860a3ff9cdd439355608b30d72d5a82f157eea842a25a7c5bc9d484dd9f616837ebfe4beff26c0795
         | 
    
        data/Puppetfile
    CHANGED
    
    | @@ -6,16 +6,16 @@ moduledir File.join(File.dirname(__FILE__), 'modules') | |
| 6 6 |  | 
| 7 7 | 
             
            # Core modules used by 'apply'
         | 
| 8 8 | 
             
            mod 'puppetlabs-service', '1.3.0'
         | 
| 9 | 
            -
            mod 'puppetlabs-puppet_agent', '4. | 
| 9 | 
            +
            mod 'puppetlabs-puppet_agent', '4.2.0'
         | 
| 10 10 | 
             
            mod 'puppetlabs-facts', '1.1.0'
         | 
| 11 11 |  | 
| 12 12 | 
             
            # Core types and providers for Puppet 6
         | 
| 13 13 | 
             
            mod 'puppetlabs-augeas_core', '1.1.1'
         | 
| 14 14 | 
             
            mod 'puppetlabs-host_core', '1.0.3'
         | 
| 15 15 | 
             
            mod 'puppetlabs-scheduled_task', '2.2.1'
         | 
| 16 | 
            -
            mod 'puppetlabs-sshkeys_core', '2. | 
| 17 | 
            -
            mod 'puppetlabs-zfs_core', '1. | 
| 18 | 
            -
            mod 'puppetlabs-cron_core', '1.0. | 
| 16 | 
            +
            mod 'puppetlabs-sshkeys_core', '2.2.0'
         | 
| 17 | 
            +
            mod 'puppetlabs-zfs_core', '1.2.0'
         | 
| 18 | 
            +
            mod 'puppetlabs-cron_core', '1.0.5'
         | 
| 19 19 | 
             
            mod 'puppetlabs-mount_core', '1.0.4'
         | 
| 20 20 | 
             
            mod 'puppetlabs-selinux_core', '1.0.4'
         | 
| 21 21 | 
             
            mod 'puppetlabs-yumrepo_core', '1.0.7'
         | 
| @@ -36,6 +36,7 @@ mod 'puppetlabs-azure_inventory', '0.4.1' | |
| 36 36 | 
             
            mod 'puppetlabs-gcloud_inventory', '0.1.3'
         | 
| 37 37 | 
             
            mod 'puppetlabs-http_request', '0.2.0'
         | 
| 38 38 | 
             
            mod 'puppetlabs-pkcs7', '0.1.1'
         | 
| 39 | 
            +
            mod 'puppetlabs-secure_env_vars', '0.1.0'
         | 
| 39 40 | 
             
            mod 'puppetlabs-terraform', '0.5.0'
         | 
| 40 41 | 
             
            mod 'puppetlabs-vault', '0.3.0'
         | 
| 41 42 | 
             
            mod 'puppetlabs-yaml', '0.2.0'
         | 
| @@ -44,4 +45,3 @@ mod 'puppetlabs-yaml', '0.2.0' | |
| 44 45 | 
             
            mod 'canary', local: true
         | 
| 45 46 | 
             
            mod 'aggregate', local: true
         | 
| 46 47 | 
             
            mod 'puppetdb_fact', local: true
         | 
| 47 | 
            -
            mod 'secure_env_vars', local: true
         | 
| @@ -112,7 +112,7 @@ Puppet::Functions.create_function(:download_file, Puppet::Functions::InternalFun | |
| 112 112 | 
             
                  call_function('debug', "Simulating file download of '#{source}' - no targets given - no action taken")
         | 
| 113 113 | 
             
                  r = Bolt::ResultSet.new([])
         | 
| 114 114 | 
             
                else
         | 
| 115 | 
            -
                  r = executor.download_file(targets, source, destination, options)
         | 
| 115 | 
            +
                  r = executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 116 116 | 
             
                end
         | 
| 117 117 |  | 
| 118 118 | 
             
                if !r.ok && !options[:catch_errors]
         | 
| @@ -3,6 +3,12 @@ | |
| 3 3 | 
             
            require 'bolt/error'
         | 
| 4 4 |  | 
| 5 5 | 
             
            # Returns the facts hash for a target.
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # Using the `facts` function does not automatically collect facts for a target,
         | 
| 8 | 
            +
            # and will only return facts that are currently set in the inventory. To collect
         | 
| 9 | 
            +
            # facts from a target and set them in the inventory, run the
         | 
| 10 | 
            +
            # [facts](writing_plans.md#collect-facts-from-targets) plan or
         | 
| 11 | 
            +
            # [puppetdb_fact](writing_plans.md#collect-facts-from-puppetdb) plan.
         | 
| 6 12 | 
             
            Puppet::Functions.create_function(:facts) do
         | 
| 7 13 | 
             
              # @param target A target.
         | 
| 8 14 | 
             
              # @return The target's facts.
         | 
| @@ -2,12 +2,12 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require 'bolt/error'
         | 
| 4 4 |  | 
| 5 | 
            -
            # Makes a query to  | 
| 5 | 
            +
            # Makes a query to [puppetdb](https://puppet.com/docs/puppetdb/latest/index.html)
         | 
| 6 6 | 
             
            # using Bolt's PuppetDB client.
         | 
| 7 7 | 
             
            Puppet::Functions.create_function(:puppetdb_query) do
         | 
| 8 8 | 
             
              # rubocop:disable Layout/LineLength
         | 
| 9 9 | 
             
              # @param query A PQL query.
         | 
| 10 | 
            -
              #    | 
| 10 | 
            +
              #   Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
         | 
| 11 11 | 
             
              # @return Results of the PuppetDB query.
         | 
| 12 12 | 
             
              # @example Request certnames for all nodes
         | 
| 13 13 | 
             
              #   puppetdb_query('nodes[certname] {}')
         | 
| @@ -69,7 +69,7 @@ Puppet::Functions.create_function(:run_command) do | |
| 69 69 | 
             
                  call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
         | 
| 70 70 | 
             
                  r = Bolt::ResultSet.new([])
         | 
| 71 71 | 
             
                else
         | 
| 72 | 
            -
                  r = executor.run_command(targets, command, options)
         | 
| 72 | 
            +
                  r = executor.run_command(targets, command, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 73 73 | 
             
                end
         | 
| 74 74 |  | 
| 75 75 | 
             
                if !r.ok && !options[:catch_errors]
         | 
| @@ -87,7 +87,7 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti | |
| 87 87 | 
             
                r = if targets.empty?
         | 
| 88 88 | 
             
                      Bolt::ResultSet.new([])
         | 
| 89 89 | 
             
                    else
         | 
| 90 | 
            -
                      executor.run_script(targets, found, arguments, options)
         | 
| 90 | 
            +
                      executor.run_script(targets, found, arguments, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 91 91 | 
             
                    end
         | 
| 92 92 |  | 
| 93 93 | 
             
                if !r.ok && !options[:catch_errors]
         | 
| @@ -133,7 +133,7 @@ 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)
         | 
| 136 | 
            +
                  result = executor.run_task(targets, task, params, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 137 137 | 
             
                  if !result.ok && !options[:catch_errors]
         | 
| 138 138 | 
             
                    raise Bolt::RunFailure.new(result, 'run_task', task_name)
         | 
| 139 139 | 
             
                  end
         | 
| @@ -180,7 +180,7 @@ 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)
         | 
| 183 | 
            +
                  task_result = executor.run_task_with(target_mapping, task, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 184 184 | 
             
                  result = Bolt::ResultSet.new(task_result.results + error_set)
         | 
| 185 185 |  | 
| 186 186 | 
             
                  if !result.ok && !options[:catch_errors]
         | 
| @@ -83,7 +83,7 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct | |
| 83 83 | 
             
                  call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
         | 
| 84 84 | 
             
                  r = Bolt::ResultSet.new([])
         | 
| 85 85 | 
             
                else
         | 
| 86 | 
            -
                  r = executor.upload_file(targets, found, destination, options)
         | 
| 86 | 
            +
                  r = executor.upload_file(targets, found, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
         | 
| 87 87 | 
             
                end
         | 
| 88 88 |  | 
| 89 89 | 
             
                if !r.ok && !options[:catch_errors]
         | 
    
        data/guides/logging.txt
    ADDED
    
    | @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            TOPIC
         | 
| 2 | 
            +
                logging
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            DESCRIPTION
         | 
| 5 | 
            +
                Bolt prints messages both to the console and to log files. Messages can
         | 
| 6 | 
            +
                either come from Bolt's 'outputter', which logs user-facing messages like
         | 
| 7 | 
            +
                progress and results, or from the 'logger', which logs warnings, errors, and
         | 
| 8 | 
            +
                log-structured output to log files. Both of these message streams are
         | 
| 9 | 
            +
                configurable.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                By default, Bolt logs to the console at 'warn' level and writes a log file to
         | 
| 12 | 
            +
                '<project>/bolt-debug.log' at 'debug' level. Unless you are running a plan,
         | 
| 13 | 
            +
                Bolt runs in verbose mode by default.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                To learn more about projects, see the 'project' guide.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            DOCUMENTATION
         | 
| 18 | 
            +
                https://pup.pt/bolt-logging
         | 
    
        data/lib/bolt/error.rb
    CHANGED
    
    
    
        data/lib/bolt/executor.rb
    CHANGED
    
    | @@ -253,33 +253,33 @@ module Bolt | |
| 253 253 | 
             
                  result
         | 
| 254 254 | 
             
                end
         | 
| 255 255 |  | 
| 256 | 
            -
                def run_command(targets, command, options = {})
         | 
| 256 | 
            +
                def run_command(targets, command, options = {}, position = [])
         | 
| 257 257 | 
             
                  description = options.fetch(:description, "command '#{command}'")
         | 
| 258 258 | 
             
                  log_action(description, targets) do
         | 
| 259 259 | 
             
                    options[:run_as] = run_as if run_as && !options.key?(:run_as)
         | 
| 260 260 |  | 
| 261 261 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 262 262 | 
             
                      with_node_logging("Running command '#{command}'", batch) do
         | 
| 263 | 
            -
                        transport.batch_command(batch, command, options, &method(:publish_event))
         | 
| 263 | 
            +
                        transport.batch_command(batch, command, options, position, &method(:publish_event))
         | 
| 264 264 | 
             
                      end
         | 
| 265 265 | 
             
                    end
         | 
| 266 266 | 
             
                  end
         | 
| 267 267 | 
             
                end
         | 
| 268 268 |  | 
| 269 | 
            -
                def run_script(targets, script, arguments, options = {})
         | 
| 269 | 
            +
                def run_script(targets, script, arguments, options = {}, position = [])
         | 
| 270 270 | 
             
                  description = options.fetch(:description, "script #{script}")
         | 
| 271 271 | 
             
                  log_action(description, targets) do
         | 
| 272 272 | 
             
                    options[:run_as] = run_as if run_as && !options.key?(:run_as)
         | 
| 273 273 |  | 
| 274 274 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 275 275 | 
             
                      with_node_logging("Running script #{script} with '#{arguments.to_json}'", batch) do
         | 
| 276 | 
            -
                        transport.batch_script(batch, script, arguments, options, &method(:publish_event))
         | 
| 276 | 
            +
                        transport.batch_script(batch, script, arguments, options, position, &method(:publish_event))
         | 
| 277 277 | 
             
                      end
         | 
| 278 278 | 
             
                    end
         | 
| 279 279 | 
             
                  end
         | 
| 280 280 | 
             
                end
         | 
| 281 281 |  | 
| 282 | 
            -
                def run_task(targets, task, arguments, options = {})
         | 
| 282 | 
            +
                def run_task(targets, task, arguments, options = {}, position = [])
         | 
| 283 283 | 
             
                  description = options.fetch(:description, "task #{task.name}")
         | 
| 284 284 | 
             
                  log_action(description, targets) do
         | 
| 285 285 | 
             
                    options[:run_as] = run_as if run_as && !options.key?(:run_as)
         | 
| @@ -287,13 +287,13 @@ module Bolt | |
| 287 287 |  | 
| 288 288 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 289 289 | 
             
                      with_node_logging("Running task #{task.name} with '#{arguments.to_json}'", batch) do
         | 
| 290 | 
            -
                        transport.batch_task(batch, task, arguments, options, &method(:publish_event))
         | 
| 290 | 
            +
                        transport.batch_task(batch, task, arguments, options, position, &method(:publish_event))
         | 
| 291 291 | 
             
                      end
         | 
| 292 292 | 
             
                    end
         | 
| 293 293 | 
             
                  end
         | 
| 294 294 | 
             
                end
         | 
| 295 295 |  | 
| 296 | 
            -
                def run_task_with(target_mapping, task, options = {})
         | 
| 296 | 
            +
                def run_task_with(target_mapping, task, options = {}, position = [])
         | 
| 297 297 | 
             
                  targets = target_mapping.keys
         | 
| 298 298 | 
             
                  description = options.fetch(:description, "task #{task.name}")
         | 
| 299 299 |  | 
| @@ -303,26 +303,26 @@ module Bolt | |
| 303 303 |  | 
| 304 304 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 305 305 | 
             
                      with_node_logging("Running task #{task.name}'", batch) do
         | 
| 306 | 
            -
                        transport.batch_task_with(batch, task, target_mapping, options, &method(:publish_event))
         | 
| 306 | 
            +
                        transport.batch_task_with(batch, task, target_mapping, options, position, &method(:publish_event))
         | 
| 307 307 | 
             
                      end
         | 
| 308 308 | 
             
                    end
         | 
| 309 309 | 
             
                  end
         | 
| 310 310 | 
             
                end
         | 
| 311 311 |  | 
| 312 | 
            -
                def upload_file(targets, source, destination, options = {})
         | 
| 312 | 
            +
                def upload_file(targets, source, destination, options = {}, position = [])
         | 
| 313 313 | 
             
                  description = options.fetch(:description, "file upload from #{source} to #{destination}")
         | 
| 314 314 | 
             
                  log_action(description, targets) do
         | 
| 315 315 | 
             
                    options[:run_as] = run_as if run_as && !options.key?(:run_as)
         | 
| 316 316 |  | 
| 317 317 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 318 318 | 
             
                      with_node_logging("Uploading file #{source} to #{destination}", batch) do
         | 
| 319 | 
            -
                        transport.batch_upload(batch, source, destination, options, &method(:publish_event))
         | 
| 319 | 
            +
                        transport.batch_upload(batch, source, destination, options, position, &method(:publish_event))
         | 
| 320 320 | 
             
                      end
         | 
| 321 321 | 
             
                    end
         | 
| 322 322 | 
             
                  end
         | 
| 323 323 | 
             
                end
         | 
| 324 324 |  | 
| 325 | 
            -
                def download_file(targets, source, destination, options = {})
         | 
| 325 | 
            +
                def download_file(targets, source, destination, options = {}, position = [])
         | 
| 326 326 | 
             
                  description = options.fetch(:description, "file download from #{source} to #{destination}")
         | 
| 327 327 |  | 
| 328 328 | 
             
                  begin
         | 
| @@ -337,7 +337,7 @@ module Bolt | |
| 337 337 |  | 
| 338 338 | 
             
                    batch_execute(targets) do |transport, batch|
         | 
| 339 339 | 
             
                      with_node_logging("Downloading file #{source} to #{destination}", batch) do
         | 
| 340 | 
            -
                        transport.batch_download(batch, source, destination, options, &method(:publish_event))
         | 
| 340 | 
            +
                        transport.batch_download(batch, source, destination, options, position, &method(:publish_event))
         | 
| 341 341 | 
             
                      end
         | 
| 342 342 | 
             
                    end
         | 
| 343 343 | 
             
                  end
         | 
| @@ -187,6 +187,7 @@ module Bolt | |
| 187 187 | 
             
                  ok = Installer.new(config).install(path, moduledir)
         | 
| 188 188 |  | 
| 189 189 | 
             
                  # Automatically generate types after installing modules
         | 
| 190 | 
            +
                  @outputter.print_action_step("Generating type references")
         | 
| 190 191 | 
             
                  @pal.generate_types
         | 
| 191 192 |  | 
| 192 193 | 
             
                  @outputter.print_puppetfile_result(ok, path, moduledir)
         | 
    
        data/lib/bolt/pal.rb
    CHANGED
    
    | @@ -14,17 +14,11 @@ module Bolt | |
| 14 14 | 
             
                # Bolt::Errors
         | 
| 15 15 | 
             
                class PALError < Bolt::Error
         | 
| 16 16 | 
             
                  def self.from_preformatted_error(err)
         | 
| 17 | 
            -
                    if err.cause.is_a? Bolt::Error
         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  # Generate a Bolt::Pal::PALError for non-bolt errors
         | 
| 25 | 
            -
                  def self.from_error(err)
         | 
| 26 | 
            -
                    # Use the original error message if available
         | 
| 27 | 
            -
                    message = err.cause ? err.cause.message : err.message
         | 
| 17 | 
            +
                    error = if err.cause.is_a? Bolt::Error
         | 
| 18 | 
            +
                              err.cause
         | 
| 19 | 
            +
                            else
         | 
| 20 | 
            +
                              from_error(err)
         | 
| 21 | 
            +
                            end
         | 
| 28 22 |  | 
| 29 23 | 
             
                    # Provide the location of an error if it came from a plan
         | 
| 30 24 | 
             
                    details = {}
         | 
| @@ -32,8 +26,15 @@ module Bolt | |
| 32 26 | 
             
                    details[:line]   = err.line if defined?(err.line)
         | 
| 33 27 | 
             
                    details[:column] = err.pos if defined?(err.pos)
         | 
| 34 28 |  | 
| 35 | 
            -
                     | 
| 29 | 
            +
                    error.add_filelineno(details)
         | 
| 30 | 
            +
                    error
         | 
| 31 | 
            +
                  end
         | 
| 36 32 |  | 
| 33 | 
            +
                  # Generate a Bolt::Pal::PALError for non-bolt errors
         | 
| 34 | 
            +
                  def self.from_error(err)
         | 
| 35 | 
            +
                    # Use the original error message if available
         | 
| 36 | 
            +
                    message = err.cause ? err.cause.message : err.message
         | 
| 37 | 
            +
                    e = new(message)
         | 
| 37 38 | 
             
                    e.set_backtrace(err.backtrace)
         | 
| 38 39 | 
             
                    e
         | 
| 39 40 | 
             
                  end
         | 
| @@ -256,19 +257,24 @@ module Bolt | |
| 256 257 |  | 
| 257 258 | 
             
                # TODO: PUP-8553 should replace this
         | 
| 258 259 | 
             
                def with_puppet_settings
         | 
| 259 | 
            -
                  Dir.mktmpdir('bolt') | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 262 | 
            -
             | 
| 263 | 
            -
                     | 
| 264 | 
            -
                    Puppet.settings.send(:clear_everything_for_tests)
         | 
| 265 | 
            -
                    Puppet.initialize_settings(cli)
         | 
| 266 | 
            -
                    Puppet::GettextConfig.create_default_text_domain
         | 
| 267 | 
            -
                    Puppet[:trusted_external_command] = @trusted_external
         | 
| 268 | 
            -
                    Puppet.settings[:hiera_config] = @hiera_config
         | 
| 269 | 
            -
                    self.class.configure_logging
         | 
| 270 | 
            -
                    yield
         | 
| 260 | 
            +
                  dir = Dir.mktmpdir('bolt')
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                  cli = []
         | 
| 263 | 
            +
                  Puppet::Settings::REQUIRED_APP_SETTINGS.each do |setting|
         | 
| 264 | 
            +
                    cli << "--#{setting}" << dir
         | 
| 271 265 | 
             
                  end
         | 
| 266 | 
            +
                  Puppet.settings.send(:clear_everything_for_tests)
         | 
| 267 | 
            +
                  Puppet.initialize_settings(cli)
         | 
| 268 | 
            +
                  Puppet::GettextConfig.create_default_text_domain
         | 
| 269 | 
            +
                  Puppet[:trusted_external_command] = @trusted_external
         | 
| 270 | 
            +
                  Puppet.settings[:hiera_config] = @hiera_config
         | 
| 271 | 
            +
                  self.class.configure_logging
         | 
| 272 | 
            +
                  yield
         | 
| 273 | 
            +
                ensure
         | 
| 274 | 
            +
                  # Delete the tmpdir if it still exists. This check is needed to
         | 
| 275 | 
            +
                  # prevent Bolt from erroring if the tmpdir is somehow deleted
         | 
| 276 | 
            +
                  # before reaching this point.
         | 
| 277 | 
            +
                  FileUtils.remove_entry_secure(dir) if File.exist?(dir)
         | 
| 272 278 | 
             
                end
         | 
| 273 279 |  | 
| 274 280 | 
             
                # Parses a snippet of Puppet manifest code and returns the AST represented
         | 
    
        data/lib/bolt/pal/yaml_plan.rb
    CHANGED
    
    | @@ -98,10 +98,12 @@ module Bolt | |
| 98 98 | 
             
                  # subclasses this parent class in order to implement its own evaluation
         | 
| 99 99 | 
             
                  # logic.
         | 
| 100 100 | 
             
                  class EvaluableString
         | 
| 101 | 
            -
                    attr_reader :value
         | 
| 101 | 
            +
                    attr_reader :file, :line, :value
         | 
| 102 102 |  | 
| 103 | 
            -
                    def initialize(value)
         | 
| 103 | 
            +
                    def initialize(value, file = nil, line = nil)
         | 
| 104 104 | 
             
                      @value = value
         | 
| 105 | 
            +
                      @file  = file
         | 
| 106 | 
            +
                      @line  = line
         | 
| 105 107 | 
             
                    end
         | 
| 106 108 |  | 
| 107 109 | 
             
                    def ==(other)
         | 
| @@ -191,7 +191,11 @@ module Bolt | |
| 191 191 | 
             
                          o[key] = evaluate_code_blocks(scope, v)
         | 
| 192 192 | 
             
                        end
         | 
| 193 193 | 
             
                      when EvaluableString
         | 
| 194 | 
            -
                         | 
| 194 | 
            +
                        begin
         | 
| 195 | 
            +
                          value.evaluate(scope, @evaluator)
         | 
| 196 | 
            +
                        rescue StandardError => e
         | 
| 197 | 
            +
                          raise format_evaluate_error(e, value)
         | 
| 198 | 
            +
                        end
         | 
| 195 199 | 
             
                      else
         | 
| 196 200 | 
             
                        value
         | 
| 197 201 | 
             
                      end
         | 
| @@ -203,6 +207,24 @@ module Bolt | |
| 203 207 | 
             
                    def evaluate(value, _scope)
         | 
| 204 208 | 
             
                      value
         | 
| 205 209 | 
             
                    end
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                    def format_evaluate_error(error, value)
         | 
| 212 | 
            +
                      # The Puppet::PreformattedError includes the line number of the
         | 
| 213 | 
            +
                      # evaluable string that caused the error, while the value includes the
         | 
| 214 | 
            +
                      # line number of the YAML plan that the string began on. To get the
         | 
| 215 | 
            +
                      # actual line number of the error, add these two numbers together.
         | 
| 216 | 
            +
                      line = error.line + value.line
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                      # If the evaluable string is not a scalar literal, correct for it
         | 
| 219 | 
            +
                      # being on the same line as the step key.
         | 
| 220 | 
            +
                      line -= 1 if value.is_a?(BareString)
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                      Bolt::PlanFailure.new(
         | 
| 223 | 
            +
                        error.basic_message,
         | 
| 224 | 
            +
                        'bolt/evaluation-error',
         | 
| 225 | 
            +
                        { file: value.file, line: line }
         | 
| 226 | 
            +
                      )
         | 
| 227 | 
            +
                    end
         | 
| 206 228 | 
             
                  end
         | 
| 207 229 | 
             
                end
         | 
| 208 230 | 
             
              end
         | 
| @@ -9,10 +9,15 @@ module Bolt | |
| 9 9 | 
             
                class YamlPlan
         | 
| 10 10 | 
             
                  class Loader
         | 
| 11 11 | 
             
                    class PuppetVisitor < Psych::Visitors::NoAliasRuby
         | 
| 12 | 
            -
                      def  | 
| 12 | 
            +
                      def initialize(scanner, class_loader, file)
         | 
| 13 | 
            +
                        super(scanner, class_loader)
         | 
| 14 | 
            +
                        @file = file
         | 
| 15 | 
            +
                      end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                      def self.create_visitor(source_ref)
         | 
| 13 18 | 
             
                        class_loader = Psych::ClassLoader::Restricted.new([], [])
         | 
| 14 19 | 
             
                        scanner = Psych::ScalarScanner.new(class_loader)
         | 
| 15 | 
            -
                        new(scanner, class_loader)
         | 
| 20 | 
            +
                        new(scanner, class_loader, source_ref)
         | 
| 16 21 | 
             
                      end
         | 
| 17 22 |  | 
| 18 23 | 
             
                      def deserialize(node)
         | 
| @@ -23,18 +28,18 @@ module Bolt | |
| 23 28 | 
             
                            # @ss is a ScalarScanner, from the base ToRuby visitor class
         | 
| 24 29 | 
             
                            node.value
         | 
| 25 30 | 
             
                          when Psych::Nodes::Scalar::DOUBLE_QUOTED
         | 
| 26 | 
            -
                            DoubleQuotedString.new(node.value)
         | 
| 27 | 
            -
                          # | style string | 
| 28 | 
            -
                          when Psych::Nodes::Scalar::LITERAL | 
| 29 | 
            -
                            CodeLiteral.new(node.value)
         | 
| 30 | 
            -
                          #  | 
| 31 | 
            +
                            DoubleQuotedString.new(node.value, @file, node.start_line + 1)
         | 
| 32 | 
            +
                          # | style string
         | 
| 33 | 
            +
                          when Psych::Nodes::Scalar::LITERAL
         | 
| 34 | 
            +
                            CodeLiteral.new(node.value, @file, node.start_line + 1)
         | 
| 35 | 
            +
                          # > style string
         | 
| 31 36 | 
             
                          else
         | 
| 32 37 | 
             
                            @ss.tokenize(node.value)
         | 
| 33 38 | 
             
                          end
         | 
| 34 39 | 
             
                        else
         | 
| 35 40 | 
             
                          value = @ss.tokenize(node.value)
         | 
| 36 41 | 
             
                          if value.is_a?(String)
         | 
| 37 | 
            -
                            BareString.new(value)
         | 
| 42 | 
            +
                            BareString.new(value, @file, node.start_line + 1)
         | 
| 38 43 | 
             
                          else
         | 
| 39 44 | 
             
                            value
         | 
| 40 45 | 
             
                          end
         | 
| @@ -50,7 +55,7 @@ module Bolt | |
| 50 55 | 
             
                                   else
         | 
| 51 56 | 
             
                                     Psych.parse(yaml_string, source_ref)
         | 
| 52 57 | 
             
                                   end
         | 
| 53 | 
            -
                      PuppetVisitor.create_visitor.accept(parse_tree)
         | 
| 58 | 
            +
                      PuppetVisitor.create_visitor(source_ref).accept(parse_tree)
         | 
| 54 59 | 
             
                    end
         | 
| 55 60 |  | 
| 56 61 | 
             
                    def self.from_string(name, yaml_string, source_ref)
         | 
    
        data/lib/bolt/result.rb
    CHANGED
    
    | @@ -7,47 +7,58 @@ module Bolt | |
| 7 7 | 
             
              class Result
         | 
| 8 8 | 
             
                attr_reader :target, :value, :action, :object
         | 
| 9 9 |  | 
| 10 | 
            -
                def self.from_exception(target, exception, action: 'action')
         | 
| 10 | 
            +
                def self.from_exception(target, exception, action: 'action', position: [])
         | 
| 11 | 
            +
                  details = create_details(position)
         | 
| 11 12 | 
             
                  if exception.is_a?(Bolt::Error)
         | 
| 12 | 
            -
                    error = exception.to_h
         | 
| 13 | 
            +
                    error = Bolt::Util.deep_merge({ 'details' => details }, exception.to_h)
         | 
| 13 14 | 
             
                  else
         | 
| 15 | 
            +
                    details['class'] = exception.class.to_s
         | 
| 14 16 | 
             
                    error = {
         | 
| 15 17 | 
             
                      'kind' => 'puppetlabs.tasks/exception-error',
         | 
| 16 18 | 
             
                      'issue_code' => 'EXCEPTION',
         | 
| 17 19 | 
             
                      'msg' => exception.message,
         | 
| 18 | 
            -
                      'details' =>  | 
| 20 | 
            +
                      'details' => details
         | 
| 19 21 | 
             
                    }
         | 
| 20 22 | 
             
                    error['details']['stack_trace'] = exception.backtrace.join('\n') if exception.backtrace
         | 
| 21 23 | 
             
                  end
         | 
| 22 24 | 
             
                  Result.new(target, error: error, action: action)
         | 
| 23 25 | 
             
                end
         | 
| 24 26 |  | 
| 25 | 
            -
                def self. | 
| 27 | 
            +
                def self.create_details(position)
         | 
| 28 | 
            +
                  %w[file line].zip(position).to_h.compact
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def self.for_command(target, stdout, stderr, exit_code, action, command, position)
         | 
| 26 32 | 
             
                  value = {
         | 
| 27 33 | 
             
                    'stdout' => stdout,
         | 
| 28 34 | 
             
                    'stderr' => stderr,
         | 
| 29 35 | 
             
                    'exit_code' => exit_code
         | 
| 30 36 | 
             
                  }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  details = create_details(position)
         | 
| 31 39 | 
             
                  unless exit_code == 0
         | 
| 40 | 
            +
                    details['exit_code'] = exit_code
         | 
| 32 41 | 
             
                    value['_error'] = {
         | 
| 33 42 | 
             
                      'kind' => 'puppetlabs.tasks/command-error',
         | 
| 34 43 | 
             
                      'issue_code' => 'COMMAND_ERROR',
         | 
| 35 44 | 
             
                      'msg' => "The command failed with exit code #{exit_code}",
         | 
| 36 | 
            -
                      'details' =>  | 
| 45 | 
            +
                      'details' => details
         | 
| 37 46 | 
             
                    }
         | 
| 38 47 | 
             
                  end
         | 
| 39 48 | 
             
                  new(target, value: value, action: action, object: command)
         | 
| 40 49 | 
             
                end
         | 
| 41 50 |  | 
| 42 | 
            -
                def self.for_task(target, stdout, stderr, exit_code, task)
         | 
| 51 | 
            +
                def self.for_task(target, stdout, stderr, exit_code, task, position)
         | 
| 43 52 | 
             
                  stdout.force_encoding('utf-8') unless stdout.encoding == Encoding::UTF_8
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  details = create_details(position)
         | 
| 44 55 | 
             
                  value = if stdout.valid_encoding?
         | 
| 45 56 | 
             
                            parse_hash(stdout) || { '_output' => stdout }
         | 
| 46 57 | 
             
                          else
         | 
| 47 58 | 
             
                            { '_error' => { 'kind' => 'puppetlabs.tasks/task-error',
         | 
| 48 59 | 
             
                                            'issue_code' => 'TASK_ERROR',
         | 
| 49 60 | 
             
                                            'msg' => 'The task result contained invalid UTF-8 on stdout',
         | 
| 50 | 
            -
                                            'details' =>  | 
| 61 | 
            +
                                            'details' => details } }
         | 
| 51 62 | 
             
                          end
         | 
| 52 63 |  | 
| 53 64 | 
             
                  if exit_code != 0 && value['_error'].nil?
         | 
| @@ -60,24 +71,26 @@ module Bolt | |
| 60 71 | 
             
                          else
         | 
| 61 72 | 
             
                            "The task failed with exit code #{exit_code}"
         | 
| 62 73 | 
             
                          end
         | 
| 74 | 
            +
                    details['exit_code'] = exit_code
         | 
| 63 75 | 
             
                    value['_error'] = { 'kind' => 'puppetlabs.tasks/task-error',
         | 
| 64 76 | 
             
                                        'issue_code' => 'TASK_ERROR',
         | 
| 65 77 | 
             
                                        'msg' => msg,
         | 
| 66 | 
            -
                                        'details' =>  | 
| 78 | 
            +
                                        'details' => details }
         | 
| 67 79 | 
             
                  end
         | 
| 68 80 |  | 
| 69 81 | 
             
                  if value.key?('_error')
         | 
| 70 82 | 
             
                    unless value['_error'].is_a?(Hash) && value['_error'].key?('msg')
         | 
| 83 | 
            +
                      details['original_error'] = value['_error']
         | 
| 71 84 | 
             
                      value['_error'] = {
         | 
| 72 85 | 
             
                        'msg'     => "Invalid error returned from task #{task}: #{value['_error'].inspect}. Error "\
         | 
| 73 86 | 
             
                                     "must be an object with a msg key.",
         | 
| 74 87 | 
             
                        'kind'    => 'bolt/invalid-task-error',
         | 
| 75 | 
            -
                        'details' =>  | 
| 88 | 
            +
                        'details' => details
         | 
| 76 89 | 
             
                      }
         | 
| 77 90 | 
             
                    end
         | 
| 78 91 |  | 
| 79 92 | 
             
                    value['_error']['kind']    ||= 'bolt/error'
         | 
| 80 | 
            -
                    value['_error']['details'] ||=  | 
| 93 | 
            +
                    value['_error']['details'] ||= details
         | 
| 81 94 | 
             
                  end
         | 
| 82 95 |  | 
| 83 96 | 
             
                  if value.key?('_sensitive')
         | 
| @@ -221,7 +234,6 @@ module Bolt | |
| 221 234 | 
             
                def error
         | 
| 222 235 | 
             
                  if error_hash
         | 
| 223 236 | 
             
                    Puppet::DataTypes::Error.from_asserted_hash(error_hash)
         | 
| 224 | 
            -
             | 
| 225 237 | 
             
                  end
         | 
| 226 238 | 
             
                end
         | 
| 227 239 |  | 
    
        data/lib/bolt/shell/bash.rb
    CHANGED
    
    | @@ -21,14 +21,16 @@ module Bolt | |
| 21 21 | 
             
                    ['shell']
         | 
| 22 22 | 
             
                  end
         | 
| 23 23 |  | 
| 24 | 
            -
                  def run_command(command, options = {})
         | 
| 24 | 
            +
                  def run_command(command, options = {}, position = [])
         | 
| 25 25 | 
             
                    running_as(options[:run_as]) do
         | 
| 26 26 | 
             
                      output = execute(command, environment: options[:env_vars], sudoable: true)
         | 
| 27 27 | 
             
                      Bolt::Result.for_command(target,
         | 
| 28 28 | 
             
                                               output.stdout.string,
         | 
| 29 29 | 
             
                                               output.stderr.string,
         | 
| 30 30 | 
             
                                               output.exit_code,
         | 
| 31 | 
            -
                                               'command', | 
| 31 | 
            +
                                               'command',
         | 
| 32 | 
            +
                                               command,
         | 
| 33 | 
            +
                                               position)
         | 
| 32 34 | 
             
                    end
         | 
| 33 35 | 
             
                  end
         | 
| 34 36 |  | 
| @@ -71,7 +73,7 @@ module Bolt | |
| 71 73 | 
             
                    end
         | 
| 72 74 | 
             
                  end
         | 
| 73 75 |  | 
| 74 | 
            -
                  def run_script(script, arguments, options = {})
         | 
| 76 | 
            +
                  def run_script(script, arguments, options = {}, position = [])
         | 
| 75 77 | 
             
                    # unpack any Sensitive data
         | 
| 76 78 | 
             
                    arguments = unwrap_sensitive_args(arguments)
         | 
| 77 79 |  | 
| @@ -84,12 +86,14 @@ module Bolt | |
| 84 86 | 
             
                                                 output.stdout.string,
         | 
| 85 87 | 
             
                                                 output.stderr.string,
         | 
| 86 88 | 
             
                                                 output.exit_code,
         | 
| 87 | 
            -
                                                 'script', | 
| 89 | 
            +
                                                 'script',
         | 
| 90 | 
            +
                                                 script,
         | 
| 91 | 
            +
                                                 position)
         | 
| 88 92 | 
             
                      end
         | 
| 89 93 | 
             
                    end
         | 
| 90 94 | 
             
                  end
         | 
| 91 95 |  | 
| 92 | 
            -
                  def run_task(task, arguments, options = {})
         | 
| 96 | 
            +
                  def run_task(task, arguments, options = {}, position = [])
         | 
| 93 97 | 
             
                    implementation = select_implementation(target, task)
         | 
| 94 98 | 
             
                    executable = implementation['path']
         | 
| 95 99 | 
             
                    input_method = implementation['input_method']
         | 
| @@ -148,7 +152,8 @@ module Bolt | |
| 148 152 | 
             
                      Bolt::Result.for_task(target, output.stdout.string,
         | 
| 149 153 | 
             
                                            output.stderr.string,
         | 
| 150 154 | 
             
                                            output.exit_code,
         | 
| 151 | 
            -
                                            task.name | 
| 155 | 
            +
                                            task.name,
         | 
| 156 | 
            +
                                            position)
         | 
| 152 157 | 
             
                    end
         | 
| 153 158 | 
             
                  end
         | 
| 154 159 |  | 
| @@ -174,7 +174,7 @@ module Bolt | |
| 174 174 | 
             
                    Bolt::Result.for_download(target, source, destination, download)
         | 
| 175 175 | 
             
                  end
         | 
| 176 176 |  | 
| 177 | 
            -
                  def run_command(command, options = {})
         | 
| 177 | 
            +
                  def run_command(command, options = {}, position = [])
         | 
| 178 178 | 
             
                    command = [*env_declarations(options[:env_vars]), command].join("\r\n") if options[:env_vars]
         | 
| 179 179 |  | 
| 180 180 | 
             
                    output = execute(command)
         | 
| @@ -182,10 +182,12 @@ module Bolt | |
| 182 182 | 
             
                                             output.stdout.string,
         | 
| 183 183 | 
             
                                             output.stderr.string,
         | 
| 184 184 | 
             
                                             output.exit_code,
         | 
| 185 | 
            -
                                             'command', | 
| 185 | 
            +
                                             'command',
         | 
| 186 | 
            +
                                             command,
         | 
| 187 | 
            +
                                             position)
         | 
| 186 188 | 
             
                  end
         | 
| 187 189 |  | 
| 188 | 
            -
                  def run_script(script, arguments, options = {})
         | 
| 190 | 
            +
                  def run_script(script, arguments, options = {}, position = [])
         | 
| 189 191 | 
             
                    # unpack any Sensitive data
         | 
| 190 192 | 
             
                    arguments = unwrap_sensitive_args(arguments)
         | 
| 191 193 | 
             
                    with_tmpdir do |dir|
         | 
| @@ -204,11 +206,13 @@ module Bolt | |
| 204 206 | 
             
                                               output.stdout.string,
         | 
| 205 207 | 
             
                                               output.stderr.string,
         | 
| 206 208 | 
             
                                               output.exit_code,
         | 
| 207 | 
            -
                                               'script', | 
| 209 | 
            +
                                               'script',
         | 
| 210 | 
            +
                                               script,
         | 
| 211 | 
            +
                                               position)
         | 
| 208 212 | 
             
                    end
         | 
| 209 213 | 
             
                  end
         | 
| 210 214 |  | 
| 211 | 
            -
                  def run_task(task, arguments, _options = {})
         | 
| 215 | 
            +
                  def run_task(task, arguments, _options = {}, position = [])
         | 
| 212 216 | 
             
                    implementation = select_implementation(target, task)
         | 
| 213 217 | 
             
                    executable = implementation['path']
         | 
| 214 218 | 
             
                    input_method = implementation['input_method']
         | 
| @@ -259,7 +263,8 @@ module Bolt | |
| 259 263 | 
             
                      Bolt::Result.for_task(target, output.stdout.string,
         | 
| 260 264 | 
             
                                            output.stderr.string,
         | 
| 261 265 | 
             
                                            output.exit_code,
         | 
| 262 | 
            -
                                            task.name | 
| 266 | 
            +
                                            task.name,
         | 
| 267 | 
            +
                                            position)
         | 
| 263 268 | 
             
                    end
         | 
| 264 269 | 
             
                  end
         | 
| 265 270 |  | 
    
        data/lib/bolt/transport/base.rb
    CHANGED
    
    | @@ -43,13 +43,13 @@ module Bolt | |
| 43 43 | 
             
                    @logger = Bolt::Logger.logger(self)
         | 
| 44 44 | 
             
                  end
         | 
| 45 45 |  | 
| 46 | 
            -
                  def with_events(target, callback, action)
         | 
| 46 | 
            +
                  def with_events(target, callback, action, position)
         | 
| 47 47 | 
             
                    callback&.call(type: :node_start, target: target)
         | 
| 48 48 |  | 
| 49 49 | 
             
                    result = begin
         | 
| 50 50 | 
             
                      yield
         | 
| 51 51 | 
             
                    rescue StandardError, NotImplementedError => e
         | 
| 52 | 
            -
                      Bolt::Result.from_exception(target, e, action: action)
         | 
| 52 | 
            +
                      Bolt::Result.from_exception(target, e, action: action, position: position)
         | 
| 53 53 | 
             
                    end
         | 
| 54 54 |  | 
| 55 55 | 
             
                    callback&.call(type: :node_result, result: result)
         | 
| @@ -100,12 +100,12 @@ module Bolt | |
| 100 100 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 101 101 | 
             
                  #
         | 
| 102 102 | 
             
                  # Transports may override this method to implement their own batch processing.
         | 
| 103 | 
            -
                  def batch_task(targets, task, arguments, options = {}, &callback)
         | 
| 103 | 
            +
                  def batch_task(targets, task, arguments, options = {}, position = [], &callback)
         | 
| 104 104 | 
             
                    assert_batch_size_one("batch_task()", targets)
         | 
| 105 105 | 
             
                    target = targets.first
         | 
| 106 | 
            -
                    with_events(target, callback, 'task') do
         | 
| 106 | 
            +
                    with_events(target, callback, 'task', position) do
         | 
| 107 107 | 
             
                      @logger.debug { "Running task '#{task.name}' on #{target.safe_name}" }
         | 
| 108 | 
            -
                      run_task(target, task, arguments, options)
         | 
| 108 | 
            +
                      run_task(target, task, arguments, options, position)
         | 
| 109 109 | 
             
                    end
         | 
| 110 110 | 
             
                  end
         | 
| 111 111 |  | 
| @@ -114,14 +114,14 @@ module Bolt | |
| 114 114 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 115 115 | 
             
                  #
         | 
| 116 116 | 
             
                  # Transports may override this method to implment their own batch processing.
         | 
| 117 | 
            -
                  def batch_task_with(targets, task, target_mapping, options = {}, &callback)
         | 
| 117 | 
            +
                  def batch_task_with(targets, task, target_mapping, options = {}, position = [], &callback)
         | 
| 118 118 | 
             
                    assert_batch_size_one("batch_task_with()", targets)
         | 
| 119 119 | 
             
                    target = targets.first
         | 
| 120 120 | 
             
                    arguments = target_mapping[target]
         | 
| 121 121 |  | 
| 122 | 
            -
                    with_events(target, callback, 'task') do
         | 
| 122 | 
            +
                    with_events(target, callback, 'task', position) do
         | 
| 123 123 | 
             
                      @logger.debug { "Running task '#{task.name}' on #{target.safe_name} with '#{arguments.to_json}'" }
         | 
| 124 | 
            -
                      run_task(target, task, arguments, options)
         | 
| 124 | 
            +
                      run_task(target, task, arguments, options, position)
         | 
| 125 125 | 
             
                    end
         | 
| 126 126 | 
             
                  end
         | 
| 127 127 |  | 
| @@ -130,12 +130,12 @@ module Bolt | |
| 130 130 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 131 131 | 
             
                  #
         | 
| 132 132 | 
             
                  # Transports may override this method to implement their own batch processing.
         | 
| 133 | 
            -
                  def batch_command(targets, command, options = {}, &callback)
         | 
| 133 | 
            +
                  def batch_command(targets, command, options = {}, position = [], &callback)
         | 
| 134 134 | 
             
                    assert_batch_size_one("batch_command()", targets)
         | 
| 135 135 | 
             
                    target = targets.first
         | 
| 136 | 
            -
                    with_events(target, callback, 'command') do
         | 
| 136 | 
            +
                    with_events(target, callback, 'command', position) do
         | 
| 137 137 | 
             
                      @logger.debug("Running command '#{command}' on #{target.safe_name}")
         | 
| 138 | 
            -
                      run_command(target, command, options)
         | 
| 138 | 
            +
                      run_command(target, command, options, position)
         | 
| 139 139 | 
             
                    end
         | 
| 140 140 | 
             
                  end
         | 
| 141 141 |  | 
| @@ -144,12 +144,12 @@ module Bolt | |
| 144 144 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 145 145 | 
             
                  #
         | 
| 146 146 | 
             
                  # Transports may override this method to implement their own batch processing.
         | 
| 147 | 
            -
                  def batch_script(targets, script, arguments, options = {}, &callback)
         | 
| 147 | 
            +
                  def batch_script(targets, script, arguments, options = {}, position = [], &callback)
         | 
| 148 148 | 
             
                    assert_batch_size_one("batch_script()", targets)
         | 
| 149 149 | 
             
                    target = targets.first
         | 
| 150 | 
            -
                    with_events(target, callback, 'script') do
         | 
| 150 | 
            +
                    with_events(target, callback, 'script', position) do
         | 
| 151 151 | 
             
                      @logger.debug { "Running script '#{script}' on #{target.safe_name}" }
         | 
| 152 | 
            -
                      run_script(target, script, arguments, options)
         | 
| 152 | 
            +
                      run_script(target, script, arguments, options, position)
         | 
| 153 153 | 
             
                    end
         | 
| 154 154 | 
             
                  end
         | 
| 155 155 |  | 
| @@ -158,10 +158,10 @@ module Bolt | |
| 158 158 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 159 159 | 
             
                  #
         | 
| 160 160 | 
             
                  # Transports may override this method to implement their own batch processing.
         | 
| 161 | 
            -
                  def batch_upload(targets, source, destination, options = {}, &callback)
         | 
| 161 | 
            +
                  def batch_upload(targets, source, destination, options = {}, position = [], &callback)
         | 
| 162 162 | 
             
                    assert_batch_size_one("batch_upload()", targets)
         | 
| 163 163 | 
             
                    target = targets.first
         | 
| 164 | 
            -
                    with_events(target, callback, 'upload') do
         | 
| 164 | 
            +
                    with_events(target, callback, 'upload', position) do
         | 
| 165 165 | 
             
                      @logger.debug { "Uploading: '#{source}' to #{destination} on #{target.safe_name}" }
         | 
| 166 166 | 
             
                      upload(target, source, destination, options)
         | 
| 167 167 | 
             
                    end
         | 
| @@ -173,12 +173,12 @@ module Bolt | |
| 173 173 | 
             
                  # The default implementation only supports batches of size 1 and will fail otherwise.
         | 
| 174 174 | 
             
                  #
         | 
| 175 175 | 
             
                  # Transports may override this method to implement their own batch processing.
         | 
| 176 | 
            -
                  def batch_download(targets, source, destination, options = {}, &callback)
         | 
| 176 | 
            +
                  def batch_download(targets, source, destination, options = {}, position = [], &callback)
         | 
| 177 177 | 
             
                    require 'erb'
         | 
| 178 178 |  | 
| 179 179 | 
             
                    assert_batch_size_one("batch_download()", targets)
         | 
| 180 180 | 
             
                    target = targets.first
         | 
| 181 | 
            -
                    with_events(target, callback, 'download') do
         | 
| 181 | 
            +
                    with_events(target, callback, 'download', position) do
         | 
| 182 182 | 
             
                      escaped_name = ERB::Util.url_encode(target.safe_name)
         | 
| 183 183 | 
             
                      target_destination = File.expand_path(escaped_name, destination)
         | 
| 184 184 | 
             
                      @logger.debug { "Downloading: '#{source}' on #{target.safe_name} to #{target_destination}" }
         | 
| @@ -46,7 +46,7 @@ module Bolt | |
| 46 46 | 
             
                    end
         | 
| 47 47 | 
             
                  end
         | 
| 48 48 |  | 
| 49 | 
            -
                  def run_command(target, command, options = {})
         | 
| 49 | 
            +
                  def run_command(target, command, options = {}, position = [])
         | 
| 50 50 | 
             
                    execute_options = {}
         | 
| 51 51 | 
             
                    execute_options[:tty] = target.options['tty']
         | 
| 52 52 | 
             
                    execute_options[:environment] = options[:env_vars]
         | 
| @@ -58,11 +58,17 @@ module Bolt | |
| 58 58 | 
             
                    end
         | 
| 59 59 | 
             
                    with_connection(target) do |conn|
         | 
| 60 60 | 
             
                      stdout, stderr, exitcode = conn.execute(*Shellwords.split(command), execute_options)
         | 
| 61 | 
            -
                      Bolt::Result.for_command(target, | 
| 61 | 
            +
                      Bolt::Result.for_command(target,
         | 
| 62 | 
            +
                                               stdout,
         | 
| 63 | 
            +
                                               stderr,
         | 
| 64 | 
            +
                                               exitcode,
         | 
| 65 | 
            +
                                               'command',
         | 
| 66 | 
            +
                                               command,
         | 
| 67 | 
            +
                                               position)
         | 
| 62 68 | 
             
                    end
         | 
| 63 69 | 
             
                  end
         | 
| 64 70 |  | 
| 65 | 
            -
                  def run_script(target, script, arguments, options = {})
         | 
| 71 | 
            +
                  def run_script(target, script, arguments, options = {}, position = [])
         | 
| 66 72 | 
             
                    # unpack any Sensitive data
         | 
| 67 73 | 
             
                    arguments = unwrap_sensitive_args(arguments)
         | 
| 68 74 | 
             
                    execute_options = {}
         | 
| @@ -72,12 +78,18 @@ module Bolt | |
| 72 78 | 
             
                      conn.with_remote_tmpdir do |dir|
         | 
| 73 79 | 
             
                        remote_path = conn.write_remote_executable(dir, script)
         | 
| 74 80 | 
             
                        stdout, stderr, exitcode = conn.execute(remote_path, *arguments, execute_options)
         | 
| 75 | 
            -
                        Bolt::Result.for_command(target, | 
| 81 | 
            +
                        Bolt::Result.for_command(target,
         | 
| 82 | 
            +
                                                 stdout,
         | 
| 83 | 
            +
                                                 stderr,
         | 
| 84 | 
            +
                                                 exitcode,
         | 
| 85 | 
            +
                                                 'script',
         | 
| 86 | 
            +
                                                 script,
         | 
| 87 | 
            +
                                                 position)
         | 
| 76 88 | 
             
                      end
         | 
| 77 89 | 
             
                    end
         | 
| 78 90 | 
             
                  end
         | 
| 79 91 |  | 
| 80 | 
            -
                  def run_task(target, task, arguments, _options = {})
         | 
| 92 | 
            +
                  def run_task(target, task, arguments, _options = {}, position = [])
         | 
| 81 93 | 
             
                    implementation = task.select_implementation(target, provided_features)
         | 
| 82 94 | 
             
                    executable = implementation['path']
         | 
| 83 95 | 
             
                    input_method = implementation['input_method']
         | 
| @@ -113,7 +125,12 @@ module Bolt | |
| 113 125 | 
             
                        end
         | 
| 114 126 |  | 
| 115 127 | 
             
                        stdout, stderr, exitcode = conn.execute(remote_task_path, execute_options)
         | 
| 116 | 
            -
                        Bolt::Result.for_task(target, | 
| 128 | 
            +
                        Bolt::Result.for_task(target,
         | 
| 129 | 
            +
                                              stdout,
         | 
| 130 | 
            +
                                              stderr,
         | 
| 131 | 
            +
                                              exitcode,
         | 
| 132 | 
            +
                                              task.name,
         | 
| 133 | 
            +
                                              position)
         | 
| 117 134 | 
             
                      end
         | 
| 118 135 | 
             
                    end
         | 
| 119 136 | 
             
                  end
         | 
    
        data/lib/bolt/transport/orch.rb
    CHANGED
    
    | @@ -53,7 +53,7 @@ module Bolt | |
| 53 53 | 
             
                    conn
         | 
| 54 54 | 
             
                  end
         | 
| 55 55 |  | 
| 56 | 
            -
                  def process_run_results(targets, results, task_name)
         | 
| 56 | 
            +
                  def process_run_results(targets, results, task_name, position = [])
         | 
| 57 57 | 
             
                    targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
         | 
| 58 58 | 
             
                    results.map do |node_result|
         | 
| 59 59 | 
             
                      target = targets_by_name[node_result['name']]
         | 
| @@ -63,25 +63,31 @@ module Bolt | |
| 63 63 | 
             
                      # If it's finished or already has a proper error simply pass it to the
         | 
| 64 64 | 
             
                      # the result otherwise make sure an error is generated
         | 
| 65 65 | 
             
                      if state == 'finished' || (result && result['_error'])
         | 
| 66 | 
            +
                        if result['_error']
         | 
| 67 | 
            +
                          file_line = %w[file line].zip(position).to_h.compact
         | 
| 68 | 
            +
                          result['_error']['details'].merge!(file_line) unless result['_error']['details']['file']
         | 
| 69 | 
            +
                        end
         | 
| 70 | 
            +
             | 
| 66 71 | 
             
                        Bolt::Result.new(target, value: result, action: 'task', object: task_name)
         | 
| 67 72 | 
             
                      elsif state == 'skipped'
         | 
| 73 | 
            +
                        details = %w[file line].zip(position).to_h.compact
         | 
| 68 74 | 
             
                        Bolt::Result.new(
         | 
| 69 75 | 
             
                          target,
         | 
| 70 76 | 
             
                          value: { '_error' => {
         | 
| 71 77 | 
             
                            'kind' => 'puppetlabs.tasks/skipped-node',
         | 
| 72 78 | 
             
                            'msg' => "Target #{target.safe_name} was skipped",
         | 
| 73 | 
            -
                            'details' =>  | 
| 79 | 
            +
                            'details' => details
         | 
| 74 80 | 
             
                          } },
         | 
| 75 81 | 
             
                          action: 'task', object: task_name
         | 
| 76 82 | 
             
                        )
         | 
| 77 83 | 
             
                      else
         | 
| 78 84 | 
             
                        # Make a generic error with a unkown exit_code
         | 
| 79 | 
            -
                        Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name)
         | 
| 85 | 
            +
                        Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name, position)
         | 
| 80 86 | 
             
                      end
         | 
| 81 87 | 
             
                    end
         | 
| 82 88 | 
             
                  end
         | 
| 83 89 |  | 
| 84 | 
            -
                  def batch_command(targets, command, options = {}, &callback)
         | 
| 90 | 
            +
                  def batch_command(targets, command, options = {}, position = [], &callback)
         | 
| 85 91 | 
             
                    if options[:env_vars] && !options[:env_vars].empty?
         | 
| 86 92 | 
             
                      raise NotImplementedError, "pcp transport does not support setting environment variables"
         | 
| 87 93 | 
             
                    end
         | 
| @@ -93,6 +99,7 @@ module Bolt | |
| 93 99 | 
             
                                           BOLT_COMMAND_TASK,
         | 
| 94 100 | 
             
                                           params,
         | 
| 95 101 | 
             
                                           options,
         | 
| 102 | 
            +
                                           position,
         | 
| 96 103 | 
             
                                           &callback)
         | 
| 97 104 | 
             
                    callback ||= proc {}
         | 
| 98 105 | 
             
                    results.map! { |result| unwrap_bolt_result(result.target, result, 'command', command) }
         | 
| @@ -101,7 +108,7 @@ module Bolt | |
| 101 108 | 
             
                    end
         | 
| 102 109 | 
             
                  end
         | 
| 103 110 |  | 
| 104 | 
            -
                  def batch_script(targets, script, arguments, options = {}, &callback)
         | 
| 111 | 
            +
                  def batch_script(targets, script, arguments, options = {}, position = [], &callback)
         | 
| 105 112 | 
             
                    if options[:env_vars] && !options[:env_vars].empty?
         | 
| 106 113 | 
             
                      raise NotImplementedError, "pcp transport does not support setting environment variables"
         | 
| 107 114 | 
             
                    end
         | 
| @@ -114,7 +121,7 @@ module Bolt | |
| 114 121 | 
             
                      'name' => Pathname(script).basename.to_s
         | 
| 115 122 | 
             
                    }
         | 
| 116 123 | 
             
                    callback ||= proc {}
         | 
| 117 | 
            -
                    results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, &callback)
         | 
| 124 | 
            +
                    results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, position, &callback)
         | 
| 118 125 | 
             
                    results.map! { |result| unwrap_bolt_result(result.target, result, 'script', script) }
         | 
| 119 126 | 
             
                    results.each do |result|
         | 
| 120 127 | 
             
                      callback.call(type: :node_result, result: result)
         | 
| @@ -155,7 +162,7 @@ module Bolt | |
| 155 162 | 
             
                    output&.close
         | 
| 156 163 | 
             
                  end
         | 
| 157 164 |  | 
| 158 | 
            -
                  def batch_upload(targets, source, destination, options = {}, &callback)
         | 
| 165 | 
            +
                  def batch_upload(targets, source, destination, options = {}, position = [], &callback)
         | 
| 159 166 | 
             
                    stat = File.stat(source)
         | 
| 160 167 | 
             
                    content = if stat.directory?
         | 
| 161 168 | 
             
                                pack(source)
         | 
| @@ -171,7 +178,7 @@ module Bolt | |
| 171 178 | 
             
                      'directory' => stat.directory?
         | 
| 172 179 | 
             
                    }
         | 
| 173 180 | 
             
                    callback ||= proc {}
         | 
| 174 | 
            -
                    results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, &callback)
         | 
| 181 | 
            +
                    results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, position, &callback)
         | 
| 175 182 | 
             
                    results.map! do |result|
         | 
| 176 183 | 
             
                      if result.error_hash
         | 
| 177 184 | 
             
                        result
         | 
| @@ -200,7 +207,7 @@ module Bolt | |
| 200 207 | 
             
                    targets.group_by { |target| Connection.get_key(target.options) }.values
         | 
| 201 208 | 
             
                  end
         | 
| 202 209 |  | 
| 203 | 
            -
                  def run_task_job(targets, task, arguments, options)
         | 
| 210 | 
            +
                  def run_task_job(targets, task, arguments, options, position)
         | 
| 204 211 | 
             
                    targets.each do |target|
         | 
| 205 212 | 
             
                      yield(type: :node_start, target: target) if block_given?
         | 
| 206 213 | 
             
                    end
         | 
| @@ -210,7 +217,7 @@ module Bolt | |
| 210 217 | 
             
                      arguments = unwrap_sensitive_args(arguments)
         | 
| 211 218 | 
             
                      results = get_connection(targets.first.options).run_task(targets, task, arguments, options)
         | 
| 212 219 |  | 
| 213 | 
            -
                      process_run_results(targets, results, task.name)
         | 
| 220 | 
            +
                      process_run_results(targets, results, task.name, position)
         | 
| 214 221 | 
             
                    rescue OrchestratorClient::ApiError => e
         | 
| 215 222 | 
             
                      targets.map do |target|
         | 
| 216 223 | 
             
                        Bolt::Result.new(target, error: e.data)
         | 
| @@ -222,15 +229,15 @@ module Bolt | |
| 222 229 | 
             
                    end
         | 
| 223 230 | 
             
                  end
         | 
| 224 231 |  | 
| 225 | 
            -
                  def batch_task(targets, task, arguments, options = {}, &callback)
         | 
| 232 | 
            +
                  def batch_task(targets, task, arguments, options = {}, position = [], &callback)
         | 
| 226 233 | 
             
                    callback ||= proc {}
         | 
| 227 | 
            -
                    results = run_task_job(targets, task, arguments, options, &callback)
         | 
| 234 | 
            +
                    results = run_task_job(targets, task, arguments, options, position, &callback)
         | 
| 228 235 | 
             
                    results.each do |result|
         | 
| 229 236 | 
             
                      callback.call(type: :node_result, result: result)
         | 
| 230 237 | 
             
                    end
         | 
| 231 238 | 
             
                  end
         | 
| 232 239 |  | 
| 233 | 
            -
                  def batch_task_with(_targets, _task, _target_mapping, _options = {})
         | 
| 240 | 
            +
                  def batch_task_with(_targets, _task, _target_mapping, _options = {}, _position = [])
         | 
| 234 241 | 
             
                    raise NotImplementedError, "pcp transport does not support run_task_with()"
         | 
| 235 242 | 
             
                  end
         | 
| 236 243 |  | 
| @@ -248,11 +255,13 @@ module Bolt | |
| 248 255 | 
             
                      return result
         | 
| 249 256 | 
             
                    end
         | 
| 250 257 |  | 
| 258 | 
            +
                    # If we get here, there's no error so we don't need the file or line
         | 
| 259 | 
            +
                    # number
         | 
| 251 260 | 
             
                    Bolt::Result.for_command(target,
         | 
| 252 261 | 
             
                                             result.value['stdout'],
         | 
| 253 262 | 
             
                                             result.value['stderr'],
         | 
| 254 263 | 
             
                                             result.value['exit_code'],
         | 
| 255 | 
            -
                                             action, obj)
         | 
| 264 | 
            +
                                             action, obj, [])
         | 
| 256 265 | 
             
                  end
         | 
| 257 266 | 
             
                end
         | 
| 258 267 | 
             
              end
         | 
| @@ -26,14 +26,14 @@ module Bolt | |
| 26 26 | 
             
                  end
         | 
| 27 27 |  | 
| 28 28 | 
             
                  # Cannot batch because arugments differ
         | 
| 29 | 
            -
                  def run_task(target, task, arguments, options = {})
         | 
| 29 | 
            +
                  def run_task(target, task, arguments, options = {}, position = [])
         | 
| 30 30 | 
             
                    proxy_target = get_proxy(target)
         | 
| 31 31 | 
             
                    transport = @executor.transport(proxy_target.transport)
         | 
| 32 32 | 
             
                    arguments = arguments.merge('_target' => target.to_h.reject { |_, v| v.nil? })
         | 
| 33 33 |  | 
| 34 34 | 
             
                    remote_task = task.remote_instance
         | 
| 35 35 |  | 
| 36 | 
            -
                    result = transport.run_task(proxy_target, remote_task, arguments, options)
         | 
| 36 | 
            +
                    result = transport.run_task(proxy_target, remote_task, arguments, options, position)
         | 
| 37 37 | 
             
                    Bolt::Result.new(target, value: result.value, action: 'task', object: task.name)
         | 
| 38 38 | 
             
                  end
         | 
| 39 39 | 
             
                end
         | 
| @@ -20,9 +20,9 @@ module Bolt | |
| 20 20 | 
             
                    false
         | 
| 21 21 | 
             
                  end
         | 
| 22 22 |  | 
| 23 | 
            -
                  def run_command(target, command, options = {})
         | 
| 23 | 
            +
                  def run_command(target, command, options = {}, position = [])
         | 
| 24 24 | 
             
                    with_connection(target) do |conn|
         | 
| 25 | 
            -
                      conn.shell.run_command(command, options)
         | 
| 25 | 
            +
                      conn.shell.run_command(command, options, position)
         | 
| 26 26 | 
             
                    end
         | 
| 27 27 | 
             
                  end
         | 
| 28 28 |  | 
| @@ -38,15 +38,15 @@ module Bolt | |
| 38 38 | 
             
                    end
         | 
| 39 39 | 
             
                  end
         | 
| 40 40 |  | 
| 41 | 
            -
                  def run_script(target, script, arguments, options = {})
         | 
| 41 | 
            +
                  def run_script(target, script, arguments, options = {}, position = [])
         | 
| 42 42 | 
             
                    with_connection(target) do |conn|
         | 
| 43 | 
            -
                      conn.shell.run_script(script, arguments, options)
         | 
| 43 | 
            +
                      conn.shell.run_script(script, arguments, options, position)
         | 
| 44 44 | 
             
                    end
         | 
| 45 45 | 
             
                  end
         | 
| 46 46 |  | 
| 47 | 
            -
                  def run_task(target, task, arguments, options = {})
         | 
| 47 | 
            +
                  def run_task(target, task, arguments, options = {}, position = [])
         | 
| 48 48 | 
             
                    with_connection(target) do |conn|
         | 
| 49 | 
            -
                      conn.shell.run_task(task, arguments, options)
         | 
| 49 | 
            +
                      conn.shell.run_task(task, arguments, options, position)
         | 
| 50 50 | 
             
                    end
         | 
| 51 51 | 
             
                  end
         | 
| 52 52 | 
             
                end
         | 
    
        data/lib/bolt/version.rb
    CHANGED
    
    
| @@ -48,7 +48,7 @@ module BoltSpec | |
| 48 48 | 
             
                    ([segments[0]] + segments[2..-1]).join('/')
         | 
| 49 49 | 
             
                  end
         | 
| 50 50 |  | 
| 51 | 
            -
                  def run_command(targets, command, options = {})
         | 
| 51 | 
            +
                  def run_command(targets, command, options = {}, _position = [])
         | 
| 52 52 | 
             
                    result = nil
         | 
| 53 53 | 
             
                    if (doub = @command_doubles[command] || @command_doubles[:default])
         | 
| 54 54 | 
             
                      result = doub.process(targets, command, options)
         | 
| @@ -61,7 +61,7 @@ module BoltSpec | |
| 61 61 | 
             
                    result
         | 
| 62 62 | 
             
                  end
         | 
| 63 63 |  | 
| 64 | 
            -
                  def run_script(targets, script_path, arguments, options = {})
         | 
| 64 | 
            +
                  def run_script(targets, script_path, arguments, options = {}, _position = [])
         | 
| 65 65 | 
             
                    script = module_file_id(script_path)
         | 
| 66 66 | 
             
                    result = nil
         | 
| 67 67 | 
             
                    if (doub = @script_doubles[script] || @script_doubles[:default])
         | 
| @@ -76,7 +76,7 @@ module BoltSpec | |
| 76 76 | 
             
                    result
         | 
| 77 77 | 
             
                  end
         | 
| 78 78 |  | 
| 79 | 
            -
                  def run_task(targets, task, arguments, options = {})
         | 
| 79 | 
            +
                  def run_task(targets, task, arguments, options = {}, _position = [])
         | 
| 80 80 | 
             
                    result = nil
         | 
| 81 81 | 
             
                    if (doub = @task_doubles[task.name] || @task_doubles[:default])
         | 
| 82 82 | 
             
                      result = doub.process(targets, task.name, arguments, options)
         | 
| @@ -90,7 +90,7 @@ module BoltSpec | |
| 90 90 | 
             
                    result
         | 
| 91 91 | 
             
                  end
         | 
| 92 92 |  | 
| 93 | 
            -
                  def download_file(targets, source, destination, options = {})
         | 
| 93 | 
            +
                  def download_file(targets, source, destination, options = {}, _position = [])
         | 
| 94 94 | 
             
                    result = nil
         | 
| 95 95 | 
             
                    if (doub = @download_doubles[source] || @download_doubles[:default])
         | 
| 96 96 | 
             
                      result = doub.process(targets, source, destination, options)
         | 
| @@ -103,7 +103,7 @@ module BoltSpec | |
| 103 103 | 
             
                    result
         | 
| 104 104 | 
             
                  end
         | 
| 105 105 |  | 
| 106 | 
            -
                  def upload_file(targets, source_path, destination, options = {})
         | 
| 106 | 
            +
                  def upload_file(targets, source_path, destination, options = {}, _position = [])
         | 
| 107 107 | 
             
                    source = module_file_id(source_path)
         | 
| 108 108 | 
             
                    result = nil
         | 
| 109 109 | 
             
                    if (doub = @upload_doubles[source] || @upload_doubles[:default])
         | 
    
        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: 2. | 
| 4 | 
            +
              version: 2.33.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Puppet
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020- | 
| 11 | 
            +
            date: 2020-11-02 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: addressable
         | 
| @@ -438,6 +438,7 @@ files: | |
| 438 438 | 
             
            - bolt-modules/system/lib/puppet/functions/system/env.rb
         | 
| 439 439 | 
             
            - exe/bolt
         | 
| 440 440 | 
             
            - guides/inventory.txt
         | 
| 441 | 
            +
            - guides/logging.txt
         | 
| 441 442 | 
             
            - guides/module.txt
         | 
| 442 443 | 
             
            - guides/modulepath.txt
         | 
| 443 444 | 
             
            - guides/project.txt
         | 
| @@ -597,7 +598,6 @@ files: | |
| 597 598 | 
             
            - modules/canary/lib/puppet/functions/canary/skip.rb
         | 
| 598 599 | 
             
            - modules/canary/plans/init.pp
         | 
| 599 600 | 
             
            - modules/puppetdb_fact/plans/init.pp
         | 
| 600 | 
            -
            - modules/secure_env_vars/plans/init.pp
         | 
| 601 601 | 
             
            homepage: https://github.com/puppetlabs/bolt
         | 
| 602 602 | 
             
            licenses:
         | 
| 603 603 | 
             
            - Apache-2.0
         | 
| @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            plan secure_env_vars(
         | 
| 2 | 
            -
              TargetSpec $targets,
         | 
| 3 | 
            -
              Optional[String] $command = undef,
         | 
| 4 | 
            -
              Optional[String] $script = undef
         | 
| 5 | 
            -
            ) {
         | 
| 6 | 
            -
              $env_vars = parsejson(system::env('BOLT_ENV_VARS'))
         | 
| 7 | 
            -
              unless type($command) == Undef or type($script) == Undef {
         | 
| 8 | 
            -
                  fail_plan('Cannot specify both script and command for secure_env_vars')
         | 
| 9 | 
            -
              }
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              return if $command {
         | 
| 12 | 
            -
                       run_command($command, $targets, '_env_vars' => $env_vars)
         | 
| 13 | 
            -
                     }
         | 
| 14 | 
            -
                     elsif $script {
         | 
| 15 | 
            -
                       run_script($script, $targets, '_env_vars' => $env_vars)
         | 
| 16 | 
            -
                     }
         | 
| 17 | 
            -
                     else {
         | 
| 18 | 
            -
                       fail_plan('Must specify either script or command for secure_env_vars')
         | 
| 19 | 
            -
                     }
         | 
| 20 | 
            -
            }
         |