suspend and resume, test for both and failures, small refactor of the Hobo::VM#start and the use of Ping.pingecho in SSH.up?
This commit is contained in:
parent
c9d341ae2b
commit
d0f728b353
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env ruby
|
||||
begin
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/ruby/1.8/environment"))
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require 'git-style-binary/command'
|
||||
|
||||
# Get hobo
|
||||
hobodir = File.join(File.dirname(__FILE__), '..', 'lib')
|
||||
$:.unshift(hobodir) unless $:.include?(hobodir)
|
||||
require 'hobo'
|
||||
|
||||
GitStyleBinary.command do
|
||||
short_desc "resumes the hobo environment"
|
||||
banner <<-EOS
|
||||
Usage: #{command.full_name} #{all_options_string}
|
||||
|
||||
Resumes the hobo environment.
|
||||
|
||||
EOS
|
||||
|
||||
run do |command|
|
||||
Hobo::VM.resume
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env ruby
|
||||
begin
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/ruby/1.8/environment"))
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require 'git-style-binary/command'
|
||||
|
||||
# Get hobo
|
||||
hobodir = File.join(File.dirname(__FILE__), '..', 'lib')
|
||||
$:.unshift(hobodir) unless $:.include?(hobodir)
|
||||
require 'hobo'
|
||||
|
||||
GitStyleBinary.command do
|
||||
short_desc "suspends the hobo environment"
|
||||
banner <<-EOS
|
||||
Usage: #{command.full_name} #{all_options_string}
|
||||
|
||||
Suspends the hobo environment.
|
||||
|
||||
EOS
|
||||
|
||||
run do |command|
|
||||
Hobo::VM.suspend
|
||||
end
|
||||
end
|
|
@ -7,6 +7,8 @@ require 'pathname'
|
|||
require 'logger'
|
||||
require 'virtualbox'
|
||||
require 'net/ssh'
|
||||
require 'ping'
|
||||
require 'hobo/error'
|
||||
require 'hobo/config'
|
||||
require 'hobo/env'
|
||||
require 'hobo/ssh'
|
||||
|
|
|
@ -8,6 +8,8 @@ module Hobo
|
|||
@@persisted_vm = nil
|
||||
@@root_path = nil
|
||||
|
||||
extend Hobo::Error
|
||||
|
||||
class << self
|
||||
def persisted_vm; @@persisted_vm; end
|
||||
def root_path; @@root_path; end
|
||||
|
@ -79,17 +81,6 @@ error
|
|||
return
|
||||
end
|
||||
end
|
||||
|
||||
def error_and_exit(error)
|
||||
puts <<-error
|
||||
=====================================================================
|
||||
Hobo experienced an error!
|
||||
|
||||
#{error.chomp}
|
||||
=====================================================================
|
||||
error
|
||||
exit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module Hobo
|
||||
module Error
|
||||
def error_and_exit(error)
|
||||
puts <<-error
|
||||
=====================================================================
|
||||
Hobo experienced an error!
|
||||
|
||||
#{error.chomp}
|
||||
=====================================================================
|
||||
error
|
||||
exit
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ module Hobo
|
|||
class SSH
|
||||
SCRIPT = File.join(File.dirname(__FILE__), '..', '..', 'script', 'hobo-ssh-expect.sh')
|
||||
|
||||
class <<self
|
||||
class << self
|
||||
def connect(opts={})
|
||||
options = {}
|
||||
[:port, :host, :pass, :uname].each do |param|
|
||||
|
@ -17,6 +17,10 @@ module Hobo
|
|||
yield ssh
|
||||
end
|
||||
end
|
||||
|
||||
def up?
|
||||
Ping.pingecho "localhost", 1, Hobo.config[:ssh][:port]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,9 @@ module Hobo
|
|||
class VM
|
||||
attr_reader :vm
|
||||
|
||||
class <<self
|
||||
extend Hobo::Error
|
||||
|
||||
class << self
|
||||
# Bring up the virtual machine. Imports the base image and
|
||||
# provisions it.
|
||||
def up
|
||||
|
@ -21,6 +23,27 @@ module Hobo
|
|||
SSH.connect
|
||||
end
|
||||
|
||||
|
||||
# Save the state of the current hobo environment to disk
|
||||
def suspend
|
||||
Env.require_persisted_vm
|
||||
error_and_exit(<<-error) if Env.persisted_vm.saved?
|
||||
The hobo virtual environment you are trying to reume is already in a
|
||||
suspended state.
|
||||
error
|
||||
Env.persisted_vm.save_state(true)
|
||||
end
|
||||
|
||||
# Resume the current hobo environment from disk
|
||||
def resume
|
||||
Env.require_persisted_vm
|
||||
error_and_exit(<<-error) unless Env.persisted_vm.saved?
|
||||
The hobo virtual environment you are trying to resume is not in a
|
||||
suspended state.
|
||||
error
|
||||
Env.persisted_vm.start
|
||||
end
|
||||
|
||||
# Finds a virtual machine by a given UUID and either returns
|
||||
# a Hobo::VM object or returns nil.
|
||||
def find(uuid)
|
||||
|
@ -94,23 +117,23 @@ module Hobo
|
|||
|
||||
# Now we have to wait for the boot to be successful
|
||||
HOBO_LOGGER.info "Waiting for VM to boot..."
|
||||
counter = 1
|
||||
begin
|
||||
|
||||
Hobo.config[:ssh][:max_tries].to_i.times do |i|
|
||||
sleep 5 unless ENV['HOBO_ENV'] == 'test'
|
||||
HOBO_LOGGER.info "Trying to connect (attempt ##{counter} of #{Hobo.config[:ssh][:max_tries]})..."
|
||||
SSH.execute { |ssh| }
|
||||
rescue Errno::ECONNREFUSED
|
||||
if counter >= Hobo.config[:ssh][:max_tries].to_i
|
||||
HOBO_LOGGER.info "Failed to connect to VM! Failed to boot?"
|
||||
return false
|
||||
end
|
||||
|
||||
counter += 1
|
||||
retry
|
||||
end
|
||||
HOBO_LOGGER.info "Trying to connect (attempt ##{i+1} of #{Hobo.config[:ssh][:max_tries]})..."
|
||||
|
||||
if Hobo::SSH.up?
|
||||
HOBO_LOGGER.info "VM booted and ready for use!"
|
||||
true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
HOBO_LOGGER.info "Failed to connect to VM! Failed to boot?"
|
||||
false
|
||||
end
|
||||
|
||||
def saved?; @vm.saved? end
|
||||
|
||||
def save_state(errs); @vm.save_state(errs) end
|
||||
end
|
||||
end
|
|
@ -112,15 +112,15 @@ class VMTest < Test::Unit::TestCase
|
|||
@vm.start
|
||||
end
|
||||
|
||||
should "repeatedly SSH while waiting for the VM to start" do
|
||||
ssh_seq = sequence("ssh_seq")
|
||||
Net::SSH.expects(:start).once.raises(Errno::ECONNREFUSED).in_sequence(ssh_seq)
|
||||
Net::SSH.expects(:start).once.in_sequence(ssh_seq)
|
||||
@vm.start
|
||||
should "repeatedly ping the SSH port and return false with no response" do
|
||||
seq = sequence('pings')
|
||||
Ping.expects(:pingecho).times(Hobo.config[:ssh][:max_tries].to_i - 1).returns(false).in_sequence(seq)
|
||||
Ping.expects(:pingecho).once.returns(true).in_sequence(seq)
|
||||
assert @vm.start
|
||||
end
|
||||
|
||||
should "try the max number of times then just return" do
|
||||
Net::SSH.expects(:start).times(Hobo.config[:ssh][:max_tries].to_i).raises(Errno::ECONNREFUSED)
|
||||
should "ping the max number of times then just return" do
|
||||
Ping.expects(:pingecho).times(Hobo.config[:ssh][:max_tries].to_i).returns(false)
|
||||
assert !@vm.start
|
||||
end
|
||||
end
|
||||
|
@ -182,5 +182,48 @@ class VMTest < Test::Unit::TestCase
|
|||
@vm.setup_shared_folder
|
||||
end
|
||||
end
|
||||
|
||||
context "suspending a vm" do
|
||||
should "put the vm in a suspended state" do
|
||||
saved_state_expectations(false)
|
||||
Hobo::VM.suspend
|
||||
end
|
||||
|
||||
should "results in an error and exit if the vm is already in a saved state" do
|
||||
saved_state_expectations(true)
|
||||
Hobo::VM.expects(:error_and_exit)
|
||||
Hobo::VM.suspend
|
||||
end
|
||||
|
||||
def saved_state_expectations(saved)
|
||||
@persisted_vm.expects(:saved?).returns(saved)
|
||||
|
||||
# In this case the exit, is ignored so the expectation of save_state on the persisted
|
||||
# vm must be set
|
||||
@persisted_vm.expects(:save_state).with(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "resuming a vm" do
|
||||
should "start a vm in a suspended state" do
|
||||
start_state_expectaions(true)
|
||||
Hobo::VM.resume
|
||||
end
|
||||
|
||||
should "results in an error and exit if the vm is not in a saved state" do
|
||||
start_state_expectaions(false)
|
||||
|
||||
# In this case the exit, is ignored so the expectation of start on the persisted
|
||||
# vm must be set
|
||||
# TODO research the matter of mocking exit
|
||||
Hobo::VM.expects(:error_and_exit)
|
||||
Hobo::VM.resume
|
||||
end
|
||||
|
||||
def start_state_expectaions(saved)
|
||||
@persisted_vm.expects(:saved?).returns(saved)
|
||||
Hobo::Env.persisted_vm.expects(:start).once.returns(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue