diff --git a/plugins/providers/hyperv/action.rb b/plugins/providers/hyperv/action.rb index 64fbec180..64d4bc396 100644 --- a/plugins/providers/hyperv/action.rb +++ b/plugins/providers/hyperv/action.rb @@ -117,6 +117,7 @@ module VagrantPlugins b2.use Provision b2.use NetSetVLan + b2.use NetSetMac b2.use StartInstance b2.use WaitForIPAddress b2.use WaitForCommunicator, [:running] @@ -218,6 +219,7 @@ module VagrantPlugins autoload :SuspendVM, action_root.join("suspend_vm") autoload :WaitForIPAddress, action_root.join("wait_for_ip_address") autoload :NetSetVLan, action_root.join("net_set_vlan") + autoload :NetSetMac, action_root.join("net_set_mac") autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy") end end diff --git a/plugins/providers/hyperv/action/net_set_mac.rb b/plugins/providers/hyperv/action/net_set_mac.rb new file mode 100644 index 000000000..633af5ae0 --- /dev/null +++ b/plugins/providers/hyperv/action/net_set_mac.rb @@ -0,0 +1,20 @@ +module VagrantPlugins + module HyperV + module Action + class NetSetMac + def initialize(app, env) + @app = app + end + + def call(env) + mac = env[:machine].provider_config.mac + if mac + env[:ui].info("[Settings] [Network Adapter] Setting MAC address to: #{mac}") + env[:machine].provider.driver.net_set_mac(mac) + end + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/hyperv/config.rb b/plugins/providers/hyperv/config.rb index fe247a242..2bff9663d 100644 --- a/plugins/providers/hyperv/config.rb +++ b/plugins/providers/hyperv/config.rb @@ -10,6 +10,7 @@ module VagrantPlugins attr_accessor :cpus # Number of cpu's @return [Integer] attr_accessor :vmname # Name that will be shoen in Hyperv Manager @return [String] attr_accessor :vlan_id # VLAN ID for network interface for the virtual machine. @return [Integer] + attr_accessor :mac # MAC address for network interface for the virtual machine. @return [String] def initialize @ip_address_timeout = UNSET_VALUE @@ -18,6 +19,7 @@ module VagrantPlugins @cpus = UNSET_VALUE @vmname = UNSET_VALUE @vlan_id = UNSET_VALUE + @mac = UNSET_VALUE end def finalize! @@ -29,6 +31,7 @@ module VagrantPlugins @cpus = nil if @cpus == UNSET_VALUE @vmname = nil if @vmname == UNSET_VALUE @vlan_id = nil if @vlan_id == UNSET_VALUE + @mac = nil if @mac == UNSET_VALUE end def validate(machine) diff --git a/plugins/providers/hyperv/driver.rb b/plugins/providers/hyperv/driver.rb index db99d5dfe..324599fa1 100644 --- a/plugins/providers/hyperv/driver.rb +++ b/plugins/providers/hyperv/driver.rb @@ -81,6 +81,10 @@ module VagrantPlugins execute("set_network_vlan.ps1", { VmId: vm_id, VlanId: vlan_id }) end + def net_set_mac(mac_addr) + execute("set_network_mac.ps1", { VmId: vm_id, Mac: mac_addr }) + end + protected def execute_powershell(path, options, &block) diff --git a/plugins/providers/hyperv/scripts/set_network_mac.ps1 b/plugins/providers/hyperv/scripts/set_network_mac.ps1 new file mode 100644 index 000000000..141b6f35a --- /dev/null +++ b/plugins/providers/hyperv/scripts/set_network_mac.ps1 @@ -0,0 +1,18 @@ +param ( + [string]$VmId = $(throw "-VmId is required."), + [string]$Mac = $(throw "-Mac ") + ) + +# Include the following modules +$presentDir = Split-Path -parent $PSCommandPath +$modules = @() +$modules += $presentDir + "\utils\write_messages.ps1" +forEach ($module in $modules) { . $module } + +try { + $vm = Get-VM -Id $VmId -ErrorAction "stop" + Set-VMNetworkAdapter $vm -StaticMacAddress $Mac -ErrorAction "stop" +} +catch { + Write-Error-Message "Failed to set VM's MAC address $_" +} diff --git a/test/unit/plugins/providers/hyperv/config_test.rb b/test/unit/plugins/providers/hyperv/config_test.rb index e7b5a6d71..467fc7f97 100644 --- a/test/unit/plugins/providers/hyperv/config_test.rb +++ b/test/unit/plugins/providers/hyperv/config_test.rb @@ -23,6 +23,14 @@ describe VagrantPlugins::HyperV::Config do end end + describe "#mac" do + it "can be set" do + subject.mac = "001122334455" + subject.finalize! + expect(subject.mac).to eq("001122334455") + end + end + describe "#vmname" do it "can be set" do subject.vmname = "test" diff --git a/website/docs/source/v2/hyperv/configuration.html.md b/website/docs/source/v2/hyperv/configuration.html.md index b9f255181..33a3afbb3 100644 --- a/website/docs/source/v2/hyperv/configuration.html.md +++ b/website/docs/source/v2/hyperv/configuration.html.md @@ -19,6 +19,8 @@ you may set. A complete reference is shown below: Defaults is taken from box image XML. * `vlan_id` (integer) - Number of Vlan ID for your guest network interface Defaults is not defined, vlan configuration will be untouched if not set. + * `mac` (string) - MAC address for your guest network interface + Default is not defined, MAC address will be dynamically assigned by Hyper-V if not set. * `ip_address_timeout` (integer) - The time in seconds to wait for the virtual machine to report an IP address. This defaults to 120 seconds. This may have to be increased if your VM takes longer to boot.