Update XVA builder to use shared StepCreateInstance step

This commit is contained in:
Dom Del Nano 2023-04-15 15:01:00 -07:00
parent 7c4b652c17
commit 2fe14d14ac
2 changed files with 3 additions and 192 deletions

View File

@ -141,7 +141,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
VdiName: self.config.ToolsIsoName,
VdiUuidKey: "tools_vdi_uuid",
},
new(stepCreateFromTemplate),
&xscommon.StepCreateInstance{
AssumePreInstalledOS: true,
},
new(stepImportInstance),
&xscommon.StepAttachVdi{
VdiUuidKey: "floppy_vdi_uuid",

View File

@ -1,191 +0,0 @@
package xva
import (
"context"
"fmt"
"log"
"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 stepCreateFromTemplate struct {
instance *xsclient.VMRef
}
func (self *stepCreateFromTemplate) 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: Create Instance from Template")
if config.CloneTemplate == "" {
log.Println("Skipping creation from template - no `clone_template` configured.")
return multistep.ActionContinue
}
// Get the template to clone from
vms, err := c.GetClient().VM.GetByNameLabel(c.GetSessionRef(), config.CloneTemplate)
switch {
case len(vms) == 0:
ui.Error(fmt.Sprintf("Couldn't find a template with the name-label '%s'. Aborting.", config.CloneTemplate))
return multistep.ActionHalt
case len(vms) > 1:
ui.Error(fmt.Sprintf("Found more than one template with the name '%s'. The name must be unique. Aborting.", config.CloneTemplate))
return multistep.ActionHalt
}
template := vms[0]
// Clone that VM template
instance, err := c.GetClient().VM.Clone(c.GetSessionRef(), template, config.VMName)
if err != nil {
ui.Error(fmt.Sprintf("Error cloning VM: %s", err.Error()))
return multistep.ActionHalt
}
self.instance = &instance
err = c.GetClient().VM.SetIsATemplate(c.GetSessionRef(), instance, false)
if err != nil {
ui.Error(fmt.Sprintf("Error setting is_a_template=false: %s", err.Error()))
return multistep.ActionHalt
}
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
}
memory := int(config.VMMemory * 1024 * 1024)
err = c.GetClient().VM.SetMemoryLimits(c.GetSessionRef(), instance, memory, memory, memory, memory)
if err != nil {
ui.Error(fmt.Sprintf("Error setting VM memory=%d: %s", memory, err.Error()))
return multistep.ActionHalt
}
err = c.GetClient().VM.SetPlatform(c.GetSessionRef(), instance, config.PlatformArgs)
if err != nil {
ui.Error(fmt.Sprintf("Error setting VM platform: %s", 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
}
// Connect Network
var network xsclient.NetworkRef
if len(config.NetworkNames) == 0 {
// No network has be specified. Use the management interface
log.Println("No network name given, attempting to use management interface")
pifs, err := c.GetClient().PIF.GetAll(c.GetSessionRef())
if err != nil {
ui.Error(fmt.Sprintf("Error getting PIFs: %s", err.Error()))
return multistep.ActionHalt
}
for _, pif := range pifs {
pif_rec, err := c.GetClient().PIF.GetRecord(c.GetSessionRef(), pif)
if err != nil {
ui.Error(fmt.Sprintf("Error getting PIF record: %s", err.Error()))
return multistep.ActionHalt
}
if pif_rec.Management {
network = pif_rec.Network
}
}
if string(network) == "" {
ui.Error("Error: couldn't find management network. Aborting.")
return multistep.ActionHalt
}
log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance)
_, err = xscommon.ConnectNetwork(c, network, instance, "0")
if err != nil {
ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err))
return multistep.ActionHalt
}
} else {
log.Printf("Using provided network names: %v\n", config.NetworkNames)
// Look up each network by it's name label
for i, networkNameLabel := range config.NetworkNames {
networks, err := c.GetClient().Network.GetByNameLabel(c.GetSessionRef(), networkNameLabel)
if err != nil {
ui.Error(fmt.Sprintf("Error occured getting Network by name-label: %s", err.Error()))
return multistep.ActionHalt
}
switch {
case len(networks) == 0:
ui.Error(fmt.Sprintf("Couldn't find a network with the specified name-label '%s'. Aborting.", networkNameLabel))
return multistep.ActionHalt
case len(networks) > 1:
ui.Error(fmt.Sprintf("Found more than one network with the name '%s'. The name must be unique. Aborting.", networkNameLabel))
return multistep.ActionHalt
}
//we need the VIF index string
vifIndexString := fmt.Sprintf("%d", i)
_, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString)
if err != nil {
ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error()))
}
}
}
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)
ui.Say(fmt.Sprintf("Created instance '%s'", instanceId))
return multistep.ActionContinue
}
func (self *stepCreateFromTemplate) Cleanup(state multistep.StateBag) {
config := state.Get("config").(xscommon.Config)
if config.ShouldKeepVM(state) {
return
}
ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*xscommon.Connection)
if self.instance != nil {
ui.Say("Destroying VM")
_ = c.GetClient().VM.HardShutdown(c.GetSessionRef(), *self.instance) // redundant, just in case
err := c.GetClient().VM.Destroy(c.GetSessionRef(), *self.instance)
if err != nil {
ui.Error(err.Error())
}
}
}