Skip to content

Commit

Permalink
Import: generate new MAC address for Shared 'net0' if base_mac is alr…
Browse files Browse the repository at this point in the history
…eady in use (fixes #66)

It happens during the first VM up (import)
  • Loading branch information
legal90 committed Dec 25, 2013
1 parent a6224a3 commit 2922ea4
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 6 deletions.
1 change: 0 additions & 1 deletion .ruby-gemset

This file was deleted.

2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -7,7 +7,7 @@ group :development do
# We depend on Vagrant for development, but we don't add it as a
# gem dependency because we expect to be installed within the
# Vagrant environment itself using `vagrant plugin`.
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git'
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.4.1'
gem 'vagrant-spec', git: "https://github.com/mitchellh/vagrant-spec.git"
gem 'debugger-xml'
gem 'pry'
Expand Down
13 changes: 10 additions & 3 deletions lib/vagrant-parallels/action/match_mac_address.rb
Expand Up @@ -9,9 +9,16 @@ def initialize(app, env)
def call(env)
raise Vagrant::Errors::VMBaseMacNotSpecified if !env[:machine].config.vm.base_mac

# Create the proc which we want to use to modify the virtual machine
env[:ui].info I18n.t("vagrant.actions.vm.match_mac.matching")
env[:machine].provider.driver.set_mac_address(env[:machine].config.vm.base_mac)
env[:ui].info I18n.t("vagrant_parallels.actions.vm.match_mac.matching")

base_mac = env[:machine].config.vm.base_mac
# Generate new base mac if the specified address is already in use
if env[:machine].provider.driver.mac_in_use?(base_mac)
env[:ui].info I18n.t("vagrant_parallels.actions.vm.match_mac.generate")
env[:machine].provider.driver.set_mac_address('auto')
else
env[:machine].provider.driver.set_mac_address(base_mac)
end

@app.call(env)
end
Expand Down
12 changes: 12 additions & 0 deletions lib/vagrant-parallels/driver/prl_ctl.rb
Expand Up @@ -217,6 +217,18 @@ def ip
end
end


def mac_in_use?(mac)
all_macs_in_use = []
read_all_info.each do |vm|
all_macs_in_use << vm.fetch('Hardware', {}).fetch('net0',{}).fetch('mac', '')
end

valid_mac = mac.upcase.tr('^A-F0-9', '')

all_macs_in_use.include?(valid_mac)
end

# Returns a hash of all UUIDs assigned to VMs and templates currently
# known by Parallels. Keys are 'name' values
#
Expand Down
5 changes: 4 additions & 1 deletion locales/en.yml
Expand Up @@ -890,7 +890,10 @@ en:
The VM import failed! Try running `prlctl import` on the box file
manually for more verbose error output.
match_mac:
matching: Matching MAC address for NAT networking...
generate: |-
The specified base MAC is already in use. Generating a new unique MAC
address for Shared network...
matching: Matching MAC address for Shared network...
no_base_mac: |-
No base MAC address was specified. This is required for the NAT networking
to work properly (and hence port forwarding, SSH, etc.). Specifying this
Expand Down
36 changes: 36 additions & 0 deletions test/unit/driver/prl_ctl_test.rb
Expand Up @@ -59,6 +59,42 @@
end
end

describe "mac_in_use?" do
vm_1 = {
'Hardware' => {
'net0' => {'mac' => '001C42BB5901'},
'net1' => {'mac' => '001C42BB5902'},
}
}
vm_2 = {
'Hardware' => {
'net0' => {'mac' => '001C42BB5903'},
'net1' => {'mac' => '001C42BB5904'},
}
}

it "checks the MAC address is already in use" do
subject.stub(:read_all_info).and_return([vm_1, vm_2])

subject.mac_in_use?('00:1c:42:bb:59:01').should be_true
subject.mac_in_use?('00:1c:42:bb:59:02').should be_false
subject.mac_in_use?('00:1c:42:bb:59:03').should be_true
subject.mac_in_use?('00:1c:42:bb:59:04').should be_false
end
end

describe "set_mac_address" do
it "sets base MAC address to the Shared network adapter" do
subprocess.should_receive(:execute).exactly(2).times.
with("prlctl", "set", uuid, '--device-set', 'net0', '--type', 'shared', '--mac',
an_instance_of(String), an_instance_of(Hash)).
and_return(subprocess_result(stdout: "Settings applied"))

subject.set_mac_address('001C42DD5902')
subject.set_mac_address('auto')
end
end

describe "start" do
it "starts the VM" do
subprocess.should_receive(:execute).
Expand Down

0 comments on commit 2922ea4

Please sign in to comment.