From d63518195d150250d065457b6a896777b3f31893 Mon Sep 17 00:00:00 2001 From: Rob Dobson Date: Mon, 23 Feb 2015 18:30:57 +0000 Subject: [PATCH] Re-adding support for bypassing ISO upload and just using and attaching one already present on an available SR. Signed-off-by: Rob Dobson --- builder/xenserver/common/step_find_vdi.go | 5 + builder/xenserver/common/step_upload_vdi.go | 15 ++- builder/xenserver/iso/builder.go | 117 +++++++++++++------- builder/xenserver/xva/builder.go | 4 +- 4 files changed, 94 insertions(+), 47 deletions(-) diff --git a/builder/xenserver/common/step_find_vdi.go b/builder/xenserver/common/step_find_vdi.go index c48a661..32c1a95 100644 --- a/builder/xenserver/common/step_find_vdi.go +++ b/builder/xenserver/common/step_find_vdi.go @@ -17,6 +17,11 @@ func (self *StepFindVdi) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) client := state.Get("client").(xsclient.XenAPIClient) + // Ignore if VdiName is not specified + if self.VdiName == "" { + return multistep.ActionContinue + } + vdis, err := client.GetVdiByNameLabel(self.VdiName) switch { diff --git a/builder/xenserver/common/step_upload_vdi.go b/builder/xenserver/common/step_upload_vdi.go index 1b05abe..ecb0bfe 100644 --- a/builder/xenserver/common/step_upload_vdi.go +++ b/builder/xenserver/common/step_upload_vdi.go @@ -11,7 +11,7 @@ import ( ) type StepUploadVdi struct { - VdiName string + VdiNameFunc func() string ImagePathFunc func() string VdiUuidKey string } @@ -22,12 +22,13 @@ func (self *StepUploadVdi) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(xsclient.XenAPIClient) imagePath := self.ImagePathFunc() + vdiName := self.VdiNameFunc() if imagePath == "" { // skip if no disk image to attach return multistep.ActionContinue } - ui.Say(fmt.Sprintf("Step: Upload VDI '%s'", self.VdiName)) + ui.Say(fmt.Sprintf("Step: Upload VDI '%s'", vdiName)) // Create VDI for the image sr, err := config.GetSR(client) @@ -52,15 +53,15 @@ func (self *StepUploadVdi) Run(state multistep.StateBag) multistep.StepAction { fileLength := fstat.Size() // Create the VDI - vdi, err := sr.CreateVdi(self.VdiName, fileLength) + vdi, err := sr.CreateVdi(vdiName, fileLength) if err != nil { - ui.Error(fmt.Sprintf("Unable to create VDI '%s': %s", self.VdiName, err.Error())) + ui.Error(fmt.Sprintf("Unable to create VDI '%s': %s", vdiName, err.Error())) return multistep.ActionHalt } vdiUuid, err := vdi.GetUuid() if err != nil { - ui.Error(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", self.VdiName, err.Error())) + ui.Error(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", vdiName, err.Error())) return multistep.ActionHalt } state.Put(self.VdiUuidKey, vdiUuid) @@ -83,6 +84,8 @@ func (self *StepUploadVdi) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) client := state.Get("client").(xsclient.XenAPIClient) + vdiName := self.VdiNameFunc() + if config.ShouldKeepVM(state) { return } @@ -119,7 +122,7 @@ func (self *StepUploadVdi) Cleanup(state multistep.StateBag) { ui.Error(fmt.Sprintf("Can't destroy VDI '%s': %s", vdiUuid, err.Error())) return } - ui.Say(fmt.Sprintf("Destroyed VDI '%s'", self.VdiName)) + ui.Say(fmt.Sprintf("Destroyed VDI '%s'", vdiName)) state.Put(self.VdiUuidKey, "") } diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index 36e4c23..4a0f5b4 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -27,6 +27,7 @@ type config struct { ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOUrls []string `mapstructure:"iso_urls"` ISOUrl string `mapstructure:"iso_url"` + ISOName string `mapstructure:"iso_name"` PlatformArgs map[string]string `mapstructure:"platform_args"` @@ -95,6 +96,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error "iso_checksum": &self.config.ISOChecksum, "iso_checksum_type": &self.config.ISOChecksumType, "iso_url": &self.config.ISOUrl, + "iso_name": &self.config.ISOName, "install_timeout": &self.config.RawInstallTimeout, } for i := range self.config.ISOUrls { @@ -117,46 +119,55 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error errs, fmt.Errorf("Failed to parse install_timeout: %s", err)) } - if self.config.ISOChecksumType == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("The iso_checksum_type must be specified.")) - } else { - self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType) - if self.config.ISOChecksumType != "none" { - if self.config.ISOChecksum == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("Due to the file size being large, an iso_checksum is required.")) - } else { - self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum) - } + if self.config.ISOName == "" { - if hash := common.HashForType(self.config.ISOChecksumType); hash == nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType)) - } + // If ISO name is not specified, assume a URL and checksum has been provided. - } - } + if self.config.ISOChecksumType == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("The iso_checksum_type must be specified.")) + } else { + self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType) + if self.config.ISOChecksumType != "none" { + if self.config.ISOChecksum == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Due to the file size being large, an iso_checksum is required.")) + } else { + self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum) + } - if len(self.config.ISOUrls) == 0 { - if self.config.ISOUrl == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("One of iso_url or iso_urls must be specified.")) - } else { - self.config.ISOUrls = []string{self.config.ISOUrl} - } - } else if self.config.ISOUrl != "" { - errs = packer.MultiErrorAppend( - errs, errors.New("Only one of iso_url or iso_urls may be specified.")) - } + if hash := common.HashForType(self.config.ISOChecksumType); hash == nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType)) + } - for i, url := range self.config.ISOUrls { - self.config.ISOUrls[i], err = common.DownloadableURL(url) - if err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Failed to parse iso_urls[%d]: %s", i, err)) - } - } + } + } + + if len(self.config.ISOUrls) == 0 { + if self.config.ISOUrl == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("One of iso_url or iso_urls must be specified.")) + } else { + self.config.ISOUrls = []string{self.config.ISOUrl} + } + } else if self.config.ISOUrl != "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Only one of iso_url or iso_urls may be specified.")) + } + + for i, url := range self.config.ISOUrls { + self.config.ISOUrls[i], err = common.DownloadableURL(url) + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Failed to parse iso_urls[%d]: %s", i, err)) + } + } + } else { + + // An ISO name has been provided. It should be attached from an available SR. + + } if len(errs.Errors) > 0 { retErr = errors.New(errs.Error()) @@ -190,7 +201,7 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa httpReqChan := make(chan string, 1) //Build the steps - steps := []multistep.Step{ + download_steps := []multistep.Step{ &common.StepDownload{ Checksum: self.config.ISOChecksum, ChecksumType: self.config.ISOChecksumType, @@ -198,6 +209,9 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa ResultKey: "iso_path", Url: self.config.ISOUrls, }, + } + + steps := []multistep.Step{ &xscommon.StepPrepareOutputDir{ Force: self.config.PackerForce, Path: self.config.OutputDir, @@ -209,7 +223,9 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa Chan: httpReqChan, }, &xscommon.StepUploadVdi{ - VdiName: "Packer-floppy-disk", + VdiNameFunc: func() string { + return "Packer-floppy-disk" + }, ImagePathFunc: func() string { if floppyPath, ok := state.GetOk("floppy_path"); ok { return floppyPath.(string) @@ -219,9 +235,17 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa VdiUuidKey: "floppy_vdi_uuid", }, &xscommon.StepUploadVdi{ - VdiName: path.Base(self.config.ISOUrls[0]), + VdiNameFunc: func() string { + if len(self.config.ISOUrls) > 0 { + return path.Base(self.config.ISOUrls[0]) + } + return "" + }, ImagePathFunc: func() string { - return state.Get("iso_path").(string) + if isoPath, ok := state.GetOk("iso_path"); ok { + return isoPath.(string) + } + return "" }, VdiUuidKey: "iso_vdi_uuid", }, @@ -229,6 +253,10 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa VdiName: self.config.ToolsIsoName, VdiUuidKey: "tools_vdi_uuid", }, + &xscommon.StepFindVdi{ + VdiName: self.config.ISOName, + VdiUuidKey: "isoname_vdi_uuid", + }, new(stepCreateInstance), &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", @@ -238,6 +266,10 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa VdiUuidKey: "iso_vdi_uuid", VdiType: xsclient.CD, }, + &xscommon.StepAttachVdi{ + VdiUuidKey: "isoname_vdi_uuid", + VdiType: xsclient.CD, + }, &xscommon.StepAttachVdi{ VdiUuidKey: "tools_vdi_uuid", VdiType: xsclient.CD, @@ -293,6 +325,11 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa new(xscommon.StepExport), } + if self.config.ISOName == "" { + steps = append(download_steps, steps...) + } + + self.runner = &multistep.BasicRunner{Steps: steps} self.runner.Run(state) diff --git a/builder/xenserver/xva/builder.go b/builder/xenserver/xva/builder.go index 0676bc4..3dea26e 100644 --- a/builder/xenserver/xva/builder.go +++ b/builder/xenserver/xva/builder.go @@ -127,7 +127,9 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa }, new(xscommon.StepHTTPServer), &xscommon.StepUploadVdi{ - VdiName: "Packer-floppy-disk", + VdiNameFunc: func() string { + return "Packer-floppy-disk" + }, ImagePathFunc: func() string { if floppyPath, ok := state.GetOk("floppy_path"); ok { return floppyPath.(string)