From a628274e94b817d48abd595125894b56e16ca607 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 21 Jan 2010 23:52:10 -0800 Subject: [PATCH] Initial commit for VirtualBox class. --- Gemfile | 2 +- lib/hobo.rb | 6 ++- lib/hobo/virtual_box.rb | 81 +++++++++++++++++++++++++++++++++++ test/hobo/virtual_box_test.rb | 15 +++++++ test/test_helper.rb | 2 +- 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 lib/hobo/virtual_box.rb create mode 100644 test/hobo/virtual_box_test.rb diff --git a/Gemfile b/Gemfile index 9ea89dbd6..7b3a9d251 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem "net-ssh", ">= 2.0.19" # gem bundle test only :test do 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' end diff --git a/lib/hobo.rb b/lib/hobo.rb index a0ce2be90..83a98abd0 100644 --- a/lib/hobo.rb +++ b/lib/hobo.rb @@ -2,8 +2,12 @@ libdir = File.dirname(__FILE__) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) PROJECT_ROOT = File.join(libdir, '..') - require 'ostruct' require 'ftools' +require 'logger' require 'hobo/config' require 'hobo/env' +require 'hobo/virtual_box' + +# TODO: Make this configurable +HOBO_LOGGER = Logger.new(STDOUT) diff --git a/lib/hobo/virtual_box.rb b/lib/hobo/virtual_box.rb new file mode 100644 index 000000000..dfe844722 --- /dev/null +++ b/lib/hobo/virtual_box.rb @@ -0,0 +1,81 @@ +class VirtualBox + class < 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 \ No newline at end of file diff --git a/test/hobo/virtual_box_test.rb b/test/hobo/virtual_box_test.rb new file mode 100644 index 000000000..21ad9d44d --- /dev/null +++ b/test/hobo/virtual_box_test.rb @@ -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 \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 64d6c7c07..7157964b4 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -20,4 +20,4 @@ rescue LoadError; end require File.join(File.dirname(__FILE__), '..', 'lib', 'hobo') require 'contest' -require 'mocha' +require 'flexmock/test_unit'