commit
50403a3ed6
@ -79,7 +79,7 @@ To get you started, there is an example config file which you can use `examples/
|
||||
"host_ip": "10.81.2.105",
|
||||
"instance_name": "packer-centos-6-4",
|
||||
"instance_memory": "2048000000",
|
||||
"root_disk_size": "5000000000",
|
||||
"root_disk_size": "40000000000",
|
||||
"iso_name": "CentOS-6.4-x86_64-minimal.iso",
|
||||
"http_directory": "http",
|
||||
"local_ip": "10.80.3.223",
|
||||
|
@ -2,18 +2,16 @@ package xenserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
|
||||
type LocalArtifact struct {
|
||||
dir string
|
||||
f []string
|
||||
}
|
||||
|
||||
|
||||
func NewArtifact(dir string) (packer.Artifact, error) {
|
||||
files := make([]string, 0, 1)
|
||||
visit := func(path string, info os.FileInfo, err error) error {
|
||||
|
@ -1,22 +1,20 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/common"
|
||||
"fmt"
|
||||
"log"
|
||||
"errors"
|
||||
"time"
|
||||
"os"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/common"
|
||||
commonssh "github.com/mitchellh/packer/common/ssh"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
// Set the unique ID for this builder
|
||||
const BuilderId = "packer.xenserver"
|
||||
|
||||
|
||||
type config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
|
||||
@ -40,7 +38,7 @@ type config struct {
|
||||
RawBootWait string `mapstructure:"boot_wait"`
|
||||
|
||||
BootWait time.Duration ``
|
||||
sshWaitTimeout time.Duration ``
|
||||
SSHWaitTimeout time.Duration ``
|
||||
|
||||
ISOChecksum string `mapstructure:"iso_checksum"`
|
||||
ISOChecksumType string `mapstructure:"iso_checksum_type"`
|
||||
@ -65,14 +63,12 @@ type config struct {
|
||||
tpl *packer.ConfigTemplate
|
||||
}
|
||||
|
||||
|
||||
type Builder struct {
|
||||
config config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
|
||||
func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr error) {
|
||||
func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error) {
|
||||
|
||||
md, err := common.DecodeConfig(&self.config, raws...)
|
||||
if err != nil {
|
||||
@ -120,7 +116,7 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
self.config.OutputDir = fmt.Sprintf("output-%s", self.config.PackerBuildName)
|
||||
}
|
||||
|
||||
templates := map[string]*string {
|
||||
templates := map[string]*string{
|
||||
"username": &self.config.Username,
|
||||
"password": &self.config.Password,
|
||||
"host_ip": &self.config.HostIp,
|
||||
@ -144,7 +140,6 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
"output_directory": &self.config.OutputDir,
|
||||
}
|
||||
|
||||
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = self.config.tpl.Process(*ptr, nil)
|
||||
@ -153,12 +148,12 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
if self.config.IsoUrl == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("a iso url must be specified"))
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
self.config.BootWait, err = time.ParseDuration(self.config.RawBootWait)
|
||||
if err != nil {
|
||||
@ -166,7 +161,7 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
errs, errors.New("Failed to parse boot_wait."))
|
||||
}
|
||||
|
||||
self.config.sshWaitTimeout, err = time.ParseDuration(self.config.RawSSHWaitTimeout)
|
||||
self.config.SSHWaitTimeout, err = time.ParseDuration(self.config.RawSSHWaitTimeout)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Failed to parse ssh_wait_timeout: %s", err))
|
||||
@ -227,12 +222,12 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
self.config.CloneTemplate = "Other install media"
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
if self.config.LocalIp == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("A local IP visible to XenServer's mangement interface is required to serve files."))
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
if len(self.config.PlatformArgs) == 0 {
|
||||
pargs := make(map[string]string)
|
||||
@ -254,7 +249,7 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("the host min port must be less than the max"))
|
||||
}
|
||||
/*
|
||||
/*
|
||||
if self.config.ISOChecksumType == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("The iso_checksum_type must be specified."))
|
||||
@ -290,7 +285,7 @@ func (self *Builder) Prepare (raws ...interface{}) (params []string, retErr erro
|
||||
errs, fmt.Errorf("Failed to parse the iso_url (%d): %s", i, err))
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
if len(errs.Errors) > 0 {
|
||||
retErr = errors.New(errs.Error())
|
||||
}
|
||||
@ -319,7 +314,6 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
||||
|
||||
//Build the steps
|
||||
steps := []multistep.Step{
|
||||
/*
|
||||
@ -358,7 +352,7 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
&common.StepConnectSSH{
|
||||
SSHAddress: sshLocalAddress,
|
||||
SSHConfig: sshConfig,
|
||||
SSHWaitTimeout: self.config.sshWaitTimeout,
|
||||
SSHWaitTimeout: self.config.SSHWaitTimeout,
|
||||
},
|
||||
new(common.StepProvision),
|
||||
new(stepShutdownAndExport),
|
||||
@ -376,7 +370,6 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
return artifact, nil
|
||||
}
|
||||
|
||||
|
||||
func (self *Builder) Cancel() {
|
||||
if self.runner != nil {
|
||||
log.Println("Cancelling the step runner...")
|
||||
@ -384,4 +377,3 @@ func (self *Builder) Cancel() {
|
||||
}
|
||||
fmt.Println("Cancelling the builder")
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/nilshell/xmlrpc"
|
||||
"log"
|
||||
"fmt"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func check(err error) {
|
||||
@ -13,7 +13,6 @@ func check(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type XenAPIClient struct {
|
||||
Session interface{}
|
||||
Host string
|
||||
@ -23,7 +22,6 @@ type XenAPIClient struct {
|
||||
RPC *xmlrpc.Client
|
||||
}
|
||||
|
||||
|
||||
type APIResult struct {
|
||||
Status string
|
||||
Value interface{}
|
||||
@ -70,7 +68,7 @@ type Pool struct {
|
||||
Client *XenAPIClient
|
||||
}
|
||||
|
||||
func (c *XenAPIClient) RPCCall (result interface{}, method string, params []interface{}) (err error) {
|
||||
func (c *XenAPIClient) RPCCall(result interface{}, method string, params []interface{}) (err error) {
|
||||
fmt.Println(params)
|
||||
p := new(xmlrpc.Params)
|
||||
p.Params = params
|
||||
@ -78,8 +76,7 @@ func (c *XenAPIClient) RPCCall (result interface{}, method string, params []inte
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) Login () (err error) {
|
||||
func (client *XenAPIClient) Login() (err error) {
|
||||
//Do loging call
|
||||
result := xmlrpc.Struct{}
|
||||
|
||||
@ -92,14 +89,14 @@ func (client *XenAPIClient) Login () (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *XenAPIClient) APICall (result *APIResult, method string, params ...interface{}) (err error) {
|
||||
func (client *XenAPIClient) APICall(result *APIResult, method string, params ...interface{}) (err error) {
|
||||
if client.Session == nil {
|
||||
fmt.Println("Error: no session")
|
||||
return fmt.Errorf("No session. Unable to make call")
|
||||
}
|
||||
|
||||
//Make a params slice which will include the session
|
||||
p := make([]interface{}, len(params) + 1)
|
||||
p := make([]interface{}, len(params)+1)
|
||||
p[0] = client.Session
|
||||
|
||||
if params != nil {
|
||||
@ -129,8 +126,7 @@ func (client *XenAPIClient) APICall (result *APIResult, method string, params ..
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetHosts () (err error) {
|
||||
func (client *XenAPIClient) GetHosts() (err error) {
|
||||
result := APIResult{}
|
||||
_ = client.APICall(&result, "host.get_all")
|
||||
hosts := result.Value
|
||||
@ -138,8 +134,7 @@ func (client *XenAPIClient) GetHosts () (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetPools () (pools []*Pool, err error) {
|
||||
func (client *XenAPIClient) GetPools() (pools []*Pool, err error) {
|
||||
pools = make([]*Pool, 0)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "pool.get_all")
|
||||
@ -157,8 +152,7 @@ func (client *XenAPIClient) GetPools () (pools []*Pool, err error) {
|
||||
return pools, nil
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetDefaultSR () (sr *SR, err error) {
|
||||
func (client *XenAPIClient) GetDefaultSR() (sr *SR, err error) {
|
||||
pools, err := client.GetPools()
|
||||
|
||||
if err != nil {
|
||||
@ -182,8 +176,7 @@ func (client *XenAPIClient) GetDefaultSR () (sr *SR, err error) {
|
||||
return sr, nil
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetVMByUuid (vm_uuid string) (vm *VM, err error) {
|
||||
func (client *XenAPIClient) GetVMByUuid(vm_uuid string) (vm *VM, err error) {
|
||||
vm = new(VM)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "VM.get_by_uuid", vm_uuid)
|
||||
@ -195,8 +188,7 @@ func (client *XenAPIClient) GetVMByUuid (vm_uuid string) (vm *VM, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetVMByNameLabel (name_label string) (vms []*VM, err error) {
|
||||
func (client *XenAPIClient) GetVMByNameLabel(name_label string) (vms []*VM, err error) {
|
||||
vms = make([]*VM, 0)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "VM.get_by_name_label", name_label)
|
||||
@ -214,8 +206,7 @@ func (client *XenAPIClient) GetVMByNameLabel (name_label string) (vms []*VM, err
|
||||
return vms, nil
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetSRByNameLabel (name_label string) (srs []*SR, err error) {
|
||||
func (client *XenAPIClient) GetSRByNameLabel(name_label string) (srs []*SR, err error) {
|
||||
srs = make([]*SR, 0)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "SR.get_by_name_label", name_label)
|
||||
@ -233,7 +224,7 @@ func (client *XenAPIClient) GetSRByNameLabel (name_label string) (srs []*SR, err
|
||||
return srs, nil
|
||||
}
|
||||
|
||||
func (client *XenAPIClient) GetNetworkByUuid (network_uuid string) (network *Network, err error) {
|
||||
func (client *XenAPIClient) GetNetworkByUuid(network_uuid string) (network *Network, err error) {
|
||||
network = new(Network)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "network.get_by_uuid", network_uuid)
|
||||
@ -245,8 +236,7 @@ func (client *XenAPIClient) GetNetworkByUuid (network_uuid string) (network *Net
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetNetworkByNameLabel (name_label string) (networks []*Network, err error) {
|
||||
func (client *XenAPIClient) GetNetworkByNameLabel(name_label string) (networks []*Network, err error) {
|
||||
networks = make([]*Network, 0)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "network.get_by_name_label", name_label)
|
||||
@ -264,7 +254,7 @@ func (client *XenAPIClient) GetNetworkByNameLabel (name_label string) (networks
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (client *XenAPIClient) GetVdiByNameLabel (name_label string) (vdis []*VDI, err error) {
|
||||
func (client *XenAPIClient) GetVdiByNameLabel(name_label string) (vdis []*VDI, err error) {
|
||||
vdis = make([]*VDI, 0)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "VDI.get_by_name_label", name_label)
|
||||
@ -282,8 +272,7 @@ func (client *XenAPIClient) GetVdiByNameLabel (name_label string) (vdis []*VDI,
|
||||
return vdis, nil
|
||||
}
|
||||
|
||||
|
||||
func (client *XenAPIClient) GetSRByUuid (sr_uuid string) (sr *SR, err error) {
|
||||
func (client *XenAPIClient) GetSRByUuid(sr_uuid string) (sr *SR, err error) {
|
||||
sr = new(SR)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "SR.get_by_uuid", sr_uuid)
|
||||
@ -295,7 +284,7 @@ func (client *XenAPIClient) GetSRByUuid (sr_uuid string) (sr *SR, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (client *XenAPIClient) GetVdiByUuid (vdi_uuid string) (vdi *VDI, err error) {
|
||||
func (client *XenAPIClient) GetVdiByUuid(vdi_uuid string) (vdi *VDI, err error) {
|
||||
vdi = new(VDI)
|
||||
result := APIResult{}
|
||||
err = client.APICall(&result, "VDI.get_by_uuid", vdi_uuid)
|
||||
@ -326,7 +315,7 @@ func (client *XenAPIClient) GetPIFs() (pifs []*PIF, err error) {
|
||||
|
||||
// VM associated functions
|
||||
|
||||
func (self *VM) Clone (label string) (new_instance *VM, err error) {
|
||||
func (self *VM) Clone(label string) (new_instance *VM, err error) {
|
||||
new_instance = new(VM)
|
||||
|
||||
result := APIResult{}
|
||||
@ -357,7 +346,7 @@ func (self *VM) CleanShutdown() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (self *VM) Unpause () (err error) {
|
||||
func (self *VM) Unpause() (err error) {
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VM.unpause", self.Ref)
|
||||
if err != nil {
|
||||
@ -427,7 +416,6 @@ func (self *VM) GetVBDs() (vbds []VBD, err error) {
|
||||
return vbds, nil
|
||||
}
|
||||
|
||||
|
||||
func (self *VM) GetVIFs() (vifs []VIF, err error) {
|
||||
vifs = make([]VIF, 0)
|
||||
result := APIResult{}
|
||||
@ -508,7 +496,7 @@ func (self *VM) SetStaticMemoryRange(min, max string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (self *VM) ConnectVdi (vdi *VDI, iso bool) (err error) {
|
||||
func (self *VM) ConnectVdi(vdi *VDI, iso bool) (err error) {
|
||||
|
||||
// 1. Create a VBD
|
||||
|
||||
@ -546,7 +534,7 @@ func (self *VM) ConnectVdi (vdi *VDI, iso bool) (err error) {
|
||||
err = self.Client.APICall(&result, "VBD.get_uuid", vbd_ref)
|
||||
|
||||
fmt.Println("VBD UUID: ", result.Value.(string))
|
||||
/*
|
||||
/*
|
||||
// 2. Plug VBD (Non need - the VM hasn't booted.
|
||||
// @todo - check VM state
|
||||
result = APIResult{}
|
||||
@ -555,7 +543,7 @@ func (self *VM) ConnectVdi (vdi *VDI, iso bool) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*/
|
||||
*/
|
||||
return
|
||||
}
|
||||
|
||||
@ -574,8 +562,7 @@ func (self *VM) SetPlatform(params map[string]string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (self *VM) ConnectNetwork (network *Network, device string) (vif *VIF, err error) {
|
||||
func (self *VM) ConnectNetwork(network *Network, device string) (vif *VIF, err error) {
|
||||
// Create the VIF
|
||||
|
||||
vif_rec := make(xmlrpc.Struct)
|
||||
@ -604,7 +591,7 @@ func (self *VM) ConnectNetwork (network *Network, device string) (vif *VIF, err
|
||||
|
||||
// Setters
|
||||
|
||||
func (self *VM) SetIsATemplate (is_a_template bool) (err error) {
|
||||
func (self *VM) SetIsATemplate(is_a_template bool) (err error) {
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VM.set_is_a_template", self.Ref, is_a_template)
|
||||
if err != nil {
|
||||
@ -615,7 +602,7 @@ func (self *VM) SetIsATemplate (is_a_template bool) (err error) {
|
||||
|
||||
// SR associated functions
|
||||
|
||||
func (self *SR) CreateVdi (name_label, size string) (vdi *VDI, err error) {
|
||||
func (self *SR) CreateVdi(name_label, size string) (vdi *VDI, err error) {
|
||||
vdi = new(VDI)
|
||||
|
||||
vdi_rec := make(xmlrpc.Struct)
|
||||
@ -630,7 +617,6 @@ func (self *SR) CreateVdi (name_label, size string) (vdi *VDI, err error) {
|
||||
oc["temp"] = "temp"
|
||||
vdi_rec["other_config"] = oc
|
||||
|
||||
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VDI.create", vdi_rec)
|
||||
if err != nil {
|
||||
@ -645,7 +631,7 @@ func (self *SR) CreateVdi (name_label, size string) (vdi *VDI, err error) {
|
||||
|
||||
// Network associated functions
|
||||
|
||||
func (self *Network) GetAssignedIPs () (ip_map map[string]string, err error) {
|
||||
func (self *Network) GetAssignedIPs() (ip_map map[string]string, err error) {
|
||||
ip_map = make(map[string]string, 0)
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "network.get_assigned_ips", self.Ref)
|
||||
@ -660,7 +646,7 @@ func (self *Network) GetAssignedIPs () (ip_map map[string]string, err error) {
|
||||
|
||||
// PIF associated functions
|
||||
|
||||
func (self *PIF) GetRecord () (record map[string]interface{}, err error) {
|
||||
func (self *PIF) GetRecord() (record map[string]interface{}, err error) {
|
||||
record = make(map[string]interface{})
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "PIF.get_record", self.Ref)
|
||||
@ -675,7 +661,7 @@ func (self *PIF) GetRecord () (record map[string]interface{}, err error) {
|
||||
|
||||
// Pool associated functions
|
||||
|
||||
func (self *Pool) GetRecord () (record map[string]interface{}, err error) {
|
||||
func (self *Pool) GetRecord() (record map[string]interface{}, err error) {
|
||||
record = make(map[string]interface{})
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "pool.get_record", self.Ref)
|
||||
@ -688,9 +674,8 @@ func (self *Pool) GetRecord () (record map[string]interface{}, err error) {
|
||||
return record, nil
|
||||
}
|
||||
|
||||
|
||||
// VBD associated functions
|
||||
func (self *VBD) GetRecord () (record map[string]interface{}, err error) {
|
||||
func (self *VBD) GetRecord() (record map[string]interface{}, err error) {
|
||||
record = make(map[string]interface{})
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VBD.get_record", self.Ref)
|
||||
@ -703,7 +688,7 @@ func (self *VBD) GetRecord () (record map[string]interface{}, err error) {
|
||||
return record, nil
|
||||
}
|
||||
|
||||
func (self *VBD) GetVDI () (vdi *VDI, err error) {
|
||||
func (self *VBD) GetVDI() (vdi *VDI, err error) {
|
||||
vbd_rec, err := self.GetRecord()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -716,7 +701,7 @@ func (self *VBD) GetVDI () (vdi *VDI, err error) {
|
||||
return vdi, nil
|
||||
}
|
||||
|
||||
func (self *VBD) Eject () (err error) {
|
||||
func (self *VBD) Eject() (err error) {
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VBD.eject", self.Ref)
|
||||
if err != nil {
|
||||
@ -727,7 +712,7 @@ func (self *VBD) Eject () (err error) {
|
||||
|
||||
// VIF associated functions
|
||||
|
||||
func (self *VIF) Destroy () (err error) {
|
||||
func (self *VIF) Destroy() (err error) {
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VIF.destroy", self.Ref)
|
||||
if err != nil {
|
||||
@ -738,7 +723,7 @@ func (self *VIF) Destroy () (err error) {
|
||||
|
||||
// VDI associated functions
|
||||
|
||||
func (self *VDI) GetUuid () (vdi_uuid string, err error) {
|
||||
func (self *VDI) GetUuid() (vdi_uuid string, err error) {
|
||||
result := APIResult{}
|
||||
err = self.Client.APICall(&result, "VDI.get_uuid", self.Ref)
|
||||
if err != nil {
|
||||
@ -748,10 +733,9 @@ func (self *VDI) GetUuid () (vdi_uuid string, err error) {
|
||||
return vdi_uuid, nil
|
||||
}
|
||||
|
||||
|
||||
// Client Initiator
|
||||
|
||||
func NewXenAPIClient (host, username, password string) (client XenAPIClient) {
|
||||
func NewXenAPIClient(host, username, password string) (client XenAPIClient) {
|
||||
client.Host = host
|
||||
client.Url = "http://" + host
|
||||
client.Username = username
|
||||
|
@ -1,16 +1,16 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
gossh "code.google.com/p/go.crypto/ssh"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
commonssh "github.com/mitchellh/packer/common/ssh"
|
||||
"github.com/mitchellh/packer/communicator/ssh"
|
||||
"strings"
|
||||
"log"
|
||||
"bytes"
|
||||
"net"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func sshAddress(state multistep.StateBag) (string, error) {
|
||||
@ -50,19 +50,16 @@ func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func execute_ssh_cmd (cmd, host, port, username, password string) (stdout string, err error) {
|
||||
func execute_ssh_cmd(cmd, host, port, username, password string) (stdout string, err error) {
|
||||
// Setup connection config
|
||||
config := &gossh.ClientConfig {
|
||||
config := &gossh.ClientConfig{
|
||||
User: username,
|
||||
Auth: []gossh.AuthMethod {
|
||||
Auth: []gossh.AuthMethod{
|
||||
gossh.Password(password),
|
||||
},
|
||||
}
|
||||
|
||||
client, err := gossh.Dial("tcp", host + ":" + port, config)
|
||||
client, err := gossh.Dial("tcp", host+":"+port, config)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -87,36 +84,40 @@ func execute_ssh_cmd (cmd, host, port, username, password string) (stdout string
|
||||
return strings.Trim(b.String(), "\n"), nil
|
||||
}
|
||||
|
||||
func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) {
|
||||
ssh_client_conn, err := gossh.Dial("tcp", server + ":22", config)
|
||||
func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) error {
|
||||
ssh_client_conn, err := gossh.Dial("tcp", server+":22", config)
|
||||
if err != nil {
|
||||
log.Fatalf("local ssh.Dial error: %s", err)
|
||||
log.Printf("local ssh.Dial error: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
remote_loc := fmt.Sprintf("%s:%d", remote_dest, remote_port)
|
||||
ssh_conn, err := ssh_client_conn.Dial("tcp", remote_loc)
|
||||
if err != nil {
|
||||
log.Fatalf("ssh.Dial error: %s", err)
|
||||
log.Printf("ssh.Dial error: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
_, err = io.Copy(ssh_conn, local_conn)
|
||||
if err != nil {
|
||||
log.Fatalf("io.copy failed: %v", err)
|
||||
log.Printf("io.copy failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
_, err = io.Copy(local_conn, ssh_conn)
|
||||
if err != nil {
|
||||
log.Fatalf("io.copy failed: %v", err)
|
||||
log.Printf("io.copy failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ssh_port_forward(local_port uint, remote_port uint, remote_dest, host, username, password string) (err error) {
|
||||
func ssh_port_forward(local_port uint, remote_port uint, remote_dest, host, username, password string) error {
|
||||
|
||||
config := &gossh.ClientConfig {
|
||||
config := &gossh.ClientConfig{
|
||||
User: username,
|
||||
Auth: []gossh.AuthMethod{
|
||||
gossh.Password(password),
|
||||
@ -129,7 +130,7 @@ func ssh_port_forward(local_port uint, remote_port uint, remote_dest, host, user
|
||||
"127.0.0.1",
|
||||
local_port))
|
||||
if err != nil {
|
||||
log.Fatalf("Local listen failed: %s", err)
|
||||
log.Printf("Local listen failed: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -137,16 +138,13 @@ func ssh_port_forward(local_port uint, remote_port uint, remote_dest, host, user
|
||||
local_connection, err := local_listener.Accept()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Local accept failed: %s", err)
|
||||
log.Printf("Local accept failed: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Forward to a remote port
|
||||
go forward(local_connection, config, host, remote_dest, remote_port)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
type stepBootWait struct{}
|
||||
|
||||
func (self *stepBootWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
@ -27,4 +26,3 @@ func (self *stepBootWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
}
|
||||
|
||||
func (self *stepBootWait) Cleanup(state multistep.StateBag) {}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
package xenserver
|
||||
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
@ -20,7 +19,6 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
|
||||
|
||||
ui.Say("Step: Create Instance")
|
||||
|
||||
|
||||
// Get the template to clone from
|
||||
|
||||
vms, err := client.GetVMByNameLabel(config.CloneTemplate)
|
||||
@ -55,7 +53,6 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// Use the provided name label to find the SR to use
|
||||
srs, err := client.GetSRByNameLabel(config.SrName)
|
||||
@ -151,10 +148,8 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
|
||||
// Connect the ISO
|
||||
//iso_vdi_uuid := state.Get("iso_vdi_uuid").(string)
|
||||
|
||||
|
||||
isos, err := client.GetVdiByNameLabel(config.IsoName)
|
||||
|
||||
|
||||
switch {
|
||||
case len(isos) == 0:
|
||||
log.Fatal(fmt.Sprintf("Couldn't find an ISO named '%s'. Aborting", config.IsoName))
|
||||
@ -180,12 +175,11 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
||||
func (self *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
||||
|
||||
// client := state.Get("client").(*XenAPIClient)
|
||||
// config := state.Get("config").(config)
|
||||
// ui := state.Get("ui").(packer.Ui)
|
||||
// client := state.Get("client").(*XenAPIClient)
|
||||
// config := state.Get("config").(config)
|
||||
// ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
// If instance hasn't been created, we have nothing to do.
|
||||
if self.InstanceId == "" {
|
||||
|
@ -1,17 +1,16 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"net"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type stepForwardPortOverSSH struct {
|
||||
|
||||
RemotePort func (state multistep.StateBag) (uint, error)
|
||||
RemoteDest func (state multistep.StateBag) (string, error)
|
||||
RemotePort func(state multistep.StateBag) (uint, error)
|
||||
RemoteDest func(state multistep.StateBag) (string, error)
|
||||
|
||||
HostPortMin uint
|
||||
HostPortMax uint
|
||||
@ -19,7 +18,6 @@ type stepForwardPortOverSSH struct {
|
||||
ResultKey string
|
||||
}
|
||||
|
||||
|
||||
func (self *stepForwardPortOverSSH) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
config := state.Get("config").(config)
|
||||
@ -31,7 +29,6 @@ func (self *stepForwardPortOverSSH) Run(state multistep.StateBag) multistep.Step
|
||||
self.HostPortMin,
|
||||
self.HostPortMax)
|
||||
|
||||
|
||||
var sshHostPort uint
|
||||
var foundPort bool
|
||||
|
||||
@ -54,13 +51,11 @@ func (self *stepForwardPortOverSSH) Run(state multistep.StateBag) multistep.Step
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
|
||||
ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort))
|
||||
|
||||
remotePort, _ := self.RemotePort(state)
|
||||
remoteDest, _ := self.RemoteDest(state)
|
||||
|
||||
|
||||
go ssh_port_forward(sshHostPort, remotePort, remoteDest, config.HostIp, config.Username, config.Password)
|
||||
ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, config.HostIp))
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
package xenserver
|
||||
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type stepGetVNCPort struct {}
|
||||
|
||||
type stepGetVNCPort struct{}
|
||||
|
||||
func (self *stepGetVNCPort) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
@ -37,16 +35,15 @@ func (self *stepGetVNCPort) Run(state multistep.StateBag) multistep.StepAction {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
||||
func (self *stepGetVNCPort) Cleanup(state multistep.StateBag) {
|
||||
}
|
||||
|
||||
func instanceVNCPort (state multistep.StateBag) (uint, error) {
|
||||
func instanceVNCPort(state multistep.StateBag) (uint, error) {
|
||||
vncPort := state.Get("instance_vnc_port").(uint)
|
||||
return vncPort, nil
|
||||
}
|
||||
|
||||
func instanceVNCIP (state multistep.StateBag) (string, error) {
|
||||
func instanceVNCIP(state multistep.StateBag) (string, error) {
|
||||
// The port is in Dom0, so we want to forward from localhost
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ package xenserver
|
||||
/* Taken from https://raw.githubusercontent.com/mitchellh/packer/master/builder/qemu/step_prepare_output_dir.go */
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type stepShutdownAndExport struct{}
|
||||
@ -43,7 +43,6 @@ func downloadFile(url, filename string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (stepShutdownAndExport) Run(state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
@ -90,8 +89,7 @@ func (stepShutdownAndExport) Run(state multistep.StateBag) multistep.StepAction
|
||||
downloadFile(disk_export_url, disk_export_filename)
|
||||
}
|
||||
|
||||
|
||||
ui.Say("Download complteded: " + config.OutputDir)
|
||||
ui.Say("Download completed: " + config.OutputDir)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"time"
|
||||
"log"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type stepStartOnHIMN struct{}
|
||||
|
||||
|
||||
/*
|
||||
* This step starts the installed guest on the Host Internal Management Network
|
||||
* as there exists an API to obtain the IP allocated to the VM by XAPI.
|
||||
@ -37,7 +36,6 @@ func (self *stepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
|
||||
himn := networks[0]
|
||||
|
||||
// Create a VIF for the HIMN
|
||||
@ -51,11 +49,10 @@ func (self *stepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
|
||||
// Start the VM
|
||||
instance.Start(false, false)
|
||||
|
||||
|
||||
var himn_iface_ip string = ""
|
||||
|
||||
// Obtain the allocated IP
|
||||
for i:=0; i < 10; i++ {
|
||||
for i := 0; i < 10; i++ {
|
||||
ips, _ := himn.GetAssignedIPs()
|
||||
log.Printf("IPs: %s", ips)
|
||||
log.Printf("Ref: %s", instance.Ref)
|
||||
@ -68,7 +65,7 @@ func (self *stepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
|
||||
}
|
||||
|
||||
ui.Say("Wait for IP address...")
|
||||
time.Sleep(10*time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
@ -80,13 +77,12 @@ func (self *stepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
|
||||
// Wait for the VM to boot, and check we can ping this interface
|
||||
|
||||
ping_cmd := fmt.Sprintf("ping -c 1 %s", himn_iface_ip)
|
||||
|
||||
err = nil
|
||||
for i:=0; i < 30; i++ {
|
||||
for i := 0; i < 30; i++ {
|
||||
ui.Message(fmt.Sprintf("Attempting to ping interface: %s", ping_cmd))
|
||||
_, err := execute_ssh_cmd(ping_cmd, config.HostIp, "22", config.Username, config.Password)
|
||||
|
||||
@ -112,13 +108,11 @@ func (self *stepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
|
||||
|
||||
func (self *stepStartOnHIMN) Cleanup(state multistep.StateBag) {}
|
||||
|
||||
|
||||
func himnSSHIP (state multistep.StateBag) (string, error) {
|
||||
func himnSSHIP(state multistep.StateBag) (string, error) {
|
||||
ip := state.Get("himn_ssh_address").(string)
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
|
||||
func himnSSHPort (state multistep.StateBag) (uint, error) {
|
||||
func himnSSHPort(state multistep.StateBag) (uint, error) {
|
||||
return 22, nil
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
package xenserver
|
||||
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
)
|
||||
|
||||
type stepStartVmPaused struct {}
|
||||
type stepStartVmPaused struct{}
|
||||
|
||||
func (self *stepStartVmPaused) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
@ -25,6 +24,5 @@ func (self *stepStartVmPaused) Run(state multistep.StateBag) multistep.StepActio
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
||||
func (self *stepStartVmPaused) Cleanup(state multistep.StateBag) {
|
||||
}
|
||||
|
@ -22,10 +22,9 @@ type bootCommandTemplateData struct {
|
||||
HTTPPort uint
|
||||
}
|
||||
|
||||
|
||||
type stepTypeBootCommand struct{}
|
||||
|
||||
func (self *stepTypeBootCommand) Run (state multistep.StateBag) multistep.StepAction {
|
||||
func (self *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vnc_port := state.Get("local_vnc_port").(uint)
|
||||
@ -59,7 +58,7 @@ func (self *stepTypeBootCommand) Run (state multistep.StateBag) multistep.StepAc
|
||||
log.Printf("Connected to the VNC console: %s", c.DesktopName)
|
||||
|
||||
// @todo - include http port/ip so kickstarter files can be grabbed
|
||||
tplData := &bootCommandTemplateData {
|
||||
tplData := &bootCommandTemplateData{
|
||||
config.LocalIp,
|
||||
http_port,
|
||||
}
|
||||
@ -88,7 +87,7 @@ func (self *stepTypeBootCommand) Run (state multistep.StateBag) multistep.StepAc
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (self *stepTypeBootCommand) Cleanup (multistep.StateBag) {}
|
||||
func (self *stepTypeBootCommand) Cleanup(multistep.StateBag) {}
|
||||
|
||||
// Taken from qemu's builder plugin - not an exported function.
|
||||
func vncSendString(c *vnc.ClientConn, original string) {
|
||||
|
@ -1,16 +1,15 @@
|
||||
package xenserver
|
||||
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
"strconv"
|
||||
"os/exec"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type stepUploadIso struct {}
|
||||
type stepUploadIso struct{}
|
||||
|
||||
func (self *stepUploadIso) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
@ -48,7 +47,7 @@ func (self *stepUploadIso) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
filesize_str := strconv.FormatInt(iso_filesize, 10)
|
||||
log.Printf("Filesize of the ISO is %d", filesize_str)
|
||||
vdi, err := sr.CreateVdi("Packer Gen " + stat.Name(), filesize_str)
|
||||
vdi, err := sr.CreateVdi("Packer Gen "+stat.Name(), filesize_str)
|
||||
|
||||
if err != nil {
|
||||
ui.Error(err.Error())
|
||||
@ -72,10 +71,8 @@ func (self *stepUploadIso) Run(state multistep.StateBag) multistep.StepAction {
|
||||
// Stash the vdi uuid to be used in preference
|
||||
state.Put("iso_vdi_uuid", vdi_uuid)
|
||||
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
||||
func (self *stepUploadIso) Cleanup(state multistep.StateBag) {
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"time"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
|
||||
type stepWait struct{}
|
||||
|
||||
func (self *stepWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
@ -16,7 +14,6 @@ func (self *stepWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
ui.Say("Step: Wait for install to complete.")
|
||||
|
||||
|
||||
//Expect install to be configured to shutdown on completion
|
||||
|
||||
instance_id := state.Get("instance_uuid").(string)
|
||||
@ -41,13 +38,12 @@ func (self *stepWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
// Hack - should encapsulate this in the client really
|
||||
// This is needed because we can't guarentee the type
|
||||
// returned by the xmlrpc lib will be string
|
||||
switch reflect.TypeOf(rec["type"]).Kind() {
|
||||
case reflect.String:
|
||||
if rec["type"].(string) == "CD" {
|
||||
if recType, ok := rec["type"].(string); ok {
|
||||
if recType == "CD" {
|
||||
ui.Say("Ejecting CD...")
|
||||
vbd.Eject()
|
||||
}
|
||||
default:
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -63,4 +59,3 @@ func (self *stepWait) Run(state multistep.StateBag) multistep.StepAction {
|
||||
}
|
||||
|
||||
func (self *stepWait) Cleanup(state multistep.StateBag) {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user