bolt 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bolt/cli.rb +65 -28
  3. data/lib/bolt/config.rb +18 -8
  4. data/lib/bolt/executor.rb +21 -6
  5. data/lib/bolt/node.rb +3 -0
  6. data/lib/bolt/node/result.rb +5 -0
  7. data/lib/bolt/node/ssh.rb +81 -25
  8. data/lib/bolt/node/winrm.rb +70 -31
  9. data/lib/bolt/notifier.rb +20 -0
  10. data/lib/bolt/outputter.rb +21 -0
  11. data/lib/bolt/outputter/human.rb +30 -0
  12. data/lib/bolt/outputter/json.rb +51 -0
  13. data/lib/bolt/result.rb +32 -5
  14. data/lib/bolt/version.rb +1 -1
  15. data/vendored/puppet/lib/puppet.rb +4 -5
  16. data/vendored/puppet/lib/puppet/agent.rb +22 -2
  17. data/vendored/puppet/lib/puppet/application/agent.rb +1 -1
  18. data/vendored/puppet/lib/puppet/application/apply.rb +1 -1
  19. data/vendored/puppet/lib/puppet/configurer/downloader_factory.rb +10 -0
  20. data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +4 -4
  21. data/vendored/puppet/lib/puppet/defaults.rb +21 -2
  22. data/vendored/puppet/lib/puppet/external/nagios/parser.rb +1 -1
  23. data/vendored/puppet/lib/puppet/file_serving/configuration.rb +3 -0
  24. data/vendored/puppet/lib/puppet/file_serving/configuration/parser.rb +2 -0
  25. data/vendored/puppet/lib/puppet/file_serving/mount/locales.rb +35 -0
  26. data/vendored/puppet/lib/puppet/forge.rb +9 -3
  27. data/vendored/puppet/lib/puppet/forge/repository.rb +1 -1
  28. data/vendored/puppet/lib/puppet/functions/file_upload.rb +20 -15
  29. data/vendored/puppet/lib/puppet/functions/new.rb +1 -4
  30. data/vendored/puppet/lib/puppet/functions/run_command.rb +15 -13
  31. data/vendored/puppet/lib/puppet/functions/run_script.rb +27 -14
  32. data/vendored/puppet/lib/puppet/functions/run_task.rb +21 -19
  33. data/vendored/puppet/lib/puppet/gettext/config.rb +86 -28
  34. data/vendored/puppet/lib/puppet/indirector/catalog/compiler.rb +25 -5
  35. data/vendored/puppet/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  36. data/vendored/puppet/lib/puppet/module.rb +13 -17
  37. data/vendored/puppet/lib/puppet/pops/evaluator/access_operator.rb +20 -21
  38. data/vendored/puppet/lib/puppet/pops/evaluator/compare_operator.rb +3 -3
  39. data/vendored/puppet/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -0
  40. data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +20 -1
  41. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +2 -1
  42. data/vendored/puppet/lib/puppet/pops/loaders.rb +6 -41
  43. data/vendored/puppet/lib/puppet/pops/pcore.rb +9 -0
  44. data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +64 -10
  45. data/vendored/puppet/lib/puppet/pops/serialization/json_path.rb +2 -1
  46. data/vendored/puppet/lib/puppet/pops/types/execution_result.rb +7 -4
  47. data/vendored/puppet/lib/puppet/pops/types/p_binary_type.rb +9 -2
  48. data/vendored/puppet/lib/puppet/pops/types/p_init_type.rb +1 -1
  49. data/vendored/puppet/lib/puppet/pops/types/p_meta_type.rb +4 -0
  50. data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +81 -4
  51. data/vendored/puppet/lib/puppet/pops/types/p_object_type_extension.rb +213 -0
  52. data/vendored/puppet/lib/puppet/pops/types/p_sem_ver_type.rb +10 -2
  53. data/vendored/puppet/lib/puppet/pops/types/puppet_object.rb +11 -1
  54. data/vendored/puppet/lib/puppet/pops/types/type_calculator.rb +2 -2
  55. data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +16 -6
  56. data/vendored/puppet/lib/puppet/pops/types/type_formatter.rb +22 -14
  57. data/vendored/puppet/lib/puppet/pops/types/type_parser.rb +17 -15
  58. data/vendored/puppet/lib/puppet/pops/types/types.rb +181 -72
  59. data/vendored/puppet/lib/puppet/provider.rb +18 -8
  60. data/vendored/puppet/lib/puppet/provider/package/yum.rb +22 -7
  61. data/vendored/puppet/lib/puppet/provider/service/base.rb +21 -8
  62. data/vendored/puppet/lib/puppet/provider/service/launchd.rb +2 -3
  63. data/vendored/puppet/lib/puppet/provider/user/aix.rb +1 -0
  64. data/vendored/puppet/lib/puppet/provider/user/user_role_add.rb +7 -1
  65. data/vendored/puppet/lib/puppet/provider/user/useradd.rb +3 -2
  66. data/vendored/puppet/lib/puppet/provider/zfs/zfs.rb +5 -1
  67. data/vendored/puppet/lib/puppet/type/exec.rb +5 -4
  68. data/vendored/puppet/lib/puppet/type/macauthorization.rb +1 -1
  69. data/vendored/puppet/lib/puppet/type/user.rb +19 -0
  70. data/vendored/puppet/lib/puppet/util/log/destinations.rb +10 -0
  71. data/vendored/puppet/lib/puppet/util/windows/file.rb +35 -4
  72. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -1
  73. data/vendored/puppet/lib/puppet/version.rb +1 -1
  74. data/vendored/puppet/lib/puppet_pal.rb +15 -5
  75. metadata +8 -3
  76. 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")
@@ -94,6 +94,8 @@ class Puppet::FileServing::Configuration::Parser
94
94
  mount = Mount::Plugins.new(name)
95
95
  when "tasks"
96
96
  mount = Mount::Tasks.new(name)
97
+ when "locales"
98
+ mount = Mount::Locales.new(name)
97
99
  else
98
100
  mount = Mount::File.new(name)
99
101
  end
@@ -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 nodes and returns the result from each upload.
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 'NodeOrNodes = Variant[String[1], Array[NodeOrNodes]]'
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 'NodeOrNodes', :nodes
19
+ repeated_param 'TargetOrTargets', :targets
22
20
  end
23
21
 
24
- def file_upload(scope, source, destination, *nodes)
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
- unless Puppet.features.bolt?
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
- hosts = nodes.flatten
41
- if hosts.empty?
42
- call_function('debug', "Simulating file upload of '#{found}' - no hosts given - no action taken")
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
- Puppet::Pops::Types::ExecutionResult.from_bolt(Bolt::Executor.from_uris(hosts).file_upload(found, destination))
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 = catch :undefined_value do
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 nodes and returns the result from each command execution.
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 'NodeOrNodes = Variant[String[1], Array[NodeOrNodes]]'
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 'NodeOrNodes', :nodes
17
+ repeated_param 'TargetOrTargets', :targets
20
18
  end
21
19
 
22
- def run_command(command, *nodes)
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
- hosts = nodes.flatten
35
- if hosts.empty?
36
- call_function('debug', "Simulating run_command('#{command}') - no hosts given - no action taken")
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 nodes and returns the result of having each node execute the script.
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 'NodeOrNodes = Variant[String[1], Array[NodeOrNodes]]'
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 'NodeOrNodes', :nodes
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 run_script(scope, script, *nodes)
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
- hosts = nodes.flatten
44
- if hosts.empty?
45
- call_function('debug', "Simulating run_script of '#{found}' - no hosts given - no action taken")
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 nodes and returns the result from each.
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 'NodeOrNodes = Variant[String[1], Array[NodeOrNodes]]'
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 'NodeOrNodes', :nodes
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 'NodeOrNodes', :nodes
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 'NodeOrNodes', :nodes
29
+ repeated_param 'TargetOrTargets', :targets
32
30
  end
33
31
 
34
- def run_task_type(task_type, nodes, task_args = nil)
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, nodes)
35
+ run_task_instance(task_instance, targets)
38
36
  end
39
37
 
40
- def run_named_task(task_name, nodes, task_args = nil)
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, nodes)
45
+ run_task_instance(task_instance, targets)
48
46
  end
49
47
 
50
- def run_task_instance(task, *nodes)
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
- if hosts.empty?
64
- call_function('debug', "Simulating run of task #{task._pcore_type.name} - no hosts given - no action taken")
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