Add support for mac spoofing and dynamic memory.
To enable nested virtualization, mac spoofing, no dynamic memory and at least 4gb of ram should be set for the vm. Set warning if this has not been done. Detected Virtualization Extensions are supported by the machine your are running on, as it only works for Windows 10 and Windows Server 2016 onwards.
This commit is contained in:
parent
1277a25d0b
commit
9fbd1e472a
|
@ -72,9 +72,15 @@ type Driver interface {
|
|||
|
||||
DeleteVirtualMachine(string) error
|
||||
|
||||
SetVirtualMachineCpu(string, uint, bool) error
|
||||
SetVirtualMachineCpuCount(string, uint) error
|
||||
|
||||
SetSecureBoot(string, bool) error
|
||||
SetVirtualMachineMacSpoofing(string, bool) error
|
||||
|
||||
SetVirtualMachineDynamicMemory(string, bool) error
|
||||
|
||||
SetVirtualMachineSecureBoot(string, bool) error
|
||||
|
||||
SetVirtualMachineVirtualizationExtensions(string, bool) error
|
||||
|
||||
EnableVirtualMachineIntegrationService(string, string) error
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/powershell"
|
||||
"github.com/mitchellh/packer/powershell/hyperv"
|
||||
"log"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/packer/powershell"
|
||||
"github.com/mitchellh/packer/powershell/hyperv"
|
||||
)
|
||||
|
||||
type HypervPS4Driver struct {
|
||||
|
@ -177,12 +178,24 @@ func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error {
|
|||
return hyperv.DeleteVirtualMachine(vmName)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) SetVirtualMachineCpu(vmName string, cpu uint, exposeVirtualizationExtensions bool) error {
|
||||
return hyperv.SetVirtualMachineCpu(vmName, cpu, exposeVirtualizationExtensions)
|
||||
func (d *HypervPS4Driver) SetVirtualMachineCpuCount(vmName string, cpu uint) error {
|
||||
return hyperv.SetVirtualMachineCpuCount(vmName, cpu)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) SetSecureBoot(vmName string, enable bool) error {
|
||||
return hyperv.SetSecureBoot(vmName, enable)
|
||||
func (d *HypervPS4Driver) SetVirtualMachineMacSpoofing(vmName string, enable bool) error {
|
||||
return hyperv.SetVirtualMachineMacSpoofing(vmName, enable)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) SetVirtualMachineDynamicMemory(vmName string, enable bool) error {
|
||||
return hyperv.SetVirtualMachineDynamicMemory(vmName, enable)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) SetVirtualMachineSecureBoot(vmName string, enable bool) error {
|
||||
return hyperv.SetVirtualMachineSecureBoot(vmName, enable)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) SetVirtualMachineVirtualizationExtensions(vmName string, enable bool) error {
|
||||
return hyperv.SetVirtualMachineVirtualizationExtensions(vmName, enable)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) EnableVirtualMachineIntegrationService(vmName string, integrationServiceName string) error {
|
||||
|
|
|
@ -6,6 +6,7 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
)
|
||||
|
@ -15,13 +16,15 @@ import (
|
|||
// Produces:
|
||||
// VMName string - The name of the VM
|
||||
type StepCreateVM struct {
|
||||
VMName string
|
||||
SwitchName string
|
||||
RamSizeMB uint
|
||||
DiskSize uint
|
||||
Generation uint
|
||||
Cpu uint
|
||||
EnableSecureBoot bool
|
||||
VMName string
|
||||
SwitchName string
|
||||
RamSizeMB uint
|
||||
DiskSize uint
|
||||
Generation uint
|
||||
Cpu uint
|
||||
EnableMacSpoofing bool
|
||||
EnableDynamicMemory bool
|
||||
EnableSecureBoot bool
|
||||
EnableVirtualizationExtensions bool
|
||||
}
|
||||
|
||||
|
@ -36,10 +39,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
|||
ram := int64(s.RamSizeMB * 1024 * 1024)
|
||||
diskSize := int64(s.DiskSize * 1024 * 1024)
|
||||
|
||||
switchName := s.SwitchName
|
||||
enableSecureBoot := s.EnableSecureBoot
|
||||
|
||||
err := driver.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName, s.Generation)
|
||||
err := driver.CreateVirtualMachine(s.VMName, path, ram, diskSize, s.SwitchName, s.Generation)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating virtual machine: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -47,7 +47,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
err = driver.SetVirtualMachineCpu(s.VMName, s.Cpu, s.EnableVirtualizationExtensions)
|
||||
err = driver.SetVirtualMachineCpuCount(s.VMName, s.Cpu)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating setting virtual machine cpu: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -55,8 +55,28 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if s.EnableDynamicMemory {
|
||||
err = driver.SetVirtualMachineDynamicMemory(s.VMName, s.EnableDynamicMemory)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating setting virtual machine dynamic memory: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
if s.EnableMacSpoofing {
|
||||
err = driver.SetVirtualMachineMacSpoofing(s.VMName, s.EnableMacSpoofing)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating setting virtual machine mac spoofing: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
if s.Generation == 2 {
|
||||
err = driver.SetSecureBoot(s.VMName, enableSecureBoot)
|
||||
err = driver.SetVirtualMachineSecureBoot(s.VMName, s.EnableSecureBoot)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error setting secure boot: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -65,6 +85,17 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
}
|
||||
|
||||
if s.EnableVirtualizationExtensions {
|
||||
//This is only supported on Windows 10 and Windows Server 2016 onwards
|
||||
err = driver.SetVirtualMachineVirtualizationExtensions(s.VMName, s.EnableVirtualizationExtensions)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating setting virtual machine virtualization extensions: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
// Set the final name in the state bag so others can use it
|
||||
state.Put("vmName", s.VMName)
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ const (
|
|||
MinDiskSize = 256 // 256MB
|
||||
MaxDiskSize = 64 * 1024 * 1024 // 64TB
|
||||
|
||||
DefaultRamSize = 1 * 1024 // 1GB
|
||||
MinRamSize = 32 // 32MB
|
||||
MaxRamSize = 32 * 1024 // 32GB
|
||||
DefaultRamSize = 1 * 1024 // 1GB
|
||||
MinRamSize = 32 // 32MB
|
||||
MaxRamSize = 32 * 1024 // 32GB
|
||||
MinNestedVirtualizationRamSize = 4 * 1024 // 4GB
|
||||
|
||||
LowRam = 256 // 256MB
|
||||
|
||||
|
@ -84,12 +85,14 @@ type Config struct {
|
|||
// By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build.
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
|
||||
BootCommand []string `mapstructure:"boot_command"`
|
||||
SwitchName string `mapstructure:"switch_name"`
|
||||
Cpu uint `mapstructure:"cpu"`
|
||||
Generation uint `mapstructure:"generation"`
|
||||
EnableSecureBoot bool `mapstructure:"enable_secure_boot"`
|
||||
EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"`
|
||||
BootCommand []string `mapstructure:"boot_command"`
|
||||
SwitchName string `mapstructure:"switch_name"`
|
||||
Cpu uint `mapstructure:"cpu"`
|
||||
Generation uint `mapstructure:"generation"`
|
||||
EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"`
|
||||
EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"`
|
||||
EnableSecureBoot bool `mapstructure:"enable_secure_boot"`
|
||||
EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"`
|
||||
|
||||
Communicator string `mapstructure:"communicator"`
|
||||
|
||||
|
@ -227,6 +230,17 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if b.config.EnableVirtualizationExtensions {
|
||||
hasVirtualMachineVirtualizationExtensions, err := powershell.HasVirtualMachineVirtualizationExtensions()
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting virtual machine virtualization extensions support: %s", err))
|
||||
} else {
|
||||
if !hasVirtualMachineVirtualizationExtensions {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("This version of Hyper-V does not support virtual machine virtualization extension. Please use Windows 10 or Windows Server 2016 or newer."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Warnings
|
||||
|
||||
if b.config.ShutdownCommand == "" {
|
||||
|
@ -240,6 +254,23 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
warnings = appendWarnings(warnings, warning)
|
||||
}
|
||||
|
||||
if b.config.EnableVirtualizationExtensions {
|
||||
if b.config.EnableDynamicMemory {
|
||||
warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, dynamic memory should not be allowed.")
|
||||
warnings = appendWarnings(warnings, warning)
|
||||
}
|
||||
|
||||
if !b.config.EnableMacSpoofing {
|
||||
warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, mac spoofing should be allowed.")
|
||||
warnings = appendWarnings(warnings, warning)
|
||||
}
|
||||
|
||||
if b.config.RamSizeMB < MinNestedVirtualizationRamSize {
|
||||
warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, there should be 4GB or more memory set for the vm, otherwise Hyper-V may fail to start any nested VMs.")
|
||||
warnings = appendWarnings(warnings, warning)
|
||||
}
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return warnings, errs
|
||||
}
|
||||
|
@ -292,13 +323,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
SwitchName: b.config.SwitchName,
|
||||
},
|
||||
&hypervcommon.StepCreateVM{
|
||||
VMName: b.config.VMName,
|
||||
SwitchName: b.config.SwitchName,
|
||||
RamSizeMB: b.config.RamSizeMB,
|
||||
DiskSize: b.config.DiskSize,
|
||||
Generation: b.config.Generation,
|
||||
Cpu: b.config.Cpu,
|
||||
EnableSecureBoot: b.config.EnableSecureBoot,
|
||||
VMName: b.config.VMName,
|
||||
SwitchName: b.config.SwitchName,
|
||||
RamSizeMB: b.config.RamSizeMB,
|
||||
DiskSize: b.config.DiskSize,
|
||||
Generation: b.config.Generation,
|
||||
Cpu: b.config.Cpu,
|
||||
EnableMacSpoofing: b.config.EnableMacSpoofing,
|
||||
EnableDynamicMemory: b.config.EnableDynamicMemory,
|
||||
EnableSecureBoot: b.config.EnableSecureBoot,
|
||||
EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions,
|
||||
},
|
||||
&hypervcommon.StepEnableIntegrationService{},
|
||||
|
|
|
@ -217,23 +217,67 @@ New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHD
|
|||
}
|
||||
}
|
||||
|
||||
func SetVirtualMachineCpu(vmName string, cpu uint, enableVirtualizationExtensions bool) error {
|
||||
func SetVirtualMachineCpuCount(vmName string, cpu uint) error {
|
||||
|
||||
var script = `
|
||||
param([string]$vmName, [int]$cpu, [string]$exposeVirtualizationExtensions)
|
||||
$nested = [System.Boolean]::Parse($exposeVirtualizationExtensions)
|
||||
Set-VMProcessor -VMName $vmName -Count $cpu -exposeVirtualizationExtensions $nested
|
||||
param([string]$vmName, [int]$cpu)
|
||||
Set-VMProcessor -VMName $vmName -Count $cpu
|
||||
`
|
||||
var ps powershell.PowerShellCmd
|
||||
err := ps.Run(script, vmName, strconv.FormatInt(int64(cpu), 10))
|
||||
return err
|
||||
}
|
||||
|
||||
func SetVirtualMachineVirtualizationExtensions(vmName string, enableVirtualizationExtensions bool) error {
|
||||
|
||||
var script = `
|
||||
param([string]$vmName, [string]$exposeVirtualizationExtensionsString)
|
||||
$exposeVirtualizationExtensions = [System.Boolean]::Parse($exposeVirtualizationExtensionsString)
|
||||
Set-VMProcessor -VMName $vmName -ExposeVirtualizationExtensions $exposeVirtualizationExtensions
|
||||
`
|
||||
exposeVirtualizationExtensionsString := "False"
|
||||
if enableVirtualizationExtensions {
|
||||
exposeVirtualizationExtensionsString = "True"
|
||||
}
|
||||
}
|
||||
var ps powershell.PowerShellCmd
|
||||
err := ps.Run(script, vmName, strconv.FormatInt(int64(cpu), 10), exposeVirtualizationExtensionsString)
|
||||
err := ps.Run(script, vmName, exposeVirtualizationExtensionsString)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetSecureBoot(vmName string, enable bool) error {
|
||||
func SetVirtualMachineDynamicMemory(vmName string, enableDynamicMemory bool) error {
|
||||
|
||||
var script = `
|
||||
param([string]$vmName, [string]$enableDynamicMemoryString)
|
||||
$enableDynamicMemory = [System.Boolean]::Parse($enableDynamicMemoryString)
|
||||
Set-VMMemory -VMName $vmName -DynamicMemoryEnabled $enableDynamicMemory
|
||||
`
|
||||
enableDynamicMemoryString := "False"
|
||||
if enableDynamicMemory {
|
||||
enableDynamicMemoryString = "True"
|
||||
}
|
||||
var ps powershell.PowerShellCmd
|
||||
err := ps.Run(script, vmName, enableDynamicMemoryString)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetVirtualMachineMacSpoofing(vmName string, enableMacSpoofing bool) error {
|
||||
var script = `
|
||||
param([string]$vmName, $enableMacSpoofing)
|
||||
Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoofing
|
||||
`
|
||||
|
||||
var ps powershell.PowerShellCmd
|
||||
|
||||
enableMacSpoofingString := "Off"
|
||||
if enableMacSpoofing {
|
||||
enableMacSpoofingString = "On"
|
||||
}
|
||||
|
||||
err := ps.Run(script, vmName, enableMacSpoofingString)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetVirtualMachineSecureBoot(vmName string, enableSecureBoot bool) error {
|
||||
var script = `
|
||||
param([string]$vmName, $enableSecureBoot)
|
||||
Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot
|
||||
|
@ -241,12 +285,12 @@ Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot
|
|||
|
||||
var ps powershell.PowerShellCmd
|
||||
|
||||
enableSecureBoot := "Off"
|
||||
if enable {
|
||||
enableSecureBoot = "On"
|
||||
enableSecureBootString := "Off"
|
||||
if enableSecureBoot {
|
||||
enableSecureBootString = "On"
|
||||
}
|
||||
|
||||
err := ps.Run(script, vmName, enableSecureBoot)
|
||||
err := ps.Run(script, vmName, enableSecureBootString)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,23 @@ param([string]$moduleName)
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func HasVirtualMachineVirtualizationExtensions() (bool, error) {
|
||||
|
||||
var script = `
|
||||
(GET-Command Set-VMProcessor).parameters.keys -contains "ExposeVirtualizationExtensions"
|
||||
`
|
||||
|
||||
var ps PowerShellCmd
|
||||
cmdOut, err := ps.Output(script)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var hasVirtualMachineVirtualizationExtensions = strings.TrimSpace(cmdOut) == "True"
|
||||
return hasVirtualMachineVirtualizationExtensions, err
|
||||
}
|
||||
|
||||
func SetUnattendedProductKey(path string, productKey string) error {
|
||||
|
||||
var script = `
|
||||
|
|
Loading…
Reference in New Issue