From d7268a11f74bc2a142153e8fc21fe4d33f1437e8 Mon Sep 17 00:00:00 2001 From: iweb Date: Thu, 17 Jul 2014 15:01:19 +0100 Subject: [PATCH 1/2] Add support for building QEMU images from pre-existing image files If the `disk_image` parameter is set to true treat the ISO location as the source of the disk image, copy it to the destination, resize and boot it. --- builder/qemu/builder.go | 3 +++ builder/qemu/step_copy_disk.go | 45 ++++++++++++++++++++++++++++++++ builder/qemu/step_create_disk.go | 4 +++ builder/qemu/step_resize_disk.go | 43 ++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 builder/qemu/step_copy_disk.go create mode 100644 builder/qemu/step_resize_disk.go diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 7f404a566..8479e0a03 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -61,6 +61,7 @@ type config struct { FloppyFiles []string `mapstructure:"floppy_files"` Format string `mapstructure:"format"` Headless bool `mapstructure:"headless"` + DiskImage bool `mapstructure:"disk_image"` HTTPDir string `mapstructure:"http_directory"` HTTPPortMin uint `mapstructure:"http_port_min"` HTTPPortMax uint `mapstructure:"http_port_max"` @@ -396,6 +397,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Files: b.config.FloppyFiles, }, new(stepCreateDisk), + new(stepCopyDisk), + new(stepResizeDisk), new(stepHTTPServer), new(stepForwardSSH), new(stepConfigureVNC), diff --git a/builder/qemu/step_copy_disk.go b/builder/qemu/step_copy_disk.go new file mode 100644 index 000000000..c3645926b --- /dev/null +++ b/builder/qemu/step_copy_disk.go @@ -0,0 +1,45 @@ +package qemu + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "path/filepath" + "strings" +) + +// This step copies the virtual disk that will be used as the +// hard drive for the virtual machine. +type stepCopyDisk struct{} + +func (s *stepCopyDisk) Run(state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*config) + driver := state.Get("driver").(Driver) + isoPath := state.Get("iso_path").(string) + ui := state.Get("ui").(packer.Ui) + path := filepath.Join(config.OutputDir, fmt.Sprintf("%s.%s", config.VMName, + strings.ToLower(config.Format))) + + command := []string{ + "convert", + "-f", config.Format, + isoPath, + path, + } + + if config.DiskImage == false { + return multistep.ActionContinue + } + + ui.Say("Copying hard drive...") + if err := driver.QemuImg(command...); err != nil { + err := fmt.Errorf("Error creating hard drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepCopyDisk) Cleanup(state multistep.StateBag) {} diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index 7e6f09b7d..7545a19f0 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -26,6 +26,10 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { fmt.Sprintf("%vM", config.DiskSize), } + if config.DiskImage == true { + return multistep.ActionContinue + } + ui.Say("Creating hard drive...") if err := driver.QemuImg(command...); err != nil { err := fmt.Errorf("Error creating hard drive: %s", err) diff --git a/builder/qemu/step_resize_disk.go b/builder/qemu/step_resize_disk.go new file mode 100644 index 000000000..d81a4f127 --- /dev/null +++ b/builder/qemu/step_resize_disk.go @@ -0,0 +1,43 @@ +package qemu + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "path/filepath" + "strings" +) + +// This step resizes the virtual disk that will be used as the +// hard drive for the virtual machine. +type stepResizeDisk struct{} + +func (s *stepResizeDisk) Run(state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*config) + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + path := filepath.Join(config.OutputDir, fmt.Sprintf("%s.%s", config.VMName, + strings.ToLower(config.Format))) + + command := []string{ + "resize", + path, + fmt.Sprintf("%vM", config.DiskSize), + } + + if config.DiskImage == false { + return multistep.ActionContinue + } + + ui.Say("Resizing hard drive...") + if err := driver.QemuImg(command...); err != nil { + err := fmt.Errorf("Error creating hard drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepResizeDisk) Cleanup(state multistep.StateBag) {} From ddd794c38ed574a984561f1752618c67b990a99e Mon Sep 17 00:00:00 2001 From: Aaron Brady Date: Thu, 17 Jul 2014 15:30:54 +0100 Subject: [PATCH 2/2] Update QEMU builder documentation with `disk_image` flag --- website/source/docs/builders/qemu.html.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/source/docs/builders/qemu.html.markdown b/website/source/docs/builders/qemu.html.markdown index 2430c737f..c757b5fb8 100644 --- a/website/source/docs/builders/qemu.html.markdown +++ b/website/source/docs/builders/qemu.html.markdown @@ -248,6 +248,11 @@ each category, the available options are alphabetized and described. Packer will choose a randomly available port in this range to use as the host port. +* `disk_image` (boolean) - Packer defaults to building from an ISO file, + this parameter controls whether the ISO URL supplied is actually a bootable + QEMU image. When this value is set to true, the machine will clone the + source, resize it according to `disk_size` and boot the image. + ## Boot Command The `boot_command` configuration is very important: it specifies the keys