Handle stale machine id / container name

This commit is contained in:
Fabio Rehm 2013-03-02 01:18:38 -03:00
parent 661b00ea22
commit 5291f13316
3 changed files with 65 additions and 4 deletions

View file

@ -12,11 +12,21 @@ module Vagrant
# Include this so we can use `Subprocess` more easily. # Include this so we can use `Subprocess` more easily.
include Vagrant::Util::Retryable include Vagrant::Util::Retryable
# This is raised if the container can't be found when initializing it with
# an UUID.
class NotFound < StandardError; end
attr_reader :name
def initialize(name) def initialize(name)
@name = name @name = name
@logger = Log4r::Logger.new("vagrant::provider::lxc::container") @logger = Log4r::Logger.new("vagrant::provider::lxc::container")
end end
def validate!
raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name)
end
def create def create
# FIXME: Ruby 1.8 users dont have SecureRandom # FIXME: Ruby 1.8 users dont have SecureRandom
name = SecureRandom.hex(6) name = SecureRandom.hex(6)
@ -53,7 +63,7 @@ module Vagrant
end end
def state def state
if lxc(:info, '--name', @name) =~ /^state:[^A-Z]+([A-Z]+)$/ if @name && lxc(:info, '--name', @name) =~ /^state:[^A-Z]+([A-Z]+)$/
$1.downcase.to_sym $1.downcase.to_sym
elsif @name elsif @name
:unknown :unknown

View file

@ -6,14 +6,32 @@ require "log4r"
module Vagrant module Vagrant
module LXC module LXC
# DISCUSS: VirtualBox provider has a #machine_id_changed, do we need to handle it as well?
class Provider < Vagrant.plugin("2", :provider) class Provider < Vagrant.plugin("2", :provider)
attr_reader :container attr_reader :container
def initialize(machine) def initialize(machine)
@logger = Log4r::Logger.new("vagrant::provider::lxc") @logger = Log4r::Logger.new("vagrant::provider::lxc")
@machine = machine @machine = machine
@container = Container.new(@machine.id)
machine_id_changed
end
# If the machine ID changed, then we need to rebuild our underlying
# container.
def machine_id_changed
id = @machine.id
begin
@logger.debug("Instantiating the container for: #{id.inspect}")
@container = Container.new(id)
@container.validate!
rescue Container::NotFound
# The container doesn't exist, so we probably have a stale
# ID. Just clear the id out of the machine and reload it.
@logger.debug("Container not found! Clearing saved machine ID and reloading.")
id = nil
retry
end
end end
# @see Vagrant::Plugin::V1::Provider#action # @see Vagrant::Plugin::V1::Provider#action
@ -28,7 +46,11 @@ module Vagrant
end end
def state def state
LXC::MachineState.new(@container.state) state_id = nil
state_id = :not_created if !@container.name
state_id = @container.state if !state_id
state_id = :unknown if !state_id
LXC::MachineState.new(state_id)
end end
def to_s def to_s

View file

@ -7,6 +7,35 @@ describe Vagrant::LXC::Container do
let(:name) { nil } let(:name) { nil }
subject { described_class.new(name) } subject { described_class.new(name) }
describe 'container name validation' do
let(:unknown_container) { described_class.new('unknown') }
let(:valid_container) { described_class.new('valid') }
let(:new_container) { described_class.new(nil) }
before do
unknown_container.stub(lxc: 'valid')
valid_container.stub(lxc: 'valid')
end
it 'raises a NotFound error if an unknown container name gets provided' do
expect {
unknown_container.validate!
}.to raise_error(Vagrant::LXC::Container::NotFound)
end
it 'does not raise a NotFound error if a valid container name gets provided' do
expect {
valid_container.validate!
}.to_not raise_error(Vagrant::LXC::Container::NotFound)
end
it 'does not raise a NotFound error if nil is provider as name' do
expect {
new_container.validate!
}.to_not raise_error(Vagrant::LXC::Container::NotFound)
end
end
describe 'lxc commands execution' do describe 'lxc commands execution' do
let(:args) { @args } let(:args) { @args }