Class: Bolt::Transport::Base
- Inherits:
-
Object
- Object
- Bolt::Transport::Base
- Defined in:
- lib/bolt/transport/base.rb
Overview
This class provides the default behavior for Transports. A Transport is responsible for uploading files and running commands, scripts, and tasks on Targets.
Bolt executes work on the Transport in “batches”. To do that, it calls the batches() method, which is responsible for dividing the list of Targets into batches according to how it wants to handle them. It will then call Transport#batch_task, or the corresponding method for another operation, passing a list of Targets. The Transport returns a list of Bolt::Result objects, one per Target. Each batch is executed on a separate thread, controlled by the ‘concurrency` setting, so many batches may be running in parallel.
The default batch implementation splits the list of Targets into batches of 1. It then calls run_task(), or a corresponding method for other operations, passing in the single Target.
Most Transport implementations, like the SSH and WinRM transports, don’t need to do their own batching, since they only operate on a single Target at a time. Those Transports can implement the run_task() and related methods, which will automatically handle running many Targets in parallel, and will handle publishing start and finish events for each Target.
Transports that need their own batching, like the Orch transport, can instead override the batches() method to split Targets into sets that can be executed together, and override the batch_task() and related methods to execute a batch of targets. In that case, those Transports should accept a block argument and call it with a :node_start event for each Target before executing, and a :node_result event for each Target after execution.
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
Instance Method Summary collapse
-
#assert_batch_size_one(method, targets) ⇒ Object
Raises an error if more than one target was given in the batch.
-
#batch_command(targets, command, options = {}, &callback) ⇒ Object
Runs the given command on a batch of targets.
- #batch_connected?(targets) ⇒ Boolean
-
#batch_download(targets, source, destination, options = {}, &callback) ⇒ Object
Downloads the given source file from a batch of targets to the destination location on the host.
-
#batch_script(targets, script, arguments, options = {}, &callback) ⇒ Object
Runs the given script on a batch of targets.
-
#batch_task(targets, task, arguments, options = {}, &callback) ⇒ Object
Runs the given task on a batch of targets.
-
#batch_task_with(targets, task, target_mapping, options = {}, &callback) ⇒ Object
Runs the given task on a batch of targets with variable parameters.
-
#batch_upload(targets, source, destination, options = {}, &callback) ⇒ Object
Uploads the given source file to the destination location on a batch of targets.
-
#batches(targets) ⇒ Object
Split the given list of targets into a list of batches.
-
#connected?(_targets) ⇒ Boolean
Transports should override this method with their own implementation of a connection test.
- #default_input_method(_executable) ⇒ Object
-
#download(*_args) ⇒ Object
Transports should override this method with their own implementation of file download.
-
#envify_params(params) ⇒ Object
Transform a parameter map to an environment variable map, with parameter names prefixed with ‘PT_’ and values transformed to JSON unless they’re strings.
-
#initialize ⇒ Base
constructor
A new instance of Base.
- #provided_features ⇒ Object
-
#run_command(*_args) ⇒ Object
Transports should override this method with their own implementation of running a command.
-
#run_script(*_args) ⇒ Object
Transports should override this method with their own implementation of running a script.
-
#run_task(*_args) ⇒ Object
Transports should override this method with their own implementation of running a task.
- #select_implementation(target, task) ⇒ Object
- #select_interpreter(executable, interpreters) ⇒ Object
-
#unwrap_sensitive_args(arguments) ⇒ Object
Unwraps any Sensitive data in an arguments Hash, so the plain-text is passed to the Task/Script.
-
#upload(*_args) ⇒ Object
Transports should override this method with their own implementation of file upload.
- #with_events(target, callback, action) ⇒ Object
Constructor Details
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
40 41 42 |
# File 'lib/bolt/transport/base.rb', line 40 def logger @logger end |
Instance Method Details
#assert_batch_size_one(method, targets) ⇒ Object
Raises an error if more than one target was given in the batch.
The default implementations of batch_* strictly assume the transport is using the default batch size of 1. This method ensures that is the case and raises an error if it’s not.
91 92 93 94 95 96 |
# File 'lib/bolt/transport/base.rb', line 91 def assert_batch_size_one(method, targets) if targets.length > 1 = "#{self.class.name} must implement #{method} to support batches (got #{targets.length} targets)" raise NotImplementedError, end end |
#batch_command(targets, command, options = {}, &callback) ⇒ Object
Runs the given command on a batch of targets.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implement their own batch processing.
133 134 135 136 137 138 139 140 |
# File 'lib/bolt/transport/base.rb', line 133 def batch_command(targets, command, = {}, &callback) assert_batch_size_one("batch_command()", targets) target = targets.first with_events(target, callback, 'command') do @logger.debug("Running command '#{command}' on #{target.safe_name}") run_command(target, command, ) end end |
#batch_connected?(targets) ⇒ Boolean
189 190 191 192 |
# File 'lib/bolt/transport/base.rb', line 189 def batch_connected?(targets) assert_batch_size_one("connected?()", targets) connected?(targets.first) end |
#batch_download(targets, source, destination, options = {}, &callback) ⇒ Object
Downloads the given source file from a batch of targets to the destination location on the host.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implement their own batch processing.
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/bolt/transport/base.rb', line 176 def batch_download(targets, source, destination, = {}, &callback) require 'erb' assert_batch_size_one("batch_download()", targets) target = targets.first with_events(target, callback, 'download') do escaped_name = ERB::Util.url_encode(target.safe_name) target_destination = File.(escaped_name, destination) @logger.debug { "Downloading: '#{source}' on #{target.safe_name} to #{target_destination}" } download(target, source, target_destination, ) end end |
#batch_script(targets, script, arguments, options = {}, &callback) ⇒ Object
Runs the given script on a batch of targets.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implement their own batch processing.
147 148 149 150 151 152 153 154 |
# File 'lib/bolt/transport/base.rb', line 147 def batch_script(targets, script, arguments, = {}, &callback) assert_batch_size_one("batch_script()", targets) target = targets.first with_events(target, callback, 'script') do @logger.debug { "Running script '#{script}' on #{target.safe_name}" } run_script(target, script, arguments, ) end end |
#batch_task(targets, task, arguments, options = {}, &callback) ⇒ Object
Runs the given task on a batch of targets.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implement their own batch processing.
103 104 105 106 107 108 109 110 |
# File 'lib/bolt/transport/base.rb', line 103 def batch_task(targets, task, arguments, = {}, &callback) assert_batch_size_one("batch_task()", targets) target = targets.first with_events(target, callback, 'task') do @logger.debug { "Running task '#{task.name}' on #{target.safe_name}" } run_task(target, task, arguments, ) end end |
#batch_task_with(targets, task, target_mapping, options = {}, &callback) ⇒ Object
Runs the given task on a batch of targets with variable parameters.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implment their own batch processing.
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/bolt/transport/base.rb', line 117 def batch_task_with(targets, task, target_mapping, = {}, &callback) assert_batch_size_one("batch_task_with()", targets) target = targets.first arguments = target_mapping[target] with_events(target, callback, 'task') do @logger.debug { "Running task '#{task.name}' on #{target.safe_name} with '#{arguments.to_json}'" } run_task(target, task, arguments, ) end end |
#batch_upload(targets, source, destination, options = {}, &callback) ⇒ Object
Uploads the given source file to the destination location on a batch of targets.
The default implementation only supports batches of size 1 and will fail otherwise.
Transports may override this method to implement their own batch processing.
161 162 163 164 165 166 167 168 |
# File 'lib/bolt/transport/base.rb', line 161 def batch_upload(targets, source, destination, = {}, &callback) assert_batch_size_one("batch_upload()", targets) target = targets.first with_events(target, callback, 'upload') do @logger.debug { "Uploading: '#{source}' to #{destination} on #{target.safe_name}" } upload(target, source, destination, ) end end |
#batches(targets) ⇒ Object
Split the given list of targets into a list of batches. The default implementation returns single-target batches.
Transports may override this method, and the corresponding batch_* methods, to implement their own batch processing.
199 200 201 |
# File 'lib/bolt/transport/base.rb', line 199 def batches(targets) targets.map { |target| [target] } end |
#connected?(_targets) ⇒ Boolean
Transports should override this method with their own implementation of a connection test.
229 230 231 |
# File 'lib/bolt/transport/base.rb', line 229 def connected?(_targets) raise NotImplementedError, "connected?() must be implemented by the transport class" end |
#default_input_method(_executable) ⇒ Object
63 64 65 |
# File 'lib/bolt/transport/base.rb', line 63 def default_input_method(_executable) 'both' end |
#download(*_args) ⇒ Object
Transports should override this method with their own implementation of file download.
224 225 226 |
# File 'lib/bolt/transport/base.rb', line 224 def download(*_args) raise NotImplementedError, "download() must be implemented by the transport class" end |
#envify_params(params) ⇒ Object
Transform a parameter map to an environment variable map, with parameter names prefixed with ‘PT_’ and values transformed to JSON unless they’re strings.
79 80 81 82 83 84 |
# File 'lib/bolt/transport/base.rb', line 79 def envify_params(params) params.each_with_object({}) do |(k, v), h| v = v.to_json unless v.is_a?(String) h["PT_#{k}"] = v end end |
#provided_features ⇒ Object
59 60 61 |
# File 'lib/bolt/transport/base.rb', line 59 def provided_features [] end |
#run_command(*_args) ⇒ Object
Transports should override this method with their own implementation of running a command.
204 205 206 |
# File 'lib/bolt/transport/base.rb', line 204 def run_command(*_args) raise NotImplementedError, "run_command() must be implemented by the transport class" end |
#run_script(*_args) ⇒ Object
Transports should override this method with their own implementation of running a script.
209 210 211 |
# File 'lib/bolt/transport/base.rb', line 209 def run_script(*_args) raise NotImplementedError, "run_script() must be implemented by the transport class" end |
#run_task(*_args) ⇒ Object
Transports should override this method with their own implementation of running a task.
214 215 216 |
# File 'lib/bolt/transport/base.rb', line 214 def run_task(*_args) raise NotImplementedError, "run_task() must be implemented by the transport class" end |
#select_implementation(target, task) ⇒ Object
67 68 69 70 71 |
# File 'lib/bolt/transport/base.rb', line 67 def select_implementation(target, task) impl = task.select_implementation(target, provided_features) impl['input_method'] ||= default_input_method(impl['path']) impl end |
#select_interpreter(executable, interpreters) ⇒ Object
73 74 75 |
# File 'lib/bolt/transport/base.rb', line 73 def select_interpreter(executable, interpreters) interpreters[Pathname(executable).extname] if interpreters end |
#unwrap_sensitive_args(arguments) ⇒ Object
Unwraps any Sensitive data in an arguments Hash, so the plain-text is passed to the Task/Script.
This works on deeply nested data structures composed of Hashes, Arrays, and and plain-old data types (int, string, etc).
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/bolt/transport/base.rb', line 238 def unwrap_sensitive_args(arguments) # Skip this if Puppet isn't loaded return arguments unless defined?(Puppet::Pops::Types::PSensitiveType::Sensitive) case arguments when Array # iterate over the array, unwrapping all elements arguments.map { |x| unwrap_sensitive_args(x) } when Hash # iterate over the arguments hash and unwrap all keys and values arguments.each_with_object({}) { |(k, v), h| h[unwrap_sensitive_args(k)] = unwrap_sensitive_args(v) } when Puppet::Pops::Types::PSensitiveType::Sensitive # this value is Sensitive, unwrap it unwrap_sensitive_args(arguments.unwrap) else # unknown data type, just return it arguments end end |
#upload(*_args) ⇒ Object
Transports should override this method with their own implementation of file upload.
219 220 221 |
# File 'lib/bolt/transport/base.rb', line 219 def upload(*_args) raise NotImplementedError, "upload() must be implemented by the transport class" end |
#with_events(target, callback, action) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/bolt/transport/base.rb', line 46 def with_events(target, callback, action) callback&.call(type: :node_start, target: target) result = begin yield rescue StandardError, NotImplementedError => e Bolt::Result.from_exception(target, e, action: action) end callback&.call(type: :node_result, result: result) result end |