`vagrant up`!
This commit is contained in:
parent
aaeb060f33
commit
b659191a02
|
@ -184,6 +184,10 @@ module Vagrant
|
|||
|
||||
# Store the ID locally
|
||||
@id = value
|
||||
|
||||
# Notify the provider that the ID changed in case it needs to do
|
||||
# any accounting from it.
|
||||
@provider.machine_id_changed
|
||||
end
|
||||
|
||||
# This returns a clean inspect value so that printing the value via
|
||||
|
|
|
@ -21,6 +21,15 @@ module Vagrant
|
|||
nil
|
||||
end
|
||||
|
||||
# This method is called if the underying machine ID changes. Providers
|
||||
# can use this method to load in new data for the actual backing
|
||||
# machine or to realize that the machine is now gone (the ID can
|
||||
# become `nil`). No parameters are given, since the underlying machine
|
||||
# is simply the machine instance given to this object. And no
|
||||
# return value is necessary.
|
||||
def machine_id_changed
|
||||
end
|
||||
|
||||
# This should return a hash of information that explains how to
|
||||
# SSH into the machine. If the machine is not at a point where
|
||||
# SSH is even possible, then `nil` should be returned.
|
||||
|
|
|
@ -11,10 +11,10 @@ module VagrantPlugins
|
|||
|
||||
def execute
|
||||
options = {}
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: vagrant up [vm-name] [--[no-]provision] [-h]"
|
||||
opts.separator ""
|
||||
build_start_options(opts, options)
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant up [vm-name] [--[no-]provision] [-h]"
|
||||
o.separator ""
|
||||
build_start_options(o, options)
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -23,20 +23,13 @@ module VagrantPlugins
|
|||
|
||||
# Go over each VM and bring it up
|
||||
@logger.debug("'Up' each target VM...")
|
||||
with_target_vms(argv) do |vm|
|
||||
if vm.created?
|
||||
@logger.info("Booting: #{vm.name}")
|
||||
vm.ui.info I18n.t("vagrant.commands.up.vm_created")
|
||||
vm.start(options)
|
||||
else
|
||||
@logger.info("Creating: #{vm.name}")
|
||||
vm.up(options)
|
||||
end
|
||||
with_target_vms(argv) do |machine|
|
||||
machine.action(:up)
|
||||
end
|
||||
|
||||
# Success, exit status 0
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,9 @@ module VagrantPlugins
|
|||
module Action
|
||||
autoload :Boot, File.expand_path("../action/boot", __FILE__)
|
||||
autoload :CheckAccessible, File.expand_path("../action/check_accessible", __FILE__)
|
||||
autoload :CheckBox, File.expand_path("../action/check_box", __FILE__)
|
||||
autoload :CheckCreated, File.expand_path("../action/check_created", __FILE__)
|
||||
autoload :CheckGuestAdditions, File.expand_path("../action/check_guest_additions", __FILE__)
|
||||
autoload :CheckPortCollisions, File.expand_path("../action/check_port_collisions", __FILE__)
|
||||
autoload :CheckRunning, File.expand_path("../action/check_running", __FILE__)
|
||||
autoload :CheckVirtualbox, File.expand_path("../action/check_virtualbox", __FILE__)
|
||||
|
@ -15,6 +17,7 @@ module VagrantPlugins
|
|||
autoload :ClearSharedFolders, File.expand_path("../action/clear_shared_folders", __FILE__)
|
||||
autoload :Created, File.expand_path("../action/created", __FILE__)
|
||||
autoload :Customize, File.expand_path("../action/customize", __FILE__)
|
||||
autoload :DefaultName, File.expand_path("../action/default_name", __FILE__)
|
||||
autoload :Destroy, File.expand_path("../action/destroy", __FILE__)
|
||||
autoload :DestroyConfirm, File.expand_path("../action/destroy_confirm", __FILE__)
|
||||
autoload :DestroyUnusedNetworkInterfaces, File.expand_path("../action/destroy_unused_network_interfaces", __FILE__)
|
||||
|
@ -22,7 +25,10 @@ module VagrantPlugins
|
|||
autoload :ForwardPorts, File.expand_path("../action/forward_ports", __FILE__)
|
||||
autoload :Halt, File.expand_path("../action/halt", __FILE__)
|
||||
autoload :HostName, File.expand_path("../action/host_name", __FILE__)
|
||||
autoload :Import, File.expand_path("../action/import", __FILE__)
|
||||
autoload :IsRunning, File.expand_path("../action/is_running", __FILE__)
|
||||
autoload :IsSaved, File.expand_path("../action/is_saved", __FILE__)
|
||||
autoload :MatchMACAddress, File.expand_path("../action/match_mac_address", __FILE__)
|
||||
autoload :MessageNotCreated, File.expand_path("../action/message_not_created", __FILE__)
|
||||
autoload :MessageNotRunning, File.expand_path("../action/message_not_running", __FILE__)
|
||||
autoload :MessageWillNotDestroy, File.expand_path("../action/message_will_not_destroy", __FILE__)
|
||||
|
@ -40,6 +46,29 @@ module VagrantPlugins
|
|||
# things.
|
||||
include Vagrant::Action::Builtin
|
||||
|
||||
# This action boots the VM, assuming the VM is in a state that requires
|
||||
# a bootup (i.e. not saved).
|
||||
def self.action_boot
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use CheckAccessible
|
||||
b.use CleanMachineFolder
|
||||
b.use ClearForwardedPorts
|
||||
b.use EnvSet, :port_collision_handler => :correct
|
||||
b.use ForwardPorts
|
||||
b.use Provision
|
||||
b.use PruneNFSExports
|
||||
b.use NFS
|
||||
b.use ClearSharedFolders
|
||||
b.use ShareFolders
|
||||
b.use ClearNetworkInterfaces
|
||||
b.use Network
|
||||
b.use HostName
|
||||
b.use SaneDefaults
|
||||
b.use Customize
|
||||
b.use Boot
|
||||
end
|
||||
end
|
||||
|
||||
# This is the action that is primarily responsible for completely
|
||||
# freeing the resources of the underlying virtual machine.
|
||||
def self.action_destroy
|
||||
|
@ -175,22 +204,21 @@ module VagrantPlugins
|
|||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use CheckVirtualbox
|
||||
b.use Vagrant::Action::General::Validate
|
||||
b.use CheckAccessible
|
||||
b.use CleanMachineFolder
|
||||
b.use ClearForwardedPorts
|
||||
b.use EnvSet, :port_collision_handler => :correct
|
||||
b.use ForwardPorts
|
||||
b.use Provision
|
||||
b.use PruneNFSExports
|
||||
b.use NFS
|
||||
b.use ClearSharedFolders
|
||||
b.use ShareFolders
|
||||
b.use ClearNetworkInterfaces
|
||||
b.use Network
|
||||
b.use HostName
|
||||
b.use SaneDefaults
|
||||
b.use Customize
|
||||
b.use Boot
|
||||
b.use Call, IsRunning do |env, b2|
|
||||
# If the VM is running, then our work here is done, exit
|
||||
next if env[:result]
|
||||
|
||||
b2.use Call, IsSaved do |env2, b3|
|
||||
if env2[:result]
|
||||
# The VM is saved, so just resume it
|
||||
b3.use action_resume
|
||||
else
|
||||
# The VM is not saved, so we must have to boot it up
|
||||
# like normal. Boot!
|
||||
b3.use action_boot
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -209,6 +237,27 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This action brings the machine up from nothing, including importing
|
||||
# the box, configuring metadata, and booting.
|
||||
def self.action_up
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use CheckVirtualbox
|
||||
b.use Vagrant::Action::General::Validate
|
||||
b.use Call, Created do |env, b2|
|
||||
# If the VM is NOT created yet, then do the setup steps
|
||||
if !env[:result]
|
||||
b2.use CheckAccessible
|
||||
b2.use CheckBox
|
||||
b2.use Import
|
||||
b2.use CheckGuestAdditions
|
||||
b2.use DefaultName
|
||||
b2.use MatchMACAddress
|
||||
end
|
||||
end
|
||||
b.use action_start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class CheckBox
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
box_name = env[:machine].config.vm.box
|
||||
raise Vagrant::Errors::BoxNotSpecified if !box_name
|
||||
|
||||
if !env[:box_collection].find(box_name, :virtualbox)
|
||||
box_url = env[:machine].config.vm.box_url
|
||||
raise Vagrant::Errors::BoxSpecifiedDoesntExist, :name => box_name if !box_url
|
||||
|
||||
# Add the box then reload the box collection so that it becomes
|
||||
# aware of it.
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.check_box.not_found", :name => box_name)
|
||||
env[:box_collection].add(box_name, box_url)
|
||||
env[:box_collection].reload!
|
||||
|
||||
# Reload the environment and set the VM to be the new loaded VM.
|
||||
env[:machine].env.reload!
|
||||
env[:machine] = env[:machine].env.vms[env[:machine].name]
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class CheckGuestAdditions
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Use the raw interface for now, while the virtualbox gem
|
||||
# doesn't support guest properties (due to cross platform issues)
|
||||
version = env[:machine].provider.driver.read_guest_additions_version
|
||||
if !version
|
||||
env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_additions.not_detected")
|
||||
else
|
||||
# Strip the -OSE/_OSE off from the guest additions and the virtual box
|
||||
# version since all the matters are that the version _numbers_ match up.
|
||||
guest_version, vb_version = [version, env[:machine].provider.driver.version].map do |v|
|
||||
v.gsub(/[-_]ose/i, '')
|
||||
end
|
||||
|
||||
if guest_version != vb_version
|
||||
env[:ui].warn(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch",
|
||||
:guest_version => version,
|
||||
:virtualbox_version => vb_version))
|
||||
end
|
||||
end
|
||||
|
||||
# Continue
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
require "log4r"
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class DefaultName
|
||||
def initialize(app, env)
|
||||
@logger = Log4r::Logger.new("vagrant::action::vm::defaultname")
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@logger.info("Setting the default name of the VM")
|
||||
name = env[:root_path].basename.to_s + "_#{Time.now.to_i}"
|
||||
env[:machine].provider.driver.set_name(name)
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class Import
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.import.importing",
|
||||
:name => env[:machine].box.name)
|
||||
|
||||
# Import the virtual machine
|
||||
ovf_file = env[:machine].box.directory.join("box.ovf").to_s
|
||||
env[:machine].id = env[:machine].provider.driver.import(ovf_file) do |progress|
|
||||
env[:ui].clear_line
|
||||
env[:ui].report_progress(progress, 100, false)
|
||||
end
|
||||
|
||||
# Clear the line one last time since the progress meter doesn't disappear
|
||||
# immediately.
|
||||
env[:ui].clear_line
|
||||
|
||||
# If we got interrupted, then the import could have been
|
||||
# interrupted and its not a big deal. Just return out.
|
||||
return if env[:interrupted]
|
||||
|
||||
# Flag as erroneous and return if import failed
|
||||
raise Vagrant::Errors::VMImportFailure if !env[:machine].id
|
||||
|
||||
# Import completed successfully. Continue the chain
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def recover(env)
|
||||
if env[:machine].provider.state != :not_created
|
||||
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
||||
|
||||
# Interrupted, destroy the VM. We note that we don't want to
|
||||
# validate the configuration here.
|
||||
destroy_env = env.clone
|
||||
destroy_env[:validate] = false
|
||||
env[:action_runner].run(Action.action_destroy, destroy_env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class IsSaved
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Set the result to be true if the machine is saved.
|
||||
env[:result] = env[:machine].state == :saved
|
||||
|
||||
# Call the next if we have one (but we shouldn't, since this
|
||||
# middleware is built to run with the Call-type middlewares)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class MatchMACAddress
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
raise Vagrant::Errors::VMBaseMacNotSpecified if !env[:machine].config.vm.base_mac
|
||||
|
||||
# Create the proc which we want to use to modify the virtual machine
|
||||
env[:ui].info I18n.t("vagrant.actions.vm.match_mac.matching")
|
||||
env[:machine].provider.driver.set_mac_address(env[:machine].config.vm.base_mac)
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,16 +9,9 @@ module VagrantPlugins
|
|||
@logger = Log4r::Logger.new("vagrant::provider::virtualbox")
|
||||
@machine = machine
|
||||
|
||||
begin
|
||||
@logger.debug("Instantiating the driver for machine ID: #{@machine.id.inspect}")
|
||||
@driver = Driver::Meta.new(@machine.id)
|
||||
rescue Driver::Meta::VMNotFound
|
||||
# The virtual machine doesn't exist, so we probably have a stale
|
||||
# ID. Just clear the id out of the machine and reload it.
|
||||
@logger.debug("VM not found! Clearing saved machine ID and reloading.")
|
||||
@machine.id = nil
|
||||
retry
|
||||
end
|
||||
# This method will load in our driver, so we call it now to
|
||||
# initialize it.
|
||||
machine_id_changed
|
||||
end
|
||||
|
||||
# @see Vagrant::Plugin::V1::Provider#action
|
||||
|
@ -31,6 +24,23 @@ module VagrantPlugins
|
|||
nil
|
||||
end
|
||||
|
||||
# If the machine ID changed, then we need to rebuild our underlying
|
||||
# driver.
|
||||
def machine_id_changed
|
||||
id = @machine.id
|
||||
|
||||
begin
|
||||
@logger.debug("Instantiating the driver for machine ID: #{@machine.id.inspect}")
|
||||
@driver = Driver::Meta.new(id)
|
||||
rescue Driver::Meta::VMNotFound
|
||||
# The virtual machine doesn't exist, so we probably have a stale
|
||||
# ID. Just clear the id out of the machine and reload it.
|
||||
@logger.debug("VM not found! Clearing saved machine ID and reloading.")
|
||||
id = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the SSH info for accessing the VirtualBox VM.
|
||||
def ssh_info
|
||||
# If the VM is not created then we cannot possibly SSH into it, so
|
||||
|
|
|
@ -90,6 +90,10 @@ describe Vagrant::Machine do
|
|||
end
|
||||
|
||||
it "should have access to the ID" do
|
||||
# Stub this because #id= calls it.
|
||||
provider.stub(:machine_id_changed)
|
||||
|
||||
# Set the ID on the previous instance so that it is persisted
|
||||
instance.id = "foo"
|
||||
|
||||
provider_init_test do |machine|
|
||||
|
@ -270,6 +274,10 @@ describe Vagrant::Machine do
|
|||
end
|
||||
|
||||
describe "setting the ID" do
|
||||
before(:each) do
|
||||
provider.stub(:machine_id_changed)
|
||||
end
|
||||
|
||||
it "should not have an ID by default" do
|
||||
instance.id.should be_nil
|
||||
end
|
||||
|
@ -279,6 +287,12 @@ describe Vagrant::Machine do
|
|||
instance.id.should == "bar"
|
||||
end
|
||||
|
||||
it "should notify the machine that the ID changed" do
|
||||
provider.should_receive(:machine_id_changed).once
|
||||
|
||||
instance.id = "bar"
|
||||
end
|
||||
|
||||
it "should persist the ID" do
|
||||
instance.id = "foo"
|
||||
new_instance.id.should == "foo"
|
||||
|
|
Loading…
Reference in New Issue