Adds Support to configure hyper-v disk block size

This commit is contained in:
Stefan Henseler 2018-02-23 20:19:26 +01:00
parent b1ab60031a
commit 103186af86
7 changed files with 133 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View File

@ -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

View File

@ -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()

View File

@ -53,6 +53,22 @@ $ip
return cmdOut, err
}
//func CreateVirtualHardDiskDrive(vmName string, diskPath string, diskSize int64, diskBlockSize int64, generation uint) (uint, uint, error) {
//
// var script = `
//param([string]$vmName, [string]$path,
//
//
//[long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation)
//$vhdx = $vmName + '.vhdx'
//$vhdPath = Join-Path -Path $path -ChildPath $vhdx
//New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation
//`
// var ps powershell.PowerShellCmd
// err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10))
// return err
//}
func CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, error) {
var ps powershell.PowerShellCmd
var script string
@ -187,45 +203,47 @@ 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
}
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation
} else {
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation
New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
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
}
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
} else {
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName
New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
}
`
var ps powershell.PowerShellCmd
@ -872,16 +890,16 @@ Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -SwitchName $swi
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]$vhdBlockSizeInBize [string]$controllerType)
$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName
New-VHD $vhdPath -SizeBytes $vhdSizeInBytes
New-VHD -path $vhdPath -SizeBytes $vhdSizeInBytes -BlockSizeBytes $vhdBlockSizeInBize
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
}