Use arp
to grab container ip instead of dig
(it seems to be more reliable)
References: #31
This commit is contained in:
parent
238b5cd681
commit
d2a1eeeabc
7 changed files with 88 additions and 34 deletions
1
example/Vagrantfile
vendored
1
example/Vagrantfile
vendored
|
@ -24,7 +24,6 @@ Vagrant.configure("2") do |config|
|
|||
config.vm.synced_folder cache_dir, "/var/cache/apt/archives"
|
||||
|
||||
config.vm.provider :lxc do |lxc|
|
||||
lxc.lxc_dhcp_ip = '10.0.254.1' if ENV['USER'] == 'vagrant'
|
||||
lxc.start_opts << 'lxc.cgroup.memory.limit_in_bytes=400M'
|
||||
lxc.start_opts << 'lxc.cgroup.memory.memsw.limit_in_bytes=500M'
|
||||
end
|
||||
|
|
|
@ -6,15 +6,8 @@ module Vagrant
|
|||
# @return [Array]
|
||||
attr_reader :start_opts
|
||||
|
||||
# The ip set for the built in LXC dhcp server (defaults to configured ip
|
||||
# at /etc/default/lxc or 10.0.3.1)
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :lxc_dhcp_ip
|
||||
|
||||
def initialize
|
||||
@start_opts = []
|
||||
@lxc_dhcp_ip = '10.0.3.1'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,9 @@ require "vagrant-lxc/errors"
|
|||
module Vagrant
|
||||
module LXC
|
||||
class Container
|
||||
# Root folder where containers are stored
|
||||
CONTAINERS_PATH = '/var/lib/lxc'
|
||||
|
||||
# Include this so we can use `Subprocess` more easily.
|
||||
include Vagrant::Util::Retryable
|
||||
|
||||
|
@ -16,8 +19,6 @@ module Vagrant
|
|||
# a name.
|
||||
class NotFound < StandardError; end
|
||||
|
||||
CONTAINERS_PATH = '/var/lib/lxc'
|
||||
|
||||
attr_reader :name
|
||||
|
||||
def initialize(name)
|
||||
|
@ -29,6 +30,14 @@ module Vagrant
|
|||
raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name)
|
||||
end
|
||||
|
||||
def base_path
|
||||
Pathname.new("#{CONTAINERS_PATH}/#{@name}")
|
||||
end
|
||||
|
||||
def rootfs_path
|
||||
Pathname.new("#{base_path}/rootfs")
|
||||
end
|
||||
|
||||
def create(metadata = {})
|
||||
# FIXME: Ruby 1.8 users dont have SecureRandom
|
||||
@logger.debug('Creating container using lxc-create...')
|
||||
|
@ -52,10 +61,6 @@ module Vagrant
|
|||
@name
|
||||
end
|
||||
|
||||
def rootfs_path
|
||||
Pathname.new("#{CONTAINERS_PATH}/#{@name}/rootfs")
|
||||
end
|
||||
|
||||
def share_folders(folders, config)
|
||||
folders.each do |folder|
|
||||
guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, ''))
|
||||
|
@ -109,15 +114,18 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
def dhcp_ip(server_ip)
|
||||
def assigned_ip
|
||||
unless File.read(base_path.join('config')) =~ /^lxc\.network\.hwaddr\s*=\s*([a-z0-9:]+)\s*$/
|
||||
raise 'Unknown Container MAC Address'
|
||||
end
|
||||
mac_addr = $1
|
||||
|
||||
#`ip neigh flush all > /dev/null`
|
||||
|
||||
ip = ''
|
||||
# Right after creation lxc reports the container as running
|
||||
# before DNS is returning the right IP, so have to wait for a while
|
||||
# See: http://programminglinuxblog.blogspot.com.br/2007/11/detecting-ip-address-from-mac-address.html
|
||||
retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do
|
||||
# By default LXC supplies a dns server on 10.0.3.1 so we request the IP
|
||||
# of our target from there.
|
||||
# Tks to: https://github.com/neerolyte/vagueant/blob/master/bin/vagueant#L340
|
||||
r = (raw 'dig', @name, "@#{server_ip}", '+short')
|
||||
r = (raw 'arp', '-n')
|
||||
|
||||
# If the command was a failure then raise an exception that is nicely
|
||||
# handled by Vagrant.
|
||||
|
@ -125,14 +133,15 @@ module Vagrant
|
|||
if @interrupted
|
||||
@logger.info("Exit code != 0, but interrupted. Ignoring.")
|
||||
else
|
||||
raise LXC::Errors::ExecuteError, :command => ['dig', @name, "@#{server_ip}", '+short'].inspect
|
||||
raise LXC::Errors::ExecuteError, :command => ['arp', '-n'].inspect
|
||||
end
|
||||
end
|
||||
|
||||
ip = r.stdout.gsub("\r\n", "\n").strip
|
||||
if ip.empty?
|
||||
|
||||
unless r.stdout.gsub("\r\n", "\n").strip =~ /^([0-9.]+).+#{Regexp.escape mac_addr}/
|
||||
raise LXC::Errors::ExecuteError, 'Unable to identify container ip'
|
||||
end
|
||||
ip = $1.to_s
|
||||
|
||||
# Sometimes lxc reports the container as running before DNS is returning
|
||||
# the right IP, so have to try a couple of times sometimes.
|
||||
|
|
|
@ -52,7 +52,7 @@ module Vagrant
|
|||
return nil if state == :not_created
|
||||
|
||||
{
|
||||
:host => @container.dhcp_ip(@machine.provider_config.lxc_dhcp_ip),
|
||||
:host => @container.assigned_ip,
|
||||
:port => 22 # @driver.ssh_port(@machine.config.ssh.guest_port)
|
||||
}
|
||||
end
|
||||
|
|
4
spec/fixtures/sample-arp-output
vendored
Normal file
4
spec/fixtures/sample-arp-output
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
Address HWtype HWaddress Flags Mask Iface
|
||||
120.0.3.30 ether 10:16:3e:c8:f9:b7 C lxcbr0
|
||||
10.0.3.30 ether 00:16:3e:64:d6:74 C lxcbr0
|
||||
192.168.25.1 ether 2c:e4:12:95:90:45 C wlan0
|
47
spec/fixtures/sample-config
vendored
Normal file
47
spec/fixtures/sample-config
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
lxc.network.type=veth
|
||||
lxc.network.link=lxcbr0
|
||||
lxc.network.flags=up
|
||||
lxc.network.hwaddr = 00:16:3e:64:d6:74
|
||||
lxc.rootfs = /var/lib/lxc/a91df47bfc6e/rootfs
|
||||
lxc.utsname = a91df47bfc6e
|
||||
|
||||
lxc.devttydir = lxc
|
||||
lxc.tty = 4
|
||||
lxc.pts = 1024
|
||||
lxc.mount = /var/lib/lxc/a91df47bfc6e/fstab
|
||||
lxc.arch = amd64
|
||||
lxc.cap.drop = sys_module mac_admin mac_override
|
||||
lxc.pivotdir = lxc_putold
|
||||
|
||||
# uncomment the next line to run the container unconfined:
|
||||
#lxc.aa_profile = unconfined
|
||||
|
||||
lxc.cgroup.devices.deny = a
|
||||
# Allow any mknod (but not using the node)
|
||||
lxc.cgroup.devices.allow = c *:* m
|
||||
lxc.cgroup.devices.allow = b *:* m
|
||||
# /dev/null and zero
|
||||
lxc.cgroup.devices.allow = c 1:3 rwm
|
||||
lxc.cgroup.devices.allow = c 1:5 rwm
|
||||
# consoles
|
||||
lxc.cgroup.devices.allow = c 5:1 rwm
|
||||
lxc.cgroup.devices.allow = c 5:0 rwm
|
||||
#lxc.cgroup.devices.allow = c 4:0 rwm
|
||||
#lxc.cgroup.devices.allow = c 4:1 rwm
|
||||
# /dev/{,u}random
|
||||
lxc.cgroup.devices.allow = c 1:9 rwm
|
||||
lxc.cgroup.devices.allow = c 1:8 rwm
|
||||
lxc.cgroup.devices.allow = c 136:* rwm
|
||||
lxc.cgroup.devices.allow = c 5:2 rwm
|
||||
# rtc
|
||||
lxc.cgroup.devices.allow = c 254:0 rwm
|
||||
#fuse
|
||||
lxc.cgroup.devices.allow = c 10:229 rwm
|
||||
#tun
|
||||
lxc.cgroup.devices.allow = c 10:200 rwm
|
||||
#full
|
||||
lxc.cgroup.devices.allow = c 1:7 rwm
|
||||
#hpet
|
||||
lxc.cgroup.devices.allow = c 10:228 rwm
|
||||
#kvm
|
||||
lxc.cgroup.devices.allow = c 10:232 rwm
|
|
@ -4,7 +4,6 @@ require "vendored_vagrant"
|
|||
require 'vagrant-lxc/container'
|
||||
|
||||
describe Vagrant::LXC::Container do
|
||||
# Default subject and container name for specs
|
||||
let(:name) { nil }
|
||||
subject { described_class.new(name) }
|
||||
|
||||
|
@ -181,20 +180,23 @@ describe Vagrant::LXC::Container do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'dhcp ip' do
|
||||
let(:name) { 'random-container-name' }
|
||||
let(:ip) { "10.0.4.123" }
|
||||
let(:server_ip) { "10.0.4.1" }
|
||||
describe 'assigned ip' do
|
||||
# This ip is set on the sample-arp-output based on mac address from sample-config
|
||||
let(:ip) { "10.0.3.30" }
|
||||
let(:conf_file_contents) { File.read('spec/fixtures/sample-config') }
|
||||
let(:name) { 'random-container-name' }
|
||||
|
||||
before do
|
||||
@arp_output = File.read('spec/fixtures/sample-arp-output')
|
||||
subject.stub(:raw) {
|
||||
mock(stdout: "#{ip}\n", exit_code: 0)
|
||||
mock(stdout: "#{@arp_output}\n", exit_code: 0)
|
||||
}
|
||||
File.stub(read: conf_file_contents)
|
||||
end
|
||||
|
||||
it 'digs the container ip from lxc dns server' do
|
||||
subject.dhcp_ip(server_ip).should == ip
|
||||
subject.should have_received(:raw).with('dig', name, "@#{server_ip}", '+short')
|
||||
it 'gets parsed from `arp` based on lxc mac address' do
|
||||
subject.assigned_ip.should == ip
|
||||
subject.should have_received(:raw).with('arp', '-n')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue