Class: Bolt::Transport::SSH::ExecConnection
- Inherits:
-
Object
- Object
- Bolt::Transport::SSH::ExecConnection
- Defined in:
- lib/bolt/transport/ssh/exec_connection.rb
Instance Attribute Summary collapse
-
#target ⇒ Object
readonly
Returns the value of attribute target.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Instance Method Summary collapse
- #build_ssh_command(command) ⇒ Object
-
#connect ⇒ Object
This is used to verify we can connect to targets with ‘connected?`.
- #disconnect ⇒ Object
- #download_file(source, dest, _download) ⇒ Object
- #execute(command) ⇒ Object
-
#initialize(target) ⇒ ExecConnection
constructor
A new instance of ExecConnection.
-
#reset_cwd? ⇒ Boolean
This is used by the Bash shell to decide whether to ‘cd` before executing commands as a run-as user.
- #shell ⇒ Object
- #ssh_opts ⇒ Object
- #upload_file(source, dest) ⇒ Object
- #userhost ⇒ Object
Constructor Details
#initialize(target) ⇒ ExecConnection
Returns a new instance of ExecConnection.
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 11 def initialize(target) raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host @target = target begin ssh_config = Net::SSH::Config.for(target.host) @user = @target.user || ssh_config[:user] || Etc.getlogin rescue StandardError @user = @target.user || Etc.getlogin end @logger = Bolt::Logger.logger(self) end |
Instance Attribute Details
#target ⇒ Object (readonly)
Returns the value of attribute target.
9 10 11 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 9 def target @target end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
9 10 11 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 9 def user @user end |
Instance Method Details
#build_ssh_command(command) ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 67 def build_ssh_command(command) ssh_conf = @target.transport_config['ssh-command'] || 'ssh' ssh_cmd = Array(ssh_conf) ssh_cmd += ssh_opts ssh_cmd << userhost # Add option separator before command for wrappers around SSH ssh_cmd << '--' ssh_cmd << command end |
#connect ⇒ Object
This is used to verify we can connect to targets with ‘connected?`
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 25 def connect cmd = build_ssh_command('exit') _, err, stat = Open3.capture3(*cmd) unless stat.success? raise Bolt::Node::ConnectError.new( "Failed to connect to #{@target.safe_name}: #{err}", 'CONNECT_ERROR' ) end end |
#disconnect ⇒ Object
36 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 36 def disconnect; end |
#download_file(source, dest, _download) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 106 def download_file(source, dest, _download) @logger.trace { "Downloading #{userhost}:#{source} to #{dest}" } FileUtils.mkdir_p(dest) cp_conf = @target.transport_config['copy-command'] || ["scp", "-r"] cp_cmd = Array(cp_conf) cp_cmd += ssh_opts cp_cmd << "#{userhost}:#{Shellwords.escape(source)}" cp_cmd << dest _, err, stat = Open3.capture3(*cp_cmd) if stat.success? @logger.trace "Successfully downloaded #{userhost}:#{source} to #{dest}" else = "Could not copy file to #{dest}: #{err}" raise Bolt::Node::FileError.new(, 'COPY_ERROR') end end |
#execute(command) ⇒ Object
127 128 129 130 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 127 def execute(command) cmd_array = build_ssh_command(command) Open3.popen3(*cmd_array) end |
#reset_cwd? ⇒ Boolean
This is used by the Bash shell to decide whether to ‘cd` before executing commands as a run-as user
134 135 136 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 134 def reset_cwd? true end |
#shell ⇒ Object
38 39 40 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 38 def shell Bolt::Shell::Bash.new(@target, self) end |
#ssh_opts ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 46 def ssh_opts # NOTE: not all commands we might use here support various `-o` options, # always provide a way to run without them. cmd = [] # BatchMode is SSH's noninteractive option: if key authentication # fails it will error out instead of falling back to password prompt cmd += %w[-o BatchMode=yes] if @target.transport_config['batch-mode'] cmd += %W[-o Port=#{@target.port}] if @target.port if @target.transport_config.key?('host-key-check') hkc = @target.transport_config['host-key-check'] ? 'yes' : 'no' cmd += %W[-o StrictHostKeyChecking=#{hkc}] end if (key = target.transport_config['private-key']) cmd += ['-i', key] end cmd end |
#upload_file(source, dest) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 77 def upload_file(source, dest) @logger.trace { "Uploading #{source} to #{dest}" } unless source.is_a?(StringIO) cp_conf = @target.transport_config['copy-command'] || ["scp", "-r"] cp_cmd = Array(cp_conf) cp_cmd += ssh_opts _, err, stat = if source.is_a?(StringIO) Tempfile.create(File.basename(dest)) do |f| f.write(source.read) f.close cp_cmd << f.path cp_cmd << "#{userhost}:#{Shellwords.escape(dest)}" Open3.capture3(*cp_cmd) end else cp_cmd << source cp_cmd << "#{userhost}:#{Shellwords.escape(dest)}" Open3.capture3(*cp_cmd) end if stat.success? @logger.trace "Successfully uploaded #{source} to #{dest}" else = "Could not copy file to #{dest}: #{err}" raise Bolt::Node::FileError.new(, 'COPY_ERROR') end end |
#userhost ⇒ Object
42 43 44 |
# File 'lib/bolt/transport/ssh/exec_connection.rb', line 42 def userhost "#{@user}@#{@target.host}" end |