VM shared folders can now be added easily.

This commit is contained in:
Mitchell Hashimoto 2010-02-09 00:21:27 -08:00
parent 9cfa89855d
commit 19f82e72aa
2 changed files with 100 additions and 50 deletions

View File

@ -25,7 +25,6 @@ module Hobo
SSH.connect
end
# Save the state of the current hobo environment to disk
def suspend
Env.require_persisted_vm
@ -61,14 +60,16 @@ error
end
def create
share_folder("hobo-root", Env.root_path, Hobo.config.vm.project_directory)
import
move_hd if Hobo.config[:vm][:hd_location]
persist
setup_mac_address
forward_ports
setup_shared_folder
setup_shared_folders
start
mount_shared_folder
mount_shared_folders
end
def destroy
@ -93,7 +94,7 @@ error
# TODO image extension default?
new_image = hd.image.clone(new_image_file , HD_EXT_DEFAULT, true)
hd.image = new_image
logger.info "Attaching new disk to VM ..."
@vm.save
@ -132,20 +133,28 @@ error
@vm.save(true)
end
def setup_shared_folder
logger.info "Creating shared folders..."
folder = VirtualBox::SharedFolder.new
folder.name = "hobo-root-path"
folder.hostpath = Env.root_path
@vm.shared_folders << folder
def setup_shared_folders
logger.info "Creating shared folders metadata..."
shared_folders.each do |name, hostpath, guestpath|
folder = VirtualBox::SharedFolder.new
folder.name = name
folder.hostpath = hostpath
@vm.shared_folders << folder
end
@vm.save(true)
end
def mount_shared_folder
HOBO_LOGGER.info "Mounting shared folders..."
def mount_shared_folders
logger.info "Mounting shared folders..."
Hobo::SSH.execute do |ssh|
ssh.exec!("sudo mkdir -p #{Hobo.config.vm.project_directory}")
ssh.exec!("sudo mount -t vboxsf hobo-root-path #{Hobo.config.vm.project_directory}")
shared_folders.each do |name, hostpath, guestpath|
logger.info "-- #{name}: #{guestpath}"
ssh.exec!("sudo mkdir -p #{guestpath}")
ssh.exec!("sudo mount -t vboxsf #{name} #{guestpath}")
end
end
end
@ -155,7 +164,7 @@ error
# Now we have to wait for the boot to be successful
logger.info "Waiting for VM to boot..."
Hobo.config[:ssh][:max_tries].to_i.times do |i|
sleep 5 unless ENV['HOBO_ENV'] == 'test'
logger.info "Trying to connect (attempt ##{i+1} of #{Hobo.config[:ssh][:max_tries]})..."
@ -170,11 +179,26 @@ error
false
end
def saved?; @vm.saved? end
def shared_folders(clear=false)
@shared_folders = nil if clear
@shared_folders ||= []
end
def save_state(errs); @vm.save_state(errs) end
def share_folder(name, hostpath, guestpath)
shared_folders << [name, hostpath, guestpath]
end
def saved?
@vm.saved?
end
def save_state(errs)
@vm.save_state(errs)
end
# TODO need a better way to which controller is the hd
def hd; @vm.storage_controllers.first.devices.first end
def hd
@vm.storage_controllers.first.devices.first
end
end
end

View File

@ -78,9 +78,9 @@ class VMTest < Test::Unit::TestCase
@vm.expects(:persist).in_sequence(create_seq)
@vm.expects(:setup_mac_address).in_sequence(create_seq)
@vm.expects(:forward_ports).in_sequence(create_seq)
@vm.expects(:setup_shared_folder).in_sequence(create_seq)
@vm.expects(:setup_shared_folders).in_sequence(create_seq)
@vm.expects(:start).in_sequence(create_seq)
@vm.expects(:mount_shared_folder).in_sequence(create_seq)
@vm.expects(:mount_shared_folders).in_sequence(create_seq)
@vm.create
end
end
@ -170,31 +170,6 @@ class VMTest < Test::Unit::TestCase
end
end
context "setting up the shared folder" do
should "create a shared folder with the root folder for the VM" do
shared_folder = mock("shared_folder")
shared_folder.stubs(:name=)
shared_folder.expects(:hostpath=).with(Hobo::Env.root_path).once
shared_folder_collection = mock("collection")
shared_folder_collection.expects(:<<).with(shared_folder)
VirtualBox::SharedFolder.expects(:new).returns(shared_folder)
@mock_vm.expects(:shared_folders).returns(shared_folder_collection)
@mock_vm.expects(:save).with(true).once
@vm.setup_shared_folder
end
end
context "mounting the shared folders" do
should "create the directory then mount the shared folder" do
mount_seq = sequence("mount_seq")
ssh = mock("ssh")
ssh.expects(:exec!).with("sudo mkdir -p #{Hobo.config.vm.project_directory}").in_sequence(mount_seq)
ssh.expects(:exec!).with("sudo mount -t vboxsf hobo-root-path #{Hobo.config.vm.project_directory}").in_sequence(mount_seq)
Hobo::SSH.expects(:execute).yields(ssh)
@vm.mount_shared_folder
end
end
context "suspending and resuming a vm" do
should "put the vm in a suspended state" do
saved_state_expectation(false)
@ -235,9 +210,60 @@ class VMTest < Test::Unit::TestCase
Hobo::Env.persisted_vm.expects(:start).once.returns(true)
end
end
context "creating a new vm with a specified disk storage location" do
context "shared folders" do
setup do
@mock_vm = mock("mock_vm")
@vm = Hobo::VM.new(@mock_vm)
end
should "not have any shared folders initially" do
assert @vm.shared_folders.empty?
end
should "be able to add shared folders" do
@vm.share_folder("foo", "from", "to")
assert_equal 1, @vm.shared_folders.length
end
should "be able to clear shared folders" do
@vm.share_folder("foo", "from", "to")
assert !@vm.shared_folders.empty?
@vm.shared_folders(true)
assert @vm.shared_folders.empty?
end
should "add all shared folders to the VM with 'setup_shared_folders'" do
@vm.share_folder("foo", "from", "to")
@vm.share_folder("bar", "bfrom", "bto")
share_seq = sequence("share_seq")
shared_folders = mock("shared_folders")
shared_folders.expects(:<<).in_sequence(share_seq).with() { |sf| sf.name == "foo" && sf.hostpath == "from" }
shared_folders.expects(:<<).in_sequence(share_seq).with() { |sf| sf.name == "bar" && sf.hostpath == "bfrom" }
@mock_vm.stubs(:shared_folders).returns(shared_folders)
@mock_vm.expects(:save).with(true).once
@vm.setup_shared_folders
end
should "mount all shared folders to the VM with `mount_shared_folders`" do
@vm.share_folder("foo", "from", "to")
@vm.share_folder("bar", "bfrom", "bto")
mount_seq = sequence("mount_seq")
ssh = mock("ssh")
@vm.shared_folders.each do |name, hostpath, guestpath|
ssh.expects(:exec!).with("sudo mkdir -p #{guestpath}").in_sequence(mount_seq)
ssh.expects(:exec!).with("sudo mount -t vboxsf #{name} #{guestpath}").in_sequence(mount_seq)
end
Hobo::SSH.expects(:execute).yields(ssh)
@vm.mount_shared_folders
end
end
context "creating a new vm with a specified disk storage location" do
should "error and exit of the vm is not powered off" do
# Exit does not prevent method from proceeding in test, so we must set expectations
vm = move_hd_expectations
@ -245,7 +271,7 @@ class VMTest < Test::Unit::TestCase
vm.expects(:error_and_exit)
vm.move_hd
end
should "create assign a new disk image, and delete the old one" do
vm = move_hd_expectations
@mock_vm.expects(:powered_off?).returns(true)
@ -261,11 +287,11 @@ class VMTest < Test::Unit::TestCase
hd.expects(:image).twice.returns(image)
hd.expects(:image=).with(image)
image.expects(:destroy)
@mock_vm.expects(:save)
vm = Hobo::VM.new(@mock_vm)
vm.expects(:hd).times(3).returns(hd)
vm