Merge pull request #5 from chengsun/master

Minor cosmetic changes
This commit is contained in:
Rob Dobson 2014-12-08 18:34:55 +00:00
commit 50403a3ed6
16 changed files with 1469 additions and 1532 deletions

View File

@ -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",

View File

@ -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 {

View File

@ -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")
}

View File

@ -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

View File

@ -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
}

View File

@ -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) {}

View File

@ -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 == "" {

View File

@ -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))

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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) {
}

View File

@ -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) {

View File

@ -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) {
}

View File

@ -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) {}

View File

@ -1,8 +1,8 @@
package main
import (
"github.com/rdobson/packer-builder-xenserver/builder/xenserver"
"github.com/mitchellh/packer/packer/plugin"
"github.com/rdobson/packer-builder-xenserver/builder/xenserver"
)
func main() {