Hack in support for fetching container IPs from dnsmasq leases
Closes #49
This commit is contained in:
parent
e4dd0620ce
commit
a9c4745b78
6 changed files with 94 additions and 5 deletions
|
@ -7,9 +7,6 @@ require "vagrant-lxc/driver/cli"
|
|||
module Vagrant
|
||||
module LXC
|
||||
class Driver
|
||||
# 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
|
||||
# a name.
|
||||
class ContainerNotFound < StandardError; end
|
||||
|
|
21
lib/vagrant-lxc/driver/builder.rb
Normal file
21
lib/vagrant-lxc/driver/builder.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require_relative 'fetch_ip_with_attach'
|
||||
require_relative 'fetch_ip_from_dnsmasq'
|
||||
|
||||
module Vagrant
|
||||
module LXC
|
||||
class Driver
|
||||
class Builder
|
||||
def self.build(id)
|
||||
version = CLI.new.version.match(/^(\d+\.\d+)\./)[1].to_f
|
||||
Driver.new(id).tap do |driver|
|
||||
mod = version >= 0.8 ?
|
||||
Driver::FetchIpWithAttach :
|
||||
Driver::FetchIpFromDsnmasq
|
||||
|
||||
driver.extend(mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
41
lib/vagrant-lxc/driver/fetch_ip_from_dnsmasq.rb
Normal file
41
lib/vagrant-lxc/driver/fetch_ip_from_dnsmasq.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
class Driver
|
||||
module FetchIpFromDsnmasq
|
||||
def assigned_ip
|
||||
@logger.debug 'Loading ip from dnsmasq leases'
|
||||
ip = nil
|
||||
# TODO: Use Vagrant::Util::Retryable
|
||||
10.times do
|
||||
if dnsmasq_leases =~ /#{Regexp.escape mac_address}\s+([0-9.]+)\s+/
|
||||
ip = $1.to_s
|
||||
break
|
||||
else
|
||||
@logger.debug 'Ip could not be parsed from dnsmasq leases file'
|
||||
sleep 2
|
||||
end
|
||||
end
|
||||
# TODO: Raise an user friendly error
|
||||
raise 'Unable to identify container IP!' unless ip
|
||||
ip
|
||||
end
|
||||
|
||||
def mac_address
|
||||
@mac_address ||= base_path.join('config').read.match(/^lxc\.network\.hwaddr\s+=\s+(.+)$/)[1]
|
||||
end
|
||||
|
||||
LEASES_PATHS = %w(
|
||||
/var/lib/misc/dnsmasq.leases
|
||||
/var/lib/dnsmasq/dnsmasq.leases
|
||||
/var/db/dnsmasq.leases
|
||||
)
|
||||
|
||||
def dnsmasq_leases
|
||||
LEASES_PATHS.map do |path|
|
||||
File.read(path) if File.exists?(path)
|
||||
end.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
lib/vagrant-lxc/driver/fetch_ip_with_attach.rb
Normal file
29
lib/vagrant-lxc/driver/fetch_ip_with_attach.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
class Driver
|
||||
module FetchIpWithAttach
|
||||
# Include this so we can use `Subprocess` more easily.
|
||||
include Vagrant::Util::Retryable
|
||||
|
||||
def assigned_ip
|
||||
ip = ''
|
||||
retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do
|
||||
unless ip = get_container_ip_from_ip_addr
|
||||
# retry
|
||||
raise LXC::Errors::ExecuteError, :command => "lxc-attach"
|
||||
end
|
||||
end
|
||||
ip
|
||||
end
|
||||
|
||||
# From: https://github.com/lxc/lxc/blob/staging/src/python-lxc/lxc/__init__.py#L371-L385
|
||||
def get_container_ip_from_ip_addr
|
||||
output = @cli.attach '/sbin/ip', '-4', 'addr', 'show', 'scope', 'global', 'eth0', namespaces: 'network'
|
||||
if output =~ /^\s+inet ([0-9.]+)\/[0-9]+\s+/
|
||||
return $1.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ require "log4r"
|
|||
|
||||
require "vagrant-lxc/action"
|
||||
require "vagrant-lxc/driver"
|
||||
require "vagrant-lxc/driver/builder"
|
||||
|
||||
module Vagrant
|
||||
module LXC
|
||||
|
@ -22,7 +23,7 @@ module Vagrant
|
|||
|
||||
begin
|
||||
@logger.debug("Instantiating the container for: #{id.inspect}")
|
||||
@driver = Driver.new(id)
|
||||
@driver = Driver::Builder.build(id)
|
||||
@driver.validate!
|
||||
rescue Driver::ContainerNotFound
|
||||
# The container doesn't exist, so we probably have a stale
|
||||
|
|
|
@ -121,7 +121,7 @@ describe Vagrant::LXC::Driver do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'assigned ip' do
|
||||
pending 'assigned ip' do
|
||||
# This ip is set on the sample-ip-addr-output fixture
|
||||
let(:ip) { "10.0.254.137" }
|
||||
let(:ifconfig_output) { File.read('spec/fixtures/sample-ip-addr-output') }
|
||||
|
|
Loading…
Reference in a new issue