From 2cea47965c616a551ed122e276ef56097df73df0 Mon Sep 17 00:00:00 2001 From: Joshua Goldie Date: Fri, 8 Jan 2016 15:51:53 -0500 Subject: [PATCH 1/2] Add option for static IP --- builder/xenserver/common/common_config.go | 5 +++-- builder/xenserver/common/step_wait_for_ip.go | 6 ++++++ docs/builders/xenserver-iso.html.markdown | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 0c644c04..474efb9e 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -45,6 +45,7 @@ type CommonConfig struct { SSHPassword string `mapstructure:"ssh_password"` SSHPort uint `mapstructure:"ssh_port"` SSHUser string `mapstructure:"ssh_username"` + SSHHost string `mapstructure:"ssh_host"` SSHConfig `mapstructure:",squash"` RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"` @@ -196,9 +197,9 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig } switch c.IPGetter { - case "auto", "tools", "http": + case "auto", "tools", "http", "static": default: - errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'")) + errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http', 'static'")) } return errs diff --git a/builder/xenserver/common/step_wait_for_ip.go b/builder/xenserver/common/step_wait_for_ip.go index 1d29a2d5..ae0fcf67 100644 --- a/builder/xenserver/common/step_wait_for_ip.go +++ b/builder/xenserver/common/step_wait_for_ip.go @@ -66,6 +66,12 @@ func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction { } + if config.IPGetter == "static" { + ip = config.SSHHost + ui.Message(fmt.Sprintf("Static IP is defined as '%s'", ip)) + return true,nil + } + return false, nil }, }.Wait(state) diff --git a/docs/builders/xenserver-iso.html.markdown b/docs/builders/xenserver-iso.html.markdown index bc7c00e3..bcc3625d 100644 --- a/docs/builders/xenserver-iso.html.markdown +++ b/docs/builders/xenserver-iso.html.markdown @@ -180,6 +180,10 @@ each category, the available options are alphabetized and described. If it doesn't shut down in this time, it is an error. By default, the timeout is "5m", or five minutes. +* `ssh_host` - The IP address to use for the virtual machine. This is useful for + building in an environment where static IP assignment must be used. The + `ip_getter` option must also be set to `static`. + * `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, From 6f32accc2d17ebf98ca757a9d9d5c0cdab1ade51 Mon Sep 17 00:00:00 2001 From: Joshua Goldie Date: Tue, 12 Jan 2016 22:33:21 -0500 Subject: [PATCH 2/2] This REALLY needs cleanup, but I have no more time to mess with it now. --- builder/xenserver/common/client.go | 8 +- builder/xenserver/common/common_config.go | 3 + builder/xenserver/common/step_attach_vdi.go | 1 + builder/xenserver/iso/builder.go | 2 + builder/xenserver/iso/step_add_disks.go | 108 ++++++++++++++++++ builder/xenserver/iso/step_create_instance.go | 3 + 6 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 builder/xenserver/iso/step_add_disks.go diff --git a/builder/xenserver/common/client.go b/builder/xenserver/common/client.go index 33f27846..b9a19d43 100644 --- a/builder/xenserver/common/client.go +++ b/builder/xenserver/common/client.go @@ -576,14 +576,18 @@ func (self *VM) SetStaticMemoryRange(min, max uint) (err error) { return } -func (self *VM) ConnectVdi(vdi *VDI, vdiType VDIType) (err error) { +func (self *VM) ConnectVdi(vdi *VDI, vdiType VDIType, userdevice string) (err error) { // 1. Create a VBD vbd_rec := make(xmlrpc.Struct) vbd_rec["VM"] = self.Ref vbd_rec["VDI"] = vdi.Ref - vbd_rec["userdevice"] = "autodetect" + if (userdevice == nil) { + vbd_rec["userdevice"] = "autodetect" + } else { + vbd_rec["userdevice"] = userdevice + } vbd_rec["empty"] = false vbd_rec["other_config"] = make(xmlrpc.Struct) vbd_rec["qos_algorithm_type"] = "" diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 474efb9e..d8db6a39 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -55,6 +55,9 @@ type CommonConfig struct { Format string `mapstructure:"format"` KeepVM string `mapstructure:"keep_vm"` IPGetter string `mapstructure:"ip_getter"` + + DiskBSize uint `mapstructure:"diskb_size"` + DiskCSize uint `mapstructure:"diskc_size"` } func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error { diff --git a/builder/xenserver/common/step_attach_vdi.go b/builder/xenserver/common/step_attach_vdi.go index 059dc499..4e8b6199 100644 --- a/builder/xenserver/common/step_attach_vdi.go +++ b/builder/xenserver/common/step_attach_vdi.go @@ -42,6 +42,7 @@ func (self *StepAttachVdi) Run(state multistep.StateBag) multistep.StepAction { } err = instance.ConnectVdi(self.vdi, self.VdiType, "") + ui.Error(fmt.Sprintf("VDI %s", self.vdi)) if err != nil { ui.Error(fmt.Sprintf("Error attaching VDI '%s': '%s'", vdiUuid, err.Error())) return multistep.ActionHalt diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index 58ece251..ba6e5d8b 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -273,6 +273,8 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa VdiUuidKey: "tools_vdi_uuid", VdiType: xsclient.CD, }, + //Add the extra disks here? + new(stepAddDisks), new(xscommon.StepStartVmPaused), new(xscommon.StepGetVNCPort), &xscommon.StepForwardPortOverSSH{ diff --git a/builder/xenserver/iso/step_add_disks.go b/builder/xenserver/iso/step_add_disks.go new file mode 100644 index 00000000..e09ce1a7 --- /dev/null +++ b/builder/xenserver/iso/step_add_disks.go @@ -0,0 +1,108 @@ +package iso + +import ( + "fmt" + + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + xsclient "github.com/xenserver/go-xenserver-client" +) + +type stepAddDisks struct { + instance *xsclient.VM + vdiB *xsclient.VDI + vdiC *xsclient.VDI +} + + +func (self *stepAddDisks) Run(state multistep.StateBag) multistep.StepAction { + + client := state.Get("client").(xsclient.XenAPIClient) + config := state.Get("config").(config) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Step: Add disks") + + sr, err := config.GetSR(client) + if err != nil { + ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error())) + return multistep.ActionHalt + } + + uuid := state.Get("instance_uuid").(string) + instance, err := client.GetVMByUuid(uuid) + if err != nil { + ui.Error(fmt.Sprintf("Unable to get VM from UUID '%s': %s", uuid, err.Error())) + return multistep.ActionHalt + } + + // Add additional disks - this is a terrible hack until my golang gets better + if (config.DiskBSize !=0) { + ui.Say(fmt.Sprintf("Creating second disk with size %d", config.DiskBSize)) + + vdiB, err := sr.CreateVdi("Packer-disk-b", int64(config.DiskBSize*1024*1024)) + if err != nil { + ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error())) + } + + self.vdiB = vdiB + + err = instance.ConnectVdi(vdiB, xsclient.Disk, "") + if err != nil { + ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) + return multistep.ActionHalt + } + + + } + + if (config.DiskCSize !=0) { + ui.Say(fmt.Sprintf("Creating third disk with size %d", config.DiskCSize)) + + vdiC, err := sr.CreateVdi("Packer-disk-c", int64(config.DiskCSize*1024*1024)) + if err != nil { + ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error())) + } + + self.vdiC = vdiC + + err = instance.ConnectVdi(vdiC, xsclient.Disk, "") + if err != nil { + ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) + return multistep.ActionHalt + } + + } + + return multistep.ActionContinue +} + +func (self *stepAddDisks) Cleanup(state multistep.StateBag) { + config := state.Get("config").(config) + if config.ShouldKeepVM(state) { + return + } + + ui := state.Get("ui").(packer.Ui) + + ui.Say("Destroying additional disks") + + + //TODO: learn golang and make this better + if self.vdiB != nil { + ui.Say("Destroying second VDI") + err := self.vdiB.Destroy() + if err != nil { + ui.Error(err.Error()) + } + } + + if self.vdiC != nil { + ui.Say("Destroying third VDI") + err := self.vdiB.Destroy() + if err != nil { + ui.Error(err.Error()) + } + } + +} \ No newline at end of file diff --git a/builder/xenserver/iso/step_create_instance.go b/builder/xenserver/iso/step_create_instance.go index f0aaf1b6..bdef12a1 100644 --- a/builder/xenserver/iso/step_create_instance.go +++ b/builder/xenserver/iso/step_create_instance.go @@ -11,6 +11,8 @@ import ( type stepCreateInstance struct { instance *xsclient.VM vdi *xsclient.VDI + vdiB *xsclient.VDI + vdiC *xsclient.VDI } func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { @@ -192,4 +194,5 @@ func (self *stepCreateInstance) Cleanup(state multistep.StateBag) { ui.Error(err.Error()) } } + }