SSH object is now on the VM, rather than the environment

This commit is contained in:
Mitchell Hashimoto 2010-05-07 21:40:32 -07:00
parent 7419563b80
commit 2e547bda26
14 changed files with 90 additions and 35 deletions

View File

@ -30,7 +30,7 @@ module Vagrant
@runner.env.config.ssh.max_tries.to_i.times do |i| @runner.env.config.ssh.max_tries.to_i.times do |i|
logger.info "Trying to connect (attempt ##{i+1} of #{@runner.env.config[:ssh][:max_tries]})..." logger.info "Trying to connect (attempt ##{i+1} of #{@runner.env.config[:ssh][:max_tries]})..."
if @runner.env.ssh.up? if @runner.ssh.up?
logger.info "VM booted and ready for use!" logger.info "VM booted and ready for use!"
return true return true
end end

View File

@ -7,11 +7,19 @@ module Vagrant
class Base class Base
include Vagrant::Util include Vagrant::Util
# The environment which this is being provisioned in # The VM which this is being provisioned for
attr_reader :env attr_reader :vm
def initialize(env) def initialize(vm)
@env = env @vm = vm
end
# This method returns the environment which the provisioner is working
# on. This is also the environment of the VM. This method is provided
# as a simple helper since the environment is often used throughout the
# provisioner.
def env
@vm.env
end end
# This is the method called to "prepare" the provisioner. This is called # This is the method called to "prepare" the provisioner. This is called

View File

@ -77,7 +77,7 @@ module Vagrant
def chown_provisioning_folder def chown_provisioning_folder
logger.info "Setting permissions on chef provisioning folder..." logger.info "Setting permissions on chef provisioning folder..."
env.ssh.execute do |ssh| vm.ssh.execute do |ssh|
ssh.exec!("sudo mkdir -p #{env.config.chef.provisioning_path}") ssh.exec!("sudo mkdir -p #{env.config.chef.provisioning_path}")
ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.chef.provisioning_path}") ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.chef.provisioning_path}")
end end
@ -89,7 +89,7 @@ module Vagrant
}.merge(template_vars)) }.merge(template_vars))
logger.info "Uploading chef configuration script..." logger.info "Uploading chef configuration script..."
env.ssh.upload!(StringIO.new(config_file), File.join(env.config.chef.provisioning_path, filename)) vm.ssh.upload!(StringIO.new(config_file), File.join(env.config.chef.provisioning_path, filename))
end end
def setup_json def setup_json
@ -110,7 +110,7 @@ module Vagrant
json = data.to_json json = data.to_json
env.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json")) vm.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json"))
end end
end end
end end

View File

@ -64,7 +64,7 @@ module Vagrant
end end
def guest_validation_key_path def guest_validation_key_path
File.join(@env.config.chef.provisioning_path, "validation.pem") File.join(env.config.chef.provisioning_path, "validation.pem")
end end
end end
end end

View File

@ -30,7 +30,7 @@ module Vagrant
#------------------------------------------------------------------- #-------------------------------------------------------------------
def halt def halt
logger.info "Attempting graceful shutdown of linux..." logger.info "Attempting graceful shutdown of linux..."
vm.env.ssh.execute do |ssh| vm.ssh.execute do |ssh|
ssh.exec!("sudo halt") ssh.exec!("sudo halt")
end end

View File

@ -20,9 +20,14 @@ module Vagrant
@env = env @env = env
@vm = vm @vm = vm
load_system! unless @env.nil? load_system! if !@env.nil?
end end
# Loads the system associated with the VM. The system class is
# responsible for OS-specific functionality. More information
# can be found by reading the documentation on {Vagrant::Systems::Base}.
#
# **This method should never be called manually.**
def load_system! def load_system!
system = env.config.vm.system system = env.config.vm.system
@ -31,9 +36,7 @@ module Vagrant
error_and_exit(:system_invalid_class, :system => system.to_s) unless @system.is_a?(Systems::Base) error_and_exit(:system_invalid_class, :system => system.to_s) unless @system.is_a?(Systems::Base)
elsif system.is_a?(Symbol) elsif system.is_a?(Symbol)
# Hard-coded internal systems # Hard-coded internal systems
mapping = { mapping = { :linux => Systems::Linux }
:linux => Systems::Linux
}
if !mapping.has_key?(system) if !mapping.has_key?(system)
error_and_exit(:system_unknown_type, :system => system.to_s) error_and_exit(:system_unknown_type, :system => system.to_s)
@ -46,6 +49,13 @@ module Vagrant
end end
end end
# Access the {Vagrant::SSH} object associated with this VM.
# On the initial call, this will initialize the object. On
# subsequent calls it will reuse the existing object.
def ssh
@ssh ||= SSH.new(env)
end
def uuid def uuid
vm ? vm.uuid : nil vm ? vm.uuid : nil
end end

View File

@ -73,6 +73,14 @@ class Test::Unit::TestCase
environment environment
end end
# Sets up the mocks for a VM
def mock_vm
vm = Vagrant::VM.new(nil, nil)
vm.stubs(:env).returns(mock_environment)
vm.stubs(:ssh).returns(Vagrant::SSH.new(vm.env))
vm
end
# Sets up the mocks and instantiates an action for testing # Sets up the mocks and instantiates an action for testing
def mock_action(action_klass, *args) def mock_action(action_klass, *args)
vm = mock("vboxvm") vm = mock("vboxvm")
@ -87,6 +95,11 @@ class Test::Unit::TestCase
mock_vm.stubs(:actions).returns([action]) mock_vm.stubs(:actions).returns([action])
mock_vm.stubs(:env).returns(mock_environment) mock_vm.stubs(:env).returns(mock_environment)
mock_ssh = Vagrant::SSH.new(mock_vm.env)
mock_ssh.stubs(:execute)
mock_vm.stubs(:ssh).returns(mock_ssh)
vm.stubs(:env).returns(mock_vm.env) vm.stubs(:env).returns(mock_vm.env)
[mock_vm, vm, action] [mock_vm, vm, action]

View File

@ -43,13 +43,13 @@ class BootActionTest < Test::Unit::TestCase
context "waiting for boot" do context "waiting for boot" do
should "repeatedly ping the SSH port and return false with no response" do should "repeatedly ping the SSH port and return false with no response" do
seq = sequence('pings') seq = sequence('pings')
@runner.env.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i - 1).returns(false).in_sequence(seq) @runner.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i - 1).returns(false).in_sequence(seq)
@runner.env.ssh.expects(:up?).once.returns(true).in_sequence(seq) @runner.ssh.expects(:up?).once.returns(true).in_sequence(seq)
assert @action.wait_for_boot(0) assert @action.wait_for_boot(0)
end end
should "ping the max number of times then just return" do should "ping the max number of times then just return" do
@runner.env.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i).returns(false) @runner.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i).returns(false)
assert !@action.wait_for_boot(0) assert !@action.wait_for_boot(0)
end end
end end

View File

@ -7,13 +7,13 @@ class BaseProvisionerTest < Test::Unit::TestCase
context "base instance" do context "base instance" do
setup do setup do
@env = mock_environment @vm = mock("vm")
@base = Vagrant::Provisioners::Base.new(@env) @base = Vagrant::Provisioners::Base.new(@vm)
end end
should "set the environment" do should "set the environment" do
base = Vagrant::Provisioners::Base.new(@env) base = Vagrant::Provisioners::Base.new(@vm)
assert_equal @env, base.env assert_equal @vm, base.vm
end end
should "implement provision! which does nothing" do should "implement provision! which does nothing" do

View File

@ -2,8 +2,9 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ChefServerProvisionerTest < Test::Unit::TestCase class ChefServerProvisionerTest < Test::Unit::TestCase
setup do setup do
@env = mock_environment @vm = mock_vm
@action = Vagrant::Provisioners::ChefServer.new(@env) @env = @vm.env
@action = Vagrant::Provisioners::ChefServer.new(@vm)
end end
context "provisioning" do context "provisioning" do

View File

@ -2,8 +2,9 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ChefSoloProvisionerTest < Test::Unit::TestCase class ChefSoloProvisionerTest < Test::Unit::TestCase
setup do setup do
@env = mock_environment @vm = mock_vm
@action = Vagrant::Provisioners::ChefSolo.new(@env) @env = @vm.env
@action = Vagrant::Provisioners::ChefSolo.new(@vm)
end end
context "preparing" do context "preparing" do

View File

@ -2,8 +2,9 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ChefProvisionerTest < Test::Unit::TestCase class ChefProvisionerTest < Test::Unit::TestCase
setup do setup do
@env = mock_environment @vm = mock_vm
@action = Vagrant::Provisioners::Chef.new(@env) @env = @vm.env
@action = Vagrant::Provisioners::Chef.new(@vm)
end end
context "preparing" do context "preparing" do
@ -67,14 +68,14 @@ class ChefProvisionerTest < Test::Unit::TestCase
ssh = mock("ssh") ssh = mock("ssh")
ssh.expects(:exec!).with("sudo mkdir -p #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq) ssh.expects(:exec!).with("sudo mkdir -p #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
ssh.expects(:exec!).with("sudo chown #{@env.config.ssh.username} #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq) ssh.expects(:exec!).with("sudo chown #{@env.config.ssh.username} #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
@env.ssh.expects(:execute).yields(ssh) @vm.ssh.expects(:execute).yields(ssh)
@action.chown_provisioning_folder @action.chown_provisioning_folder
end end
end end
context "generating and uploading chef configuration file" do context "generating and uploading chef configuration file" do
setup do setup do
@env.ssh.stubs(:upload!) @vm.ssh.stubs(:upload!)
@template = "template" @template = "template"
@filename = "foo.rb" @filename = "foo.rb"
@ -88,7 +89,7 @@ class ChefProvisionerTest < Test::Unit::TestCase
Vagrant::Util::TemplateRenderer.expects(:render).with(@template, anything).returns(template_data) Vagrant::Util::TemplateRenderer.expects(:render).with(@template, anything).returns(template_data)
StringIO.expects(:new).with(template_data).returns(string_io) StringIO.expects(:new).with(template_data).returns(string_io)
File.expects(:join).with(@env.config.chef.provisioning_path, @filename).once.returns("bar") File.expects(:join).with(@env.config.chef.provisioning_path, @filename).once.returns("bar")
@env.ssh.expects(:upload!).with(string_io, "bar") @vm.ssh.expects(:upload!).with(string_io, "bar")
@action.setup_config(@template, @filename, {}) @action.setup_config(@template, @filename, {})
end end
@ -124,7 +125,7 @@ class ChefProvisionerTest < Test::Unit::TestCase
context "generating and uploading json" do context "generating and uploading json" do
def assert_json def assert_json
@env.ssh.expects(:upload!).with do |json, path| @vm.ssh.expects(:upload!).with do |json, path|
data = JSON.parse(json.read) data = JSON.parse(json.read)
yield data yield data
true true
@ -155,7 +156,7 @@ class ChefProvisionerTest < Test::Unit::TestCase
should "upload a StringIO to dna.json" do should "upload a StringIO to dna.json" do
StringIO.expects(:new).with(anything).returns("bar") StringIO.expects(:new).with(anything).returns("bar")
File.expects(:join).with(@env.config.chef.provisioning_path, "dna.json").once.returns("baz") File.expects(:join).with(@env.config.chef.provisioning_path, "dna.json").once.returns("baz")
@env.ssh.expects(:upload!).with("bar", "baz").once @vm.ssh.expects(:upload!).with("bar", "baz").once
@action.setup_json @action.setup_json
end end
end end

View File

@ -4,8 +4,7 @@ class LinuxSystemTest < Test::Unit::TestCase
setup do setup do
@klass = Vagrant::Systems::Linux @klass = Vagrant::Systems::Linux
@vm = mock("vm") @vm = mock_vm
@vm.stubs(:env).returns(mock_environment)
@instance = @klass.new(@vm) @instance = @klass.new(@vm)
end end
@ -14,7 +13,7 @@ class LinuxSystemTest < Test::Unit::TestCase
@ssh_session = mock("ssh_session") @ssh_session = mock("ssh_session")
@ssh = mock("ssh") @ssh = mock("ssh")
@ssh.stubs(:execute).yields(@ssh_session) @ssh.stubs(:execute).yields(@ssh_session)
@vm.env.stubs(:ssh).returns(@ssh) @vm.stubs(:ssh).returns(@ssh)
@real_vm = mock("real_vm") @real_vm = mock("real_vm")
@real_vm.stubs(:state).returns(:powered_off) @real_vm.stubs(:state).returns(:powered_off)

View File

@ -39,6 +39,28 @@ class VMTest < Test::Unit::TestCase
@mock_vm.stubs(:uuid).returns("foo") @mock_vm.stubs(:uuid).returns("foo")
end end
context "accessing the SSH object" do
setup do
# Reset this to nil to force the reload
@vm.instance_variable_set(:@ssh, nil)
@ssh = mock("ssh")
Vagrant::SSH.stubs(:new).returns(@ssh)
end
should "load it the first time" do
Vagrant::SSH.expects(:new).with(@env).once.returns(@ssh)
@vm.ssh
@vm.ssh
@vm.ssh
end
should "use the same value once its loaded" do
result = @vm.ssh
assert_equal result, @vm.ssh
end
end
context "loading associated system" do context "loading associated system" do
should "error and exit if system is not specified" do should "error and exit if system is not specified" do
@vm.env.config.vm.system = nil @vm.env.config.vm.system = nil