* [builder/qemu] Skip resize step when skip_resize_disk is enable #9860 * Update builder/qemu/builder_test.go Improve the code quality Co-authored-by: Wilken Rivera <dev@wilkenrivera.com> * Update files for unit tests Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
This commit is contained in:
parent
2da89db272
commit
b4ff0ea4bc
|
@ -130,6 +130,10 @@ type Config struct {
|
||||||
// for disk_size, Packer uses a default of `40960M` (40 GB). If a disk_size
|
// for disk_size, Packer uses a default of `40960M` (40 GB). If a disk_size
|
||||||
// number is provided with no units, Packer will default to Megabytes.
|
// number is provided with no units, Packer will default to Megabytes.
|
||||||
DiskSize string `mapstructure:"disk_size" required:"false"`
|
DiskSize string `mapstructure:"disk_size" required:"false"`
|
||||||
|
// Packer resizes the QCOW2 image using
|
||||||
|
// qemu-img resize. Set this option to true to disable resizing.
|
||||||
|
// Defaults to false.
|
||||||
|
SkipResizeDisk bool `mapstructure:"skip_resize_disk" required:"false"`
|
||||||
// The cache mode to use for disk. Allowed values include any of
|
// The cache mode to use for disk. Allowed values include any of
|
||||||
// `writethrough`, `writeback`, `none`, `unsafe` or `directsync`. By
|
// `writethrough`, `writeback`, `none`, `unsafe` or `directsync`. By
|
||||||
// default, this is set to `writeback`.
|
// default, this is set to `writeback`.
|
||||||
|
@ -509,6 +513,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||||
errs, errors.New("disk_additional_size can only be used when disk_image is false"))
|
errs, errors.New("disk_additional_size can only be used when disk_image is false"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.config.SkipResizeDisk && !(b.config.DiskImage) {
|
||||||
|
errs = packer.MultiErrorAppend(
|
||||||
|
errs, errors.New("skip_resize_disk can only be used when disk_image is true"))
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := accels[b.config.Accelerator]; !ok {
|
if _, ok := accels[b.config.Accelerator]; !ok {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', 'hax', 'hvf', 'whpx', or 'none' are allowed"))
|
errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', 'hax', 'hvf', 'whpx', or 'none' are allowed"))
|
||||||
|
|
|
@ -93,6 +93,7 @@ type FlatConfig struct {
|
||||||
CpuCount *int `mapstructure:"cpus" required:"false" cty:"cpus" hcl:"cpus"`
|
CpuCount *int `mapstructure:"cpus" required:"false" cty:"cpus" hcl:"cpus"`
|
||||||
DiskInterface *string `mapstructure:"disk_interface" required:"false" cty:"disk_interface" hcl:"disk_interface"`
|
DiskInterface *string `mapstructure:"disk_interface" required:"false" cty:"disk_interface" hcl:"disk_interface"`
|
||||||
DiskSize *string `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"`
|
DiskSize *string `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"`
|
||||||
|
SkipResizeDisk *bool `mapstructure:"skip_resize_disk" required:"false" cty:"skip_resize_disk" hcl:"skip_resize_disk"`
|
||||||
DiskCache *string `mapstructure:"disk_cache" required:"false" cty:"disk_cache" hcl:"disk_cache"`
|
DiskCache *string `mapstructure:"disk_cache" required:"false" cty:"disk_cache" hcl:"disk_cache"`
|
||||||
DiskDiscard *string `mapstructure:"disk_discard" required:"false" cty:"disk_discard" hcl:"disk_discard"`
|
DiskDiscard *string `mapstructure:"disk_discard" required:"false" cty:"disk_discard" hcl:"disk_discard"`
|
||||||
DetectZeroes *string `mapstructure:"disk_detect_zeroes" required:"false" cty:"disk_detect_zeroes" hcl:"disk_detect_zeroes"`
|
DetectZeroes *string `mapstructure:"disk_detect_zeroes" required:"false" cty:"disk_detect_zeroes" hcl:"disk_detect_zeroes"`
|
||||||
|
@ -218,6 +219,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"cpus": &hcldec.AttrSpec{Name: "cpus", Type: cty.Number, Required: false},
|
"cpus": &hcldec.AttrSpec{Name: "cpus", Type: cty.Number, Required: false},
|
||||||
"disk_interface": &hcldec.AttrSpec{Name: "disk_interface", Type: cty.String, Required: false},
|
"disk_interface": &hcldec.AttrSpec{Name: "disk_interface", Type: cty.String, Required: false},
|
||||||
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.String, Required: false},
|
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.String, Required: false},
|
||||||
|
"skip_resize_disk": &hcldec.AttrSpec{Name: "skip_resize_disk", Type: cty.Bool, Required: false},
|
||||||
"disk_cache": &hcldec.AttrSpec{Name: "disk_cache", Type: cty.String, Required: false},
|
"disk_cache": &hcldec.AttrSpec{Name: "disk_cache", Type: cty.String, Required: false},
|
||||||
"disk_discard": &hcldec.AttrSpec{Name: "disk_discard", Type: cty.String, Required: false},
|
"disk_discard": &hcldec.AttrSpec{Name: "disk_discard", Type: cty.String, Required: false},
|
||||||
"disk_detect_zeroes": &hcldec.AttrSpec{Name: "disk_detect_zeroes", Type: cty.String, Required: false},
|
"disk_detect_zeroes": &hcldec.AttrSpec{Name: "disk_detect_zeroes", Type: cty.String, Required: false},
|
||||||
|
|
|
@ -302,6 +302,21 @@ func TestBuilderPrepare_UseBackingFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_SkipResizeDisk(t *testing.T) {
|
||||||
|
config := testConfig()
|
||||||
|
config["skip_resize_disk"] = true
|
||||||
|
config["disk_image"] = false
|
||||||
|
|
||||||
|
b := Builder{}
|
||||||
|
_, warns, err := b.Prepare(config)
|
||||||
|
if len(warns) > 0 {
|
||||||
|
t.Errorf("unexpected warns when calling prepare with skip_resize_disk set to true: %#v", warns)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("setting skip_resize_disk to true when disk_image is false should have error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package qemu
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type DriverMock struct {
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
|
StopCalled bool
|
||||||
|
StopErr error
|
||||||
|
|
||||||
|
QemuCalls [][]string
|
||||||
|
QemuErrs []error
|
||||||
|
|
||||||
|
WaitForShutdownCalled bool
|
||||||
|
WaitForShutdownState bool
|
||||||
|
|
||||||
|
QemuImgCalls [][]string
|
||||||
|
QemuImgErrs []error
|
||||||
|
|
||||||
|
VerifyCalled bool
|
||||||
|
VerifyErr error
|
||||||
|
|
||||||
|
VersionCalled bool
|
||||||
|
VersionResult string
|
||||||
|
VersionErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) Stop() error {
|
||||||
|
d.StopCalled = true
|
||||||
|
return d.StopErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) Qemu(args ...string) error {
|
||||||
|
d.QemuCalls = append(d.QemuCalls, args)
|
||||||
|
|
||||||
|
if len(d.QemuErrs) >= len(d.QemuCalls) {
|
||||||
|
return d.QemuErrs[len(d.QemuCalls)-1]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) WaitForShutdown(cancelCh <-chan struct{}) bool {
|
||||||
|
d.WaitForShutdownCalled = true
|
||||||
|
return d.WaitForShutdownState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) QemuImg(args ...string) error {
|
||||||
|
d.QemuImgCalls = append(d.QemuImgCalls, args)
|
||||||
|
|
||||||
|
if len(d.QemuImgErrs) >= len(d.QemuImgCalls) {
|
||||||
|
return d.QemuImgErrs[len(d.QemuImgCalls)-1]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) Verify() error {
|
||||||
|
d.VerifyCalled = true
|
||||||
|
return d.VerifyErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) Version() (string, error) {
|
||||||
|
d.VersionCalled = true
|
||||||
|
return d.VersionResult, d.VersionErr
|
||||||
|
}
|
|
@ -25,7 +25,8 @@ func (s *stepResizeDisk) Run(ctx context.Context, state multistep.StateBag) mult
|
||||||
path,
|
path,
|
||||||
config.DiskSize,
|
config.DiskSize,
|
||||||
}
|
}
|
||||||
if config.DiskImage == false {
|
|
||||||
|
if config.DiskImage == false || config.SkipResizeDisk == true {
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStepResizeDisk_Run(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
driver := state.Get("driver").(*DriverMock)
|
||||||
|
|
||||||
|
config := &Config{
|
||||||
|
DiskImage: true,
|
||||||
|
SkipResizeDisk: false,
|
||||||
|
DiskSize: "4096M",
|
||||||
|
Format: "qcow2",
|
||||||
|
OutputDir: "/test/",
|
||||||
|
VMName: "test",
|
||||||
|
}
|
||||||
|
state.Put("config", config)
|
||||||
|
step := new(stepResizeDisk)
|
||||||
|
|
||||||
|
// Test the run
|
||||||
|
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||||
|
t.Fatalf("bad action: %#v", action)
|
||||||
|
}
|
||||||
|
if _, ok := state.GetOk("error"); ok {
|
||||||
|
t.Fatal("should NOT have error")
|
||||||
|
}
|
||||||
|
if len(driver.QemuImgCalls) == 0 {
|
||||||
|
t.Fatal("should qemu-img called")
|
||||||
|
}
|
||||||
|
if len(driver.QemuImgCalls[0]) != 5 {
|
||||||
|
t.Fatal("should 5 qemu-img parameters")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepResizeDisk_SkipIso(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
driver := state.Get("driver").(*DriverMock)
|
||||||
|
config := &Config{
|
||||||
|
DiskImage: false,
|
||||||
|
SkipResizeDisk: false,
|
||||||
|
}
|
||||||
|
state.Put("config", config)
|
||||||
|
step := new(stepResizeDisk)
|
||||||
|
|
||||||
|
// Test the run
|
||||||
|
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||||
|
t.Fatalf("bad action: %#v", action)
|
||||||
|
}
|
||||||
|
if _, ok := state.GetOk("error"); ok {
|
||||||
|
t.Fatal("should NOT have error")
|
||||||
|
}
|
||||||
|
if len(driver.QemuImgCalls) > 0 {
|
||||||
|
t.Fatal("should NOT qemu-img called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepResizeDisk_SkipOption(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
driver := state.Get("driver").(*DriverMock)
|
||||||
|
config := &Config{
|
||||||
|
DiskImage: false,
|
||||||
|
SkipResizeDisk: true,
|
||||||
|
}
|
||||||
|
state.Put("config", config)
|
||||||
|
step := new(stepResizeDisk)
|
||||||
|
|
||||||
|
// Test the run
|
||||||
|
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||||
|
t.Fatalf("bad action: %#v", action)
|
||||||
|
}
|
||||||
|
if _, ok := state.GetOk("error"); ok {
|
||||||
|
t.Fatal("should NOT have error")
|
||||||
|
}
|
||||||
|
if len(driver.QemuImgCalls) > 0 {
|
||||||
|
t.Fatal("should NOT qemu-img called")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testState(t *testing.T) multistep.StateBag {
|
||||||
|
state := new(multistep.BasicStateBag)
|
||||||
|
state.Put("driver", new(DriverMock))
|
||||||
|
state.Put("ui", &packer.BasicUi{
|
||||||
|
Reader: new(bytes.Buffer),
|
||||||
|
Writer: new(bytes.Buffer),
|
||||||
|
})
|
||||||
|
return state
|
||||||
|
}
|
|
@ -53,6 +53,10 @@
|
||||||
for disk_size, Packer uses a default of `40960M` (40 GB). If a disk_size
|
for disk_size, Packer uses a default of `40960M` (40 GB). If a disk_size
|
||||||
number is provided with no units, Packer will default to Megabytes.
|
number is provided with no units, Packer will default to Megabytes.
|
||||||
|
|
||||||
|
- `skip_resize_disk` (bool) - Packer resizes the QCOW2 image using
|
||||||
|
qemu-img resize. Set this option to true to disable resizing.
|
||||||
|
Defaults to false.
|
||||||
|
|
||||||
- `disk_cache` (string) - The cache mode to use for disk. Allowed values include any of
|
- `disk_cache` (string) - The cache mode to use for disk. Allowed values include any of
|
||||||
`writethrough`, `writeback`, `none`, `unsafe` or `directsync`. By
|
`writethrough`, `writeback`, `none`, `unsafe` or `directsync`. By
|
||||||
default, this is set to `writeback`.
|
default, this is set to `writeback`.
|
||||||
|
|
Loading…
Reference in New Issue