This commit is contained in:
parent
ba1ca4d2fb
commit
2f8f2d5ad1
|
@ -17,14 +17,27 @@ import (
|
|||
const BuilderId = "transcend.qemu"
|
||||
|
||||
var netDevice = map[string]bool{
|
||||
"ne2k_pci": true,
|
||||
"i82551": true,
|
||||
"i82557b": true,
|
||||
"i82559er": true,
|
||||
"rtl8139": true,
|
||||
"e1000": true,
|
||||
"pcnet": true,
|
||||
"virtio": true,
|
||||
"ne2k_pci": true,
|
||||
"i82551": true,
|
||||
"i82557b": true,
|
||||
"i82559er": true,
|
||||
"rtl8139": true,
|
||||
"e1000": true,
|
||||
"pcnet": 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{
|
||||
|
|
|
@ -35,6 +35,84 @@ func cancelCallback(state multistep.StateBag) bool {
|
|||
return cancel
|
||||
}
|
||||
|
||||
func (s *stepRun) getCommandArgs(
|
||||
bootDrive string,
|
||||
state multistep.StateBag) []string {
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config := state.Get("config").(*config)
|
||||
vmName := config.VMName
|
||||
imgPath := filepath.Join(config.OutputDir,
|
||||
fmt.Sprintf("%s.%s", vmName, strings.ToLower(config.Format)))
|
||||
isoPath := state.Get("iso_path").(string)
|
||||
vncPort := state.Get("vnc_port").(uint)
|
||||
guiArgument := "sdl"
|
||||
sshHostPort := state.Get("sshHostPort").(uint)
|
||||
vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900)
|
||||
|
||||
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.")
|
||||
guiArgument = "none"
|
||||
}
|
||||
|
||||
defaultArgs := make(map[string]string)
|
||||
defaultArgs["-name"] = vmName
|
||||
defaultArgs["-machine"] = fmt.Sprintf("type=pc-1.0,accel=%s", config.Accelerator)
|
||||
defaultArgs["-display"] = guiArgument
|
||||
defaultArgs["-netdev"] = "user,id=user.0"
|
||||
defaultArgs["-device"] = fmt.Sprintf("%s,netdev=user.0", config.NetDevice)
|
||||
defaultArgs["-drive"] = fmt.Sprintf("file=%s,if=%s", imgPath, config.DiskInterface)
|
||||
defaultArgs["-cdrom"] = isoPath
|
||||
defaultArgs["-boot"] = bootDrive
|
||||
defaultArgs["-m"] = "512m"
|
||||
defaultArgs["-redir"] = fmt.Sprintf("tcp:%v::22", sshHostPort)
|
||||
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,
|
||||
|
@ -45,35 +123,8 @@ func (s *stepRun) runVM(
|
|||
ui := state.Get("ui").(packer.Ui)
|
||||
vmName := config.VMName
|
||||
|
||||
imgPath := filepath.Join(config.OutputDir,
|
||||
fmt.Sprintf("%s.%s", vmName, strings.ToLower(config.Format)))
|
||||
isoPath := state.Get("iso_path").(string)
|
||||
vncPort := state.Get("vnc_port").(uint)
|
||||
guiArgument := "sdl"
|
||||
sshHostPort := state.Get("sshHostPort").(uint)
|
||||
vnc := fmt.Sprintf("0.0.0.0:%d", vncPort-5900)
|
||||
|
||||
ui.Say("Starting the virtual machine for OS Install...")
|
||||
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.")
|
||||
guiArgument = "none"
|
||||
}
|
||||
|
||||
command := []string{
|
||||
"-name", vmName,
|
||||
"-machine", fmt.Sprintf("type=pc-1.0,accel=%s", config.Accelerator),
|
||||
"-display", guiArgument,
|
||||
"-net", fmt.Sprintf("nic,model=%s", config.NetDevice),
|
||||
"-net", "user",
|
||||
"-drive", fmt.Sprintf("file=%s,if=%s", imgPath, config.DiskInterface),
|
||||
"-cdrom", isoPath,
|
||||
"-boot", bootDrive,
|
||||
"-m", "512m",
|
||||
"-redir", fmt.Sprintf("tcp:%v::22", sshHostPort),
|
||||
"-vnc", vnc,
|
||||
}
|
||||
command := s.getCommandArgs(bootDrive, state)
|
||||
if err := driver.Qemu(vmName, command...); err != nil {
|
||||
err := fmt.Errorf("Error launching VM: %s", err)
|
||||
ui.Error(err.Error())
|
||||
|
|
|
@ -223,7 +223,38 @@ Optional:
|
|||
values "ne2k_pci," "i82551," "i82557b," "i82559er," "rtl8139," "e1000,"
|
||||
"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
|
||||
resulting virtual machine will be created. This may be relative or absolute.
|
||||
|
|
Loading…
Reference in New Issue