diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 942d28e93..66c78e45e 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -83,6 +83,7 @@ type Config struct { common.ISOConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` + ISOSkipCache bool `mapstructure:"iso_skip_cache"` Accelerator string `mapstructure:"accelerator"` BootCommand []string `mapstructure:"boot_command"` DiskInterface string `mapstructure:"disk_interface"` @@ -221,6 +222,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError warnings := make([]string, 0) + if b.config.ISOSkipCache { + b.config.ISOChecksumType = "none" + } + isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) @@ -326,8 +331,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steprun.Message = "Starting VM, booting disk image" } - steps := []multistep.Step{ - &common.StepDownload{ + steps := []multistep.Step{} + if !b.config.ISOSkipCache { + steps = append(steps, &common.StepDownload{ Checksum: b.config.ISOChecksum, ChecksumType: b.config.ISOChecksumType, Description: "ISO", @@ -336,7 +342,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, }, - new(stepPrepareOutputDir), + ) + } else { + steps = append(steps, &stepSetISO{ + ResultKey: "iso_path", + Url: b.config.ISOUrls, + }, + ) + } + + steps = append(steps, new(stepPrepareOutputDir), &common.StepCreateFloppy{ Files: b.config.FloppyFiles, }, @@ -362,7 +377,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(common.StepProvision), new(stepShutdown), new(stepConvertDisk), - } + ) // Setup the state bag state := new(multistep.BasicStateBag) diff --git a/builder/qemu/step_set_iso.go b/builder/qemu/step_set_iso.go new file mode 100644 index 000000000..eb39f1448 --- /dev/null +++ b/builder/qemu/step_set_iso.go @@ -0,0 +1,56 @@ +package qemu + +import ( + "fmt" + "net/http" + + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" +) + +// This step set iso_patch to available url +type stepSetISO struct { + ResultKey string + Url []string +} + +func (s *stepSetISO) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + iso_path := "" + + for _, url := range s.Url { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + continue + } + + req.Header.Set("User-Agent", "Packer") + + httpClient := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + }, + } + + res, err := httpClient.Do(req) + if err == nil && (res.StatusCode >= 200 && res.StatusCode < 300) { + if res.Header.Get("Accept-Ranges") == "bytes" { + iso_path = url + } + } + } + + if iso_path == "" { + err := fmt.Errorf("No byte serving support. The HTTP server must support Accept-Ranges=bytes") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + state.Put(s.ResultKey, iso_path) + + return multistep.ActionContinue +} + +func (s *stepSetISO) Cleanup(state multistep.StateBag) {} diff --git a/website/source/docs/builders/qemu.html.markdown b/website/source/docs/builders/qemu.html.markdown index 5cfc767d3..bc257efcf 100644 --- a/website/source/docs/builders/qemu.html.markdown +++ b/website/source/docs/builders/qemu.html.markdown @@ -173,10 +173,13 @@ builder. to force the HTTP server to be on one port, make this minimum and maximum port the same. By default the values are 8000 and 9000, respectively. +- `iso_skip_cache` (boolean) - Use iso from provided url. Qemu must support + curl block device. + - `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the original filename as its name. - + - `iso_urls` (array of strings) - Multiple URLs for the ISO to download. Packer will try these in order. If anything goes wrong attempting to download or while downloading a single URL, it will move on to the next. All