2014-12-29 06:46:54 -06:00
|
|
|
package xva
|
|
|
|
|
|
|
|
import (
|
2014-12-31 09:21:54 -06:00
|
|
|
"fmt"
|
|
|
|
"os"
|
2014-12-29 06:46:54 -06:00
|
|
|
|
|
|
|
"github.com/mitchellh/multistep"
|
2014-12-31 09:21:54 -06:00
|
|
|
"github.com/mitchellh/packer/packer"
|
2014-12-29 06:46:54 -06:00
|
|
|
xscommon "github.com/rdobson/packer-builder-xenserver/builder/xenserver/common"
|
2015-03-13 08:23:20 -05:00
|
|
|
xsclient "github.com/xenserver/go-xenserver-client"
|
2014-12-29 06:46:54 -06:00
|
|
|
)
|
|
|
|
|
2014-12-31 09:21:54 -06:00
|
|
|
type stepImportInstance struct {
|
2015-03-13 08:23:20 -05:00
|
|
|
instance *xsclient.VM
|
|
|
|
vdi *xsclient.VDI
|
2014-12-29 06:46:54 -06:00
|
|
|
}
|
|
|
|
|
2014-12-31 09:21:54 -06:00
|
|
|
func (self *stepImportInstance) Run(state multistep.StateBag) multistep.StepAction {
|
|
|
|
|
2015-03-13 08:23:20 -05:00
|
|
|
client := state.Get("client").(xsclient.XenAPIClient)
|
2014-12-31 09:21:54 -06:00
|
|
|
config := state.Get("config").(config)
|
|
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
|
|
|
|
ui.Say("Step: Import Instance")
|
|
|
|
|
|
|
|
// find the SR
|
|
|
|
sr, err := config.GetSR(client)
|
|
|
|
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",
|
|
|
|
client.Host,
|
|
|
|
client.Session.(string),
|
|
|
|
sr.Ref,
|
|
|
|
), fh, state)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Unable to upload VDI: %s", err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
if result == nil {
|
|
|
|
ui.Error("XAPI did not reply with an instance reference")
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
2015-03-13 08:23:20 -05:00
|
|
|
instance := xsclient.VM(*result)
|
2014-12-29 06:46:54 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
err = instance.SetStaticMemoryRange(config.VMMemory*1024*1024, config.VMMemory*1024*1024)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error setting VM memory=%d: %s", config.VMMemory*1024*1024, err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
instance.SetPlatform(config.PlatformArgs)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error setting VM platform: %s", err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connect Network
|
|
|
|
|
|
|
|
var network *xscommon.Network
|
|
|
|
|
|
|
|
if config.NetworkName == "" {
|
|
|
|
// No network has be specified. Use the management interface
|
|
|
|
network = new(xscommon.Network)
|
|
|
|
network.Ref = ""
|
|
|
|
network.Client = &client
|
|
|
|
|
|
|
|
pifs, err := client.GetPIFs()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error getting PIFs: %s", err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, pif := range pifs {
|
|
|
|
pif_rec, err := pif.GetRecord()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error getting PIF record: %s", err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
if pif_rec["management"].(bool) {
|
|
|
|
network.Ref = pif_rec["network"].(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if network.Ref == "" {
|
|
|
|
ui.Error("Error: couldn't find management network. Aborting.")
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Look up the network by it's name label
|
|
|
|
|
|
|
|
networks, err := client.GetNetworkByNameLabel(config.NetworkName)
|
|
|
|
|
|
|
|
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.", config.NetworkName))
|
|
|
|
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.", config.NetworkName))
|
|
|
|
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-31 09:21:54 -06:00
|
|
|
instanceId, err := instance.GetUuid()
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error()))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
state.Put("instance_uuid", instanceId)
|
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-31 09:21:54 -06:00
|
|
|
ui.Say(fmt.Sprintf("Imported instance '%s'", instanceId))
|
|
|
|
|
2014-12-29 06:46:54 -06:00
|
|
|
return multistep.ActionContinue
|
|
|
|
}
|
|
|
|
|
2014-12-31 09:21:54 -06:00
|
|
|
func (self *stepImportInstance) Cleanup(state multistep.StateBag) {
|
2014-12-29 06:46:54 -06:00
|
|
|
/*
|
|
|
|
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())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|