Commit 2f8f2d5a authored by Tom Hite's avatar Tom Hite

Fixes #1 and Fixes #2 by allowing qemuargs to operate and override defaults.

parent ba1ca4d2
...@@ -17,14 +17,27 @@ import ( ...@@ -17,14 +17,27 @@ import (
const BuilderId = "transcend.qemu" const BuilderId = "transcend.qemu"
var netDevice = map[string]bool{ var netDevice = map[string]bool{
"ne2k_pci": true, "ne2k_pci": true,
"i82551": true, "i82551": true,
"i82557b": true, "i82557b": true,
"i82559er": true, "i82559er": true,
"rtl8139": true, "rtl8139": true,
"e1000": true, "e1000": true,
"pcnet": true, "pcnet": true,
"virtio": true, "virtio": true,
"virtio-net": true,
"usb-net": true,
"i82559a": true,
"i82559b": true,
"i82559c": true,
"i82550": true,
"i82562": true,
"i82557a": true,
"i82557c": true,
"i82801": true,
"vmxnet3": true,
"i82558a": true,
"i82558b": true,
} }
var diskInterface = map[string]bool{ var diskInterface = map[string]bool{
......
...@@ -35,16 +35,13 @@ func cancelCallback(state multistep.StateBag) bool { ...@@ -35,16 +35,13 @@ func cancelCallback(state multistep.StateBag) bool {
return cancel return cancel
} }
func (s *stepRun) runVM( func (s *stepRun) getCommandArgs(
sendBootCommands bool,
bootDrive string, bootDrive string,
state multistep.StateBag) multistep.StepAction { state multistep.StateBag) []string {
config := state.Get("config").(*config)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(*config)
vmName := config.VMName vmName := config.VMName
imgPath := filepath.Join(config.OutputDir, imgPath := filepath.Join(config.OutputDir,
fmt.Sprintf("%s.%s", vmName, strings.ToLower(config.Format))) fmt.Sprintf("%s.%s", vmName, strings.ToLower(config.Format)))
isoPath := state.Get("iso_path").(string) isoPath := state.Get("iso_path").(string)
...@@ -53,7 +50,6 @@ func (s *stepRun) runVM( ...@@ -53,7 +50,6 @@ func (s *stepRun) runVM(
sshHostPort := state.Get("sshHostPort").(uint) sshHostPort := state.Get("sshHostPort").(uint)
vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900) vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900)
ui.Say("Starting the virtual machine for OS Install...")
if config.Headless == true { if config.Headless == true {
ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" + 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" + "In headless mode, errors during the boot sequence or OS setup\n" +
...@@ -61,19 +57,74 @@ func (s *stepRun) runVM( ...@@ -61,19 +57,74 @@ func (s *stepRun) runVM(
guiArgument = "none" guiArgument = "none"
} }
command := []string{ defaultArgs := make(map[string]string)
"-name", vmName, defaultArgs["-name"] = vmName
"-machine", fmt.Sprintf("type=pc-1.0,accel=%s", config.Accelerator), defaultArgs["-machine"] = fmt.Sprintf("type=pc-1.0,accel=%s", config.Accelerator)
"-display", guiArgument, defaultArgs["-display"] = guiArgument
"-net", fmt.Sprintf("nic,model=%s", config.NetDevice), defaultArgs["-netdev"] = "user,id=user.0"
"-net", "user", defaultArgs["-device"] = fmt.Sprintf("%s,netdev=user.0", config.NetDevice)
"-drive", fmt.Sprintf("file=%s,if=%s", imgPath, config.DiskInterface), defaultArgs["-drive"] = fmt.Sprintf("file=%s,if=%s", imgPath, config.DiskInterface)
"-cdrom", isoPath, defaultArgs["-cdrom"] = isoPath
"-boot", bootDrive, defaultArgs["-boot"] = bootDrive
"-m", "512m", defaultArgs["-m"] = "512m"
"-redir", fmt.Sprintf("tcp:%v::22", sshHostPort), defaultArgs["-redir"] = fmt.Sprintf("tcp:%v::22", sshHostPort)
"-vnc", vnc, defaultArgs["-vnc"] = vnc
inArgs := make(map[string][]string)
if len(config.QemuArgs) > 0 {
ui.Say("Overriding defaults Qemu arguments with QemuArgs...")
// becuase qemu supports multiple appearances of the same
// switch, just different values, each key in the args hash
// will have an array of string values
for _, qemuArgs := range config.QemuArgs {
key := qemuArgs[0]
val := strings.Join(qemuArgs[1:], "")
if _, ok := inArgs[key]; !ok {
inArgs[key] = make([]string, 0)
}
if len(val) > 0 {
inArgs[key] = append(inArgs[key], val)
}
}
}
// get any remaining missing default args from the default settings
for key := range defaultArgs {
if _, ok := inArgs[key]; !ok {
arg := make([]string, 1)
arg[0] = defaultArgs[key]
inArgs[key] = arg
}
}
// Flatten to array of strings
outArgs := make([]string, 0)
for key, values := range inArgs {
if len(values) > 0 {
for idx := range values {
outArgs = append(outArgs, key, values[idx])
}
} else {
outArgs = append(outArgs, key)
}
} }
return outArgs
}
func (s *stepRun) runVM(
sendBootCommands bool,
bootDrive string,
state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*config)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmName := config.VMName
ui.Say("Starting the virtual machine for OS Install...")
command := s.getCommandArgs(bootDrive, state)
if err := driver.Qemu(vmName, command...); err != nil { if err := driver.Qemu(vmName, command...); err != nil {
err := fmt.Errorf("Error launching VM: %s", err) err := fmt.Errorf("Error launching VM: %s", err)
ui.Error(err.Error()) ui.Error(err.Error())
......
...@@ -223,7 +223,38 @@ Optional: ...@@ -223,7 +223,38 @@ Optional:
values "ne2k_pci," "i82551," "i82557b," "i82559er," "rtl8139," "e1000," values "ne2k_pci," "i82551," "i82557b," "i82559er," "rtl8139," "e1000,"
"pcnet" or "virtio." The Qemu builder uses "virtio" by default. "pcnet" or "virtio." The Qemu builder uses "virtio" by default.
* `qemuargs` (array of strings reserved for future use). * `qemuargs` (array of array of strings) - Allows complete control over
the qemu command line (though not, at this time, qemu-img). Each array
of strings makes up a command line switch that overrides matching default
switch/value pairs. Any value specified as an empty string is ignored.
All values after the switch are concatenated with no separater. For instance:
<pre class="prettyprint">
. . .
"qemuargs": [
[ "-m", "1024m" ],
[ "--no-acpi", "" ],
[
"-netdev",
"user,id=mynet0,",
"hostfwd=hostip:hostport-guestip:guestport",
""
],
[ "-device", "virtio-net,netdev=mynet0" ]
]
. . .
</pre>
would produce the following (not including other defaults supplied by the builder and not otherwise conflicting with the qemuargs):
<pre class="prettyprint">
qemu-system-x86 -m 1024m --no-acpi -netdev user,id=mynet0,hostfwd=hostip:hostport-guestip:guestport -device virtio-net,netdev=mynet0"
</pre>
Note that the qemu command line allows extreme flexibility, so beware of
conflicting arguments causing failures of your run. To see the defaults,
look in the packer.log file and search for the qemu-system-x86 command. The
arguments are all printed for review.
* `output_directory` (string) - This is the path to the directory where the * `output_directory` (string) - This is the path to the directory where the
resulting virtual machine will be created. This may be relative or absolute. resulting virtual machine will be created. This may be relative or absolute.
......
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