diff --git a/internal/distro/rhel85/pipelines.go b/internal/distro/rhel85/pipelines.go index e70ec5570..abce49732 100644 --- a/internal/distro/rhel85/pipelines.go +++ b/internal/distro/rhel85/pipelines.go @@ -55,7 +55,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "0.10") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "0.10"}) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil @@ -99,7 +99,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -130,7 +130,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -161,7 +161,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations, return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -1271,12 +1271,15 @@ func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string) return p } -func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, qcow2Compat string) *osbuild.Pipeline { +func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, formatOptions osbuild.QEMUFormatOptions) *osbuild.Pipeline { p := new(osbuild.Pipeline) p.Name = string(format) p.Build = "name:build" - qemuStage := osbuild.NewQEMUStage(qemuStageOptions(outputFilename, format, qcow2Compat), osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename)) + qemuStage := osbuild.NewQEMUStage( + osbuild.NewQEMUStageOptions(outputFilename, format, formatOptions), + osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename), + ) p.AddStage(qemuStage) return p } diff --git a/internal/distro/rhel85/stage_options.go b/internal/distro/rhel85/stage_options.go index 0d43710b5..fceffaa00 100644 --- a/internal/distro/rhel85/stage_options.go +++ b/internal/distro/rhel85/stage_options.go @@ -229,32 +229,6 @@ func xorrisofsStageOptions(filename string, arch string, isolinux bool) *osbuild return options } -func qemuStageOptions(filename string, format osbuild.QEMUFormat, compat string) *osbuild.QEMUStageOptions { - var options osbuild.QEMUFormatOptions - switch format { - case osbuild.QEMUFormatQCOW2: - options = osbuild.QCOW2Options{ - Type: format, - Compat: compat, - } - case osbuild.QEMUFormatVPC: - options = osbuild.VPCOptions{ - Type: format, - } - case osbuild.QEMUFormatVMDK: - options = osbuild.VMDKOptions{ - Type: format, - } - default: - panic("unknown format in qemu stage: " + format) - } - - return &osbuild.QEMUStageOptions{ - Filename: filename, - Format: options, - } -} - func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions { // configure nginx to work in an unprivileged container cfg := &osbuild.NginxConfig{ diff --git a/internal/distro/rhel86/pipelines.go b/internal/distro/rhel86/pipelines.go index fabaf5baa..258381dfb 100644 --- a/internal/distro/rhel86/pipelines.go +++ b/internal/distro/rhel86/pipelines.go @@ -34,7 +34,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "0.10") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "0.10"}) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil @@ -75,7 +75,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -103,7 +103,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -131,7 +131,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations, return nil, err } - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -1033,12 +1033,15 @@ func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string) return p } -func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, qcow2Compat string) *osbuild.Pipeline { +func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, formatOptions osbuild.QEMUFormatOptions) *osbuild.Pipeline { p := new(osbuild.Pipeline) p.Name = string(format) p.Build = "name:build" - qemuStage := osbuild.NewQEMUStage(qemuStageOptions(outputFilename, format, qcow2Compat), osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename)) + qemuStage := osbuild.NewQEMUStage( + osbuild.NewQEMUStageOptions(outputFilename, format, formatOptions), + osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename), + ) p.AddStage(qemuStage) return p } diff --git a/internal/distro/rhel86/stage_options.go b/internal/distro/rhel86/stage_options.go index 370e68029..911dbcab7 100644 --- a/internal/distro/rhel86/stage_options.go +++ b/internal/distro/rhel86/stage_options.go @@ -278,32 +278,6 @@ func xorrisofsStageOptions(filename, isolabel, arch string, isolinux bool) *osbu return options } -func qemuStageOptions(filename string, format osbuild.QEMUFormat, compat string) *osbuild.QEMUStageOptions { - var options osbuild.QEMUFormatOptions - switch format { - case osbuild.QEMUFormatQCOW2: - options = osbuild.QCOW2Options{ - Type: format, - Compat: compat, - } - case osbuild.QEMUFormatVPC: - options = osbuild.VPCOptions{ - Type: format, - } - case osbuild.QEMUFormatVMDK: - options = osbuild.VMDKOptions{ - Type: format, - } - default: - panic("unknown format in qemu stage: " + format) - } - - return &osbuild.QEMUStageOptions{ - Filename: filename, - Format: options, - } -} - func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions { // configure nginx to work in an unprivileged container cfg := &osbuild.NginxConfig{ diff --git a/internal/distro/rhel90/pipelines.go b/internal/distro/rhel90/pipelines.go index 57e4261e1..b0aab697e 100644 --- a/internal/distro/rhel90/pipelines.go +++ b/internal/distro/rhel90/pipelines.go @@ -35,7 +35,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "1.1") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "1.1"}) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil @@ -72,7 +72,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -97,7 +97,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -122,7 +122,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations, imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -1025,12 +1025,15 @@ func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string) return p } -func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, qcow2Compat string) *osbuild.Pipeline { +func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, formatOptions osbuild.QEMUFormatOptions) *osbuild.Pipeline { p := new(osbuild.Pipeline) p.Name = string(format) p.Build = "name:build" - qemuStage := osbuild.NewQEMUStage(qemuStageOptions(outputFilename, format, qcow2Compat), osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename)) + qemuStage := osbuild.NewQEMUStage( + osbuild.NewQEMUStageOptions(outputFilename, format, formatOptions), + osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename), + ) p.AddStage(qemuStage) return p } diff --git a/internal/distro/rhel90/stage_options.go b/internal/distro/rhel90/stage_options.go index 55c10964f..cb33cc793 100644 --- a/internal/distro/rhel90/stage_options.go +++ b/internal/distro/rhel90/stage_options.go @@ -278,32 +278,6 @@ func xorrisofsStageOptions(filename, isolabel, arch string, isolinux bool) *osbu return options } -func qemuStageOptions(filename string, format osbuild.QEMUFormat, compat string) *osbuild.QEMUStageOptions { - var options osbuild.QEMUFormatOptions - switch format { - case osbuild.QEMUFormatQCOW2: - options = osbuild.QCOW2Options{ - Type: format, - Compat: compat, - } - case osbuild.QEMUFormatVPC: - options = osbuild.VPCOptions{ - Type: format, - } - case osbuild.QEMUFormatVMDK: - options = osbuild.VMDKOptions{ - Type: format, - } - default: - panic("unknown format in qemu stage: " + format) - } - - return &osbuild.QEMUStageOptions{ - Filename: filename, - Format: options, - } -} - func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions { // configure nginx to work in an unprivileged container cfg := &osbuild.NginxConfig{ diff --git a/internal/distro/rhel90beta/pipelines.go b/internal/distro/rhel90beta/pipelines.go index b308df8f3..e8b989f04 100644 --- a/internal/distro/rhel90beta/pipelines.go +++ b/internal/distro/rhel90beta/pipelines.go @@ -51,7 +51,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "1.1") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "1.1"}) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil @@ -92,7 +92,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -121,7 +121,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatVMDK, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -149,7 +149,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations, imagePipeline := liveImagePipeline(treePipeline.Name, diskfile, partitionTable, t.arch, kernelVer) pipelines = append(pipelines, *imagePipeline) - qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, "") + qemuPipeline := qemuPipeline(imagePipeline.Name, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) pipelines = append(pipelines, *qemuPipeline) return pipelines, nil } @@ -1087,12 +1087,15 @@ func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string) return p } -func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, qcow2Compat string) *osbuild.Pipeline { +func qemuPipeline(inputPipelineName, inputFilename, outputFilename string, format osbuild.QEMUFormat, formatOptions osbuild.QEMUFormatOptions) *osbuild.Pipeline { p := new(osbuild.Pipeline) p.Name = string(format) p.Build = "name:build" - qemuStage := osbuild.NewQEMUStage(qemuStageOptions(outputFilename, format, qcow2Compat), osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename)) + qemuStage := osbuild.NewQEMUStage( + osbuild.NewQEMUStageOptions(outputFilename, format, formatOptions), + osbuild.NewQemuStagePipelineFilesInputs(inputPipelineName, inputFilename), + ) p.AddStage(qemuStage) return p } diff --git a/internal/distro/rhel90beta/stage_options.go b/internal/distro/rhel90beta/stage_options.go index 4ee78c71b..25660f0fd 100644 --- a/internal/distro/rhel90beta/stage_options.go +++ b/internal/distro/rhel90beta/stage_options.go @@ -207,29 +207,3 @@ func xorrisofsStageOptions(filename string, arch string) *osbuild.XorrisofsStage IsohybridMBR: "/usr/share/syslinux/isohdpfx.bin", } } - -func qemuStageOptions(filename string, format osbuild.QEMUFormat, compat string) *osbuild.QEMUStageOptions { - var options osbuild.QEMUFormatOptions - switch format { - case osbuild.QEMUFormatQCOW2: - options = osbuild.QCOW2Options{ - Type: format, - Compat: compat, - } - case osbuild.QEMUFormatVPC: - options = osbuild.VPCOptions{ - Type: format, - } - case osbuild.QEMUFormatVMDK: - options = osbuild.VMDKOptions{ - Type: format, - } - default: - panic("unknown format in qemu stage: " + format) - } - - return &osbuild.QEMUStageOptions{ - Filename: filename, - Format: options, - } -} diff --git a/internal/osbuild2/qemu_stage.go b/internal/osbuild2/qemu_stage.go index a694c4847..bd7e91dc9 100644 --- a/internal/osbuild2/qemu_stage.go +++ b/internal/osbuild2/qemu_stage.go @@ -40,6 +40,7 @@ const ( type QEMUFormatOptions interface { isQEMUFormatOptions() validate() error + formatType() QEMUFormat } type QCOW2Options struct { @@ -59,6 +60,10 @@ func (o QCOW2Options) validate() error { return nil } +func (o QCOW2Options) formatType() QEMUFormat { + return o.Type +} + type VDIOptions struct { // The type of the format must be 'vdi' Type QEMUFormat `json:"type"` @@ -73,6 +78,10 @@ func (o VDIOptions) validate() error { return nil } +func (o VDIOptions) formatType() QEMUFormat { + return o.Type +} + type VPCOptions struct { // The type of the format must be 'vpc' Type QEMUFormat `json:"type"` @@ -87,6 +96,10 @@ func (o VPCOptions) validate() error { return nil } +func (o VPCOptions) formatType() QEMUFormat { + return o.Type +} + type VMDKOptions struct { // The type of the format must be 'vmdk' Type QEMUFormat `json:"type"` @@ -124,6 +137,10 @@ func (o VMDKOptions) validate() error { return nil } +func (o VMDKOptions) formatType() QEMUFormat { + return o.Type +} + type VHDXOptions struct { // The type of the format must be 'vhdx' Type QEMUFormat `json:"type"` @@ -138,6 +155,10 @@ func (o VHDXOptions) validate() error { return nil } +func (o VHDXOptions) formatType() QEMUFormat { + return o.Type +} + type QEMUStageInputs struct { Image *QEMUStageInput `json:"image"` } @@ -171,6 +192,70 @@ func NewQEMUStage(options *QEMUStageOptions, inputs *QEMUStageInputs) *Stage { } } +// NewQEMUStageOptions creates a new QEMU Stage options object. +// +// In case the format-specific options are provided, they are used for +// the Stage options. +func NewQEMUStageOptions(filename string, format QEMUFormat, formatOptions QEMUFormatOptions) *QEMUStageOptions { + if formatOptions != nil { + // If the format type is not set explicitly in the provided format + // options, set it to the appropriate value based on the format options + // object type. + if formatOptions.formatType() == "" { + switch o := formatOptions.(type) { + case QCOW2Options: + o.Type = QEMUFormatQCOW2 + formatOptions = o + case VDIOptions: + o.Type = QEMUFormatVDI + formatOptions = o + case VPCOptions: + o.Type = QEMUFormatVPC + formatOptions = o + case VMDKOptions: + o.Type = QEMUFormatVMDK + formatOptions = o + case VHDXOptions: + o.Type = QEMUFormatVHDX + formatOptions = o + default: + panic(fmt.Sprintf("unknown format options type in qemu stage: %t", o)) + } + } + + // Ensure that the explicitly provided QEMU format and the format set + // in the format options structure (set by user or by this function + // above) are matching. + if t := formatOptions.formatType(); t != format { + panic(fmt.Sprintf("mismatch between passed format type %q and format options type %q", format, t)) + } + + if err := formatOptions.validate(); err != nil { + panic(err) + } + } else { + switch format { + case QEMUFormatQCOW2: + formatOptions = QCOW2Options{Type: format} + case QEMUFormatVDI: + formatOptions = VDIOptions{Type: format} + case QEMUFormatVPC: + formatOptions = VPCOptions{Type: format} + case QEMUFormatVMDK: + formatOptions = VMDKOptions{Type: format} + case QEMUFormatVHDX: + formatOptions = VHDXOptions{Type: format} + default: + panic("unknown format in qemu stage: " + format) + } + } + + return &QEMUStageOptions{ + Filename: filename, + Format: formatOptions, + } +} + // alias for custom marshaller type qemuStageOptions QEMUStageOptions diff --git a/internal/osbuild2/qemu_stage_test.go b/internal/osbuild2/qemu_stage_test.go index 7b61b49e3..7921115cc 100644 --- a/internal/osbuild2/qemu_stage_test.go +++ b/internal/osbuild2/qemu_stage_test.go @@ -1,6 +1,7 @@ package osbuild2 import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -52,3 +53,163 @@ func TestNewQemuStage(t *testing.T) { assert.Equal(t, expectedStage, actualStage) } } + +func TestNewQEMUStageOptions(t *testing.T) { + tests := []struct { + Filename string + Format QEMUFormat + FormatOptions QEMUFormatOptions + ExpectedOptions *QEMUStageOptions + Error bool + }{ + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: QCOW2Options{ + Compat: "1.1", + }, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.qcow2", + Format: QCOW2Options{ + Type: QEMUFormatQCOW2, + Compat: "1.1", + }, + }, + }, + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: QCOW2Options{ + Type: QEMUFormatQCOW2, + }, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.qcow2", + Format: QCOW2Options{ + Type: QEMUFormatQCOW2, + }, + }, + }, + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: QCOW2Options{}, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.qcow2", + Format: QCOW2Options{ + Type: QEMUFormatQCOW2, + }, + }, + }, + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: nil, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.qcow2", + Format: QCOW2Options{ + Type: QEMUFormatQCOW2, + }, + }, + }, + { + Filename: "image.vdi", + Format: QEMUFormatVDI, + FormatOptions: nil, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.vdi", + Format: VDIOptions{ + Type: QEMUFormatVDI, + }, + }, + }, + { + Filename: "image.vpc", + Format: QEMUFormatVPC, + FormatOptions: nil, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.vpc", + Format: VPCOptions{ + Type: QEMUFormatVPC, + }, + }, + }, + { + Filename: "image.vmdk", + Format: QEMUFormatVMDK, + FormatOptions: nil, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.vmdk", + Format: VMDKOptions{ + Type: QEMUFormatVMDK, + }, + }, + }, + { + Filename: "image.vmdk", + Format: QEMUFormatVMDK, + FormatOptions: VMDKOptions{ + Subformat: VMDKSubformatStreamOptimized, + }, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.vmdk", + Format: VMDKOptions{ + Type: QEMUFormatVMDK, + Subformat: VMDKSubformatStreamOptimized, + }, + }, + }, + { + Filename: "image.vhdx", + Format: QEMUFormatVHDX, + FormatOptions: nil, + ExpectedOptions: &QEMUStageOptions{ + Filename: "image.vhdx", + Format: VHDXOptions{ + Type: QEMUFormatVHDX, + }, + }, + }, + // mismatch between format and format options type + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: VMDKOptions{}, + Error: true, + }, + // mismatch between format and format options type + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: VMDKOptions{ + Type: QEMUFormatQCOW2, + }, + Error: true, + }, + // mismatch between format and format options type + { + Filename: "image.qcow2", + Format: QEMUFormatQCOW2, + FormatOptions: VMDKOptions{ + Type: QEMUFormatVMDK, + }, + Error: true, + }, + // unknown format + { + Filename: "image.qcow2", + Format: "", + FormatOptions: nil, + Error: true, + }, + } + for idx, test := range tests { + t.Run(fmt.Sprintf("test-(%d/%d)", idx, len(tests)), func(t *testing.T) { + if test.Error { + assert.Panics(t, func() { NewQEMUStageOptions(test.Filename, test.Format, test.FormatOptions) }) + } else { + stageOptions := NewQEMUStageOptions(test.Filename, test.Format, test.FormatOptions) + assert.EqualValues(t, test.ExpectedOptions, stageOptions) + } + }) + } +}