bolt 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/bolt/cli.rb +65 -28
- data/lib/bolt/config.rb +18 -8
- data/lib/bolt/executor.rb +21 -6
- data/lib/bolt/node.rb +3 -0
- data/lib/bolt/node/result.rb +5 -0
- data/lib/bolt/node/ssh.rb +81 -25
- data/lib/bolt/node/winrm.rb +70 -31
- data/lib/bolt/notifier.rb +20 -0
- data/lib/bolt/outputter.rb +21 -0
- data/lib/bolt/outputter/human.rb +30 -0
- data/lib/bolt/outputter/json.rb +51 -0
- data/lib/bolt/result.rb +32 -5
- data/lib/bolt/version.rb +1 -1
- data/vendored/puppet/lib/puppet.rb +4 -5
- data/vendored/puppet/lib/puppet/agent.rb +22 -2
- data/vendored/puppet/lib/puppet/application/agent.rb +1 -1
- data/vendored/puppet/lib/puppet/application/apply.rb +1 -1
- data/vendored/puppet/lib/puppet/configurer/downloader_factory.rb +10 -0
- data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +4 -4
- data/vendored/puppet/lib/puppet/defaults.rb +21 -2
- data/vendored/puppet/lib/puppet/external/nagios/parser.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/configuration.rb +3 -0
- data/vendored/puppet/lib/puppet/file_serving/configuration/parser.rb +2 -0
- data/vendored/puppet/lib/puppet/file_serving/mount/locales.rb +35 -0
- data/vendored/puppet/lib/puppet/forge.rb +9 -3
- data/vendored/puppet/lib/puppet/forge/repository.rb +1 -1
- data/vendored/puppet/lib/puppet/functions/file_upload.rb +20 -15
- data/vendored/puppet/lib/puppet/functions/new.rb +1 -4
- data/vendored/puppet/lib/puppet/functions/run_command.rb +15 -13
- data/vendored/puppet/lib/puppet/functions/run_script.rb +27 -14
- data/vendored/puppet/lib/puppet/functions/run_task.rb +21 -19
- data/vendored/puppet/lib/puppet/gettext/config.rb +86 -28
- data/vendored/puppet/lib/puppet/indirector/catalog/compiler.rb +25 -5
- data/vendored/puppet/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/vendored/puppet/lib/puppet/module.rb +13 -17
- data/vendored/puppet/lib/puppet/pops/evaluator/access_operator.rb +20 -21
- data/vendored/puppet/lib/puppet/pops/evaluator/compare_operator.rb +3 -3
- data/vendored/puppet/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -0
- data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +20 -1
- data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/loaders.rb +6 -41
- data/vendored/puppet/lib/puppet/pops/pcore.rb +9 -0
- data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +64 -10
- data/vendored/puppet/lib/puppet/pops/serialization/json_path.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/types/execution_result.rb +7 -4
- data/vendored/puppet/lib/puppet/pops/types/p_binary_type.rb +9 -2
- data/vendored/puppet/lib/puppet/pops/types/p_init_type.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/types/p_meta_type.rb +4 -0
- data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +81 -4
- data/vendored/puppet/lib/puppet/pops/types/p_object_type_extension.rb +213 -0
- data/vendored/puppet/lib/puppet/pops/types/p_sem_ver_type.rb +10 -2
- data/vendored/puppet/lib/puppet/pops/types/puppet_object.rb +11 -1
- data/vendored/puppet/lib/puppet/pops/types/type_calculator.rb +2 -2
- data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +16 -6
- data/vendored/puppet/lib/puppet/pops/types/type_formatter.rb +22 -14
- data/vendored/puppet/lib/puppet/pops/types/type_parser.rb +17 -15
- data/vendored/puppet/lib/puppet/pops/types/types.rb +181 -72
- data/vendored/puppet/lib/puppet/provider.rb +18 -8
- data/vendored/puppet/lib/puppet/provider/package/yum.rb +22 -7
- data/vendored/puppet/lib/puppet/provider/service/base.rb +21 -8
- data/vendored/puppet/lib/puppet/provider/service/launchd.rb +2 -3
- data/vendored/puppet/lib/puppet/provider/user/aix.rb +1 -0
- data/vendored/puppet/lib/puppet/provider/user/user_role_add.rb +7 -1
- data/vendored/puppet/lib/puppet/provider/user/useradd.rb +3 -2
- data/vendored/puppet/lib/puppet/provider/zfs/zfs.rb +5 -1
- data/vendored/puppet/lib/puppet/type/exec.rb +5 -4
- data/vendored/puppet/lib/puppet/type/macauthorization.rb +1 -1
- data/vendored/puppet/lib/puppet/type/user.rb +19 -0
- data/vendored/puppet/lib/puppet/util/log/destinations.rb +10 -0
- data/vendored/puppet/lib/puppet/util/windows/file.rb +35 -4
- data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -1
- data/vendored/puppet/lib/puppet/version.rb +1 -1
- data/vendored/puppet/lib/puppet_pal.rb +15 -5
- metadata +8 -3
- data/vendored/puppet/lib/puppet/pops/types/p_error_type.rb +0 -158
| @@ -11,13 +11,13 @@ class Puppet::Configurer::PluginHandler | |
| 11 11 | 
             
              # Retrieve facts from the central server.
         | 
| 12 12 | 
             
              def download_plugins(environment)
         | 
| 13 13 | 
             
                plugin_downloader = @factory.create_plugin_downloader(environment)
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                result = []
         | 
| 16 | 
            -
             | 
| 17 14 | 
             
                plugin_fact_downloader = @factory.create_plugin_facts_downloader(environment)
         | 
| 15 | 
            +
                locales_downloader = @factory.create_locales_downloader(environment)
         | 
| 16 | 
            +
                result = []
         | 
| 18 17 | 
             
                result += plugin_fact_downloader.evaluate
         | 
| 19 | 
            -
             | 
| 20 18 | 
             
                result += plugin_downloader.evaluate
         | 
| 19 | 
            +
                result += locales_downloader.evaluate
         | 
| 20 | 
            +
             | 
| 21 21 | 
             
                Puppet::Util::Autoload.reload_changed
         | 
| 22 22 |  | 
| 23 23 | 
             
                result
         | 
| @@ -1498,6 +1498,13 @@ EOT | |
| 1498 1498 | 
             
                      \"never run.\" If you want puppet agent to never run, you should start
         | 
| 1499 1499 | 
             
                      it with the `--no-client` option. #{AS_DURATION}",
         | 
| 1500 1500 | 
             
                },
         | 
| 1501 | 
            +
                :runtimeout => {
         | 
| 1502 | 
            +
                  :default  => 0,
         | 
| 1503 | 
            +
                  :type     => :duration,
         | 
| 1504 | 
            +
                  :desc     => "The maximum amount of time an agent run is allowed to take.
         | 
| 1505 | 
            +
                      A Puppet agent run that exceeds this timeout will be aborted.
         | 
| 1506 | 
            +
                      Defaults to 0, which is unlimited. #{AS_DURATION}",
         | 
| 1507 | 
            +
                },
         | 
| 1501 1508 | 
             
                :ca_server => {
         | 
| 1502 1509 | 
             
                  :default    => "$server",
         | 
| 1503 1510 | 
             
                  :desc       => "The server to use for certificate
         | 
| @@ -1712,6 +1719,19 @@ EOT | |
| 1712 1719 | 
             
                  :default  => "puppet:///pluginfacts",
         | 
| 1713 1720 | 
             
                  :desc     => "Where to retrieve external facts for pluginsync",
         | 
| 1714 1721 | 
             
                },
         | 
| 1722 | 
            +
                :localedest => {
         | 
| 1723 | 
            +
                  :type       => :directory,
         | 
| 1724 | 
            +
                  :default    => "$vardir/locales",
         | 
| 1725 | 
            +
                  :desc       => "Where Puppet should store translation files that it pulls down from the central
         | 
| 1726 | 
            +
                  server.",
         | 
| 1727 | 
            +
                },
         | 
| 1728 | 
            +
                :localesource => {
         | 
| 1729 | 
            +
                  :default    => "puppet:///locales",
         | 
| 1730 | 
            +
                  :desc       => "From where to retrieve translation files.  The standard Puppet `file` type
         | 
| 1731 | 
            +
                  is used for retrieval, so anything that is a valid file source can
         | 
| 1732 | 
            +
                  be used here.",
         | 
| 1733 | 
            +
                },
         | 
| 1734 | 
            +
             | 
| 1715 1735 | 
             
                :pluginsync => {
         | 
| 1716 1736 | 
             
                  :default    => true,
         | 
| 1717 1737 | 
             
                  :type       => :boolean,
         | 
| @@ -1721,9 +1741,8 @@ EOT | |
| 1721 1741 | 
             
                    Puppet.deprecation_warning "Setting 'pluginsync' is deprecated."
         | 
| 1722 1742 | 
             
                  }
         | 
| 1723 1743 | 
             
                },
         | 
| 1724 | 
            -
             | 
| 1725 1744 | 
             
                :pluginsignore => {
         | 
| 1726 | 
            -
                    :default  => ".svn CVS .git .hg",
         | 
| 1745 | 
            +
                    :default  => ".svn CVS .git .hg *.pot",
         | 
| 1727 1746 | 
             
                    :desc     => "What files to ignore when pulling down plugins.",
         | 
| 1728 1747 | 
             
                }
         | 
| 1729 1748 | 
             
              )
         | 
| @@ -14,7 +14,7 @@ require 'strscan' | |
| 14 14 | 
             
            class ::Nagios::Parser::SyntaxError < RuntimeError; end
         | 
| 15 15 |  | 
| 16 16 | 
             
            def parse(src)
         | 
| 17 | 
            -
              if src.respond_to?("force_encoding") then
         | 
| 17 | 
            +
              if (RUBY_VERSION < '2.1.0') && src.respond_to?("force_encoding") then
         | 
| 18 18 | 
             
                src.force_encoding("ASCII-8BIT")
         | 
| 19 19 | 
             
              end
         | 
| 20 20 | 
             
              @ss = StringScanner.new(src)
         | 
| @@ -4,6 +4,7 @@ require 'puppet/file_serving/mount' | |
| 4 4 | 
             
            require 'puppet/file_serving/mount/file'
         | 
| 5 5 | 
             
            require 'puppet/file_serving/mount/modules'
         | 
| 6 6 | 
             
            require 'puppet/file_serving/mount/plugins'
         | 
| 7 | 
            +
            require 'puppet/file_serving/mount/locales'
         | 
| 7 8 | 
             
            require 'puppet/file_serving/mount/pluginfacts'
         | 
| 8 9 | 
             
            require 'puppet/file_serving/mount/tasks'
         | 
| 9 10 |  | 
| @@ -81,6 +82,8 @@ class Puppet::FileServing::Configuration | |
| 81 82 | 
             
                @mounts["modules"].allow('*') if @mounts["modules"].empty?
         | 
| 82 83 | 
             
                @mounts["plugins"] ||= Mount::Plugins.new("plugins")
         | 
| 83 84 | 
             
                @mounts["plugins"].allow('*') if @mounts["plugins"].empty?
         | 
| 85 | 
            +
                @mounts["locales"] ||= Mount::Locales.new("locales")
         | 
| 86 | 
            +
                @mounts["locales"].allow('*') if @mounts["locales"].empty?
         | 
| 84 87 | 
             
                @mounts["pluginfacts"] ||= Mount::PluginFacts.new("pluginfacts")
         | 
| 85 88 | 
             
                @mounts["pluginfacts"].allow('*') if @mounts["pluginfacts"].empty?
         | 
| 86 89 | 
             
                @mounts["tasks"] ||= Mount::Tasks.new("tasks")
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            require 'puppet/file_serving/mount'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Find files in the modules' locales directories.
         | 
| 4 | 
            +
            # This is a very strange mount because it merges
         | 
| 5 | 
            +
            # many directories into one.
         | 
| 6 | 
            +
            class Puppet::FileServing::Mount::Locales < Puppet::FileServing::Mount
         | 
| 7 | 
            +
              # Return an instance of the appropriate class.
         | 
| 8 | 
            +
              def find(relative_path, request)
         | 
| 9 | 
            +
                return nil unless mod = request.environment.modules.find { |m|  m.locale(relative_path) }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                path = mod.locale(relative_path)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                path
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def search(relative_path, request)
         | 
| 17 | 
            +
                # We currently only support one kind of search on locales - return
         | 
| 18 | 
            +
                # them all.
         | 
| 19 | 
            +
                Puppet.debug("Warning: calling Locales.search with empty module path.") if request.environment.modules.empty?
         | 
| 20 | 
            +
                paths = request.environment.modules.find_all { |mod| mod.locales? }.collect { |mod| mod.locale_directory }
         | 
| 21 | 
            +
                if paths.empty?
         | 
| 22 | 
            +
                  # If the modulepath is valid then we still need to return a valid root
         | 
| 23 | 
            +
                  # directory for the search, but make sure nothing inside it is
         | 
| 24 | 
            +
                  # returned.
         | 
| 25 | 
            +
                  request.options[:recurse] = false
         | 
| 26 | 
            +
                  request.environment.modulepath.empty? ? nil : request.environment.modulepath
         | 
| 27 | 
            +
                else
         | 
| 28 | 
            +
                  paths
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def valid?
         | 
| 33 | 
            +
                true
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -65,7 +65,7 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source | |
| 65 65 |  | 
| 66 66 | 
             
                  if response.code == '200'
         | 
| 67 67 | 
             
                    result = JSON.parse(response.body)
         | 
| 68 | 
            -
                    uri = result['pagination']['next']
         | 
| 68 | 
            +
                    uri = decode_uri(result['pagination']['next'])
         | 
| 69 69 | 
             
                    matches.concat result['results']
         | 
| 70 70 | 
             
                  else
         | 
| 71 71 | 
             
                    raise ResponseError.new(:uri => URI.parse(@host).merge(uri), :response => response)
         | 
| @@ -90,7 +90,7 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source | |
| 90 90 | 
             
              # @see SemanticPuppet::Dependency::Source#fetch
         | 
| 91 91 | 
             
              def fetch(input)
         | 
| 92 92 | 
             
                name = input.tr('/', '-')
         | 
| 93 | 
            -
                uri = "/v3/releases?module=#{name}"
         | 
| 93 | 
            +
                uri = "/v3/releases?module=#{name}&sort_by=version"
         | 
| 94 94 | 
             
                if Puppet[:module_groups]
         | 
| 95 95 | 
             
                  uri += "&module_groups=#{Puppet[:module_groups].gsub('+', ' ')}"
         | 
| 96 96 | 
             
                end
         | 
| @@ -107,7 +107,7 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source | |
| 107 107 | 
             
                  end
         | 
| 108 108 |  | 
| 109 109 | 
             
                  releases.concat(process(response['results']))
         | 
| 110 | 
            -
                  uri = response['pagination']['next']
         | 
| 110 | 
            +
                  uri = decode_uri(response['pagination']['next'])
         | 
| 111 111 | 
             
                end
         | 
| 112 112 |  | 
| 113 113 | 
             
                return releases
         | 
| @@ -226,4 +226,10 @@ class Puppet::Forge < SemanticPuppet::Dependency::Source | |
| 226 226 |  | 
| 227 227 | 
             
                l.select { |r| r }
         | 
| 228 228 | 
             
              end
         | 
| 229 | 
            +
             | 
| 230 | 
            +
              def decode_uri(uri)
         | 
| 231 | 
            +
                return if uri.nil?
         | 
| 232 | 
            +
             | 
| 233 | 
            +
                URI.decode(uri.gsub('+', ' '))
         | 
| 234 | 
            +
              end
         | 
| 229 235 | 
             
            end
         | 
| @@ -44,8 +44,8 @@ class Puppet::Forge | |
| 44 44 |  | 
| 45 45 | 
             
                # Return a Net::HTTPResponse read for this +path+.
         | 
| 46 46 | 
             
                def make_http_request(path, io = nil)
         | 
| 47 | 
            -
                  Puppet.debug "HTTP GET #{@host}#{path}"
         | 
| 48 47 | 
             
                  request = get_request_object(@uri.path.chomp('/')+path)
         | 
| 48 | 
            +
                  Puppet.debug "HTTP GET #{@host}#{request.path}"
         | 
| 49 49 | 
             
                  return read_response(request, io)
         | 
| 50 50 | 
             
                end
         | 
| 51 51 |  | 
| @@ -1,34 +1,33 @@ | |
| 1 | 
            -
            # Uploads the given file or directory to the given set of  | 
| 2 | 
            -
            #
         | 
| 3 | 
            -
            # * This function does nothing if the list of nodes is empty.
         | 
| 4 | 
            -
            # * It is possible to run on the node 'localhost'
         | 
| 5 | 
            -
            # * A node is a String with a node's hostname or a URI that also describes how to connect and run the task on that node
         | 
| 6 | 
            -
            #   including "user" and "password" parts of a URI.
         | 
| 7 | 
            -
            # * The returned value contains information about the result per node. TODO: needs mapping to a runtime Pcore Object to be useful
         | 
| 1 | 
            +
            # Uploads the given file or directory to the given set of targets and returns the result from each upload.
         | 
| 8 2 | 
             
            #
         | 
| 3 | 
            +
            # * This function does nothing if the list of targets is empty.
         | 
| 4 | 
            +
            # * It is possible to run on the target 'localhost'
         | 
| 5 | 
            +
            # * A target is a String with a targets's hostname or a Target.
         | 
| 6 | 
            +
            # * The returned value contains information about the result per target.
         | 
| 9 7 | 
             
            #
         | 
| 10 8 | 
             
            # Since > 5.4.0 TODO: Update when version is known
         | 
| 11 9 | 
             
            #
         | 
| 12 10 | 
             
            Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunction) do
         | 
| 13 11 | 
             
              local_types do
         | 
| 14 | 
            -
                type ' | 
| 12 | 
            +
                type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
         | 
| 15 13 | 
             
              end
         | 
| 16 14 |  | 
| 17 15 | 
             
              dispatch :file_upload do
         | 
| 18 16 | 
             
                scope_param
         | 
| 19 17 | 
             
                param 'String[1]', :source
         | 
| 20 18 | 
             
                param 'String[1]', :destination
         | 
| 21 | 
            -
                repeated_param ' | 
| 19 | 
            +
                repeated_param 'TargetOrTargets', :targets
         | 
| 22 20 | 
             
              end
         | 
| 23 21 |  | 
| 24 | 
            -
              def file_upload(scope, source, destination, * | 
| 22 | 
            +
              def file_upload(scope, source, destination, *targets)
         | 
| 25 23 | 
             
                unless Puppet[:tasks]
         | 
| 26 24 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
         | 
| 27 25 | 
             
                    Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
         | 
| 28 26 | 
             
                    {:operation => 'file_upload'})
         | 
| 29 27 | 
             
                end
         | 
| 30 28 |  | 
| 31 | 
            -
                 | 
| 29 | 
            +
                executor = Puppet.lookup(:bolt_executor) { nil }
         | 
| 30 | 
            +
                unless executor && Puppet.features.bolt?
         | 
| 32 31 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::TASK_MISSING_BOLT, :action => _('do file uploads'))
         | 
| 33 32 | 
             
                end
         | 
| 34 33 |  | 
| @@ -37,12 +36,18 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct | |
| 37 36 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::NO_SUCH_FILE_OR_DIRECTORY, {:file => source})
         | 
| 38 37 | 
             
                end
         | 
| 39 38 |  | 
| 40 | 
            -
                 | 
| 41 | 
            -
                 | 
| 42 | 
            -
             | 
| 39 | 
            +
                # Ensure that that given targets are all Target instances
         | 
| 40 | 
            +
                targets = targets.flatten.map { |t| t.is_a?(String) ? Puppet::Pops::Types::TypeFactory.target.create(t) : t }
         | 
| 41 | 
            +
                if targets.empty?
         | 
| 42 | 
            +
                  call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
         | 
| 43 43 | 
             
                  Puppet::Pops::Types::ExecutionResult::EMPTY_RESULT
         | 
| 44 44 | 
             
                else
         | 
| 45 | 
            -
                   | 
| 45 | 
            +
                  # Awaits change in the executor, enabling it receive Target instances
         | 
| 46 | 
            +
                  hosts = targets.map { |h| h.host }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  Puppet::Pops::Types::ExecutionResult.from_bolt(
         | 
| 49 | 
            +
                    executor.file_upload(executor.from_uris(hosts), found, destination)
         | 
| 50 | 
            +
                  )
         | 
| 46 51 | 
             
                end
         | 
| 47 52 | 
             
              end
         | 
| 48 53 | 
             
            end
         | 
| @@ -14,10 +14,7 @@ Puppet::Functions.create_function(:new, Puppet::Functions::InternalFunction) do | |
| 14 14 |  | 
| 15 15 | 
             
              def new_instance(scope, t, *args)
         | 
| 16 16 | 
             
                return args[0] if args.size == 1 && !t.is_a?(Puppet::Pops::Types::PInitType) && t.instance?(args[0])
         | 
| 17 | 
            -
                result =  | 
| 18 | 
            -
                  new_function_for_type(t, scope).call(scope, *args)
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
                assert_type(t, result)
         | 
| 17 | 
            +
                result = assert_type(t, new_function_for_type(t, scope).call(scope, *args))
         | 
| 21 18 | 
             
                return block_given? ? yield(result) : result
         | 
| 22 19 | 
             
              end
         | 
| 23 20 |  | 
| @@ -1,25 +1,23 @@ | |
| 1 | 
            -
            # Runs a command on the given set of  | 
| 2 | 
            -
            #
         | 
| 3 | 
            -
            # * This function does nothing if the list of nodes is empty.
         | 
| 4 | 
            -
            # * It is possible to run on the node 'localhost'
         | 
| 5 | 
            -
            # * A node is a String with a node's hostname or a URI that also describes how to connect and run the task on that node
         | 
| 6 | 
            -
            #   including "user" and "password" parts of a URI.
         | 
| 7 | 
            -
            # * The returned value contains information about the result per node. TODO: needs mapping to a runtime Pcore Object to be useful
         | 
| 1 | 
            +
            # Runs a command on the given set of targets and returns the result from each command execution.
         | 
| 8 2 | 
             
            #
         | 
| 3 | 
            +
            # * This function does nothing if the list of targets is empty.
         | 
| 4 | 
            +
            # * It is possible to run on the target 'localhost'
         | 
| 5 | 
            +
            # * A target is a String with a targets's hostname or a Target.
         | 
| 6 | 
            +
            # * The returned value contains information about the result per target.
         | 
| 9 7 | 
             
            #
         | 
| 10 8 | 
             
            # Since > 5.4.0 TODO: Update when version is known
         | 
| 11 9 | 
             
            #
         | 
| 12 10 | 
             
            Puppet::Functions.create_function(:run_command) do
         | 
| 13 11 | 
             
              local_types do
         | 
| 14 | 
            -
                type ' | 
| 12 | 
            +
                type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
         | 
| 15 13 | 
             
              end
         | 
| 16 14 |  | 
| 17 15 | 
             
              dispatch :run_command do
         | 
| 18 16 | 
             
                param 'String[1]', :command
         | 
| 19 | 
            -
                repeated_param ' | 
| 17 | 
            +
                repeated_param 'TargetOrTargets', :targets
         | 
| 20 18 | 
             
              end
         | 
| 21 19 |  | 
| 22 | 
            -
              def run_command(command, * | 
| 20 | 
            +
              def run_command(command, *targets)
         | 
| 23 21 | 
             
                unless Puppet[:tasks]
         | 
| 24 22 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
         | 
| 25 23 | 
             
                    Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
         | 
| @@ -31,11 +29,15 @@ Puppet::Functions.create_function(:run_command) do | |
| 31 29 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::TASK_MISSING_BOLT, :action => _('run a command'))
         | 
| 32 30 | 
             
                end
         | 
| 33 31 |  | 
| 34 | 
            -
                 | 
| 35 | 
            -
                 | 
| 36 | 
            -
             | 
| 32 | 
            +
                # Ensure that that given targets are all Target instances
         | 
| 33 | 
            +
                targets = targets.flatten.map { |t| t.is_a?(String) ? Puppet::Pops::Types::TypeFactory.target.create(t) : t }
         | 
| 34 | 
            +
                if targets.empty?
         | 
| 35 | 
            +
                  call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
         | 
| 37 36 | 
             
                  Puppet::Pops::Types::ExecutionResult::EMPTY_RESULT
         | 
| 38 37 | 
             
                else
         | 
| 38 | 
            +
                  # Awaits change in the executor, enabling it receive Target instances
         | 
| 39 | 
            +
                  hosts = targets.map { |h| h.host }
         | 
| 40 | 
            +
             | 
| 39 41 | 
             
                  Puppet::Pops::Types::ExecutionResult.from_bolt(
         | 
| 40 42 | 
             
                    executor.run_command(executor.from_uris(hosts), command)
         | 
| 41 43 | 
             
                  )
         | 
| @@ -1,26 +1,35 @@ | |
| 1 | 
            -
            # Uploads the given script to the given set of  | 
| 2 | 
            -
            #
         | 
| 3 | 
            -
            # * This function does nothing if the list of nodes is empty.
         | 
| 4 | 
            -
            # * It is possible to run on the node 'localhost'
         | 
| 5 | 
            -
            # * A node is a String with a node's hostname or a URI that also describes how to connect and run the task on that node
         | 
| 6 | 
            -
            #   including "user" and "password" parts of a URI.
         | 
| 7 | 
            -
            # * The returned value contains information about the result per node. TODO: needs mapping to a runtime Pcore Object to be useful
         | 
| 1 | 
            +
            # Uploads the given script to the given set of targets and returns the result of having each target execute the script.
         | 
| 8 2 | 
             
            #
         | 
| 3 | 
            +
            # * This function does nothing if the list of targets is empty.
         | 
| 4 | 
            +
            # * It is possible to run on the target 'localhost'
         | 
| 5 | 
            +
            # * A target is a String with a targets's hostname or a Target.
         | 
| 6 | 
            +
            # * The returned value contains information about the result per target.
         | 
| 9 7 | 
             
            #
         | 
| 10 8 | 
             
            # Since > 5.4.0 TODO: Update when version is known
         | 
| 11 9 | 
             
            #
         | 
| 12 10 | 
             
            Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFunction) do
         | 
| 13 11 | 
             
              local_types do
         | 
| 14 | 
            -
                type ' | 
| 12 | 
            +
                type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              dispatch :run_script_with_args do
         | 
| 16 | 
            +
                scope_param
         | 
| 17 | 
            +
                param 'String[1]', :script
         | 
| 18 | 
            +
                param 'TargetOrTargets', :targets
         | 
| 19 | 
            +
                param 'Struct[arguments => Array[String]]', :arguments
         | 
| 15 20 | 
             
              end
         | 
| 16 21 |  | 
| 17 22 | 
             
              dispatch :run_script do
         | 
| 18 23 | 
             
                scope_param
         | 
| 19 24 | 
             
                param 'String[1]', :script
         | 
| 20 | 
            -
                repeated_param ' | 
| 25 | 
            +
                repeated_param 'TargetOrTargets', :targets
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def run_script(scope, script, *targets)
         | 
| 29 | 
            +
                run_script_with_args(scope, script, targets, 'arguments' => [])
         | 
| 21 30 | 
             
              end
         | 
| 22 31 |  | 
| 23 | 
            -
              def  | 
| 32 | 
            +
              def run_script_with_args(scope, script, targets, args_hash)
         | 
| 24 33 | 
             
                unless Puppet[:tasks]
         | 
| 25 34 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
         | 
| 26 35 | 
             
                    Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
         | 
| @@ -40,13 +49,17 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti | |
| 40 49 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::NOT_A_FILE, {:file => script})
         | 
| 41 50 | 
             
                end
         | 
| 42 51 |  | 
| 43 | 
            -
                 | 
| 44 | 
            -
                 | 
| 45 | 
            -
             | 
| 52 | 
            +
                # Ensure that that given targets are all Target instances)
         | 
| 53 | 
            +
                targets = [targets].flatten.map { |t| t.is_a?(String) ? Puppet::Pops::Types::TypeFactory.target.create(t) : t }
         | 
| 54 | 
            +
                if targets.empty?
         | 
| 55 | 
            +
                  call_function('debug', "Simulating run_script of '#{found}' - no targets given - no action taken")
         | 
| 46 56 | 
             
                  Puppet::Pops::Types::ExecutionResult::EMPTY_RESULT
         | 
| 47 57 | 
             
                else
         | 
| 58 | 
            +
                  # Awaits change in the executor, enabling it receive Target instances
         | 
| 59 | 
            +
                  hosts = targets.map { |h| h.host }
         | 
| 60 | 
            +
             | 
| 48 61 | 
             
                  Puppet::Pops::Types::ExecutionResult.from_bolt(
         | 
| 49 | 
            -
                    executor.run_script(executor.from_uris(hosts), found)
         | 
| 62 | 
            +
                    executor.run_script(executor.from_uris(hosts), found, args_hash['arguments'])
         | 
| 50 63 | 
             
                  )
         | 
| 51 64 | 
             
                end
         | 
| 52 65 | 
             
              end
         | 
| @@ -1,54 +1,51 @@ | |
| 1 | 
            -
            # Runs a given instance of a `Task` on the given set of  | 
| 2 | 
            -
            #
         | 
| 3 | 
            -
            # * This function does nothing if the list of nodes is empty.
         | 
| 4 | 
            -
            # * It is possible to run on the node 'localhost'
         | 
| 5 | 
            -
            # * A node is a String with a node's hostname or a URI that also describes how to connect and run the task on that node
         | 
| 6 | 
            -
            #   including "user" and "password" parts of a URI.
         | 
| 7 | 
            -
            # * The returned value contains information about the result per node. TODO: needs mapping to a runtime Pcore Object to be useful
         | 
| 1 | 
            +
            # Runs a given instance of a `Task` on the given set of targets and returns the result from each.
         | 
| 8 2 | 
             
            #
         | 
| 3 | 
            +
            # * This function does nothing if the list of targets is empty.
         | 
| 4 | 
            +
            # * It is possible to run on the target 'localhost'
         | 
| 5 | 
            +
            # * A target is a String with a targets's hostname or a Target.
         | 
| 6 | 
            +
            # * The returned value contains information about the result per target.
         | 
| 9 7 | 
             
            #
         | 
| 10 8 | 
             
            # Since > 5.4.0 TODO: Update when version is known
         | 
| 11 9 | 
             
            #
         | 
| 12 10 | 
             
            Puppet::Functions.create_function(:run_task) do
         | 
| 13 11 | 
             
              local_types do
         | 
| 14 | 
            -
                type ' | 
| 12 | 
            +
                type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
         | 
| 15 13 | 
             
              end
         | 
| 16 14 |  | 
| 17 15 | 
             
              dispatch :run_task_type do
         | 
| 18 16 | 
             
                param 'Type[Task]', :task_type
         | 
| 19 | 
            -
                param ' | 
| 17 | 
            +
                param 'TargetOrTargets', :targets
         | 
| 20 18 | 
             
                optional_param 'Hash[String[1], Any]', :task_args
         | 
| 21 19 | 
             
              end
         | 
| 22 20 |  | 
| 23 21 | 
             
              dispatch :run_named_task do
         | 
| 24 22 | 
             
                param 'String[1]', :task_type
         | 
| 25 | 
            -
                param ' | 
| 23 | 
            +
                param 'TargetOrTargets', :targets
         | 
| 26 24 | 
             
                optional_param 'Hash[String[1], Any]', :task_args
         | 
| 27 25 | 
             
              end
         | 
| 28 26 |  | 
| 29 27 | 
             
              dispatch :run_task_instance do
         | 
| 30 28 | 
             
                param 'Task', :task
         | 
| 31 | 
            -
                repeated_param ' | 
| 29 | 
            +
                repeated_param 'TargetOrTargets', :targets
         | 
| 32 30 | 
             
              end
         | 
| 33 31 |  | 
| 34 | 
            -
              def run_task_type(task_type,  | 
| 32 | 
            +
              def run_task_type(task_type, targets, task_args = nil)
         | 
| 35 33 | 
             
                use_args = task_args.nil? ? {} : task_args
         | 
| 36 34 | 
             
                task_instance = call_function('new', task_type, use_args)
         | 
| 37 | 
            -
                run_task_instance(task_instance,  | 
| 35 | 
            +
                run_task_instance(task_instance, targets)
         | 
| 38 36 | 
             
              end
         | 
| 39 37 |  | 
| 40 | 
            -
              def run_named_task(task_name,  | 
| 38 | 
            +
              def run_named_task(task_name, targets, task_args = nil)
         | 
| 41 39 | 
             
                task_type = Puppet.lookup(:loaders).private_environment_loader.load(:type, task_name)
         | 
| 42 40 | 
             
                if task_type.nil?
         | 
| 43 41 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::UNKNOWN_TASK, :type_name => task_name)
         | 
| 44 42 | 
             
                end
         | 
| 45 43 | 
             
                use_args = task_args.nil? ? {} : task_args
         | 
| 46 44 | 
             
                task_instance = call_function('new', task_type, use_args)
         | 
| 47 | 
            -
                run_task_instance(task_instance,  | 
| 45 | 
            +
                run_task_instance(task_instance, targets)
         | 
| 48 46 | 
             
              end
         | 
| 49 47 |  | 
| 50 | 
            -
              def run_task_instance(task, * | 
| 51 | 
            -
                hosts = nodes.flatten
         | 
| 48 | 
            +
              def run_task_instance(task, *targets)
         | 
| 52 49 | 
             
                unless Puppet[:tasks]
         | 
| 53 50 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
         | 
| 54 51 | 
             
                    Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
         | 
| @@ -60,10 +57,15 @@ Puppet::Functions.create_function(:run_task) do | |
| 60 57 | 
             
                  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(Puppet::Pops::Issues::TASK_MISSING_BOLT, :action => _('run a task'))
         | 
| 61 58 | 
             
                end
         | 
| 62 59 |  | 
| 63 | 
            -
                 | 
| 64 | 
            -
             | 
| 60 | 
            +
                # Ensure that that given targets are all Target instances
         | 
| 61 | 
            +
                targets = targets.flatten.map { |t| t.is_a?(String) ? Puppet::Pops::Types::TypeFactory.target.create(t) : t }
         | 
| 62 | 
            +
                if targets.empty?
         | 
| 63 | 
            +
                  call_function('debug', "Simulating run of task #{task._pcore_type.name} - no targets given - no action taken")
         | 
| 65 64 | 
             
                  Puppet::Pops::Types::ExecutionResult::EMPTY_RESULT
         | 
| 66 65 | 
             
                else
         | 
| 66 | 
            +
                  # Awaits change in the executor, enabling it receive Target instances
         | 
| 67 | 
            +
                  hosts = targets.map { |h| h.host }
         | 
| 68 | 
            +
             | 
| 67 69 | 
             
                  # TODO: separate handling of default since it's platform specific
         | 
| 68 70 | 
             
                  input_method = task._pcore_type['input_method'].value
         | 
| 69 71 |  |