diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb index 4169ffc..4c6f10e 100644 --- a/lib/vagrant-lxc/container.rb +++ b/lib/vagrant-lxc/container.rb @@ -103,67 +103,22 @@ module Vagrant end 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 = '' retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do - # See: http://programminglinuxblog.blogspot.com.br/2007/11/detecting-ip-address-from-mac-address.html - unless ip = get_container_ip_from_arp(mac_addr) - # Ping subnet and try to get ip again - ping_subnet! + unless ip = get_container_ip_from_ifconfig + # retry + raise LXC::Errors::ExecuteError, :command => ['arp', '-n'].inspect end end ip end - def get_container_ip_from_arp(mac_addr) - r = raw 'arp', '-n' - - # If the command was a failure then raise an exception that is nicely - # handled by Vagrant. - if r.exit_code != 0 - if @interrupted - @logger.info("Exit code != 0, but interrupted. Ignoring.") - else - raise LXC::Errors::ExecuteError, :command => ['arp', '-n'].inspect - end - end - - if r.stdout.gsub("\r\n", "\n").strip =~ /^([0-9.]+).+#{Regexp.escape mac_addr}/ + def get_container_ip_from_ifconfig + output = @cli.attach '/sbin/ifconfig', '-v', 'eth0', namespaces: 'network' + if output =~ /\s+inet addr:([0-9.]+)\s+/ return $1.to_s end end - - # FIXME: Should output an error friendly message in case fping is not installed - def ping_subnet! - raise LXC::Errors::UnknownLxcConfigFile unless File.exists?(LXC_DEFAULTS_PATH) - - raise LXC::Errors::UnknownLxcBridgeAddress unless - File.read(LXC_DEFAULTS_PATH) =~ /^LXC_ADDR\="?([0-9.]+)"?.*$/ - - cmd = ['fping', '-c', '1', '-g', '-q', "#{$1}/24"] - raw(*cmd) - - raise LXC::Errors::ExecuteError, :command => cmd.inspect - end - - # TODO: Review code below this line, it was pretty much a copy and paste from VirtualBox base driver - def raw(*command, &block) - int_callback = lambda do - @interrupted = true - @logger.info("Interrupted.") - end - - # Append in the options for subprocess - command << { :notify => [:stdout, :stderr] } - - Vagrant::Util::Busy.busy(int_callback) do - Vagrant::Util::Subprocess.execute(*command, &block) - end - end end end end diff --git a/spec/fixtures/sample-arp-output b/spec/fixtures/sample-arp-output deleted file mode 100644 index 0b68ed4..0000000 --- a/spec/fixtures/sample-arp-output +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/spec/fixtures/sample-config b/spec/fixtures/sample-config deleted file mode 100644 index 3fe64a9..0000000 --- a/spec/fixtures/sample-config +++ /dev/null @@ -1,47 +0,0 @@ -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 diff --git a/spec/fixtures/sample-ifconfig-output b/spec/fixtures/sample-ifconfig-output new file mode 100644 index 0000000..bb481a6 --- /dev/null +++ b/spec/fixtures/sample-ifconfig-output @@ -0,0 +1,18 @@ +eth0 Link encap:Ethernet HWaddr 00:16:3e:7c:dd:44 + inet addr:10.0.3.109 Bcast:10.0.3.255 Mask:255.255.255.0 + inet6 addr: fe80::216:3eff:fe7c:dd44/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:204 errors:0 dropped:0 overruns:0 frame:0 + TX packets:203 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:29663 (29.6 KB) TX bytes:30168 (30.1 KB) + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:16436 Metric:1 + RX packets:73 errors:0 dropped:0 overruns:0 frame:0 + TX packets:73 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:34173 (34.1 KB) TX bytes:34173 (34.1 KB) + diff --git a/spec/unit/container_spec.rb b/spec/unit/container_spec.rb index 38f937c..5a316f0 100644 --- a/spec/unit/container_spec.rb +++ b/spec/unit/container_spec.rb @@ -125,27 +125,19 @@ describe Vagrant::LXC::Container do end describe 'assigned ip' do - # This ip is set on the sample-arp-output fixture based on mac address from - # sample-config fixture - let(:ip) { "10.0.3.30" } - let(:conf_file_contents) { File.read('spec/fixtures/sample-config') } - let(:name) { 'random-container-name' } + # This ip is set on the sample-ifconfig-output fixture + let(:ip) { "10.0.3.109" } + let(:ifconfig_output) { File.read('spec/fixtures/sample-ifconfig-output') } + let(:name) { 'random-container-name' } + let(:cli) { fire_double('Vagrant::LXC::Container::CLI', :attach => ifconfig_output) } - context 'when container mac address gets returned from the first `arp` call' do - before do - @arp_output = File.read('spec/fixtures/sample-arp-output') - subject.stub(:raw) { - mock(stdout: "#{@arp_output}\n", exit_code: 0) - } - File.stub(read: conf_file_contents) - end + subject { described_class.new(name, cli) } - it 'gets parsed from `arp` based on lxc mac address' do + context 'when ip for eth0 gets returned from lxc-attach call' do + it 'gets parsed from ifconfig output' do subject.assigned_ip.should == ip - subject.should have_received(:raw).with('arp', '-n') + cli.should have_received(:attach).with('/sbin/ifconfig', '-v', 'eth0', namespaces: 'network') end end - - pending 'when mac address is not returned from an `arp` call' end end