Merge pull request #29 from robertbreker/add-travis-ci
Add Travis CI support.
This commit is contained in:
commit
e4f94fcc21
7
.travis.yml
Normal file
7
.travis.yml
Normal file
@ -0,0 +1,7 @@
|
||||
language: go
|
||||
go:
|
||||
# Test with the first and the latest go release - to ensure compatibility
|
||||
- 1
|
||||
- release
|
||||
script:
|
||||
- gofmtresult=$(gofmt -s -l .); if [[ -n $gofmtresult ]]; then echo -e "Please run \"gofmt -s -w .\" before committing for the below:\n$gofmtresult"; false; fi
|
@ -1,3 +1,5 @@
|
||||
[![Build Status](https://travis-ci.org/rdobson/packer-builder-xenserver?branch=master)](https://travis-ci.org/rdobson/packer-builder-xenserver)
|
||||
|
||||
# XenServer packer.io builder
|
||||
|
||||
This builder plugin extends packer.io to support building images for XenServer.
|
||||
|
@ -51,7 +51,7 @@ type CommonConfig struct {
|
||||
OutputDir string `mapstructure:"output_directory"`
|
||||
Format string `mapstructure:"format"`
|
||||
KeepVM string `mapstructure:"keep_vm"`
|
||||
IPGetter string `mapstructure:"ip_getter"`
|
||||
IPGetter string `mapstructure:"ip_getter"`
|
||||
}
|
||||
|
||||
func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error {
|
||||
@ -125,9 +125,9 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig
|
||||
c.KeepVM = "never"
|
||||
}
|
||||
|
||||
if c.IPGetter == "" {
|
||||
c.IPGetter = "auto"
|
||||
}
|
||||
if c.IPGetter == "" {
|
||||
c.IPGetter = "auto"
|
||||
}
|
||||
|
||||
// Template substitution
|
||||
|
||||
@ -149,7 +149,7 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig
|
||||
"output_directory": &c.OutputDir,
|
||||
"format": &c.Format,
|
||||
"keep_vm": &c.KeepVM,
|
||||
"ip_getter": &c.IPGetter,
|
||||
"ip_getter": &c.IPGetter,
|
||||
}
|
||||
for i := range c.FloppyFiles {
|
||||
templates[fmt.Sprintf("floppy_files[%d]", i)] = &c.FloppyFiles[i]
|
||||
@ -233,11 +233,11 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig
|
||||
errs = append(errs, errors.New("keep_vm must be one of 'always', 'never', 'on_success'"))
|
||||
}
|
||||
|
||||
switch c.IPGetter {
|
||||
case "auto", "tools", "http":
|
||||
default:
|
||||
errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'"))
|
||||
}
|
||||
switch c.IPGetter {
|
||||
case "auto", "tools", "http":
|
||||
default:
|
||||
errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'"))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
@ -17,10 +17,10 @@ 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
|
||||
}
|
||||
// Ignore if VdiName is not specified
|
||||
if self.VdiName == "" {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
vdis, err := client.GetVdiByNameLabel(self.VdiName)
|
||||
|
||||
|
@ -22,7 +22,7 @@ func (self *StepUploadVdi) Run(state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(xsclient.XenAPIClient)
|
||||
|
||||
imagePath := self.ImagePathFunc()
|
||||
vdiName := self.VdiNameFunc()
|
||||
vdiName := self.VdiNameFunc()
|
||||
if imagePath == "" {
|
||||
// skip if no disk image to attach
|
||||
return multistep.ActionContinue
|
||||
@ -84,7 +84,7 @@ func (self *StepUploadVdi) Cleanup(state multistep.StateBag) {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("client").(xsclient.XenAPIClient)
|
||||
|
||||
vdiName := self.VdiNameFunc()
|
||||
vdiName := self.VdiNameFunc()
|
||||
|
||||
if config.ShouldKeepVM(state) {
|
||||
return
|
||||
|
@ -18,7 +18,7 @@ type StepWaitForIP struct {
|
||||
func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("client").(xsclient.XenAPIClient)
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
|
||||
ui.Say("Step: Wait for VM's IP to become known to us.")
|
||||
|
||||
@ -35,36 +35,36 @@ func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction {
|
||||
PredicateInterval: 5 * time.Second,
|
||||
Predicate: func() (result bool, err error) {
|
||||
|
||||
if (config.IPGetter == "auto" || config.IPGetter == "http") {
|
||||
if config.IPGetter == "auto" || config.IPGetter == "http" {
|
||||
|
||||
// Snoop IP from HTTP fetch
|
||||
select {
|
||||
case ip = <-self.Chan:
|
||||
ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip))
|
||||
return true, nil
|
||||
default:
|
||||
}
|
||||
// Snoop IP from HTTP fetch
|
||||
select {
|
||||
case ip = <-self.Chan:
|
||||
ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip))
|
||||
return true, nil
|
||||
default:
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (config.IPGetter == "auto" || config.IPGetter == "tools") {
|
||||
if config.IPGetter == "auto" || config.IPGetter == "tools" {
|
||||
|
||||
// Look for PV IP
|
||||
metrics, err := instance.GetGuestMetrics()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if metrics != nil {
|
||||
networks := metrics["networks"].(xmlrpc.Struct)
|
||||
if ipRaw, ok := networks["0/ip"]; ok {
|
||||
if ip = ipRaw.(string); ip != "" {
|
||||
ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip))
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look for PV IP
|
||||
metrics, err := instance.GetGuestMetrics()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if metrics != nil {
|
||||
networks := metrics["networks"].(xmlrpc.Struct)
|
||||
if ipRaw, ok := networks["0/ip"]; ok {
|
||||
if ip = ipRaw.(string); ip != "" {
|
||||
ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip))
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
},
|
||||
|
@ -27,7 +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"`
|
||||
ISOName string `mapstructure:"iso_name"`
|
||||
|
||||
PlatformArgs map[string]string `mapstructure:"platform_args"`
|
||||
|
||||
@ -96,7 +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,
|
||||
"iso_name": &self.config.ISOName,
|
||||
"install_timeout": &self.config.RawInstallTimeout,
|
||||
}
|
||||
for i := range self.config.ISOUrls {
|
||||
@ -119,55 +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.ISOName == "" {
|
||||
if self.config.ISOName == "" {
|
||||
|
||||
// If ISO name is not specified, assume a URL and checksum has been provided.
|
||||
// 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 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 hash := common.HashForType(self.config.ISOChecksumType); hash == nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
|
||||
}
|
||||
if hash := common.HashForType(self.config.ISOChecksumType); hash == nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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 {
|
||||
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.
|
||||
// An ISO name has been provided. It should be attached from an available SR.
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs.Errors) > 0 {
|
||||
retErr = errors.New(errs.Error())
|
||||
@ -201,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
|
||||
download_steps := []multistep.Step{
|
||||
download_steps := []multistep.Step{
|
||||
&common.StepDownload{
|
||||
Checksum: self.config.ISOChecksum,
|
||||
ChecksumType: self.config.ISOChecksumType,
|
||||
@ -209,7 +209,7 @@ 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{
|
||||
@ -224,8 +224,8 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
},
|
||||
&xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
return "Packer-floppy-disk"
|
||||
},
|
||||
return "Packer-floppy-disk"
|
||||
},
|
||||
ImagePathFunc: func() string {
|
||||
if floppyPath, ok := state.GetOk("floppy_path"); ok {
|
||||
return floppyPath.(string)
|
||||
@ -235,17 +235,17 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
if len(self.config.ISOUrls) > 0 {
|
||||
return path.Base(self.config.ISOUrls[0])
|
||||
}
|
||||
return ""
|
||||
},
|
||||
VdiNameFunc: func() string {
|
||||
if len(self.config.ISOUrls) > 0 {
|
||||
return path.Base(self.config.ISOUrls[0])
|
||||
}
|
||||
return ""
|
||||
},
|
||||
ImagePathFunc: func() string {
|
||||
if isoPath, ok := state.GetOk("iso_path"); ok {
|
||||
return isoPath.(string)
|
||||
}
|
||||
return ""
|
||||
if isoPath, ok := state.GetOk("iso_path"); ok {
|
||||
return isoPath.(string)
|
||||
}
|
||||
return ""
|
||||
},
|
||||
VdiUuidKey: "iso_vdi_uuid",
|
||||
},
|
||||
@ -253,10 +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",
|
||||
},
|
||||
&xscommon.StepFindVdi{
|
||||
VdiName: self.config.ISOName,
|
||||
VdiUuidKey: "isoname_vdi_uuid",
|
||||
},
|
||||
new(stepCreateInstance),
|
||||
&xscommon.StepAttachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
@ -266,10 +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: "isoname_vdi_uuid",
|
||||
VdiType: xsclient.CD,
|
||||
},
|
||||
&xscommon.StepAttachVdi{
|
||||
VdiUuidKey: "tools_vdi_uuid",
|
||||
VdiType: xsclient.CD,
|
||||
@ -325,10 +325,9 @@ 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...)
|
||||
}
|
||||
|
||||
if self.config.ISOName == "" {
|
||||
steps = append(download_steps, steps...)
|
||||
}
|
||||
|
||||
self.runner = &multistep.BasicRunner{Steps: steps}
|
||||
self.runner.Run(state)
|
||||
|
@ -128,8 +128,8 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
||||
new(xscommon.StepHTTPServer),
|
||||
&xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
return "Packer-floppy-disk"
|
||||
},
|
||||
return "Packer-floppy-disk"
|
||||
},
|
||||
ImagePathFunc: func() string {
|
||||
if floppyPath, ok := state.GetOk("floppy_path"); ok {
|
||||
return floppyPath.(string)
|
||||
|
Loading…
Reference in New Issue
Block a user