`vagrant up`
This commit is contained in:
parent
7191a54ed7
commit
43cadfe830
|
@ -46,6 +46,14 @@ module Vagrant
|
||||||
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Global registry of commands that are available via the CLI.
|
||||||
|
#
|
||||||
|
# This registry is used to look up the sub-commands that are available
|
||||||
|
# to Vagrant.
|
||||||
|
def self.commands
|
||||||
|
@commands ||= Registry.new
|
||||||
|
end
|
||||||
|
|
||||||
# Global registry of config keys that are available.
|
# Global registry of config keys that are available.
|
||||||
#
|
#
|
||||||
# This registry is used to look up the keys for `config` objects.
|
# This registry is used to look up the keys for `config` objects.
|
||||||
|
@ -85,7 +93,10 @@ end
|
||||||
# # Default I18n to load the en locale
|
# # Default I18n to load the en locale
|
||||||
I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_root)
|
I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_root)
|
||||||
|
|
||||||
# Registry the build-in config keys
|
# Register the built-in commands
|
||||||
|
Vagrant.commands.register(:up) { Vagrant::Command::Up }
|
||||||
|
|
||||||
|
# Register the built-in config keys
|
||||||
Vagrant.config_keys.register(:vagrant) { Vagrant::Config::VagrantConfig }
|
Vagrant.config_keys.register(:vagrant) { Vagrant::Config::VagrantConfig }
|
||||||
Vagrant.config_keys.register(:ssh) { Vagrant::Config::SSHConfig }
|
Vagrant.config_keys.register(:ssh) { Vagrant::Config::SSHConfig }
|
||||||
Vagrant.config_keys.register(:nfs) { Vagrant::Config::NFSConfig }
|
Vagrant.config_keys.register(:nfs) { Vagrant::Config::NFSConfig }
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
|
require 'log4r'
|
||||||
require 'optparse'
|
require 'optparse'
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
# Manages the command line interface to Vagrant.
|
# Manages the command line interface to Vagrant.
|
||||||
class CLI < Command::Base
|
class CLI < Command::Base
|
||||||
def initialize(argv, env)
|
def initialize(argv, env)
|
||||||
@env = env
|
super
|
||||||
|
|
||||||
|
@logger = Log4r::Logger.new("vagrant::cli")
|
||||||
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
|
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
|
||||||
|
|
||||||
|
@logger.info("CLI: #{@main_args.inspect} #{@sub_command.inspect} #{@sub_args.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
@ -22,9 +27,18 @@ module Vagrant
|
||||||
# the help and exit.
|
# the help and exit.
|
||||||
return help
|
return help
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If we reached this far then we must have a subcommand. If not,
|
||||||
|
# then we also just print the help and exit.
|
||||||
|
command_class = Vagrant.commands.get(@sub_command.to_sym)
|
||||||
|
return help if !command_class || !@sub_command
|
||||||
|
@logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
|
||||||
|
|
||||||
|
# Initialize and execute the command class.
|
||||||
|
command_class.new(@sub_args, @env).execute
|
||||||
end
|
end
|
||||||
|
|
||||||
# This prints the help for the CLI out.
|
# This prints out the help for the CLI.
|
||||||
def help
|
def help
|
||||||
# We use the optionparser for this. Its just easier. We don't use
|
# We use the optionparser for this. Its just easier. We don't use
|
||||||
# an optionparser above because I don't think the performance hits
|
# an optionparser above because I don't think the performance hits
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Command
|
module Command
|
||||||
autoload :Base, 'vagrant/command/base'
|
autoload :Base, 'vagrant/command/base'
|
||||||
|
|
||||||
|
autoload :Up, 'vagrant/command/up'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,63 @@
|
||||||
|
require 'log4r'
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Command
|
module Command
|
||||||
|
# Base class for any CLI commands.
|
||||||
|
#
|
||||||
|
# This class provides documentation on the interface as well as helper
|
||||||
|
# functions that a command has.
|
||||||
class Base
|
class Base
|
||||||
|
def initialize(argv, env)
|
||||||
|
@argv = argv
|
||||||
|
@env = env
|
||||||
|
@logger = Log4r::Logger.new("vagrant::command::#{self.class.to_s.downcase}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# This is what is called on the class to actually execute it. Any
|
||||||
|
# subclasses should implement this method and do any option parsing
|
||||||
|
# and validation here.
|
||||||
|
def execute; end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
# Parses the options given an OptionParser instance.
|
||||||
|
#
|
||||||
|
# This is a convenience method that properly handles duping the
|
||||||
|
# originally argv array so that it is not destroyed. That is all.
|
||||||
|
def parse_options(opts)
|
||||||
|
argv = @argv.dup
|
||||||
|
opts.parse!(argv)
|
||||||
|
return argv
|
||||||
|
end
|
||||||
|
|
||||||
|
# Yields a VM for each target VM for the command.
|
||||||
|
#
|
||||||
|
# This is a convenience method for easily implementing methods that
|
||||||
|
# take a target VM (in the case of multi-VM) or every VM if no
|
||||||
|
# specific VM name is specified.
|
||||||
|
#
|
||||||
|
# @param [String] name The name of the VM. Nil if every VM.
|
||||||
|
def with_target_vms(name=nil)
|
||||||
|
# First determine the proper array of VMs.
|
||||||
|
vms = []
|
||||||
|
if name
|
||||||
|
raise Errors::MultiVMEnvironmentRequired if !@env.multivm?
|
||||||
|
vms << @env.vms[name.to_sym]
|
||||||
|
raise Errors::VMNotFoundError, :name => name if !vms[0]
|
||||||
|
else
|
||||||
|
vms = @env.vms_ordered
|
||||||
|
end
|
||||||
|
|
||||||
|
# Go through each VM and yield it!
|
||||||
|
vms.each do |old_vm|
|
||||||
|
# We get a new VM from the environment here to avoid potentially
|
||||||
|
# stale VMs (if there was a config reload on the environment
|
||||||
|
# or something).
|
||||||
|
vm = @env.vms[old_vm.name]
|
||||||
|
yield vm
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# This method will split the argv given into three parts: the
|
# This method will split the argv given into three parts: the
|
||||||
# flags to this command, the subcommand, and the flags to the
|
# flags to this command, the subcommand, and the flags to the
|
||||||
# subcommand. For example:
|
# subcommand. For example:
|
||||||
|
@ -36,6 +91,10 @@ module Vagrant
|
||||||
main_args = argv[0, i]
|
main_args = argv[0, i]
|
||||||
sub_command = argv[i]
|
sub_command = argv[i]
|
||||||
sub_args = argv[i + 1, argv.length - i + 1]
|
sub_args = argv[i + 1, argv.length - i + 1]
|
||||||
|
|
||||||
|
# Break so we don't find the next non flag and shift our
|
||||||
|
# main args.
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
module Vagrant
|
|
||||||
module Command
|
|
||||||
module Helpers
|
|
||||||
# Initializes the environment by pulling the environment out of
|
|
||||||
# the configuration hash and sets up the UI if necessary.
|
|
||||||
def initialize_environment(args, options, config)
|
|
||||||
raise Errors::CLIMissingEnvironment if !config[:env]
|
|
||||||
@env = config[:env]
|
|
||||||
end
|
|
||||||
|
|
||||||
# This returns an array of {VM} objects depending on the arguments
|
|
||||||
# given to the command.
|
|
||||||
def target_vms(name=nil)
|
|
||||||
raise Errors::NoEnvironmentError if !env.root_path
|
|
||||||
|
|
||||||
name ||= self.name rescue nil
|
|
||||||
|
|
||||||
@target_vms ||= begin
|
|
||||||
if env.multivm?
|
|
||||||
return env.vms_ordered if !name
|
|
||||||
vm = env.vms[name.to_sym]
|
|
||||||
raise Errors::VMNotFoundError, :name => name if !vm
|
|
||||||
else
|
|
||||||
raise Errors::MultiVMEnvironmentRequired if name
|
|
||||||
vm = env.vms.values.first
|
|
||||||
end
|
|
||||||
|
|
||||||
[vm]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This will yield for each target VM to the command. The VM is guaranteed
|
|
||||||
# to be loaded on each iteration.
|
|
||||||
def with_target_vms
|
|
||||||
target_vms.each do |old_vm|
|
|
||||||
# We get a new VM here to avoid potentially stale VMs
|
|
||||||
vm = env.vms[old_vm.name]
|
|
||||||
yield vm
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,15 +1,38 @@
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Command
|
module Command
|
||||||
class UpCommand < NamedBase
|
class Up < Base
|
||||||
class_option :provision, :type => :boolean, :default => true
|
|
||||||
register "up", "Creates the Vagrant environment"
|
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
with_target_vms do |vm|
|
options = {}
|
||||||
|
|
||||||
|
opts = OptionParser.new do |opts|
|
||||||
|
opts.banner = "Usage: vagrant up [vm-name] [--[no-]provision] [-h]"
|
||||||
|
|
||||||
|
opts.separator ""
|
||||||
|
|
||||||
|
opts.on("--[no-]provision", "Enable or disable provisioning") do |p|
|
||||||
|
options[:provision] = p
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on("-h", "--help", "Print this help") do
|
||||||
|
puts opts.help
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Parse the options
|
||||||
|
argv = parse_options(opts)
|
||||||
|
|
||||||
|
# Go over each VM and bring it up
|
||||||
|
@logger.debug("'Up' each target VM...")
|
||||||
|
with_target_vms(argv[0]) do |vm|
|
||||||
if vm.created?
|
if vm.created?
|
||||||
vm.env.ui.info I18n.t("vagrant.commands.up.vm_created")
|
@logger.info("Booting: #{vm.name}")
|
||||||
|
vm.ui.info I18n.t("vagrant.commands.up.vm_created")
|
||||||
vm.start("provision.enabled" => options[:provision])
|
vm.start("provision.enabled" => options[:provision])
|
||||||
else
|
else
|
||||||
|
@logger.info("Creating: #{vm.name}")
|
||||||
vm.up("provision.enabled" => options[:provision])
|
vm.up("provision.enabled" => options[:provision])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -139,6 +139,7 @@ module Vagrant
|
||||||
#
|
#
|
||||||
# @return [Array<VM>]
|
# @return [Array<VM>]
|
||||||
def vms_ordered
|
def vms_ordered
|
||||||
|
return @vms.values if !multivm?
|
||||||
@vms_enum ||= config.global.vm.defined_vm_keys.map { |name| @vms[name] }
|
@vms_enum ||= config.global.vm.defined_vm_keys.map { |name| @vms[name] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,94 @@
|
||||||
require File.expand_path("../../../base", __FILE__)
|
require File.expand_path("../../../base", __FILE__)
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
describe Vagrant::Command::Base do
|
describe Vagrant::Command::Base do
|
||||||
|
describe "parsing options" do
|
||||||
|
let(:klass) do
|
||||||
|
Class.new(described_class) do
|
||||||
|
# Make the method public since it is normally protected
|
||||||
|
public :parse_options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the remaining arguments" do
|
||||||
|
options = {}
|
||||||
|
opts = OptionParser.new do |opts|
|
||||||
|
opts.on("-f") do |f|
|
||||||
|
options[:f] = f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result = klass.new(["-f", "foo"], nil).parse_options(opts)
|
||||||
|
|
||||||
|
# Check the results
|
||||||
|
options[:f].should be
|
||||||
|
result.should == ["foo"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "target VMs" do
|
||||||
|
let(:klass) do
|
||||||
|
Class.new(described_class) do
|
||||||
|
# Make the method public since it is normally protected
|
||||||
|
public :with_target_vms
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:environment) { double("environment") }
|
||||||
|
let(:instance) { klass.new([], environment) }
|
||||||
|
|
||||||
|
it "should raise an exception if a name is given in a non-multivm environment" do
|
||||||
|
environment.stub(:multivm?).and_return(false)
|
||||||
|
|
||||||
|
expect { instance.with_target_vms("foo") }.
|
||||||
|
to raise_error(Vagrant::Errors::MultiVMEnvironmentRequired)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should yield every VM in order is no name is given" do
|
||||||
|
foo_vm = double("foo")
|
||||||
|
foo_vm.stub(:name).and_return("foo")
|
||||||
|
|
||||||
|
bar_vm = double("bar")
|
||||||
|
bar_vm.stub(:name).and_return("bar")
|
||||||
|
|
||||||
|
environment.stub(:multivm? => true,
|
||||||
|
:vms => { "foo" => foo_vm, "bar" => bar_vm },
|
||||||
|
:vms_ordered => [foo_vm, bar_vm])
|
||||||
|
|
||||||
|
vms = []
|
||||||
|
instance.with_target_vms do |vm|
|
||||||
|
vms << vm
|
||||||
|
end
|
||||||
|
|
||||||
|
vms.should == [foo_vm, bar_vm]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an exception if the named VM doesn't exist" do
|
||||||
|
environment.stub(:multivm? => true, :vms => {})
|
||||||
|
|
||||||
|
expect { instance.with_target_vms("foo") }.
|
||||||
|
to raise_error(Vagrant::Errors::VMNotFoundError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "yields the given VM if a name is given" do
|
||||||
|
foo_vm = double("foo")
|
||||||
|
foo_vm.stub(:name).and_return(:foo)
|
||||||
|
|
||||||
|
environment.stub(:multivm? => true,
|
||||||
|
:vms => { :foo => foo_vm, :bar => nil })
|
||||||
|
|
||||||
|
vms = []
|
||||||
|
instance.with_target_vms("foo") { |vm| vms << vm }
|
||||||
|
vms.should == [foo_vm]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "splitting the main and subcommand args" do
|
describe "splitting the main and subcommand args" do
|
||||||
let(:instance) do
|
let(:instance) do
|
||||||
Class.new(described_class) do
|
Class.new(described_class) do
|
||||||
# Make the method public since it is normal protected
|
# Make the method public since it is normally protected
|
||||||
public :split_main_and_subcommand
|
public :split_main_and_subcommand
|
||||||
end.new
|
end.new(nil, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should work when given all 3 parts" do
|
it "should work when given all 3 parts" do
|
||||||
|
@ -28,5 +110,10 @@ describe Vagrant::Command::Base do
|
||||||
result = instance.split_main_and_subcommand(["status"])
|
result = instance.split_main_and_subcommand(["status"])
|
||||||
result.should == [[], "status", []]
|
result.should == [[], "status", []]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "works when there are other non-flag args after the subcommand" do
|
||||||
|
result = instance.split_main_and_subcommand(["-v", "box", "add", "-h"])
|
||||||
|
result.should == [["-v"], "box", ["add", "-h"]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,10 @@ describe Vagrant do
|
||||||
described_class.source_root.should == Pathname.new(File.expand_path("../../../", __FILE__))
|
described_class.source_root.should == Pathname.new(File.expand_path("../../../", __FILE__))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "has a registry for commands" do
|
||||||
|
described_class.commands.should be_a(Vagrant::Registry)
|
||||||
|
end
|
||||||
|
|
||||||
it "has a registry for config keys" do
|
it "has a registry for config keys" do
|
||||||
described_class.config_keys.should be_a(Vagrant::Registry)
|
described_class.config_keys.should be_a(Vagrant::Registry)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue