From 48ea8173c671c386d65d4a10be936f95d5f5fbc5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 21 Dec 2011 13:37:59 -0800 Subject: [PATCH] Lots more VBoxManage --- config/default.rb | 2 +- lib/vagrant/action/builtin.rb | 5 +- lib/vagrant/action/vm/boot.rb | 2 +- lib/vagrant/action/vm/clear_shared_folders.rb | 11 +-- lib/vagrant/action/vm/forward_ports.rb | 14 --- lib/vagrant/action/vm/share_folders.rb | 17 ++-- lib/vagrant/config/vm.rb | 2 +- lib/vagrant/driver/virtualbox.rb | 95 +++++++++++++------ lib/vagrant/ssh.rb | 17 ++-- templates/locales/en.yml | 2 +- 10 files changed, 90 insertions(+), 77 deletions(-) diff --git a/config/default.rb b/config/default.rb index 37545933d..e12716f91 100644 --- a/config/default.rb +++ b/config/default.rb @@ -17,7 +17,7 @@ Vagrant::Config.run do |config| config.vm.box_url = nil config.vm.base_mac = nil config.vm.forward_port("ssh", 22, 2222, :auto => true) - config.vm.boot_mode = "vrdp" + config.vm.boot_mode = "headless" config.vm.guest = :linux # Share the root folder. This can then be overridden by diff --git a/lib/vagrant/action/builtin.rb b/lib/vagrant/action/builtin.rb index f8b21f9b1..1d1570d07 100644 --- a/lib/vagrant/action/builtin.rb +++ b/lib/vagrant/action/builtin.rb @@ -29,8 +29,9 @@ module Vagrant use VM::ShareFolders use VM::HostName use VM::Network - use VM::Customize - use VM::Modify +# TODO: Bring back some sort of "customize" feature. +# use VM::Customize +# use VM::Modify use VM::Boot end end diff --git a/lib/vagrant/action/vm/boot.rb b/lib/vagrant/action/vm/boot.rb index 6148bea17..283f5125f 100644 --- a/lib/vagrant/action/vm/boot.rb +++ b/lib/vagrant/action/vm/boot.rb @@ -19,7 +19,7 @@ module Vagrant def boot @env[:ui].info I18n.t("vagrant.actions.vm.boot.booting") - @env[:vm].vm.start(@env[:vm].config.vm.boot_mode) + @env[:vm].driver.start(@env[:vm].config.vm.boot_mode) end def wait_for_boot diff --git a/lib/vagrant/action/vm/clear_shared_folders.rb b/lib/vagrant/action/vm/clear_shared_folders.rb index f315f5f5d..7ebeee543 100644 --- a/lib/vagrant/action/vm/clear_shared_folders.rb +++ b/lib/vagrant/action/vm/clear_shared_folders.rb @@ -8,17 +8,8 @@ module Vagrant end def call(env) - proc = lambda do |vm| - if vm.shared_folders.length > 0 - env[:ui].info I18n.t("vagrant.actions.vm.clear_shared_folders.deleting") + env[:vm].driver.clear_shared_folders - vm.shared_folders.dup.each do |shared_folder| - shared_folder.destroy - end - end - end - - env["vm.modify"].call(proc) @app.call(env) end end diff --git a/lib/vagrant/action/vm/forward_ports.rb b/lib/vagrant/action/vm/forward_ports.rb index 3458c3ec1..ec246cd81 100644 --- a/lib/vagrant/action/vm/forward_ports.rb +++ b/lib/vagrant/action/vm/forward_ports.rb @@ -118,20 +118,6 @@ module Vagrant @env[:vm].driver.forward_ports(ports) end - - #-------------------------------------------------------------- - # General Helpers - #-------------------------------------------------------------- - - # Forwards a port. - def forward_port(vm, name, options) - port = VirtualBox::NATForwardedPort.new - port.name = name - port.guestport = options[:guestport] - port.hostport = options[:hostport] - port.protocol = options[:protocol] || :tcp - vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port - end end end end diff --git a/lib/vagrant/action/vm/share_folders.rb b/lib/vagrant/action/vm/share_folders.rb index f325cd14d..6bfa9fbb1 100644 --- a/lib/vagrant/action/vm/share_folders.rb +++ b/lib/vagrant/action/vm/share_folders.rb @@ -33,18 +33,17 @@ module Vagrant end def create_metadata - proc = lambda do |vm| - @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating") + @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating") - shared_folders.each do |name, data| - folder = VirtualBox::SharedFolder.new - folder.name = name - folder.host_path = File.expand_path(data[:hostpath], @env[:root_path]) - vm.shared_folders << folder - end + folders = [] + shared_folders.each do |name, data| + folders << { + :name => name, + :hostpath => File.expand_path(data[:hostpath], @env[:root_path]) + } end - @env["vm.modify"].call(proc) + @env[:vm].driver.share_folders(folders) end def mount_shared_folders diff --git a/lib/vagrant/config/vm.rb b/lib/vagrant/config/vm.rb index fe292ad86..52b3f0f50 100644 --- a/lib/vagrant/config/vm.rb +++ b/lib/vagrant/config/vm.rb @@ -95,7 +95,7 @@ module Vagrant def validate(env, errors) errors.add(I18n.t("vagrant.config.vm.box_missing")) if !box errors.add(I18n.t("vagrant.config.vm.box_not_found", :name => box)) if box && !box_url && !env.boxes.find(box) - errors.add(I18n.t("vagrant.config.vm.boot_mode_invalid")) if ![:vrdp, :gui].include?(boot_mode.to_sym) + errors.add(I18n.t("vagrant.config.vm.boot_mode_invalid")) if ![:headless, :gui].include?(boot_mode.to_sym) errors.add(I18n.t("vagrant.config.vm.base_mac_invalid")) if env.boxes.find(box) && !base_mac shared_folders.each do |name, options| diff --git a/lib/vagrant/driver/virtualbox.rb b/lib/vagrant/driver/virtualbox.rb index 283bc2757..21e8b1379 100644 --- a/lib/vagrant/driver/virtualbox.rb +++ b/lib/vagrant/driver/virtualbox.rb @@ -35,6 +35,16 @@ module Vagrant execute("modifyvm", @uuid, *args) if !args.empty? end + # This clears all the shared folders that have been set + # on the virtual machine. + def clear_shared_folders + execute("showvminfo", @uuid, "--machinereadable").split("\n").each do |line| + if line =~ /^SharedFolderNameMachineMapping\d+="(.+?)"$/ + execute("sharedfolder", "remove", @uuid, "--name", $1.to_s) + end + end + end + # This deletes the VM with the given name. def delete execute("unregistervm", @uuid, "--delete") @@ -49,8 +59,8 @@ module Vagrant # # { # :name => "foo", - # :host_port => 8500, - # :guest_port => 80, + # :hostport => 8500, + # :guestport => 80, # :adapter => 1, # :protocol => "tcp" # } @@ -66,9 +76,9 @@ module Vagrant pf_builder = [options[:name], options[:protocol] || "tcp", "", - options[:host_port], + options[:hostport], "", - options[:guest_port]] + options[:guestport]] args.concat(["--natpf#{options[:adapter] || 1}", pf_builder.join(",")]) @@ -89,6 +99,35 @@ module Vagrant nil end + # This returns a list of the forwarded ports in the form + # of `[nic, name, hostport, guestport]`. + # + # @return [Array] + def read_forwarded_ports(uuid=nil, active_only=false) + uuid ||= @uuid + + results = [] + current_nic = nil + execute("showvminfo", uuid, "--machinereadable").split("\n").each do |line| + # This is how we find the nic that a FP is attached to, + # since this comes first. + current_nic = $1.to_i if line =~ /^nic(\d+)=".+?"$/ + + # If we care about active VMs only, then we check the state + # to verify the VM is running. + if active_only && line =~ /^VMState="(.+?)"$/ && $1.to_s != "running" + return [] + end + + # Parse out the forwarded port information + if line =~ /^Forwarding.+?="(.+?),.+?,.*?,(.+?),.*?,(.+?)"$/ + results << [current_nic, $1.to_s, $2.to_i, $3.to_i] + end + end + + results + end + # This reads the guest additions version for a VM. def read_guest_additions_version output = execute("guestproperty", "get", @uuid, "/VirtualBox/GuestAdd/Version") @@ -129,35 +168,33 @@ module Vagrant execute("modifyvm", @uuid, "--macaddress1", mac) end - protected - - # This returns a list of the forwarded ports in the form - # of `[nic, name, hostport, guestport]`. + # Sets up the shared folder metadata for a virtual machine. # - # @return [Array] - def read_forwarded_ports(uuid, active_only=false) - results = [] - current_nic = nil - execute("showvminfo", uuid, "--machinereadable").split("\n").each do |line| - # This is how we find the nic that a FP is attached to, - # since this comes first. - current_nic = $1.to_i if line =~ /^nic(\d+)=".+?"$/ - - # If we care about active VMs only, then we check the state - # to verify the VM is running. - if active_only && line =~ /^VMState="(.+?)"$/ && $1.to_s != "running" - return [] - end - - # Parse out the forwarded port information - if line =~ /^Forwarding.+?="(.+?),.+?,.*?,(.+?),.*?,(.+?)"$/ - results << [current_nic, $1.to_s, $2.to_i, $3.to_i] - end + # The structure of a folder definition should be the following: + # + # { + # :name => "foo", + # :hostpath => "/foo/bar" + # } + # + # @param [Array] folders An array of folder definitions to + # setup. + def share_folders(folders) + folders.each do |folder| + execute("sharedfolder", "add", @uuid, "--name", + folder[:name], "--hostpath", folder[:hostpath]) end - - results end + # Starts the virtual machine in the given mode. + # + # @param [String] mode Mode to boot the VM: either "headless" or "gui" + def start(mode) + execute("startvm", @uuid, "--type", mode.to_s) + end + + protected + # This returns the version of VirtualBox that is running. # # @return [String] diff --git a/lib/vagrant/ssh.rb b/lib/vagrant/ssh.rb index 4074f0398..0e41f5e62 100644 --- a/lib/vagrant/ssh.rb +++ b/lib/vagrant/ssh.rb @@ -180,15 +180,14 @@ module Vagrant # Check if we have an SSH forwarded port pnum_by_name = nil pnum_by_destination = nil - @vm.vm.network_adapters.each do |na| - # Look for the port number by name... - pnum_by_name = na.nat_driver.forwarded_ports.detect do |fp| - fp.name == @vm.config.ssh.forwarded_port_key + @vm.driver.read_forwarded_ports.each do |_, name, hostport, guestport| + # Record the forwarded port if we find it by name + if name == @vm.config.ssh.forwarded_port_key + pnum_by_name = hostport end - # Look for the port number by destination... - pnum_by_destination = na.nat_driver.forwarded_ports.detect do |fp| - fp.guestport == @vm.config.ssh.forwarded_port_destination + if guestport == @vm.config.ssh.forwarded_port_destination + pnum_by_destination = hostport end # pnum_by_name is what we're looking for here, so break early @@ -196,8 +195,8 @@ module Vagrant break if pnum_by_name end - return pnum_by_name.hostport if pnum_by_name - return pnum_by_destination.hostport if pnum_by_destination + return pnum_by_name if pnum_by_name + return pnum_by_destination if pnum_by_destination # This should NEVER happen. raise Errors::SSHPortNotDetected diff --git a/templates/locales/en.yml b/templates/locales/en.yml index d5f4d5ccd..59b1cdc4d 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -178,7 +178,7 @@ en: private_key_missing: "`private_key_path` file must exist: %{path}" vm: base_mac_invalid: "Base MAC address for eth0/NAT must be set. Contact box maintainer for more information." - boot_mode_invalid: "Boot mode must be one of: vrdp or gui" + boot_mode_invalid: "Boot mode must be one of: headless or gui" box_missing: "A box must be specified." box_not_found: "The box '%{name}' could not be found." network_ip_invalid: "The host only network IP '%{ip}' is invalid."