Merge pull request #2748 from vtolstov/qcow2

add shrink step for qcow2 image format
This commit is contained in:
Mark Peek 2015-10-31 18:13:04 -07:00
commit c2fd83e04c
3 changed files with 81 additions and 0 deletions

View File

@ -88,6 +88,8 @@ type Config struct {
DiskSize uint `mapstructure:"disk_size"` DiskSize uint `mapstructure:"disk_size"`
DiskCache string `mapstructure:"disk_cache"` DiskCache string `mapstructure:"disk_cache"`
DiskDiscard string `mapstructure:"disk_discard"` DiskDiscard string `mapstructure:"disk_discard"`
SkipCompaction bool `mapstructure:"skip_compaction"`
DiskCompression bool `mapstructure:"disk_compression"`
FloppyFiles []string `mapstructure:"floppy_files"` FloppyFiles []string `mapstructure:"floppy_files"`
Format string `mapstructure:"format"` Format string `mapstructure:"format"`
Headless bool `mapstructure:"headless"` Headless bool `mapstructure:"headless"`
@ -242,6 +244,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed")) errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed"))
} }
if b.config.Format != "qcow2" {
b.config.SkipCompaction = true
b.config.DiskCompression = false
}
if _, ok := accels[b.config.Accelerator]; !ok { if _, ok := accels[b.config.Accelerator]; !ok {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed")) errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed"))
@ -364,6 +371,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
}, },
new(common.StepProvision), new(common.StepProvision),
new(stepShutdown), new(stepShutdown),
new(stepConvertDisk),
} }
// Setup the state bag // Setup the state bag

View File

@ -0,0 +1,67 @@
package qemu
import (
"fmt"
"path/filepath"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"os"
)
// This step converts the virtual disk that was used as the
// hard drive for the virtual machine.
type stepConvertDisk struct{}
func (s *stepConvertDisk) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
driver := state.Get("driver").(Driver)
diskName := state.Get("disk_filename").(string)
ui := state.Get("ui").(packer.Ui)
if config.SkipCompaction && !config.DiskCompression {
return multistep.ActionContinue
}
name := diskName + ".convert"
sourcePath := filepath.Join(config.OutputDir, diskName)
targetPath := filepath.Join(config.OutputDir, name)
command := []string{
"convert",
"-q",
}
if config.DiskCompression {
command = append(command, "-c")
}
command = append(command, []string{
"-f", config.Format,
"-O", config.Format,
sourcePath,
targetPath,
}...,
)
ui.Say("Converting hard drive...")
if err := driver.QemuImg(command...); err != nil {
err := fmt.Errorf("Error converting hard drive: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if err := os.Rename(targetPath, sourcePath); err != nil {
err := fmt.Errorf("Error moving converted hard drive: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *stepConvertDisk) Cleanup(state multistep.StateBag) {}

View File

@ -136,6 +136,12 @@ builder.
- `disk_size` (integer) - The size, in megabytes, of the hard disk to create - `disk_size` (integer) - The size, in megabytes, of the hard disk to create
for the VM. By default, this is 40000 (about 40 GB). for the VM. By default, this is 40000 (about 40 GB).
- `skip_compaction` (boolean) - Packer compacts the QCOW2 image using `qemu-img convert`.
Set this option to `true` to disable compacting. Defaults to `false`.
- `disk_compression` (boolean) - Apply compression to the QCOW2 disk file
using `qemu-img convert`. Defaults to `false`.
- `floppy_files` (array of strings) - A list of files to place onto a floppy - `floppy_files` (array of strings) - A list of files to place onto a floppy
disk that is attached when the VM is booted. This is most useful for disk that is attached when the VM is booted. This is most useful for
unattended Windows installs, which look for an `Autounattend.xml` file on unattended Windows installs, which look for an `Autounattend.xml` file on