packer-plugin-xenserver/builder/xenserver/iso/step_create_instance.go

196 lines
4.8 KiB
Go
Raw Normal View History

package iso
import (
2014-12-08 09:34:48 -06:00
"fmt"
2014-12-08 09:34:48 -06:00
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
xsclient "github.com/xenserver/go-xenserver-client"
)
type stepCreateInstance struct {
instance *xsclient.VM
vdi *xsclient.VDI
}
func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(xsclient.XenAPIClient)
2014-12-08 09:34:48 -06:00
config := state.Get("config").(config)
ui := state.Get("ui").(packer.Ui)
2014-12-08 09:34:48 -06:00
ui.Say("Step: Create Instance")
2014-12-08 09:34:48 -06:00
// Get the template to clone from
2014-12-08 09:34:48 -06:00
vms, err := client.GetVMByNameLabel(config.CloneTemplate)
2014-12-08 09:34:48 -06:00
switch {
case len(vms) == 0:
ui.Error(fmt.Sprintf("Couldn't find a template with the name-label '%s'. Aborting.", config.CloneTemplate))
2014-12-08 09:34:48 -06:00
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))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
template := vms[0]
2014-12-08 09:34:48 -06:00
// Clone that VM template
instance, err := template.Clone(config.VMName)
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Error cloning VM: %s", err.Error()))
return multistep.ActionHalt
}
2014-12-09 10:40:32 -06:00
self.instance = instance
2014-12-09 08:02:48 -06:00
err = instance.SetIsATemplate(false)
if err != nil {
ui.Error(fmt.Sprintf("Error setting is_a_template=false: %s", err.Error()))
return multistep.ActionHalt
}
err = instance.SetStaticMemoryRange(uint64(config.VMMemory*1024*1024), uint64(config.VMMemory*1024*1024))
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Error setting VM memory=%d: %s", config.VMMemory*1024*1024, err.Error()))
2014-12-09 08:02:48 -06:00
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
instance.SetPlatform(config.PlatformArgs)
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Error setting VM platform: %s", err.Error()))
return multistep.ActionHalt
}
2015-05-01 19:45:43 -05:00
instance.SetDescription(config.VMDescription)
if err != nil {
ui.Error(fmt.Sprintf("Error setting VM description: %s", err.Error()))
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
// Create VDI for the instance
2014-12-15 08:17:20 -06:00
sr, err := config.GetSR(client)
if err != nil {
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
return multistep.ActionHalt
2014-12-08 09:34:48 -06:00
}
vdi, err := sr.CreateVdi("Packer-disk", int64(config.DiskSize*1024*1024))
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error()))
return multistep.ActionHalt
}
2014-12-09 10:40:32 -06:00
self.vdi = vdi
err = instance.ConnectVdi(vdi, xsclient.Disk, "")
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error()))
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
// Connect Network
var network *xsclient.Network
2014-12-08 09:34:48 -06:00
if config.NetworkName == "" {
// No network has be specified. Use the management interface
network = new(xsclient.Network)
2014-12-08 09:34:48 -06:00
network.Ref = ""
network.Client = &client
2014-12-08 09:34:48 -06:00
pifs, err := client.GetPIFs()
2014-12-08 09:34:48 -06:00
if err != nil {
2014-12-09 08:02:48 -06:00
ui.Error(fmt.Sprintf("Error getting PIFs: %s", err.Error()))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
for _, pif := range pifs {
pif_rec, err := pif.GetRecord()
2014-12-08 09:34:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Error getting PIF record: %s", err.Error()))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
2014-12-08 09:34:48 -06:00
if pif_rec["management"].(bool) {
network.Ref = pif_rec["network"].(string)
}
2014-12-08 09:34:48 -06:00
}
2014-12-08 09:34:48 -06:00
if network.Ref == "" {
ui.Error("Error: couldn't find management network. Aborting.")
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
} else {
// Look up the network by it's name label
2014-12-08 09:34:48 -06:00
networks, err := client.GetNetworkByNameLabel(config.NetworkName)
2014-12-08 09:34:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Error occured getting Network by name-label: %s", err.Error()))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
switch {
case len(networks) == 0:
ui.Error(fmt.Sprintf("Couldn't find a network with the specified name-label '%s'. Aborting.", config.NetworkName))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
case len(networks) > 1:
2014-12-17 11:59:26 -06:00
ui.Error(fmt.Sprintf("Found more than one network with the name '%s'. The name must be unique. Aborting.", config.NetworkName))
2014-12-08 09:34:48 -06:00
return multistep.ActionHalt
}
network = networks[0]
}
if err != nil {
ui.Say(err.Error())
}
_, err = instance.ConnectNetwork(network, "0")
if err != nil {
ui.Say(err.Error())
}
2014-12-09 10:40:32 -06:00
instanceId, err := instance.GetUuid()
2014-12-09 08:02:48 -06:00
if err != nil {
ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error()))
return multistep.ActionHalt
}
2014-12-09 10:40:32 -06:00
state.Put("instance_uuid", instanceId)
ui.Say(fmt.Sprintf("Created instance '%s'", instanceId))
2014-12-08 09:34:48 -06:00
return multistep.ActionContinue
}
func (self *stepCreateInstance) Cleanup(state multistep.StateBag) {
config := state.Get("config").(config)
if config.ShouldKeepVM(state) {
return
}
2014-12-09 10:40:32 -06:00
ui := state.Get("ui").(packer.Ui)
2014-12-09 10:40:32 -06:00
if self.instance != nil {
ui.Say("Destroying VM")
_ = self.instance.HardShutdown() // redundant, just in case
2014-12-09 10:40:32 -06:00
err := self.instance.Destroy()
if err != nil {
ui.Error(err.Error())
}
2014-12-08 09:34:48 -06:00
}
2014-12-09 10:40:32 -06:00
if self.vdi != nil {
ui.Say("Destroying VDI")
err := self.vdi.Destroy()
if err != nil {
ui.Error(err.Error())
}
}
}