Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use iso_url as fallback if iso_name fails #66

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions builder/xenserver/common/step_find_vdi.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ import (
)

type StepFindVdi struct {
VdiName string
ImagePathFunc func() string
VdiUuidKey string
VdiName string
VdiUuidKey string
PreviousResult string
PreviousStepAction multistep.StepAction
ErrorFunc func(errString string) multistep.StepAction
}

func (self *StepFindVdi) ErrorHandler(msg string) multistep.StepAction {
self.PreviousResult = "FAILURE"
self.PreviousStepAction = self.ErrorFunc(msg)
return self.PreviousStepAction
}

func (self *StepFindVdi) Run(state multistep.StateBag) multistep.StepAction {
Expand All @@ -22,27 +30,47 @@ func (self *StepFindVdi) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}

if self.PreviousResult != "" {
return self.PreviousStepAction
}

self.PreviousResult = "SUCCESS"
self.PreviousStepAction = multistep.ActionContinue

if self.ErrorFunc == nil {
self.ErrorFunc = func(errString string) multistep.StepAction {
ui.Error(errString)
return multistep.ActionHalt
}
}

if len(self.VdiName) >= 7 && self.VdiName[:7] == "uuid://" {
vdiUuid := self.VdiName[7:]
_, err := client.GetVdiByUuid(vdiUuid)
if err != nil {
return self.ErrorHandler(fmt.Sprintf("Unable to get VDI from UUID '%s': %s", vdiUuid, err.Error()))
}
state.Put(self.VdiUuidKey, vdiUuid)
return self.PreviousStepAction
}

vdis, err := client.GetVdiByNameLabel(self.VdiName)

switch {
case len(vdis) == 0:
ui.Error(fmt.Sprintf("Couldn't find a VDI named '%s'", self.VdiName))
return multistep.ActionHalt
return self.ErrorHandler(fmt.Sprintf("Couldn't find a VDI named '%s'", self.VdiName))
case len(vdis) > 1:
ui.Error(fmt.Sprintf("Found more than one VDI with name '%s'. Name must be unique", self.VdiName))
return multistep.ActionHalt
return self.ErrorHandler(fmt.Sprintf("Found more than one VDI with name '%s'. Name must be unique", self.VdiName))
}

vdi := vdis[0]

vdiUuid, err := vdi.GetUuid()
if err != nil {
ui.Error(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", self.VdiName, err.Error()))
return multistep.ActionHalt
return self.ErrorHandler(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", self.VdiName, err.Error()))
}
state.Put(self.VdiUuidKey, vdiUuid)

return multistep.ActionContinue
return self.PreviousStepAction
}

func (self *StepFindVdi) Cleanup(state multistep.StateBag) {}
36 changes: 26 additions & 10 deletions builder/xenserver/iso/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
errs, fmt.Errorf("Failed to parse install_timeout: %s", err))
}

if self.config.ISOName == "" {
if self.config.ISOUrl == "" && self.config.ISOName == "" {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Either iso_url or iso_name must be specified"))
}

if self.config.ISOUrl != "" {

// If ISO name is not specified, assume a URL and checksum has been provided.

Expand Down Expand Up @@ -162,10 +166,6 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
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 {
Expand Down Expand Up @@ -210,6 +210,25 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
},
}

step_find_vdi_iso_name := &xscommon.StepFindVdi{
VdiName: self.config.ISOName,
VdiUuidKey: "isoname_vdi_uuid",
ErrorFunc: func(errString string) multistep.StepAction {
ui.Error(errString)
ui.Error("Defaulting to use \"iso_url\".")
return multistep.ActionContinue
},
}

step_find_vdi_iso_name_runner := &multistep.BasicRunner{Steps: []multistep.Step{
step_find_vdi_iso_name,
}}
step_find_vdi_iso_name_runner.Run(state)

if step_find_vdi_iso_name.PreviousResult == "FAILURE" && self.config.ISOUrl == "" {
return nil, errors.New(fmt.Sprintf("Failed to find \"iso_name\": \"%s\" and \"iso_url\" is empty. Aborting.", self.config.ISOName))
}

steps := []multistep.Step{
&xscommon.StepPrepareOutputDir{
Force: self.config.PackerForce,
Expand Down Expand Up @@ -252,10 +271,7 @@ 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",
},
step_find_vdi_iso_name,
new(stepCreateInstance),
&xscommon.StepAttachVdi{
VdiUuidKey: "floppy_vdi_uuid",
Expand Down Expand Up @@ -320,7 +336,7 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
new(xscommon.StepExport),
}

if self.config.ISOName == "" {
if self.config.ISOName == "" || (self.config.ISOUrl != "" && step_find_vdi_iso_name.PreviousResult == "FAILURE") {
steps = append(download_steps, steps...)
}

Expand Down
2 changes: 1 addition & 1 deletion builder/xenserver/iso/step_create_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (self *stepCreateInstance) Run(state multistep.StateBag) multistep.StepActi
// Clone that VM template
instance, err := template.Clone(config.VMName)
if err != nil {
ui.Error(fmt.Sprintf("Error cloning VM: %s", err.Error()))
ui.Error(fmt.Sprintf("Error cloning template: %s", err.Error()))
return multistep.ActionHalt
}
self.instance = instance
Expand Down
38 changes: 23 additions & 15 deletions docs/builders/xenserver-iso.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,29 @@ each category, the available options are alphabetized and described.

### Required:

* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
files are so large, this is required and Packer will verify it prior
to booting a virtual machine with the ISO attached. The type of the
checksum is specified with `iso_checksum_type`, documented below.

* `iso_checksum_type` (string) - The type of the checksum specified in
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
"sha512" currently. While "none" will skip checksumming, this is not
recommended since ISO files are generally large and corruption does happen
from time to time.

* `iso_url` (string) - A URL to the ISO containing the installation image.
This URL can be either an HTTP URL or a file URL (or path to a file).
If this is an HTTP URL, Packer will download it and cache it between
runs.
* Either:

* `iso_name` (string) - Unique name of an ISO available in XenCenter's storage repositories.
Or it can be the UUID of the ISO's VDI prefixed by "uuid://". For example: "uuid://aa2f2c86-b79a-4345-a35f-ce244f43c97a".
If this fails and `iso_url` is given, `iso_url` will be tried.

* OR:

* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
files are so large, this is required and Packer will verify it prior
to booting a virtual machine with the ISO attached. The type of the
checksum is specified with `iso_checksum_type`, documented below.

* `iso_checksum_type` (string) - The type of the checksum specified in
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
"sha512" currently. While "none" will skip checksumming, this is not
recommended since ISO files are generally large and corruption does happen
from time to time.

* `iso_url` (string) - A URL to the ISO containing the installation image.
This URL can be either an HTTP URL or a file URL (or path to a file).
If this is an HTTP URL, Packer will download it and cache it between
runs.

* `remote_host` (string) - The host of the remote machine.

Expand Down