Initial commit
This commit is contained in:
		
							
								
								
									
										191
									
								
								builder/xenserver/xva/builder.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								builder/xenserver/xva/builder.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
package xva
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/hashicorp/hcl/v2/hcldec"
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/communicator"
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/multistep"
 | 
			
		||||
	commonsteps "github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps"
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/packer"
 | 
			
		||||
	hconfig "github.com/hashicorp/packer-plugin-sdk/template/config"
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
 | 
			
		||||
	xsclient "github.com/terra-farm/go-xen-api-client"
 | 
			
		||||
	xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Builder struct {
 | 
			
		||||
	config xscommon.Config
 | 
			
		||||
	runner multistep.Runner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *Builder) ConfigSpec() hcldec.ObjectSpec { return self.config.FlatMapstructure().HCL2Spec() }
 | 
			
		||||
 | 
			
		||||
func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []string, retErr error) {
 | 
			
		||||
 | 
			
		||||
	var errs *packer.MultiError
 | 
			
		||||
 | 
			
		||||
	err := hconfig.Decode(&self.config, &hconfig.DecodeOpts{
 | 
			
		||||
		Interpolate: true,
 | 
			
		||||
		InterpolateFilter: &interpolate.RenderFilter{
 | 
			
		||||
			Exclude: []string{
 | 
			
		||||
				"boot_command",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}, raws...)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		packer.MultiErrorAppend(errs, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	errs = packer.MultiErrorAppend(
 | 
			
		||||
		errs, self.config.CommonConfig.Prepare(self.config.GetInterpContext(), &self.config.PackerConfig)...)
 | 
			
		||||
 | 
			
		||||
	// Set default values
 | 
			
		||||
	if self.config.VCPUsMax == 0 {
 | 
			
		||||
		self.config.VCPUsMax = 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if self.config.VCPUsAtStartup == 0 {
 | 
			
		||||
		self.config.VCPUsAtStartup = 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if self.config.VCPUsAtStartup > self.config.VCPUsMax {
 | 
			
		||||
		self.config.VCPUsAtStartup = self.config.VCPUsMax
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if self.config.VMMemory == 0 {
 | 
			
		||||
		self.config.VMMemory = 1024
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(self.config.PlatformArgs) == 0 {
 | 
			
		||||
		pargs := make(map[string]string)
 | 
			
		||||
		pargs["viridian"] = "false"
 | 
			
		||||
		pargs["nx"] = "true"
 | 
			
		||||
		pargs["pae"] = "true"
 | 
			
		||||
		pargs["apic"] = "true"
 | 
			
		||||
		pargs["timeoffset"] = "0"
 | 
			
		||||
		pargs["acpi"] = "1"
 | 
			
		||||
		self.config.PlatformArgs = pargs
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Validation
 | 
			
		||||
 | 
			
		||||
	if self.config.SourcePath == "" {
 | 
			
		||||
		errs = packer.MultiErrorAppend(errs, fmt.Errorf("A source_path must be specified"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(errs.Errors) > 0 {
 | 
			
		||||
		retErr = errors.New(errs.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil, nil, retErr
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
 | 
			
		||||
	//Setup XAPI client
 | 
			
		||||
	c, err := xscommon.NewXenAPIClient(self.config.HostIp, self.config.Username, self.config.Password)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ui.Say("XAPI client session established")
 | 
			
		||||
 | 
			
		||||
	c.GetClient().Host.GetAll(c.GetSessionRef())
 | 
			
		||||
 | 
			
		||||
	//Share state between the other steps using a statebag
 | 
			
		||||
	state := new(multistep.BasicStateBag)
 | 
			
		||||
	state.Put("client", c)
 | 
			
		||||
	// state.Put("config", self.config)
 | 
			
		||||
	state.Put("commonconfig", self.config.CommonConfig)
 | 
			
		||||
	state.Put("hook", hook)
 | 
			
		||||
	state.Put("ui", ui)
 | 
			
		||||
 | 
			
		||||
	httpReqChan := make(chan string, 1)
 | 
			
		||||
 | 
			
		||||
	//Build the steps
 | 
			
		||||
	steps := []multistep.Step{
 | 
			
		||||
		&xscommon.StepPrepareOutputDir{
 | 
			
		||||
			Force: self.config.PackerForce,
 | 
			
		||||
			Path:  self.config.OutputDir,
 | 
			
		||||
		},
 | 
			
		||||
		&commonsteps.StepCreateFloppy{
 | 
			
		||||
			Files: self.config.FloppyFiles,
 | 
			
		||||
		},
 | 
			
		||||
		new(xscommon.StepHTTPServer),
 | 
			
		||||
		&xscommon.StepUploadVdi{
 | 
			
		||||
			VdiNameFunc: func() string {
 | 
			
		||||
				return "Packer-floppy-disk"
 | 
			
		||||
			},
 | 
			
		||||
			ImagePathFunc: func() string {
 | 
			
		||||
				if floppyPath, ok := state.GetOk("floppy_path"); ok {
 | 
			
		||||
					return floppyPath.(string)
 | 
			
		||||
				}
 | 
			
		||||
				return ""
 | 
			
		||||
			},
 | 
			
		||||
			VdiUuidKey: "floppy_vdi_uuid",
 | 
			
		||||
		},
 | 
			
		||||
		&xscommon.StepFindVdi{
 | 
			
		||||
			VdiName:    self.config.ToolsIsoName,
 | 
			
		||||
			VdiUuidKey: "tools_vdi_uuid",
 | 
			
		||||
		},
 | 
			
		||||
		new(stepImportInstance),
 | 
			
		||||
		&xscommon.StepAttachVdi{
 | 
			
		||||
			VdiUuidKey: "floppy_vdi_uuid",
 | 
			
		||||
			VdiType:    xsclient.VbdTypeFloppy,
 | 
			
		||||
		},
 | 
			
		||||
		&xscommon.StepAttachVdi{
 | 
			
		||||
			VdiUuidKey: "tools_vdi_uuid",
 | 
			
		||||
			VdiType:    xsclient.VbdTypeCD,
 | 
			
		||||
		},
 | 
			
		||||
		new(xscommon.StepStartVmPaused),
 | 
			
		||||
		new(xscommon.StepSetVmHostSshAddress),
 | 
			
		||||
		new(xscommon.StepBootWait),
 | 
			
		||||
		&xscommon.StepTypeBootCommand{
 | 
			
		||||
			Ctx: *self.config.GetInterpContext(),
 | 
			
		||||
		},
 | 
			
		||||
		&xscommon.StepWaitForIP{
 | 
			
		||||
			Chan:    httpReqChan,
 | 
			
		||||
			Timeout: 300 * time.Minute, /*self.config.InstallTimeout*/ // @todo change this
 | 
			
		||||
		},
 | 
			
		||||
		&communicator.StepConnect{
 | 
			
		||||
			Config:    &self.config.SSHConfig.Comm,
 | 
			
		||||
			Host:      xscommon.CommHost,
 | 
			
		||||
			SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig),
 | 
			
		||||
			SSHPort:   xscommon.SSHPort,
 | 
			
		||||
		},
 | 
			
		||||
		new(commonsteps.StepProvision),
 | 
			
		||||
		new(xscommon.StepShutdown),
 | 
			
		||||
		&xscommon.StepDetachVdi{
 | 
			
		||||
			VdiUuidKey: "floppy_vdi_uuid",
 | 
			
		||||
		},
 | 
			
		||||
		&xscommon.StepDetachVdi{
 | 
			
		||||
			VdiUuidKey: "tools_vdi_uuid",
 | 
			
		||||
		},
 | 
			
		||||
		new(xscommon.StepExport),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	self.runner = &multistep.BasicRunner{Steps: steps}
 | 
			
		||||
	self.runner.Run(ctx, state)
 | 
			
		||||
 | 
			
		||||
	if rawErr, ok := state.GetOk("error"); ok {
 | 
			
		||||
		return nil, rawErr.(error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If we were interrupted or cancelled, then just exit.
 | 
			
		||||
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
 | 
			
		||||
		return nil, errors.New("Build was cancelled.")
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := state.GetOk(multistep.StateHalted); ok {
 | 
			
		||||
		return nil, errors.New("Build was halted.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	artifact, _ := xscommon.NewArtifact(self.config.OutputDir)
 | 
			
		||||
 | 
			
		||||
	return artifact, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								builder/xenserver/xva/builder_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								builder/xenserver/xva/builder_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
package xva
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/packer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func testConfig() map[string]interface{} {
 | 
			
		||||
	return map[string]interface{}{
 | 
			
		||||
		"remote_host":      "localhost",
 | 
			
		||||
		"remote_username":  "admin",
 | 
			
		||||
		"remote_password":  "admin",
 | 
			
		||||
		"vm_name":          "foo",
 | 
			
		||||
		"shutdown_command": "yes",
 | 
			
		||||
		"ssh_username":     "foo",
 | 
			
		||||
		"source_path":      ".",
 | 
			
		||||
 | 
			
		||||
		packer.BuildNameConfigKey: "foo",
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilder_ImplementsBuilder(t *testing.T) {
 | 
			
		||||
	var raw interface{}
 | 
			
		||||
	raw = &Builder{}
 | 
			
		||||
	if _, ok := raw.(packer.Builder); !ok {
 | 
			
		||||
		t.Error("Builder must implement builder.")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_Defaults(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("should not have error: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if b.config.ToolsIsoName != "xs-tools.iso" {
 | 
			
		||||
		t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if b.config.VMName == "" {
 | 
			
		||||
		t.Errorf("bad vm name: %s", b.config.VMName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if b.config.Format != "xva" {
 | 
			
		||||
		t.Errorf("bad format: %s", b.config.Format)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if b.config.KeepVM != "never" {
 | 
			
		||||
		t.Errorf("bad keep instance: %s", b.config.KeepVM)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_Format(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
 | 
			
		||||
	// Bad
 | 
			
		||||
	config["format"] = "foo"
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Good
 | 
			
		||||
	config["format"] = "vdi_raw"
 | 
			
		||||
	b = Builder{}
 | 
			
		||||
	_, warns, err = b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("should not have error: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_HTTPPort(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
 | 
			
		||||
	// Bad
 | 
			
		||||
	config["http_port_min"] = 1000
 | 
			
		||||
	config["http_port_max"] = 500
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Bad
 | 
			
		||||
	config["http_port_min"] = -500
 | 
			
		||||
	b = Builder{}
 | 
			
		||||
	_, warns, err = b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Good
 | 
			
		||||
	config["http_port_min"] = 500
 | 
			
		||||
	config["http_port_max"] = 1000
 | 
			
		||||
	b = Builder{}
 | 
			
		||||
	_, warns, err = b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("should not have error: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_InvalidKey(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
 | 
			
		||||
	// Add a random key
 | 
			
		||||
	config["i_should_not_be_valid"] = true
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_KeepVM(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
 | 
			
		||||
	// Bad
 | 
			
		||||
	config["keep_vm"] = "foo"
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Good
 | 
			
		||||
	config["keep_vm"] = "always"
 | 
			
		||||
	b = Builder{}
 | 
			
		||||
	_, warns, err = b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("should not have error: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBuilderPrepare_SourcePath(t *testing.T) {
 | 
			
		||||
	var b Builder
 | 
			
		||||
	config := testConfig()
 | 
			
		||||
 | 
			
		||||
	// Bad
 | 
			
		||||
	config["source_path"] = ""
 | 
			
		||||
	_, warns, err := b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("should have error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Good
 | 
			
		||||
	config["source_path"] = "."
 | 
			
		||||
	b = Builder{}
 | 
			
		||||
	_, warns, err = b.Prepare(config)
 | 
			
		||||
	if len(warns) > 0 {
 | 
			
		||||
		t.Fatalf("bad: %#v", warns)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("should not have error: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								builder/xenserver/xva/step_import_instance.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								builder/xenserver/xva/step_import_instance.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
package xva
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/multistep"
 | 
			
		||||
	"github.com/hashicorp/packer-plugin-sdk/packer"
 | 
			
		||||
	xsclient "github.com/terra-farm/go-xen-api-client"
 | 
			
		||||
	xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type stepImportInstance struct {
 | 
			
		||||
	instance xsclient.VMRef
 | 
			
		||||
	vdi      xsclient.VDIRef
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
 | 
			
		||||
 | 
			
		||||
	c := state.Get("client").(*xscommon.Connection)
 | 
			
		||||
	config := state.Get("config").(xscommon.Config)
 | 
			
		||||
	ui := state.Get("ui").(packer.Ui)
 | 
			
		||||
 | 
			
		||||
	ui.Say("Step: Import Instance")
 | 
			
		||||
 | 
			
		||||
	// find the SR
 | 
			
		||||
	srs, err := c.GetClient().SR.GetAll(c.GetSessionRef())
 | 
			
		||||
	sr := srs[0]
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Open the file for reading (NB: httpUpload closes the file for us)
 | 
			
		||||
	fh, err := os.Open(config.SourcePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Unable to open XVA '%s': %s", config.SourcePath, err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result, err := xscommon.HTTPUpload(fmt.Sprintf("https://%s/import?session_id=%s&sr_id=%s",
 | 
			
		||||
		c.Host,
 | 
			
		||||
		c.GetSession(),
 | 
			
		||||
		sr,
 | 
			
		||||
	), fh, state)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Unable to upload VDI: %s", err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
	if result == "" {
 | 
			
		||||
		ui.Error("XAPI did not reply with an instance reference")
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	instance := xsclient.VMRef(result)
 | 
			
		||||
 | 
			
		||||
	instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
	state.Put("instance_uuid", instanceId)
 | 
			
		||||
 | 
			
		||||
	err = c.GetClient().VM.SetVCPUsMax(c.GetSessionRef(), instance, int(config.VCPUsMax))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Error setting VM VCPUs Max=%d: %s", config.VCPUsMax, err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = c.GetClient().VM.SetVCPUsAtStartup(c.GetSessionRef(), instance, int(config.VCPUsAtStartup))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Error setting VM VCPUs At Startup=%d: %s", config.VCPUsAtStartup, err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = c.GetClient().VM.SetNameDescription(c.GetSessionRef(), instance, config.VMDescription)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ui.Error(fmt.Sprintf("Error setting VM description: %s", err.Error()))
 | 
			
		||||
		return multistep.ActionHalt
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ui.Say(fmt.Sprintf("Imported instance '%s'", instanceId))
 | 
			
		||||
 | 
			
		||||
	return multistep.ActionContinue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *stepImportInstance) Cleanup(state multistep.StateBag) {
 | 
			
		||||
	/*
 | 
			
		||||
		config := state.Get("config").(config)
 | 
			
		||||
		if config.ShouldKeepVM(state) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ui := state.Get("ui").(packer.Ui)
 | 
			
		||||
 | 
			
		||||
		if self.instance != nil {
 | 
			
		||||
			ui.Say("Destroying VM")
 | 
			
		||||
			_ = self.instance.HardShutdown() // redundant, just in case
 | 
			
		||||
			err := self.instance.Destroy()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ui.Error(err.Error())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if self.vdi != nil {
 | 
			
		||||
			ui.Say("Destroying VDI")
 | 
			
		||||
			err := self.vdi.Destroy()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ui.Error(err.Error())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	*/
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user