Add support for setting final VM as template and remove hard coding of SR

This commit is contained in:
Dom Del Nano 2020-12-22 12:17:42 -08:00
parent d258626c85
commit 70adca2259
5 changed files with 87 additions and 3 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/mitchellh/packer/common"
commonssh "github.com/mitchellh/packer/common/ssh"
"github.com/mitchellh/packer/template/interpolate"
xenapi "github.com/terra-farm/go-xen-api-client"
)
type CommonConfig struct {
@ -220,3 +221,45 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool {
panic(fmt.Sprintf("Unknown keep_vm value '%s'", c.KeepVM))
}
}
func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRecord, error) {
var srRecord xenapi.SRRecord
if config.SrName == "" {
hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session)
if err != nil {
return srRecord, err
}
pools, err := c.GetClient().Pool.GetAllRecords(c.session)
if err != nil {
return srRecord, err
}
for _, pool := range pools {
if pool.Master == hostRef {
return c.GetClient().SR.GetRecord(c.session, pool.DefaultSR)
}
}
return srRecord, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef))
} else {
// Use the provided name label to find the SR to use
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName)
if err != nil {
return srRecord, err
}
switch {
case len(srs) == 0:
return srRecord, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrName)
case len(srs) > 1:
return srRecord, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrName)
}
return c.GetClient().SR.GetRecord(c.session, srs[0])
}
}

View File

@ -20,6 +20,7 @@ func (self *StepAttachVdi) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*Connection)
log.Printf("Running attach vdi for key %s\n", self.VdiUuidKey)
var vdiUuid string
if vdiUuidRaw, ok := state.GetOk(self.VdiUuidKey); ok {
vdiUuid = vdiUuidRaw.(string)

View File

@ -0,0 +1,34 @@
package common
import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
type StepSetVmToTemplate struct{}
func (StepSetVmToTemplate) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*Connection)
instance_uuid := state.Get("instance_uuid").(string)
instance, err := c.client.VM.GetByUUID(c.session, instance_uuid)
if err != nil {
ui.Error(fmt.Sprintf("Could not get VM with UUID '%s': %s", instance_uuid, err.Error()))
return multistep.ActionHalt
}
err = c.client.VM.SetIsATemplate(c.session, instance, true)
if err != nil {
ui.Error(fmt.Sprintf("failed to set VM '%s' as a template with error: %v", instance_uuid, err))
return multistep.ActionHalt
}
ui.Message("Successfully set VM as a template")
return multistep.ActionContinue
}
func (StepSetVmToTemplate) Cleanup(state multistep.StateBag) {}

View File

@ -317,6 +317,7 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
},
new(common.StepProvision),
new(xscommon.StepShutdown),
new(xscommon.StepSetVmToTemplate),
&xscommon.StepDetachVdi{
VdiUuidKey: "iso_vdi_uuid",
},

View File

@ -2,6 +2,7 @@ package iso
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
@ -100,21 +101,22 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
}
// Create VDI for the instance
sr, err := config.GetSR(c)
srs, err := c.GetClient().SR.GetByNameLabel(c.GetSessionRef(), "Local storage")
sr := srs[0]
if err != nil {
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr.NameLabel))
vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{
NameLabel: "Packer-disk",
VirtualSize: int(config.DiskSize * 1024 * 1024),
Type: "user",
Sharable: false,
ReadOnly: false,
SR: sr,
SR: xenapi.SRRef(sr.UUID),
OtherConfig: map[string]string{
"temp": "temp",
},
@ -137,6 +139,7 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
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 {
@ -163,6 +166,7 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
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 {
@ -170,6 +174,7 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
}
} 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)