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.synced_folder cache_dir, "/var/cache/apt/archives"
|
||||||
|
|
||||||
config.vm.provider :lxc do |lxc|
|
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.limit_in_bytes=400M'
|
||||||
lxc.start_opts << 'lxc.cgroup.memory.memsw.limit_in_bytes=500M'
|
lxc.start_opts << 'lxc.cgroup.memory.memsw.limit_in_bytes=500M'
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,15 +6,8 @@ module Vagrant
|
||||||
# @return [Array]
|
# @return [Array]
|
||||||
attr_reader :start_opts
|
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
|
def initialize
|
||||||
@start_opts = []
|
@start_opts = []
|
||||||
@lxc_dhcp_ip = '10.0.3.1'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,9 @@ require "vagrant-lxc/errors"
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module LXC
|
module LXC
|
||||||
class Container
|
class Container
|
||||||
|
# Root folder where containers are stored
|
||||||
|
CONTAINERS_PATH = '/var/lib/lxc'
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -16,8 +19,6 @@ module Vagrant
|
||||||
# a name.
|
# a name.
|
||||||
class NotFound < StandardError; end
|
class NotFound < StandardError; end
|
||||||
|
|
||||||
CONTAINERS_PATH = '/var/lib/lxc'
|
|
||||||
|
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
def initialize(name)
|
def initialize(name)
|
||||||
|
@ -29,6 +30,14 @@ module Vagrant
|
||||||
raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name)
|
raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def base_path
|
||||||
|
Pathname.new("#{CONTAINERS_PATH}/#{@name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def rootfs_path
|
||||||
|
Pathname.new("#{base_path}/rootfs")
|
||||||
|
end
|
||||||
|
|
||||||
def create(metadata = {})
|
def create(metadata = {})
|
||||||
# FIXME: Ruby 1.8 users dont have SecureRandom
|
# FIXME: Ruby 1.8 users dont have SecureRandom
|
||||||
@logger.debug('Creating container using lxc-create...')
|
@logger.debug('Creating container using lxc-create...')
|
||||||
|
@ -52,10 +61,6 @@ module Vagrant
|
||||||
@name
|
@name
|
||||||
end
|
end
|
||||||
|
|
||||||
def rootfs_path
|
|
||||||
Pathname.new("#{CONTAINERS_PATH}/#{@name}/rootfs")
|
|
||||||
end
|
|
||||||
|
|
||||||
def share_folders(folders, config)
|
def share_folders(folders, config)
|
||||||
folders.each do |folder|
|
folders.each do |folder|
|
||||||
guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, ''))
|
guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, ''))
|
||||||
|
@ -109,15 +114,18 @@ module Vagrant
|
||||||
end
|
end
|
||||||
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 = ''
|
ip = ''
|
||||||
# Right after creation lxc reports the container as running
|
# See: http://programminglinuxblog.blogspot.com.br/2007/11/detecting-ip-address-from-mac-address.html
|
||||||
# before DNS is returning the right IP, so have to wait for a while
|
|
||||||
retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do
|
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
|
r = (raw 'arp', '-n')
|
||||||
# of our target from there.
|
|
||||||
# Tks to: https://github.com/neerolyte/vagueant/blob/master/bin/vagueant#L340
|
|
||||||
r = (raw 'dig', @name, "@#{server_ip}", '+short')
|
|
||||||
|
|
||||||
# If the command was a failure then raise an exception that is nicely
|
# If the command was a failure then raise an exception that is nicely
|
||||||
# handled by Vagrant.
|
# handled by Vagrant.
|
||||||
|
@ -125,14 +133,15 @@ module Vagrant
|
||||||
if @interrupted
|
if @interrupted
|
||||||
@logger.info("Exit code != 0, but interrupted. Ignoring.")
|
@logger.info("Exit code != 0, but interrupted. Ignoring.")
|
||||||
else
|
else
|
||||||
raise LXC::Errors::ExecuteError, :command => ['dig', @name, "@#{server_ip}", '+short'].inspect
|
raise LXC::Errors::ExecuteError, :command => ['arp', '-n'].inspect
|
||||||
end
|
end
|
||||||
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'
|
raise LXC::Errors::ExecuteError, 'Unable to identify container ip'
|
||||||
end
|
end
|
||||||
|
ip = $1.to_s
|
||||||
|
|
||||||
# Sometimes lxc reports the container as running before DNS is returning
|
# Sometimes lxc reports the container as running before DNS is returning
|
||||||
# the right IP, so have to try a couple of times sometimes.
|
# the right IP, so have to try a couple of times sometimes.
|
||||||
|
|
|
@ -52,7 +52,7 @@ module Vagrant
|
||||||
return nil if state == :not_created
|
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)
|
:port => 22 # @driver.ssh_port(@machine.config.ssh.guest_port)
|
||||||
}
|
}
|
||||||
end
|
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'
|
require 'vagrant-lxc/container'
|
||||||
|
|
||||||
describe Vagrant::LXC::Container do
|
describe Vagrant::LXC::Container do
|
||||||
# Default subject and container name for specs
|
|
||||||
let(:name) { nil }
|
let(:name) { nil }
|
||||||
subject { described_class.new(name) }
|
subject { described_class.new(name) }
|
||||||
|
|
||||||
|
@ -181,20 +180,23 @@ describe Vagrant::LXC::Container do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'dhcp ip' do
|
describe 'assigned ip' do
|
||||||
let(:name) { 'random-container-name' }
|
# This ip is set on the sample-arp-output based on mac address from sample-config
|
||||||
let(:ip) { "10.0.4.123" }
|
let(:ip) { "10.0.3.30" }
|
||||||
let(:server_ip) { "10.0.4.1" }
|
let(:conf_file_contents) { File.read('spec/fixtures/sample-config') }
|
||||||
|
let(:name) { 'random-container-name' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@arp_output = File.read('spec/fixtures/sample-arp-output')
|
||||||
subject.stub(:raw) {
|
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
|
end
|
||||||
|
|
||||||
it 'digs the container ip from lxc dns server' do
|
it 'gets parsed from `arp` based on lxc mac address' do
|
||||||
subject.dhcp_ip(server_ip).should == ip
|
subject.assigned_ip.should == ip
|
||||||
subject.should have_received(:raw).with('dig', name, "@#{server_ip}", '+short')
|
subject.should have_received(:raw).with('arp', '-n')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue