add convert step for qcow2 image format

https://ext4.wiki.kernel.org/index.php/Ext4_VM_Images does not
recommends to dd zero file and deletes it, but in case of enabling
discards and qcow2 image we can recreate qcow2 file with less used
space.
Also qemu-img able to enable compression for qcow2 files, that
sometimes may be useful because it natively supported by qemu.

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Vasiliy Tolstov 2015-10-29 10:54:25 +00:00
parent df8f88b3d1
commit 8e1cc16ab5
3 changed files with 81 additions and 0 deletions

View File

@ -88,6 +88,8 @@ type Config struct {
DiskSize uint `mapstructure:"disk_size"`
DiskCache string `mapstructure:"disk_cache"`
DiskDiscard string `mapstructure:"disk_discard"`
SkipCompaction bool `mapstructure:"skip_compaction"`
DiskCompression bool `mapstructure:"disk_compression"`
FloppyFiles []string `mapstructure:"floppy_files"`
Format string `mapstructure:"format"`
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"))
}
if b.config.Format != "qcow2" {
b.config.SkipCompaction = true
b.config.DiskCompression = false
}
if _, ok := accels[b.config.Accelerator]; !ok {
errs = packer.MultiErrorAppend(
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(stepShutdown),
new(stepConvertDisk),
}
// 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
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
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