diff --git a/builder/qemu/artifact.go b/builder/qemu/artifact.go index 1dea61c68..ac841df08 100644 --- a/builder/qemu/artifact.go +++ b/builder/qemu/artifact.go @@ -8,8 +8,9 @@ import ( // Artifact is the result of running the Qemu builder, namely a set // of files associated with the resulting machine. type Artifact struct { - dir string - f []string + dir string + f []string + state map[string]interface{} } func (*Artifact) BuilderId() string { @@ -29,7 +30,7 @@ func (a *Artifact) String() string { } func (a *Artifact) State(name string) interface{} { - return nil + return a.state[name] } func (a *Artifact) Destroy() error { diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 971613dd8..ef74fa17e 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -481,8 +481,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe artifact := &Artifact{ dir: b.config.OutputDir, f: files, + state: make(map[string]interface{}), } + artifact.state["diskName"] = state.Get("disk_filename").(string) + artifact.state["diskType"] = b.config.Format + artifact.state["diskSize"] = uint64(b.config.DiskSize) + artifact.state["domainType"] = b.config.Accelerator + return artifact, nil } diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index 7e6f09b7d..4cd98904a 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -16,8 +16,8 @@ func (s *stepCreateDisk) 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))) + name := config.VMName + "." + strings.ToLower(config.Format) + path := filepath.Join(config.OutputDir, name) command := []string{ "create", @@ -34,6 +34,8 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } + state.Put("disk_filename", name) + return multistep.ActionContinue } diff --git a/post-processor/vagrant/libvirt.go b/post-processor/vagrant/libvirt.go new file mode 100644 index 000000000..6ab0b3900 --- /dev/null +++ b/post-processor/vagrant/libvirt.go @@ -0,0 +1,64 @@ +package vagrant + +import ( + "fmt" + "github.com/mitchellh/packer/packer" + "path/filepath" + "strings" +) + +type LibVirtProvider struct{} + +func (p *LibVirtProvider) KeepInputArtifact() bool { + return false +} +func (p *LibVirtProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + diskName := artifact.State("diskName").(string) + + // Copy the disk image into the temporary directory (as box.img) + for _, path := range artifact.Files() { + if strings.HasSuffix(path, "/"+diskName) { + ui.Message(fmt.Sprintf("Copying from artifact: %s", path)) + dstPath := filepath.Join(dir, "box.img") + if err = CopyContents(dstPath, path); err != nil { + return + } + } + } + + format := artifact.State("diskType").(string) + origSize := artifact.State("diskSize").(uint64) + size := origSize / 1024 // In MB, want GB + if origSize % 1024 > 0 { + // Make sure we don't make the size smaller + size++ + } + domainType := artifact.State("domainType").(string) + + // Convert domain type to libvirt driver + var driver string + switch domainType { + case "kvm", "qemu": + driver = domainType + default: + return "", nil, fmt.Errorf("Unknown libvirt domain type: %s", domainType) + } + + // Create the metadata + metadata = map[string]interface{}{ + "provider": "libvirt", + "format": format, + "virtual_size": size, + } + + vagrantfile = fmt.Sprintf(libvirtVagrantfile, driver) + return +} + +var libvirtVagrantfile = ` +Vagrant.configure("2") do |config| + config.vm.provider :libvirt do |libvirt| + libvirt.driver = "%s" + end +end +` diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 8fb486edb..bdf1cf2cf 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -23,6 +23,7 @@ var builtins = map[string]string{ "pearkes.digitalocean": "digitalocean", "packer.parallels": "parallels", "MSOpenTech.hyperv": "hyperv", + "transcend.qemu": "libvirt", } type Config struct { @@ -223,6 +224,8 @@ func providerForName(name string) Provider { return new(ParallelsProvider) case "hyperv": return new(HypervProvider) + case "libvirt": + return new(LibVirtProvider) default: return nil }