Initial commit for VirtualBox class.
This commit is contained in:
parent
b054973dc6
commit
a628274e94
2
Gemfile
2
Gemfile
|
@ -5,7 +5,7 @@ gem "net-ssh", ">= 2.0.19"
|
||||||
# gem bundle test
|
# gem bundle test
|
||||||
only :test do
|
only :test do
|
||||||
gem "contest", ">= 0.1.2"
|
gem "contest", ">= 0.1.2"
|
||||||
gem "mocha", ">= 0.9.8"
|
gem "flexmock", ">= 0.8.2"
|
||||||
gem "ruby-debug", ">= 0.10.3" if RUBY_VERSION < '1.9'
|
gem "ruby-debug", ">= 0.10.3" if RUBY_VERSION < '1.9'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,12 @@ libdir = File.dirname(__FILE__)
|
||||||
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
||||||
PROJECT_ROOT = File.join(libdir, '..')
|
PROJECT_ROOT = File.join(libdir, '..')
|
||||||
|
|
||||||
|
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
require 'ftools'
|
require 'ftools'
|
||||||
|
require 'logger'
|
||||||
require 'hobo/config'
|
require 'hobo/config'
|
||||||
require 'hobo/env'
|
require 'hobo/env'
|
||||||
|
require 'hobo/virtual_box'
|
||||||
|
|
||||||
|
# TODO: Make this configurable
|
||||||
|
HOBO_LOGGER = Logger.new(STDOUT)
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
class VirtualBox
|
||||||
|
class <<self
|
||||||
|
def create(name, options = {})
|
||||||
|
modify_options = {
|
||||||
|
# Set up base system: memory, cpus, etc.
|
||||||
|
"memory" => options[:memory] || "360",
|
||||||
|
"vram" => options[:vram] || "12",
|
||||||
|
"ostype" => "Ubuntu",
|
||||||
|
"acpi" => "on",
|
||||||
|
"ioapic" => "off",
|
||||||
|
"cpus" => "1",
|
||||||
|
"pae" => "on",
|
||||||
|
"hwvirtex" => "on",
|
||||||
|
"hwvirtexexcl" => "off",
|
||||||
|
"nestedpaging" => "off",
|
||||||
|
"vtxvpid" => "off",
|
||||||
|
"accelerate3d" => "off",
|
||||||
|
"biosbootmenu" => "messageandmenu",
|
||||||
|
"boot1" => "disk",
|
||||||
|
"boot2" => "dvd",
|
||||||
|
"boot3" => "none",
|
||||||
|
"boot4" => "none",
|
||||||
|
"firmware" => "bios",
|
||||||
|
# Networking
|
||||||
|
"nic1" => "bridged",
|
||||||
|
"nictype1" => "Am79C973",
|
||||||
|
"cableconnected1" => "on",
|
||||||
|
"nictrace1" => "off",
|
||||||
|
"bridgeadapter1" => "en0: Ethernet",
|
||||||
|
# Ports
|
||||||
|
"audio" => "none",
|
||||||
|
"clipboard" => "bidirectional",
|
||||||
|
"usb" => "off",
|
||||||
|
"usbehci" => "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the raw machine itself. In this incarnation, nothing
|
||||||
|
# is yet configured.
|
||||||
|
HOBO_LOGGER.info("Creating VM #{name}...")
|
||||||
|
command("createvm --name #{name} --register")
|
||||||
|
|
||||||
|
# Modify the VM with the options set
|
||||||
|
modify_options.each { |key, value| modify(name, key, value) }
|
||||||
|
|
||||||
|
# Clone the hard drive that we'll be using
|
||||||
|
# TODO: Change hardcoded paths to use config module when ready
|
||||||
|
HOBO_LOGGER.info("Cloning from base disk...")
|
||||||
|
clone_disk("/Users/mitchellh/.hobo/disks/base.vmdk", "/Users/mitchellh/.hobo/disks/#{name}.vmdk")
|
||||||
|
|
||||||
|
# Attach storage controllers
|
||||||
|
HOBO_LOGGER.info("Attaching clone disk to VM...")
|
||||||
|
command("storagectl #{name} --name \"IDE Controller\" --add ide --controller PIIX4 --sataportcount 2")
|
||||||
|
command("storageattach #{name} --storagectl \"IDE Controller\" --port 0 --device 0 --type hdd --medium \"/Users/mitchellh/.hobo/disks/#{name}.vmdk\"")
|
||||||
|
end
|
||||||
|
|
||||||
|
def modify(name, key, value)
|
||||||
|
# Wrap values with spaces in quotes
|
||||||
|
value = "\"#{value}\"" if value =~ /\s/
|
||||||
|
|
||||||
|
command("modifyvm #{name} --#{key} #{value}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def clone_disk(sourcepath, destpath)
|
||||||
|
# TODO: Escape filepaths
|
||||||
|
command("clonehd #{sourcepath} #{destpath}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def command(cmd)
|
||||||
|
HOBO_LOGGER.debug "Command: #{cmd}"
|
||||||
|
result = `VBoxManage #{cmd}`
|
||||||
|
|
||||||
|
if $?.to_i >= 1
|
||||||
|
HOBO_LOGGER.error "VBoxManage command failed: #{cmd}"
|
||||||
|
# TODO: Raise error here that other commands can catch?
|
||||||
|
raise Exception.new("Failure: #{result}")
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||||
|
|
||||||
|
class VirtualBoxTest < Test::Unit::TestCase
|
||||||
|
setup do
|
||||||
|
# Stub out command so nothing actually happens
|
||||||
|
flexmock(VirtualBox)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "modifying VMs" do
|
||||||
|
should "wrap double quotes around values with spaces" do
|
||||||
|
VirtualBox.should_receive(:command).with(/"my value"/)
|
||||||
|
VirtualBox.modify(@name, "key", "my value")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,4 +20,4 @@ rescue LoadError; end
|
||||||
|
|
||||||
require File.join(File.dirname(__FILE__), '..', 'lib', 'hobo')
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'hobo')
|
||||||
require 'contest'
|
require 'contest'
|
||||||
require 'mocha'
|
require 'flexmock/test_unit'
|
||||||
|
|
Loading…
Reference in New Issue