Commit 60e608df authored by Julian Phillips's avatar Julian Phillips

Add support for vagrant with qemu

Once we have produced a qemu VM, we now have the option of using
the vagrant post-processor to create a .box file that can be used with
the vagrant-libvirt plugin.

This uses the new State method of the Artifact API to get necessary
information from the builder.
parent 90a57c41
......@@ -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 {
......
......@@ -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
}
......
......@@ -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
}
......
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
`
......@@ -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
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment