add floppy and cd to vsphere-clone
This commit is contained in:
parent
eca9b2f30d
commit
778d77e4a2
@ -41,6 +41,15 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
&common.StepConnect{
|
&common.StepConnect{
|
||||||
Config: &b.config.ConnectConfig,
|
Config: &b.config.ConnectConfig,
|
||||||
},
|
},
|
||||||
|
&packerCommon.StepCreateCD{
|
||||||
|
Files: b.config.CDConfig.CDFiles,
|
||||||
|
Label: b.config.CDConfig.CDLabel,
|
||||||
|
},
|
||||||
|
&common.StepRemoteUpload{
|
||||||
|
Datastore: b.config.Datastore,
|
||||||
|
Host: b.config.Host,
|
||||||
|
SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads,
|
||||||
|
},
|
||||||
&StepCloneVM{
|
&StepCloneVM{
|
||||||
Config: &b.config.CloneConfig,
|
Config: &b.config.CloneConfig,
|
||||||
Location: &b.config.LocationConfig,
|
Location: &b.config.LocationConfig,
|
||||||
@ -49,6 +58,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
&common.StepConfigureHardware{
|
&common.StepConfigureHardware{
|
||||||
Config: &b.config.HardwareConfig,
|
Config: &b.config.HardwareConfig,
|
||||||
},
|
},
|
||||||
|
&StepAddCDRom{
|
||||||
|
Config: &b.config.CDRomConfig,
|
||||||
|
},
|
||||||
&common.StepConfigParams{
|
&common.StepConfigParams{
|
||||||
Config: &b.config.ConfigParamsConfig,
|
Config: &b.config.ConfigParamsConfig,
|
||||||
},
|
},
|
||||||
@ -62,6 +74,17 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
|
|
||||||
if b.config.Comm.Type != "none" {
|
if b.config.Comm.Type != "none" {
|
||||||
steps = append(steps,
|
steps = append(steps,
|
||||||
|
&packerCommon.StepCreateFloppy{
|
||||||
|
Files: b.config.FloppyFiles,
|
||||||
|
Directories: b.config.FloppyDirectories,
|
||||||
|
Label: b.config.FloppyLabel,
|
||||||
|
},
|
||||||
|
&common.StepAddFloppy{
|
||||||
|
Config: &b.config.FloppyConfig,
|
||||||
|
Datastore: b.config.Datastore,
|
||||||
|
Host: b.config.Host,
|
||||||
|
SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads,
|
||||||
|
},
|
||||||
&common.StepHTTPIPDiscover{
|
&common.StepHTTPIPDiscover{
|
||||||
HTTPIP: b.config.BootConfig.HTTPIP,
|
HTTPIP: b.config.BootConfig.HTTPIP,
|
||||||
Network: b.config.WaitIpConfig.GetIPNet(),
|
Network: b.config.WaitIpConfig.GetIPNet(),
|
||||||
@ -98,10 +121,17 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
&common.StepShutdown{
|
&common.StepShutdown{
|
||||||
Config: &b.config.ShutdownConfig,
|
Config: &b.config.ShutdownConfig,
|
||||||
},
|
},
|
||||||
|
&common.StepRemoveFloppy{
|
||||||
|
Datastore: b.config.Datastore,
|
||||||
|
Host: b.config.Host,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
steps = append(steps,
|
steps = append(steps,
|
||||||
|
&common.StepRemoveCDRom{
|
||||||
|
Config: &b.config.RemoveCDRomConfig,
|
||||||
|
},
|
||||||
&common.StepCreateSnapshot{
|
&common.StepCreateSnapshot{
|
||||||
CreateSnapshot: b.config.CreateSnapshot,
|
CreateSnapshot: b.config.CreateSnapshot,
|
||||||
},
|
},
|
||||||
|
17
builder/vsphere/clone/common_test.go
Normal file
17
builder/vsphere/clone/common_test.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package clone
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func basicStateBag() *multistep.BasicStateBag {
|
||||||
|
state := new(multistep.BasicStateBag)
|
||||||
|
state.Put("ui", &packer.BasicUi{
|
||||||
|
Reader: new(bytes.Buffer),
|
||||||
|
Writer: new(bytes.Buffer),
|
||||||
|
})
|
||||||
|
return state
|
||||||
|
}
|
@ -15,6 +15,7 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
packerCommon.PackerConfig `mapstructure:",squash"`
|
packerCommon.PackerConfig `mapstructure:",squash"`
|
||||||
packerCommon.HTTPConfig `mapstructure:",squash"`
|
packerCommon.HTTPConfig `mapstructure:",squash"`
|
||||||
|
packerCommon.CDConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
common.ConnectConfig `mapstructure:",squash"`
|
common.ConnectConfig `mapstructure:",squash"`
|
||||||
CloneConfig `mapstructure:",squash"`
|
CloneConfig `mapstructure:",squash"`
|
||||||
@ -22,6 +23,9 @@ type Config struct {
|
|||||||
common.HardwareConfig `mapstructure:",squash"`
|
common.HardwareConfig `mapstructure:",squash"`
|
||||||
common.ConfigParamsConfig `mapstructure:",squash"`
|
common.ConfigParamsConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
|
CDRomConfig `mapstructure:",squash"`
|
||||||
|
common.RemoveCDRomConfig `mapstructure:",squash"`
|
||||||
|
common.FloppyConfig `mapstructure:",squash"`
|
||||||
common.RunConfig `mapstructure:",squash"`
|
common.RunConfig `mapstructure:",squash"`
|
||||||
common.BootConfig `mapstructure:",squash"`
|
common.BootConfig `mapstructure:",squash"`
|
||||||
common.WaitIpConfig `mapstructure:",squash"`
|
common.WaitIpConfig `mapstructure:",squash"`
|
||||||
@ -67,6 +71,8 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
|||||||
errs = packer.MultiErrorAppend(errs, c.HardwareConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.HardwareConfig.Prepare()...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...)
|
errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...)
|
||||||
|
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.CDRomConfig.Prepare()...)
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...)
|
errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
||||||
|
@ -22,6 +22,8 @@ type FlatConfig struct {
|
|||||||
HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"`
|
HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"`
|
||||||
HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"`
|
HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"`
|
||||||
HTTPInterface *string `mapstructure:"http_interface" undocumented:"true" cty:"http_interface" hcl:"http_interface"`
|
HTTPInterface *string `mapstructure:"http_interface" undocumented:"true" cty:"http_interface" hcl:"http_interface"`
|
||||||
|
CDFiles []string `mapstructure:"cd_files" cty:"cd_files" hcl:"cd_files"`
|
||||||
|
CDLabel *string `mapstructure:"cd_label" cty:"cd_label" hcl:"cd_label"`
|
||||||
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server" hcl:"vcenter_server"`
|
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server" hcl:"vcenter_server"`
|
||||||
Username *string `mapstructure:"username" cty:"username" hcl:"username"`
|
Username *string `mapstructure:"username" cty:"username" hcl:"username"`
|
||||||
Password *string `mapstructure:"password" cty:"password" hcl:"password"`
|
Password *string `mapstructure:"password" cty:"password" hcl:"password"`
|
||||||
@ -58,6 +60,12 @@ type FlatConfig struct {
|
|||||||
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters" hcl:"configuration_parameters"`
|
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters" hcl:"configuration_parameters"`
|
||||||
ToolsSyncTime *bool `mapstructure:"tools_sync_time" cty:"tools_sync_time" hcl:"tools_sync_time"`
|
ToolsSyncTime *bool `mapstructure:"tools_sync_time" cty:"tools_sync_time" hcl:"tools_sync_time"`
|
||||||
ToolsUpgradePolicy *bool `mapstructure:"tools_upgrade_policy" cty:"tools_upgrade_policy" hcl:"tools_upgrade_policy"`
|
ToolsUpgradePolicy *bool `mapstructure:"tools_upgrade_policy" cty:"tools_upgrade_policy" hcl:"tools_upgrade_policy"`
|
||||||
|
CdromType *string `mapstructure:"cdrom_type" cty:"cdrom_type" hcl:"cdrom_type"`
|
||||||
|
RemoveCdrom *bool `mapstructure:"remove_cdrom" cty:"remove_cdrom" hcl:"remove_cdrom"`
|
||||||
|
FloppyIMGPath *string `mapstructure:"floppy_img_path" cty:"floppy_img_path" hcl:"floppy_img_path"`
|
||||||
|
FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"`
|
||||||
|
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"`
|
||||||
|
FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"`
|
||||||
BootOrder *string `mapstructure:"boot_order" cty:"boot_order" hcl:"boot_order"`
|
BootOrder *string `mapstructure:"boot_order" cty:"boot_order" hcl:"boot_order"`
|
||||||
BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"`
|
BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"`
|
||||||
BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"`
|
BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"`
|
||||||
@ -147,6 +155,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||||||
"http_port_max": &hcldec.AttrSpec{Name: "http_port_max", Type: cty.Number, Required: false},
|
"http_port_max": &hcldec.AttrSpec{Name: "http_port_max", Type: cty.Number, Required: false},
|
||||||
"http_bind_address": &hcldec.AttrSpec{Name: "http_bind_address", Type: cty.String, Required: false},
|
"http_bind_address": &hcldec.AttrSpec{Name: "http_bind_address", Type: cty.String, Required: false},
|
||||||
"http_interface": &hcldec.AttrSpec{Name: "http_interface", Type: cty.String, Required: false},
|
"http_interface": &hcldec.AttrSpec{Name: "http_interface", Type: cty.String, Required: false},
|
||||||
|
"cd_files": &hcldec.AttrSpec{Name: "cd_files", Type: cty.List(cty.String), Required: false},
|
||||||
|
"cd_label": &hcldec.AttrSpec{Name: "cd_label", Type: cty.String, Required: false},
|
||||||
"vcenter_server": &hcldec.AttrSpec{Name: "vcenter_server", Type: cty.String, Required: false},
|
"vcenter_server": &hcldec.AttrSpec{Name: "vcenter_server", Type: cty.String, Required: false},
|
||||||
"username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false},
|
"username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false},
|
||||||
"password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false},
|
"password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false},
|
||||||
@ -183,6 +193,12 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||||||
"configuration_parameters": &hcldec.AttrSpec{Name: "configuration_parameters", Type: cty.Map(cty.String), Required: false},
|
"configuration_parameters": &hcldec.AttrSpec{Name: "configuration_parameters", Type: cty.Map(cty.String), Required: false},
|
||||||
"tools_sync_time": &hcldec.AttrSpec{Name: "tools_sync_time", Type: cty.Bool, Required: false},
|
"tools_sync_time": &hcldec.AttrSpec{Name: "tools_sync_time", Type: cty.Bool, Required: false},
|
||||||
"tools_upgrade_policy": &hcldec.AttrSpec{Name: "tools_upgrade_policy", Type: cty.Bool, Required: false},
|
"tools_upgrade_policy": &hcldec.AttrSpec{Name: "tools_upgrade_policy", Type: cty.Bool, Required: false},
|
||||||
|
"cdrom_type": &hcldec.AttrSpec{Name: "cdrom_type", Type: cty.String, Required: false},
|
||||||
|
"remove_cdrom": &hcldec.AttrSpec{Name: "remove_cdrom", Type: cty.Bool, Required: false},
|
||||||
|
"floppy_img_path": &hcldec.AttrSpec{Name: "floppy_img_path", Type: cty.String, Required: false},
|
||||||
|
"floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false},
|
||||||
|
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
|
||||||
|
"floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false},
|
||||||
"boot_order": &hcldec.AttrSpec{Name: "boot_order", Type: cty.String, Required: false},
|
"boot_order": &hcldec.AttrSpec{Name: "boot_order", Type: cty.String, Required: false},
|
||||||
"boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false},
|
"boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false},
|
||||||
"boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false},
|
"boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false},
|
||||||
|
59
builder/vsphere/clone/step_add_cdrom.go
Normal file
59
builder/vsphere/clone/step_add_cdrom.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//go:generate struct-markdown
|
||||||
|
//go:generate mapstructure-to-hcl2 -type CDRomConfig
|
||||||
|
|
||||||
|
package clone
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CDRomConfig struct {
|
||||||
|
// Which controller to use. Example: `sata`. Defaults to `ide`.
|
||||||
|
CdromType string `mapstructure:"cdrom_type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StepAddCDRom struct {
|
||||||
|
Config *CDRomConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CDRomConfig) Prepare() []error {
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
if c.CdromType != "" && c.CdromType != "ide" && c.CdromType != "sata" {
|
||||||
|
errs = append(errs, fmt.Errorf("'cdrom_type' must be 'ide' or 'sata'"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepAddCDRom) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
vm := state.Get("vm").(driver.VirtualMachine)
|
||||||
|
|
||||||
|
if s.Config.CdromType == "sata" {
|
||||||
|
if _, err := vm.FindSATAController(); err == driver.ErrNoSataController {
|
||||||
|
ui.Say("Adding SATA controller...")
|
||||||
|
if err := vm.AddSATAController(); err != nil {
|
||||||
|
state.Put("error", fmt.Errorf("error adding SATA controller: %v", err))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our custom CD, if it exists
|
||||||
|
if cd_path, _ := state.Get("cd_path").(string); cd_path != "" {
|
||||||
|
if err := vm.AddCdrom(s.Config.CdromType, cd_path); err != nil {
|
||||||
|
state.Put("error", fmt.Errorf("error mounting a CD '%v': %v", cd_path, err))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepAddCDRom) Cleanup(state multistep.StateBag) {}
|
30
builder/vsphere/clone/step_add_cdrom.hcl2spec.go
Normal file
30
builder/vsphere/clone/step_add_cdrom.hcl2spec.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Code generated by "mapstructure-to-hcl2 -type CDRomConfig"; DO NOT EDIT.
|
||||||
|
package clone
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FlatCDRomConfig is an auto-generated flat version of CDRomConfig.
|
||||||
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
type FlatCDRomConfig struct {
|
||||||
|
CdromType *string `mapstructure:"cdrom_type" cty:"cdrom_type" hcl:"cdrom_type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlatMapstructure returns a new FlatCDRomConfig.
|
||||||
|
// FlatCDRomConfig is an auto-generated flat version of CDRomConfig.
|
||||||
|
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
func (*CDRomConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||||
|
return new(FlatCDRomConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HCL2Spec returns the hcl spec of a CDRomConfig.
|
||||||
|
// This spec is used by HCL to read the fields of CDRomConfig.
|
||||||
|
// The decoded values from this spec will then be applied to a FlatCDRomConfig.
|
||||||
|
func (*FlatCDRomConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
|
s := map[string]hcldec.Spec{
|
||||||
|
"cdrom_type": &hcldec.AttrSpec{Name: "cdrom_type", Type: cty.String, Required: false},
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
200
builder/vsphere/clone/step_add_cdrom_test.go
Normal file
200
builder/vsphere/clone/step_add_cdrom_test.go
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
package clone
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCDRomConfig_Prepare(t *testing.T) {
|
||||||
|
// Data validation
|
||||||
|
tc := []struct {
|
||||||
|
name string
|
||||||
|
config *CDRomConfig
|
||||||
|
fail bool
|
||||||
|
expectedErrMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Should not fail for empty config",
|
||||||
|
config: new(CDRomConfig),
|
||||||
|
fail: false,
|
||||||
|
expectedErrMsg: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Valid cdroom type ide",
|
||||||
|
config: &CDRomConfig{CdromType: "ide"},
|
||||||
|
fail: false,
|
||||||
|
expectedErrMsg: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Valid cdroom type sata",
|
||||||
|
config: &CDRomConfig{CdromType: "ide"},
|
||||||
|
fail: false,
|
||||||
|
expectedErrMsg: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid cdroom type",
|
||||||
|
config: &CDRomConfig{CdromType: "invalid"},
|
||||||
|
fail: true,
|
||||||
|
expectedErrMsg: "'cdrom_type' must be 'ide' or 'sata'",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range tc {
|
||||||
|
errs := c.config.Prepare()
|
||||||
|
if c.fail {
|
||||||
|
if len(errs) == 0 {
|
||||||
|
t.Fatalf("Config preprare should fail")
|
||||||
|
}
|
||||||
|
if errs[0].Error() != c.expectedErrMsg {
|
||||||
|
t.Fatalf("Expected error message: %s but was '%s'", c.expectedErrMsg, errs[0].Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(errs) != 0 {
|
||||||
|
t.Fatalf("Config preprare should not fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepAddCDRom_Run(t *testing.T) {
|
||||||
|
tc := []struct {
|
||||||
|
name string
|
||||||
|
state *multistep.BasicStateBag
|
||||||
|
step *StepAddCDRom
|
||||||
|
vmMock *driver.VirtualMachineMock
|
||||||
|
expectedAction multistep.StepAction
|
||||||
|
expectedVmMock *driver.VirtualMachineMock
|
||||||
|
fail bool
|
||||||
|
errMessage string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "CDRom SATA type with all cd paths set",
|
||||||
|
state: cdPathStateBag(),
|
||||||
|
step: &StepAddCDRom{
|
||||||
|
Config: &CDRomConfig{
|
||||||
|
CdromType: "sata",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vmMock: new(driver.VirtualMachineMock),
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
expectedVmMock: &driver.VirtualMachineMock{
|
||||||
|
FindSATAControllerCalled: true,
|
||||||
|
AddCdromCalled: true,
|
||||||
|
AddCdromCalledTimes: 1,
|
||||||
|
AddCdromTypes: []string{"sata"},
|
||||||
|
AddCdromPaths: []string{"cd/path"},
|
||||||
|
},
|
||||||
|
fail: false,
|
||||||
|
errMessage: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Add SATA Controller",
|
||||||
|
state: basicStateBag(),
|
||||||
|
step: &StepAddCDRom{
|
||||||
|
Config: &CDRomConfig{
|
||||||
|
CdromType: "sata",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vmMock: &driver.VirtualMachineMock{
|
||||||
|
FindSATAControllerErr: driver.ErrNoSataController,
|
||||||
|
},
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
expectedVmMock: &driver.VirtualMachineMock{
|
||||||
|
FindSATAControllerCalled: true,
|
||||||
|
FindSATAControllerErr: driver.ErrNoSataController,
|
||||||
|
AddSATAControllerCalled: true,
|
||||||
|
},
|
||||||
|
fail: false,
|
||||||
|
errMessage: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail to add SATA Controller",
|
||||||
|
state: basicStateBag(),
|
||||||
|
step: &StepAddCDRom{
|
||||||
|
Config: &CDRomConfig{
|
||||||
|
CdromType: "sata",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vmMock: &driver.VirtualMachineMock{
|
||||||
|
FindSATAControllerErr: driver.ErrNoSataController,
|
||||||
|
AddSATAControllerErr: fmt.Errorf("AddSATAController error"),
|
||||||
|
},
|
||||||
|
expectedAction: multistep.ActionHalt,
|
||||||
|
expectedVmMock: &driver.VirtualMachineMock{
|
||||||
|
FindSATAControllerCalled: true,
|
||||||
|
AddSATAControllerCalled: true,
|
||||||
|
},
|
||||||
|
fail: true,
|
||||||
|
errMessage: fmt.Sprintf("error adding SATA controller: %v", fmt.Errorf("AddSATAController error")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IDE CDRom Type and Iso Path set",
|
||||||
|
state: basicStateBag(),
|
||||||
|
step: &StepAddCDRom{
|
||||||
|
Config: &CDRomConfig{
|
||||||
|
CdromType: "ide",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vmMock: new(driver.VirtualMachineMock),
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
expectedVmMock: new(driver.VirtualMachineMock),
|
||||||
|
fail: false,
|
||||||
|
errMessage: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail to add cdrom from state cd_path",
|
||||||
|
state: cdPathStateBag(),
|
||||||
|
step: &StepAddCDRom{
|
||||||
|
Config: new(CDRomConfig),
|
||||||
|
},
|
||||||
|
vmMock: &driver.VirtualMachineMock{
|
||||||
|
AddCdromErr: fmt.Errorf("AddCdrom error"),
|
||||||
|
},
|
||||||
|
expectedAction: multistep.ActionHalt,
|
||||||
|
expectedVmMock: &driver.VirtualMachineMock{
|
||||||
|
AddCdromCalled: true,
|
||||||
|
AddCdromCalledTimes: 1,
|
||||||
|
AddCdromTypes: []string{""},
|
||||||
|
AddCdromPaths: []string{"cd/path"},
|
||||||
|
},
|
||||||
|
fail: true,
|
||||||
|
errMessage: fmt.Sprintf("error mounting a CD 'cd/path': %v", fmt.Errorf("AddCdrom error")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range tc {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
c.state.Put("vm", c.vmMock)
|
||||||
|
if action := c.step.Run(context.TODO(), c.state); action != c.expectedAction {
|
||||||
|
t.Fatalf("unexpected action %v", action)
|
||||||
|
}
|
||||||
|
err, ok := c.state.Get("error").(error)
|
||||||
|
if ok {
|
||||||
|
if err.Error() != c.errMessage {
|
||||||
|
t.Fatalf("unexpected error %s", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if c.fail {
|
||||||
|
t.Fatalf("expected to fail but it didn't")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(c.vmMock, c.expectedVmMock,
|
||||||
|
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" {
|
||||||
|
t.Fatalf("unexpected VirtualMachine calls: %s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cdPathStateBag() *multistep.BasicStateBag {
|
||||||
|
state := basicStateBag()
|
||||||
|
state.Put("cd_path", "cd/path")
|
||||||
|
return state
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
//go:generate struct-markdown
|
//go:generate struct-markdown
|
||||||
//go:generate mapstructure-to-hcl2 -type FloppyConfig
|
//go:generate mapstructure-to-hcl2 -type FloppyConfig
|
||||||
|
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by "mapstructure-to-hcl2 -type FloppyConfig"; DO NOT EDIT.
|
// Code generated by "mapstructure-to-hcl2 -type FloppyConfig"; DO NOT EDIT.
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
@ -1,4 +1,4 @@
|
|||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,4 +1,4 @@
|
|||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestStepRemoteUpload_Run(t *testing.T) {
|
func TestStepRemoteUpload_Run(t *testing.T) {
|
||||||
state := basicStateBag()
|
state := basicStateBag(nil)
|
||||||
driverMock := driver.NewDriverMock()
|
driverMock := driver.NewDriverMock()
|
||||||
state.Put("driver", driverMock)
|
state.Put("driver", driverMock)
|
||||||
state.Put("iso_path", "[datastore] iso/path")
|
state.Put("iso_path", "[datastore] iso/path")
|
||||||
@ -48,7 +48,7 @@ func TestStepRemoteUpload_Run(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepRemoteUpload_SkipRun(t *testing.T) {
|
func TestStepRemoteUpload_SkipRun(t *testing.T) {
|
||||||
state := basicStateBag()
|
state := basicStateBag(nil)
|
||||||
driverMock := driver.NewDriverMock()
|
driverMock := driver.NewDriverMock()
|
||||||
state.Put("driver", driverMock)
|
state.Put("driver", driverMock)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
//go:generate struct-markdown
|
//go:generate struct-markdown
|
||||||
//go:generate mapstructure-to-hcl2 -type RemoveCDRomConfig
|
//go:generate mapstructure-to-hcl2 -type RemoveCDRomConfig
|
||||||
|
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by "mapstructure-to-hcl2 -type RemoveCDRomConfig"; DO NOT EDIT.
|
// Code generated by "mapstructure-to-hcl2 -type RemoveCDRomConfig"; DO NOT EDIT.
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
@ -1,4 +1,4 @@
|
|||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -52,7 +52,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
Files: b.config.CDConfig.CDFiles,
|
Files: b.config.CDConfig.CDFiles,
|
||||||
Label: b.config.CDConfig.CDLabel,
|
Label: b.config.CDConfig.CDLabel,
|
||||||
},
|
},
|
||||||
&StepRemoteUpload{
|
&common.StepRemoteUpload{
|
||||||
Datastore: b.config.Datastore,
|
Datastore: b.config.Datastore,
|
||||||
Host: b.config.Host,
|
Host: b.config.Host,
|
||||||
SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads,
|
SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads,
|
||||||
@ -80,7 +80,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
Directories: b.config.FloppyDirectories,
|
Directories: b.config.FloppyDirectories,
|
||||||
Label: b.config.FloppyLabel,
|
Label: b.config.FloppyLabel,
|
||||||
},
|
},
|
||||||
&StepAddFloppy{
|
&common.StepAddFloppy{
|
||||||
Config: &b.config.FloppyConfig,
|
Config: &b.config.FloppyConfig,
|
||||||
Datastore: b.config.Datastore,
|
Datastore: b.config.Datastore,
|
||||||
Host: b.config.Host,
|
Host: b.config.Host,
|
||||||
@ -117,7 +117,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
&common.StepShutdown{
|
&common.StepShutdown{
|
||||||
Config: &b.config.ShutdownConfig,
|
Config: &b.config.ShutdownConfig,
|
||||||
},
|
},
|
||||||
&StepRemoveFloppy{
|
&common.StepRemoveFloppy{
|
||||||
Datastore: b.config.Datastore,
|
Datastore: b.config.Datastore,
|
||||||
Host: b.config.Host,
|
Host: b.config.Host,
|
||||||
},
|
},
|
||||||
@ -125,7 +125,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||||||
}
|
}
|
||||||
|
|
||||||
steps = append(steps,
|
steps = append(steps,
|
||||||
&StepRemoveCDRom{
|
&common.StepRemoveCDRom{
|
||||||
Config: &b.config.RemoveCDRomConfig,
|
Config: &b.config.RemoveCDRomConfig,
|
||||||
},
|
},
|
||||||
&common.StepCreateSnapshot{
|
&common.StepCreateSnapshot{
|
||||||
|
@ -26,8 +26,8 @@ type Config struct {
|
|||||||
packerCommon.ISOConfig `mapstructure:",squash"`
|
packerCommon.ISOConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
CDRomConfig `mapstructure:",squash"`
|
CDRomConfig `mapstructure:",squash"`
|
||||||
RemoveCDRomConfig `mapstructure:",squash"`
|
common.RemoveCDRomConfig `mapstructure:",squash"`
|
||||||
FloppyConfig `mapstructure:",squash"`
|
common.FloppyConfig `mapstructure:",squash"`
|
||||||
common.RunConfig `mapstructure:",squash"`
|
common.RunConfig `mapstructure:",squash"`
|
||||||
common.BootConfig `mapstructure:",squash"`
|
common.BootConfig `mapstructure:",squash"`
|
||||||
common.WaitIpConfig `mapstructure:",squash"`
|
common.WaitIpConfig `mapstructure:",squash"`
|
||||||
|
@ -168,6 +168,10 @@ can be done via environment variable:
|
|||||||
|
|
||||||
@include 'common/HTTPConfig-not-required.mdx'
|
@include 'common/HTTPConfig-not-required.mdx'
|
||||||
|
|
||||||
|
### Floppy configuration
|
||||||
|
|
||||||
|
@include 'builder/vsphere/common/FloppyConfig-not-required.mdx'
|
||||||
|
|
||||||
### Connection Configuration
|
### Connection Configuration
|
||||||
|
|
||||||
@include 'builder/vsphere/common/ConnectConfig-not-required.mdx'
|
@include 'builder/vsphere/common/ConnectConfig-not-required.mdx'
|
||||||
@ -192,6 +196,16 @@ can be done via environment variable:
|
|||||||
|
|
||||||
@include 'builder/vsphere/common/WaitIpConfig-not-required.mdx'
|
@include 'builder/vsphere/common/WaitIpConfig-not-required.mdx'
|
||||||
|
|
||||||
|
### CDRom Configuration
|
||||||
|
|
||||||
|
@include 'common/CDConfig.mdx'
|
||||||
|
|
||||||
|
#### Optional:
|
||||||
|
|
||||||
|
@include 'common/CDConfig-not-required.mdx'
|
||||||
|
|
||||||
|
@include 'builder/vsphere/clone/CDRomConfig-not-required.mdx'
|
||||||
|
|
||||||
### Communicator configuration
|
### Communicator configuration
|
||||||
|
|
||||||
#### Optional common fields:
|
#### Optional common fields:
|
||||||
|
@ -97,7 +97,7 @@ source "vsphere-iso" "example" {
|
|||||||
|
|
||||||
### Floppy configuration
|
### Floppy configuration
|
||||||
|
|
||||||
@include 'builder/vsphere/iso/FloppyConfig-not-required.mdx'
|
@include 'builder/vsphere/common/FloppyConfig-not-required.mdx'
|
||||||
|
|
||||||
### Connection Configuration
|
### Connection Configuration
|
||||||
|
|
||||||
@ -174,6 +174,12 @@ iso_paths = [
|
|||||||
|
|
||||||
@include 'builder/vsphere/iso/CDRomConfig-not-required.mdx'
|
@include 'builder/vsphere/iso/CDRomConfig-not-required.mdx'
|
||||||
|
|
||||||
|
@include 'common/CDConfig.mdx'
|
||||||
|
|
||||||
|
#### Optional:
|
||||||
|
|
||||||
|
@include 'common/CDConfig-not-required.mdx'
|
||||||
|
|
||||||
### Create Configuration
|
### Create Configuration
|
||||||
|
|
||||||
@include 'builder/vsphere/iso/CreateConfig-not-required.mdx'
|
@include 'builder/vsphere/iso/CreateConfig-not-required.mdx'
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
<!-- Code generated from the comments of the CDRomConfig struct in builder/vsphere/clone/step_add_cdrom.go; DO NOT EDIT MANUALLY -->
|
||||||
|
|
||||||
|
- `cdrom_type` (string) - Which controller to use. Example: `sata`. Defaults to `ide`.
|
@ -1,4 +1,4 @@
|
|||||||
<!-- Code generated from the comments of the FloppyConfig struct in builder/vsphere/iso/step_add_floppy.go; DO NOT EDIT MANUALLY -->
|
<!-- Code generated from the comments of the FloppyConfig struct in builder/vsphere/common/step_add_floppy.go; DO NOT EDIT MANUALLY -->
|
||||||
|
|
||||||
- `floppy_img_path` (string) - Datastore path to a floppy image that will be mounted to the VM.
|
- `floppy_img_path` (string) - Datastore path to a floppy image that will be mounted to the VM.
|
||||||
Example: `[datastore1] ISO/pvscsi-Windows8.flp`.
|
Example: `[datastore1] ISO/pvscsi-Windows8.flp`.
|
@ -1,3 +1,3 @@
|
|||||||
<!-- Code generated from the comments of the RemoveCDRomConfig struct in builder/vsphere/iso/step_remove_cdrom.go; DO NOT EDIT MANUALLY -->
|
<!-- Code generated from the comments of the RemoveCDRomConfig struct in builder/vsphere/common/step_remove_cdrom.go; DO NOT EDIT MANUALLY -->
|
||||||
|
|
||||||
- `remove_cdrom` (bool) - Remove CD-ROM devices from template. Defaults to `false`.
|
- `remove_cdrom` (bool) - Remove CD-ROM devices from template. Defaults to `false`.
|
Loading…
x
Reference in New Issue
Block a user