From 5291f13316e869913f02e27bfcbff389f4670998 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 2 Mar 2013 01:18:38 -0300 Subject: [PATCH] Handle stale machine id / container name --- lib/vagrant-lxc/container.rb | 12 +++++++++++- lib/vagrant-lxc/provider.rb | 28 +++++++++++++++++++++++++--- spec/unit/container_spec.rb | 29 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb index 3db6265..0806849 100644 --- a/lib/vagrant-lxc/container.rb +++ b/lib/vagrant-lxc/container.rb @@ -12,11 +12,21 @@ module Vagrant # Include this so we can use `Subprocess` more easily. 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) @name = name @logger = Log4r::Logger.new("vagrant::provider::lxc::container") end + def validate! + raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name) + end + def create # FIXME: Ruby 1.8 users dont have SecureRandom name = SecureRandom.hex(6) @@ -53,7 +63,7 @@ module Vagrant end 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 elsif @name :unknown diff --git a/lib/vagrant-lxc/provider.rb b/lib/vagrant-lxc/provider.rb index 87bb07c..175d17e 100644 --- a/lib/vagrant-lxc/provider.rb +++ b/lib/vagrant-lxc/provider.rb @@ -6,14 +6,32 @@ require "log4r" module Vagrant module LXC - # DISCUSS: VirtualBox provider has a #machine_id_changed, do we need to handle it as well? class Provider < Vagrant.plugin("2", :provider) attr_reader :container def initialize(machine) @logger = Log4r::Logger.new("vagrant::provider::lxc") @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 # @see Vagrant::Plugin::V1::Provider#action @@ -28,7 +46,11 @@ module Vagrant end 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 def to_s diff --git a/spec/unit/container_spec.rb b/spec/unit/container_spec.rb index 2550ab3..954e462 100644 --- a/spec/unit/container_spec.rb +++ b/spec/unit/container_spec.rb @@ -7,6 +7,35 @@ describe Vagrant::LXC::Container do let(:name) { nil } 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 let(:args) { @args }