Merge pull request #2422 from vtolstov/qemu

fix qemu driver and builder
This commit is contained in:
Mark Peek 2015-10-06 21:30:38 -07:00
commit a3a7c974d0
3 changed files with 54 additions and 16 deletions

View File

@ -54,9 +54,10 @@ var netDevice = map[string]bool{
}
var diskInterface = map[string]bool{
"ide": true,
"scsi": true,
"virtio": true,
"ide": true,
"scsi": true,
"virtio": true,
"virtio-scsi": true,
}
var diskCache = map[string]bool{

View File

@ -4,7 +4,6 @@ import (
"bufio"
"bytes"
"fmt"
"github.com/mitchellh/multistep"
"io"
"log"
"os/exec"
@ -14,6 +13,8 @@ import (
"syscall"
"time"
"unicode"
"github.com/mitchellh/multistep"
)
type DriverCancelCallback func(state multistep.StateBag) bool
@ -188,8 +189,8 @@ func (d *QemuDriver) Version() (string, error) {
versionOutput := strings.TrimSpace(stdout.String())
log.Printf("Qemu --version output: %s", versionOutput)
versionRe := regexp.MustCompile("qemu-kvm-[0-9]\\.[0-9]")
matches := versionRe.Split(versionOutput, 2)
versionRe := regexp.MustCompile("[\\.[0-9]+]*")
matches := versionRe.FindStringSubmatch(versionOutput)
if len(matches) == 0 {
return "", fmt.Errorf("No version found: %s", versionOutput)
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"log"
"path/filepath"
"strconv"
"strings"
"github.com/mitchellh/multistep"
@ -62,27 +63,57 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error
vncPort := state.Get("vnc_port").(uint)
sshHostPort := state.Get("sshHostPort").(uint)
ui := state.Get("ui").(packer.Ui)
driver := state.Get("driver").(Driver)
vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900)
vmName := config.VMName
imgPath := filepath.Join(config.OutputDir, vmName)
defaultArgs := make(map[string]string)
defaultArgs := make(map[string]interface{})
var deviceArgs []string
var driveArgs []string
defaultArgs["-name"] = vmName
defaultArgs["-machine"] = fmt.Sprintf("type=%s", config.MachineType)
defaultArgs["-netdev"] = fmt.Sprintf("user,id=user.0,hostfwd=tcp::%v-:%d", sshHostPort, config.Comm.Port())
qemuVersion, err := driver.Version()
if err != nil {
return nil, err
}
parts := strings.Split(qemuVersion, ".")
qemuMajor, err := strconv.Atoi(parts[0])
if err != nil {
return nil, err
}
if qemuMajor >= 2 {
if config.DiskInterface == "virtio-scsi" {
deviceArgs = append(deviceArgs, "virtio-scsi-pci,id=scsi0", "scsi-hd,bus=scsi0.0,drive=drive0")
driveArgs = append(driveArgs, fmt.Sprintf("if=none,file=%s,id=drive0,cache=%s,discard=%s", imgPath, config.DiskCache, config.DiskDiscard))
} else {
driveArgs = append(driveArgs, fmt.Sprintf("file=%s,if=%s,cache=%s,discard=%s", imgPath, config.DiskInterface, config.DiskCache, config.DiskDiscard))
}
} else {
defaultArgs["-drive"] = fmt.Sprintf("file=%s,if=%s,cache=%s", imgPath, config.DiskInterface, config.DiskCache)
}
deviceArgs = append(deviceArgs, fmt.Sprintf("%s,netdev=user.0", config.NetDevice))
if config.Headless == true {
ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" +
"In headless mode, errors during the boot sequence or OS setup\n" +
"won't be easily visible. Use at your own discretion.")
} else {
defaultArgs["-display"] = "sdl"
if qemuMajor >= 2 {
defaultArgs["-display"] = "sdl"
} else {
ui.Message("WARNING: The version of qemu on your host doesn't support display mode.\n" +
"The display parameter will be ignored.")
}
}
defaultArgs["-name"] = vmName
defaultArgs["-machine"] = fmt.Sprintf("type=%s", config.MachineType)
defaultArgs["-netdev"] = fmt.Sprintf(
"user,id=user.0,hostfwd=tcp::%v-:%d", sshHostPort, config.Comm.Port())
defaultArgs["-device"] = fmt.Sprintf("%s,netdev=user.0", config.NetDevice)
defaultArgs["-drive"] = fmt.Sprintf("file=%s,if=%s,cache=%s,discard=%s", imgPath, config.DiskInterface, config.DiskCache, config.DiskDiscard)
defaultArgs["-device"] = deviceArgs
defaultArgs["-drive"] = driveArgs
if !config.DiskImage {
defaultArgs["-cdrom"] = isoPath
}
@ -92,7 +123,7 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error
// Append the accelerator to the machine type if it is specified
if config.Accelerator != "none" {
defaultArgs["-machine"] += fmt.Sprintf(",accel=%s", config.Accelerator)
defaultArgs["-machine"] = fmt.Sprintf("%s,accel=%s", defaultArgs["-machine"], config.Accelerator)
} else {
ui.Message("WARNING: The VM will be started with no hardware acceleration.\n" +
"The installation may take considerably longer to finish.\n")
@ -142,7 +173,12 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error
for key := range defaultArgs {
if _, ok := inArgs[key]; !ok {
arg := make([]string, 1)
arg[0] = defaultArgs[key]
switch defaultArgs[key].(type) {
case string:
arg[0] = defaultArgs[key].(string)
case []string:
arg = defaultArgs[key].([]string)
}
inArgs[key] = arg
}
}