Re-adding support for bypassing ISO upload and just using and attaching one already present on an available SR.

Signed-off-by: Rob Dobson <rob.dobson@citrix.com>
This commit is contained in:
Rob Dobson 2015-02-23 18:30:57 +00:00
parent 37433bc022
commit d63518195d
4 changed files with 94 additions and 47 deletions

View File

@ -17,6 +17,11 @@ func (self *StepFindVdi) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(xsclient.XenAPIClient) client := state.Get("client").(xsclient.XenAPIClient)
// Ignore if VdiName is not specified
if self.VdiName == "" {
return multistep.ActionContinue
}
vdis, err := client.GetVdiByNameLabel(self.VdiName) vdis, err := client.GetVdiByNameLabel(self.VdiName)
switch { switch {

View File

@ -11,7 +11,7 @@ import (
) )
type StepUploadVdi struct { type StepUploadVdi struct {
VdiName string VdiNameFunc func() string
ImagePathFunc func() string ImagePathFunc func() string
VdiUuidKey string VdiUuidKey string
} }
@ -22,12 +22,13 @@ func (self *StepUploadVdi) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(xsclient.XenAPIClient) client := state.Get("client").(xsclient.XenAPIClient)
imagePath := self.ImagePathFunc() imagePath := self.ImagePathFunc()
vdiName := self.VdiNameFunc()
if imagePath == "" { if imagePath == "" {
// skip if no disk image to attach // skip if no disk image to attach
return multistep.ActionContinue 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 // Create VDI for the image
sr, err := config.GetSR(client) sr, err := config.GetSR(client)
@ -52,15 +53,15 @@ func (self *StepUploadVdi) Run(state multistep.StateBag) multistep.StepAction {
fileLength := fstat.Size() fileLength := fstat.Size()
// Create the VDI // Create the VDI
vdi, err := sr.CreateVdi(self.VdiName, fileLength) vdi, err := sr.CreateVdi(vdiName, fileLength)
if err != nil { 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 return multistep.ActionHalt
} }
vdiUuid, err := vdi.GetUuid() vdiUuid, err := vdi.GetUuid()
if err != nil { 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 return multistep.ActionHalt
} }
state.Put(self.VdiUuidKey, vdiUuid) state.Put(self.VdiUuidKey, vdiUuid)
@ -83,6 +84,8 @@ func (self *StepUploadVdi) Cleanup(state multistep.StateBag) {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(xsclient.XenAPIClient) client := state.Get("client").(xsclient.XenAPIClient)
vdiName := self.VdiNameFunc()
if config.ShouldKeepVM(state) { if config.ShouldKeepVM(state) {
return 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())) ui.Error(fmt.Sprintf("Can't destroy VDI '%s': %s", vdiUuid, err.Error()))
return return
} }
ui.Say(fmt.Sprintf("Destroyed VDI '%s'", self.VdiName)) ui.Say(fmt.Sprintf("Destroyed VDI '%s'", vdiName))
state.Put(self.VdiUuidKey, "") state.Put(self.VdiUuidKey, "")
} }

View File

@ -27,6 +27,7 @@ type config struct {
ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOChecksumType string `mapstructure:"iso_checksum_type"`
ISOUrls []string `mapstructure:"iso_urls"` ISOUrls []string `mapstructure:"iso_urls"`
ISOUrl string `mapstructure:"iso_url"` ISOUrl string `mapstructure:"iso_url"`
ISOName string `mapstructure:"iso_name"`
PlatformArgs map[string]string `mapstructure:"platform_args"` 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": &self.config.ISOChecksum,
"iso_checksum_type": &self.config.ISOChecksumType, "iso_checksum_type": &self.config.ISOChecksumType,
"iso_url": &self.config.ISOUrl, "iso_url": &self.config.ISOUrl,
"iso_name": &self.config.ISOName,
"install_timeout": &self.config.RawInstallTimeout, "install_timeout": &self.config.RawInstallTimeout,
} }
for i := range self.config.ISOUrls { 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)) errs, fmt.Errorf("Failed to parse install_timeout: %s", err))
} }
if self.config.ISOChecksumType == "" { if self.config.ISOName == "" {
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 hash := common.HashForType(self.config.ISOChecksumType); hash == nil { // If ISO name is not specified, assume a URL and checksum has been provided.
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
}
} 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 hash := common.HashForType(self.config.ISOChecksumType); hash == nil {
if self.config.ISOUrl == "" { errs = packer.MultiErrorAppend(
errs = packer.MultiErrorAppend( errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
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( if len(self.config.ISOUrls) == 0 {
errs, fmt.Errorf("Failed to parse iso_urls[%d]: %s", i, err)) 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 { if len(errs.Errors) > 0 {
retErr = errors.New(errs.Error()) 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) httpReqChan := make(chan string, 1)
//Build the steps //Build the steps
steps := []multistep.Step{ download_steps := []multistep.Step{
&common.StepDownload{ &common.StepDownload{
Checksum: self.config.ISOChecksum, Checksum: self.config.ISOChecksum,
ChecksumType: self.config.ISOChecksumType, 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", ResultKey: "iso_path",
Url: self.config.ISOUrls, Url: self.config.ISOUrls,
}, },
}
steps := []multistep.Step{
&xscommon.StepPrepareOutputDir{ &xscommon.StepPrepareOutputDir{
Force: self.config.PackerForce, Force: self.config.PackerForce,
Path: self.config.OutputDir, Path: self.config.OutputDir,
@ -209,7 +223,9 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
Chan: httpReqChan, Chan: httpReqChan,
}, },
&xscommon.StepUploadVdi{ &xscommon.StepUploadVdi{
VdiName: "Packer-floppy-disk", VdiNameFunc: func() string {
return "Packer-floppy-disk"
},
ImagePathFunc: func() string { ImagePathFunc: func() string {
if floppyPath, ok := state.GetOk("floppy_path"); ok { if floppyPath, ok := state.GetOk("floppy_path"); ok {
return floppyPath.(string) 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", VdiUuidKey: "floppy_vdi_uuid",
}, },
&xscommon.StepUploadVdi{ &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 { 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", 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, VdiName: self.config.ToolsIsoName,
VdiUuidKey: "tools_vdi_uuid", VdiUuidKey: "tools_vdi_uuid",
}, },
&xscommon.StepFindVdi{
VdiName: self.config.ISOName,
VdiUuidKey: "isoname_vdi_uuid",
},
new(stepCreateInstance), new(stepCreateInstance),
&xscommon.StepAttachVdi{ &xscommon.StepAttachVdi{
VdiUuidKey: "floppy_vdi_uuid", 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", VdiUuidKey: "iso_vdi_uuid",
VdiType: xsclient.CD, VdiType: xsclient.CD,
}, },
&xscommon.StepAttachVdi{
VdiUuidKey: "isoname_vdi_uuid",
VdiType: xsclient.CD,
},
&xscommon.StepAttachVdi{ &xscommon.StepAttachVdi{
VdiUuidKey: "tools_vdi_uuid", VdiUuidKey: "tools_vdi_uuid",
VdiType: xsclient.CD, VdiType: xsclient.CD,
@ -293,6 +325,11 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
new(xscommon.StepExport), new(xscommon.StepExport),
} }
if self.config.ISOName == "" {
steps = append(download_steps, steps...)
}
self.runner = &multistep.BasicRunner{Steps: steps} self.runner = &multistep.BasicRunner{Steps: steps}
self.runner.Run(state) self.runner.Run(state)

View File

@ -127,7 +127,9 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
}, },
new(xscommon.StepHTTPServer), new(xscommon.StepHTTPServer),
&xscommon.StepUploadVdi{ &xscommon.StepUploadVdi{
VdiName: "Packer-floppy-disk", VdiNameFunc: func() string {
return "Packer-floppy-disk"
},
ImagePathFunc: func() string { ImagePathFunc: func() string {
if floppyPath, ok := state.GetOk("floppy_path"); ok { if floppyPath, ok := state.GetOk("floppy_path"); ok {
return floppyPath.(string) return floppyPath.(string)