New wrapper SSH session class to emit exit status as well. Will be used in the future to raise exceptions for bad exit status. For now, works as a drop-in replacement.
This commit is contained in:
parent
5f57766365
commit
f30cdf3eea
|
@ -49,7 +49,7 @@ module Vagrant
|
||||||
env.config[:ssh][:username],
|
env.config[:ssh][:username],
|
||||||
opts.merge( :port => port,
|
opts.merge( :port => port,
|
||||||
:keys => [env.config.ssh.private_key_path])) do |ssh|
|
:keys => [env.config.ssh.private_key_path])) do |ssh|
|
||||||
yield ssh
|
yield SSH::Session.new(ssh)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ module Vagrant
|
||||||
# the arguments to `Net::SCP#upload!` so view that for more information.
|
# the arguments to `Net::SCP#upload!` so view that for more information.
|
||||||
def upload!(from, to)
|
def upload!(from, to)
|
||||||
execute do |ssh|
|
execute do |ssh|
|
||||||
scp = Net::SCP.new(ssh)
|
scp = Net::SCP.new(ssh.session)
|
||||||
scp.upload!(from, to)
|
scp.upload!(from, to)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -132,4 +132,52 @@ module Vagrant
|
||||||
return env.config.ssh.port
|
return env.config.ssh.port
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class SSH
|
||||||
|
# A helper class which wraps around `Net::SSH::Connection::Session`
|
||||||
|
# in order to provide basic command error checking while still
|
||||||
|
# providing access to the actual session object.
|
||||||
|
class Session
|
||||||
|
attr_reader :session
|
||||||
|
|
||||||
|
def initialize(session)
|
||||||
|
@session = session
|
||||||
|
end
|
||||||
|
|
||||||
|
# Executes a given command on the SSH session and blocks until
|
||||||
|
# the command completes. This is an almost line for line copy of
|
||||||
|
# the actual `exec!` implementation, except that this
|
||||||
|
# implementation also reports `:exit_status` to the block if given.
|
||||||
|
def exec!(command, &block)
|
||||||
|
block ||= Proc.new do |ch, type, data|
|
||||||
|
ch[:result] ||= ""
|
||||||
|
ch[:result] << data if [:stdout, :stderr].include?(type)
|
||||||
|
end
|
||||||
|
|
||||||
|
metach = session.open_channel do |channel|
|
||||||
|
channel.exec(command) do |ch, success|
|
||||||
|
raise "could not execute command: #{command.inspect}" unless success
|
||||||
|
|
||||||
|
# Output stdout data to the block
|
||||||
|
channel.on_data do |ch2, data|
|
||||||
|
block.call(ch2, :stdout, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Output stderr data to the block
|
||||||
|
channel.on_extended_data do |ch2, type, data|
|
||||||
|
block.call(ch2, :stderr, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Output exit status information to the block
|
||||||
|
channel.on_request("exit-status") do |ch2, data|
|
||||||
|
block.call(ch2, :exit_status, data.read_long)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
metach.wait
|
||||||
|
metach[:result]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,6 +118,15 @@ class SshTest < Test::Unit::TestCase
|
||||||
Net::SSH.expects(:start).with(@env.config.ssh.host, @env.config.ssh.username, anything).once
|
Net::SSH.expects(:start).with(@env.config.ssh.host, @env.config.ssh.username, anything).once
|
||||||
@ssh.execute
|
@ssh.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "yield an SSH session object" do
|
||||||
|
raw = mock("raw")
|
||||||
|
Net::SSH.expects(:start).yields(raw)
|
||||||
|
@ssh.execute do |ssh|
|
||||||
|
assert ssh.is_a?(Vagrant::SSH::Session)
|
||||||
|
assert_equal raw, ssh.session
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "SCPing files to the remote host" do
|
context "SCPing files to the remote host" do
|
||||||
|
@ -128,8 +137,10 @@ class SshTest < Test::Unit::TestCase
|
||||||
should "use Vagrant::SSH execute to setup an SCP connection and upload" do
|
should "use Vagrant::SSH execute to setup an SCP connection and upload" do
|
||||||
scp = mock("scp")
|
scp = mock("scp")
|
||||||
ssh = mock("ssh")
|
ssh = mock("ssh")
|
||||||
|
sess = mock("session")
|
||||||
|
ssh.stubs(:session).returns(sess)
|
||||||
scp.expects(:upload!).with("foo", "bar").once
|
scp.expects(:upload!).with("foo", "bar").once
|
||||||
Net::SCP.expects(:new).with(ssh).returns(scp).once
|
Net::SCP.expects(:new).with(ssh.session).returns(scp).once
|
||||||
@ssh.expects(:execute).yields(ssh).once
|
@ssh.expects(:execute).yields(ssh).once
|
||||||
@ssh.upload!("foo", "bar")
|
@ssh.upload!("foo", "bar")
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
||||||
s.authors = ["Mitchell Hashimoto", "John Bender"]
|
s.authors = ["Mitchell Hashimoto", "John Bender"]
|
||||||
s.date = %q{2010-05-27}
|
s.date = %q{2010-05-28}
|
||||||
s.default_executable = %q{vagrant}
|
s.default_executable = %q{vagrant}
|
||||||
s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.}
|
s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.}
|
||||||
s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"]
|
s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"]
|
||||||
|
|
Loading…
Reference in New Issue