Merge pull request #5941 from synax/hyper-v-disk-block-size
Adds Support to configure hyper-v disk block size
This commit is contained in:
commit
f5c031baf9
|
@ -66,9 +66,9 @@ type Driver interface {
|
|||
|
||||
DeleteVirtualSwitch(string) error
|
||||
|
||||
CreateVirtualMachine(string, string, string, string, int64, int64, string, uint, bool) error
|
||||
CreateVirtualMachine(string, string, string, string, int64, int64, int64, string, uint, bool) error
|
||||
|
||||
AddVirtualMachineHardDrive(string, string, string, int64, string) error
|
||||
AddVirtualMachineHardDrive(string, string, string, int64, int64, string) error
|
||||
|
||||
CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string) error
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ type DriverMock struct {
|
|||
AddVirtualMachineHardDrive_VhdFile string
|
||||
AddVirtualMachineHardDrive_VhdName string
|
||||
AddVirtualMachineHardDrive_VhdSizeBytes int64
|
||||
AddVirtualMachineHardDrive_VhdBlockSize int64
|
||||
AddVirtualMachineHardDrive_ControllerType string
|
||||
AddVirtualMachineHardDrive_Err error
|
||||
|
||||
|
@ -122,6 +123,7 @@ type DriverMock struct {
|
|||
CreateVirtualMachine_VhdPath string
|
||||
CreateVirtualMachine_Ram int64
|
||||
CreateVirtualMachine_DiskSize int64
|
||||
CreateVirtualMachine_DiskBlockSize int64
|
||||
CreateVirtualMachine_SwitchName string
|
||||
CreateVirtualMachine_Generation uint
|
||||
CreateVirtualMachine_DifferentialDisk bool
|
||||
|
@ -377,17 +379,18 @@ func (d *DriverMock) CreateVirtualSwitch(switchName string, switchType string) (
|
|||
return d.CreateVirtualSwitch_Return, d.CreateVirtualSwitch_Err
|
||||
}
|
||||
|
||||
func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error {
|
||||
func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, vhdDiskBlockSize int64, controllerType string) error {
|
||||
d.AddVirtualMachineHardDrive_Called = true
|
||||
d.AddVirtualMachineHardDrive_VmName = vmName
|
||||
d.AddVirtualMachineHardDrive_VhdFile = vhdFile
|
||||
d.AddVirtualMachineHardDrive_VhdName = vhdName
|
||||
d.AddVirtualMachineHardDrive_VhdSizeBytes = vhdSizeBytes
|
||||
d.AddVirtualMachineHardDrive_VhdSizeBytes = vhdDiskBlockSize
|
||||
d.AddVirtualMachineHardDrive_ControllerType = controllerType
|
||||
return d.AddVirtualMachineHardDrive_Err
|
||||
}
|
||||
|
||||
func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
d.CreateVirtualMachine_Called = true
|
||||
d.CreateVirtualMachine_VmName = vmName
|
||||
d.CreateVirtualMachine_Path = path
|
||||
|
@ -395,6 +398,7 @@ func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddriveP
|
|||
d.CreateVirtualMachine_VhdPath = vhdPath
|
||||
d.CreateVirtualMachine_Ram = ram
|
||||
d.CreateVirtualMachine_DiskSize = diskSize
|
||||
d.CreateVirtualMachine_DiskBlockSize = diskBlockSize
|
||||
d.CreateVirtualMachine_SwitchName = switchName
|
||||
d.CreateVirtualMachine_Generation = generation
|
||||
d.CreateVirtualMachine_DifferentialDisk = diffDisks
|
||||
|
|
|
@ -174,12 +174,12 @@ func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType stri
|
|||
return hyperv.CreateVirtualSwitch(switchName, switchType)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error {
|
||||
return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, controllerType)
|
||||
func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, diskBlockSize int64, controllerType string) error {
|
||||
return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, diskBlockSize, controllerType)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation, diffDisks)
|
||||
func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, diskBlockSize, switchName, generation, diffDisks)
|
||||
}
|
||||
|
||||
func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error {
|
||||
|
|
|
@ -21,6 +21,7 @@ type StepCreateVM struct {
|
|||
HarddrivePath string
|
||||
RamSize uint
|
||||
DiskSize uint
|
||||
DiskBlockSize uint
|
||||
Generation uint
|
||||
Cpu uint
|
||||
EnableMacSpoofing bool
|
||||
|
@ -64,8 +65,9 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
// convert the MB to bytes
|
||||
ramSize := int64(s.RamSize * 1024 * 1024)
|
||||
diskSize := int64(s.DiskSize * 1024 * 1024)
|
||||
diskBlockSize := int64(s.DiskBlockSize * 1024 * 1024)
|
||||
|
||||
err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation, s.DifferencingDisk)
|
||||
err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, diskBlockSize, s.SwitchName, s.Generation, s.DifferencingDisk)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating virtual machine: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -124,7 +126,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
for index, size := range s.AdditionalDiskSize {
|
||||
diskSize := int64(size * 1024 * 1024)
|
||||
diskFile := fmt.Sprintf("%s-%d.vhdx", s.VMName, index)
|
||||
err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, "SCSI")
|
||||
err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, diskBlockSize, "SCSI")
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating and attaching additional disk drive: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -163,4 +165,6 @@ func (s *StepCreateVM) Cleanup(state multistep.StateBag) {
|
|||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err))
|
||||
}
|
||||
|
||||
// TODO: Clean up created VHDX
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ const (
|
|||
MinDiskSize = 256 // 256MB
|
||||
MaxDiskSize = 64 * 1024 * 1024 // 64TB
|
||||
|
||||
DefaultDiskBlockSize = 32 // 32MB
|
||||
MinDiskBlockSize = 1 // 1MB
|
||||
MaxDiskBlockSize = 256 // 256MB
|
||||
|
||||
DefaultRamSize = 1 * 1024 // 1GB
|
||||
MinRamSize = 32 // 32MB
|
||||
MaxRamSize = 32 * 1024 // 32GB
|
||||
|
@ -55,9 +59,15 @@ type Config struct {
|
|||
// The size, in megabytes, of the hard disk to create for the VM.
|
||||
// By default, this is 130048 (about 127 GB).
|
||||
DiskSize uint `mapstructure:"disk_size"`
|
||||
|
||||
// The size, in megabytes, of the block size used to create the hard disk.
|
||||
// By default, this is 32768 (about 32 MB)
|
||||
DiskBlockSize uint `mapstructure:"disk_block_size"`
|
||||
|
||||
// The size, in megabytes, of the computer memory in the VM.
|
||||
// By default, this is 1024 (about 1 GB).
|
||||
RamSize uint `mapstructure:"ram_size"`
|
||||
|
||||
//
|
||||
SecondaryDvdImages []string `mapstructure:"secondary_iso_images"`
|
||||
|
||||
|
@ -141,6 +151,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
err = b.checkDiskBlockSize()
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
||||
err = b.checkRamSize()
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
|
@ -352,6 +367,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
SwitchName: b.config.SwitchName,
|
||||
RamSize: b.config.RamSize,
|
||||
DiskSize: b.config.DiskSize,
|
||||
DiskBlockSize: b.config.DiskBlockSize,
|
||||
Generation: b.config.Generation,
|
||||
Cpu: b.config.Cpu,
|
||||
EnableMacSpoofing: b.config.EnableMacSpoofing,
|
||||
|
@ -492,6 +508,22 @@ func (b *Builder) checkDiskSize() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) checkDiskBlockSize() error {
|
||||
if b.config.DiskBlockSize == 0 {
|
||||
b.config.DiskBlockSize = DefaultDiskBlockSize
|
||||
}
|
||||
|
||||
log.Println(fmt.Sprintf("%s: %v", "DiskBlockSize", b.config.DiskBlockSize))
|
||||
|
||||
if b.config.DiskBlockSize < MinDiskBlockSize {
|
||||
return fmt.Errorf("disk_block_size: Virtual machine requires disk block size >= %v MB, but defined: %v", MinDiskBlockSize, b.config.DiskBlockSize)
|
||||
} else if b.config.DiskBlockSize > MaxDiskBlockSize {
|
||||
return fmt.Errorf("disk_block_size: Virtual machine requires disk block size <= %v MB, but defined: %v", MaxDiskBlockSize, b.config.DiskBlockSize)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) checkRamSize() error {
|
||||
if b.config.RamSize == 0 {
|
||||
b.config.RamSize = DefaultRamSize
|
||||
|
|
|
@ -23,6 +23,7 @@ func testConfig() map[string]interface{} {
|
|||
"ssh_username": "foo",
|
||||
"ram_size": 64,
|
||||
"disk_size": 256,
|
||||
"disk_block_size": 1,
|
||||
"guest_additions_mode": "none",
|
||||
"disk_additional_size": "50000,40000,30000",
|
||||
packer.BuildNameConfigKey: "foo",
|
||||
|
@ -86,6 +87,58 @@ func TestBuilderPrepare_DiskSize(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_DiskBlockSize(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
expected_default_block_size := uint(32)
|
||||
expected_min_block_size := uint(0)
|
||||
expected_max_block_size := uint(256)
|
||||
|
||||
// Test default with empty disk_block_size
|
||||
delete(config, "disk_block_size")
|
||||
warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad err: %s", err)
|
||||
}
|
||||
if b.config.DiskBlockSize != expected_default_block_size {
|
||||
t.Fatalf("bad default block size with empty config: %d. Expected %d", b.config.DiskBlockSize, expected_default_block_size)
|
||||
}
|
||||
|
||||
test_sizes := []uint{0, 1, 32, 256, 512, 1 * 1024, 32 * 1024}
|
||||
for _, test_size := range test_sizes {
|
||||
config["disk_block_size"] = test_size
|
||||
b = Builder{}
|
||||
warns, err = b.Prepare(config)
|
||||
if test_size > expected_max_block_size || test_size < expected_min_block_size {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad, should have no warns: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("bad, should have error but didn't. disk_block_size=%d outside expected valid range [%d,%d]", test_size, expected_min_block_size, expected_max_block_size)
|
||||
}
|
||||
} else {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad, should not have error: %s", err)
|
||||
}
|
||||
if test_size == 0 {
|
||||
if b.config.DiskBlockSize != expected_default_block_size {
|
||||
t.Fatalf("bad default block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size)
|
||||
}
|
||||
} else {
|
||||
if b.config.DiskBlockSize != test_size {
|
||||
t.Fatalf("bad block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
|
|
@ -187,49 +187,51 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null
|
|||
return err
|
||||
}
|
||||
|
||||
func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
|
||||
|
||||
if generation == 2 {
|
||||
var script = `
|
||||
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks)
|
||||
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks)
|
||||
$vhdx = $vmName + '.vhdx'
|
||||
$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx
|
||||
if ($harddrivePath){
|
||||
if($diffDisks -eq "true"){
|
||||
New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing
|
||||
New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes
|
||||
} else {
|
||||
Copy-Item -Path $harddrivePath -Destination $vhdPath
|
||||
}
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation
|
||||
} else {
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation
|
||||
Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation
|
||||
}
|
||||
`
|
||||
var ps powershell.PowerShellCmd
|
||||
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10), strconv.FormatBool(diffDisks)); err != nil {
|
||||
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatInt(int64(generation), 10), strconv.FormatBool(diffDisks)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return DisableAutomaticCheckpoints(vmName)
|
||||
} else {
|
||||
var script = `
|
||||
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [string]$diffDisks)
|
||||
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [string]$diffDisks)
|
||||
$vhdx = $vmName + '.vhdx'
|
||||
$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx
|
||||
if ($harddrivePath){
|
||||
if($diffDisks -eq "true"){
|
||||
New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing
|
||||
New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes
|
||||
}
|
||||
else{
|
||||
Copy-Item -Path $harddrivePath -Destination $vhdPath
|
||||
}
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
|
||||
} else {
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName
|
||||
Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
|
||||
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
|
||||
}
|
||||
`
|
||||
var ps powershell.PowerShellCmd
|
||||
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil {
|
||||
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -872,16 +874,16 @@ Hyper-V\Get-VMNetworkAdapter -VMName $vmName | Hyper-V\Connect-VMNetworkAdapter
|
|||
return err
|
||||
}
|
||||
|
||||
func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, controllerType string) error {
|
||||
func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, vhdBlockSize int64, controllerType string) error {
|
||||
|
||||
var script = `
|
||||
param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes, [string]$controllerType)
|
||||
param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes,[string]$vhdBlockSizeInByte [string]$controllerType)
|
||||
$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName
|
||||
New-VHD $vhdPath -SizeBytes $vhdSizeInBytes
|
||||
Hyper-V\New-VHD -path $vhdPath -SizeBytes $vhdSizeInBytes -BlockSizeBytes $vhdBlockSizeInByte
|
||||
Hyper-V\Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType
|
||||
`
|
||||
var ps powershell.PowerShellCmd
|
||||
err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), controllerType)
|
||||
err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), strconv.FormatInt(vhdBlockSize, 10), controllerType)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -230,6 +230,9 @@ can be configured for this builder.
|
|||
- `temp_path` (string) - This is the temporary path in which Packer will create the virtual
|
||||
machine. Default value is system `%temp%`
|
||||
|
||||
- `disk_block_size` (string) - The block size of the VHD to be created.
|
||||
Recommended disk block size for Linux hyper-v guests is 1 MiB. This defaults to "32 MiB".
|
||||
|
||||
## Boot Command
|
||||
|
||||
The `boot_command` configuration is very important: it specifies the keys
|
||||
|
|
Loading…
Reference in New Issue