Class: Bolt::Transport::Local

Inherits:
Base
  • Object
show all
Defined in:
lib/bolt/transport/local.rb,
lib/bolt/transport/local/shell.rb

Defined Under Namespace

Classes: Shell

Constant Summary collapse

PROVIDED_FEATURES =
['shell'].freeze

Constants inherited from Base

Base::ENVIRONMENT_METHODS, Base::STDIN_METHODS

Instance Attribute Summary

Attributes inherited from Base

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#assert_batch_size_one, #batch_command, #batch_script, #batch_task, #batch_upload, #batches, #envify_params, #filter_options, #from_api?, #unwrap_sensitive_args, #with_events

Constructor Details

#initializeLocal

Returns a new instance of Local.



21
22
23
24
25
26
27
28
29
# File 'lib/bolt/transport/local.rb', line 21

def initialize
  super

  if Bolt::Util.windows?
    raise NotImplementedError, "The local transport is not yet implemented on Windows"
  else
    @conn = Shell.new
  end
end

Class Method Details

.optionsObject



13
14
15
# File 'lib/bolt/transport/local.rb', line 13

def self.options
  %w[tmpdir]
end

.validate(_options) ⇒ Object



19
# File 'lib/bolt/transport/local.rb', line 19

def self.validate(_options); end

Instance Method Details

#copy_file(source, destination) ⇒ Object



39
40
41
42
43
# File 'lib/bolt/transport/local.rb', line 39

def copy_file(source, destination)
  FileUtils.copy_file(source, destination)
rescue StandardError => e
  raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
end

#run_command(target, command, _options = {}) ⇒ Object



60
61
62
63
64
65
# File 'lib/bolt/transport/local.rb', line 60

def run_command(target, command, _options = {})
  in_tmpdir(target.options['tmpdir']) do |dir|
    output = @conn.execute(command, dir: dir)
    Bolt::Result.for_command(target, output.stdout.string, output.stderr.string, output.exit_code)
  end
end

#run_script(target, script, arguments, _options = {}) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/bolt/transport/local.rb', line 67

def run_script(target, script, arguments, _options = {})
  with_tmpscript(File.absolute_path(script), target.options['tmpdir']) do |file, dir|
    logger.debug "Running '#{file}' with #{arguments}"

    # unpack any Sensitive data AFTER we log
    arguments = unwrap_sensitive_args(arguments)
    if arguments.empty?
      # We will always provide separated arguments, so work-around Open3's handling of a single
      # argument as the entire command string for script paths containing spaces.
      arguments = ['']
    end
    output = @conn.execute(file, *arguments, dir: dir)
    Bolt::Result.for_command(target, output.stdout.string, output.stderr.string, output.exit_code)
  end
end

#run_task(target, task, arguments, _options = {}) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/bolt/transport/local.rb', line 83

def run_task(target, task, arguments, _options = {})
  implementation = task.select_implementation(target, PROVIDED_FEATURES)
  executable = implementation['path']
  input_method = implementation['input_method'] || 'both'

  # unpack any Sensitive data, write it to a separate variable because
  # we log 'arguments' below
  unwrapped_arguments = unwrap_sensitive_args(arguments)
  stdin = STDIN_METHODS.include?(input_method) ? JSON.dump(unwrapped_arguments) : nil
  env = ENVIRONMENT_METHODS.include?(input_method) ? envify_params(unwrapped_arguments) : nil

  with_tmpscript(executable, target.options['tmpdir']) do |script, dir|
    # log the arguments with sensitive data redacted, do NOT log unwrapped_arguments
    logger.debug("Running '#{script}' with #{arguments}")

    output = @conn.execute(script, stdin: stdin, env: env, dir: dir)
    Bolt::Result.for_task(target, output.stdout.string, output.stderr.string, output.exit_code)
  end
end

#upload(target, source, destination, _options = {}) ⇒ Object



55
56
57
58
# File 'lib/bolt/transport/local.rb', line 55

def upload(target, source, destination, _options = {})
  copy_file(source, destination)
  Bolt::Result.for_upload(target, source, destination)
end