/usr/lib/ruby/vendor_ruby/specinfra/backend/ssh.rb is in ruby-specinfra 2.35.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | # -*- coding: utf-8 -*-
require 'specinfra/backend/exec'
require 'net/ssh'
require 'net/scp'
module Specinfra
module Backend
class Ssh < Exec
def run_command(cmd, opt={})
cmd = build_command(cmd)
cmd = add_pre_command(cmd)
if get_config(:ssh_without_env)
ret = ssh_exec!(cmd)
else
ret = with_env do
ssh_exec!(cmd)
end
end
ret[:stdout].gsub!(/\r\n/, "\n")
ret[:stdout].gsub!(/\A\n/, "") if sudo?
if @example
@example.metadata[:command] = cmd
@example.metadata[:stdout] = ret[:stdout]
end
CommandResult.new ret
end
def send_file(from, to)
scp_upload!(from, to)
end
def send_directory(from, to)
scp_upload!(from, to, :recursive => true)
end
def build_command(cmd)
cmd = super(cmd)
if sudo?
cmd = "#{sudo} -p '#{prompt}' #{cmd}"
end
cmd
end
private
def prompt
'Password: '
end
def with_env
env = get_config(:env) || {}
env[:LANG] ||= 'C'
ssh_options = get_config(:ssh_options) || {}
ssh_options[:send_env] ||= []
env.each do |key, value|
key = key.to_s
ENV["_SPECINFRA_#{key}"] = ENV[key];
ENV[key] = value
ssh_options[:send_env] << key
end
yield
ensure
env.each do |key, value|
key = key.to_s
ENV[key] = ENV.delete("_SPECINFRA_#{key}");
end
end
def create_ssh
Net::SSH.start(
get_config(:host),
get_config(:ssh_options)[:user],
get_config(:ssh_options)
)
end
def create_scp
ssh = get_config(:ssh)
if ssh.nil?
ssh = create_ssh
end
Net::SCP.new(ssh)
end
def scp_upload!(from, to, opt={})
if get_config(:scp).nil?
set_config(:scp, create_scp)
end
tmp = File.join('/tmp', File.basename(to))
scp = get_config(:scp)
scp.upload!(from, tmp, opt)
run_command(command.get(:move_file, tmp, to))
end
def ssh_exec!(command)
stdout_data = ''
stderr_data = ''
exit_status = nil
exit_signal = nil
retry_prompt = /^Sorry, try again/
if get_config(:ssh).nil?
set_config(:ssh, create_ssh)
end
ssh = get_config(:ssh)
ssh.open_channel do |channel|
if get_config(:sudo_password) or get_config(:request_pty)
channel.request_pty do |ch, success|
abort "Could not obtain pty " if !success
end
end
channel.exec("#{command}") do |ch, success|
abort "FAILED: couldn't execute command (ssh.channel.exec)" if !success
channel.on_data do |ch, data|
if data.match retry_prompt
abort 'Wrong sudo password! Please confirm your password.'
elsif data.match /^#{prompt}/
channel.send_data "#{get_config(:sudo_password)}\n"
else
stdout_data += data
end
end
channel.on_extended_data do |ch, type, data|
if data.match /you must have a tty to run sudo/
abort 'Please write "set :request_pty, true" in your spec_helper.rb or other appropriate file.'
end
if data.match /^sudo: no tty present and no askpass program specified/
abort 'Please set sudo password to Specinfra.configuration.sudo_password.'
else
stderr_data += data
end
end
channel.on_request("exit-status") do |ch, data|
exit_status = data.read_long
end
channel.on_request("exit-signal") do |ch, data|
exit_signal = data.read_long
end
end
end
ssh.loop
{ :stdout => stdout_data, :stderr => stderr_data, :exit_status => exit_status, :exit_signal => exit_signal }
end
def sudo
if sudo_path = get_config(:sudo_path)
sudo_path += '/sudo'
else
sudo_path = 'sudo'
end
sudo_options = get_config(:sudo_options)
if sudo_options
sudo_options = sudo_options.shelljoin if sudo_options.is_a?(Array)
sudo_options = ' ' + sudo_options
end
"#{sudo_path.shellescape}#{sudo_options}"
end
def sudo?
user = get_config(:ssh_options)[:user]
disable_sudo = get_config(:disable_sudo)
user != 'root' && !disable_sudo
end
end
end
end
|