Commit 16b82d6d authored by JessThrysoee's avatar JessThrysoee

builder/parallels: Bundle python version of prltype

Uses the Python API from Parallels Virtualization SDK to write
boot commands.

This eliminates a 3rd party requirement and makes it easier for people
not using homebrew to get started with packer.
parent 5e4ffb56
......@@ -38,7 +38,7 @@ type Driver interface {
// Version reads the version of Parallels that is installed.
Version() (string, error)
// Send scancodes to the vm using the prltype tool.
// Send scancodes to the vm using the prltype python script.
SendKeyScanCodes(string, ...string) error
// Finds the MAC address of the NIC nic0
......
......@@ -3,6 +3,7 @@ package common
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
......@@ -182,11 +183,29 @@ func (d *Parallels9Driver) Version() (string, error) {
func (d *Parallels9Driver) SendKeyScanCodes(vmName string, codes ...string) error {
var stdout, stderr bytes.Buffer
if codes == nil || len(codes) == 0 {
log.Printf("No scan codes to send")
return nil
}
f, err := ioutil.TempFile("", "prltype")
if err != nil {
return err
}
defer os.Remove(f.Name())
script := []byte(Prltype)
_, err = f.Write(script)
if err != nil {
return err
}
args := prepend(vmName, codes)
cmd := exec.Command("prltype", args...)
args = prepend(f.Name(), args)
cmd := exec.Command("/usr/bin/python", args...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
err = cmd.Run()
stdoutString := strings.TrimSpace(stdout.String())
stderrString := strings.TrimSpace(stderr.String())
......
package common
const Prltype string = `
import sys
import prlsdkapi
##
def main():
if len(sys.argv) < 3:
print "Usage: prltype VM_NAME SCANCODE..."
sys.exit(1)
vm_name = sys.argv[1]
scancodes = sys.argv[2:]
server = login()
vm, vm_io = connect(server, vm_name)
send(scancodes, vm, vm_io)
disconnect(server, vm, vm_io)
##
def login():
prlsdkapi.prlsdk.InitializeSDK(prlsdkapi.prlsdk.consts.PAM_DESKTOP_MAC)
server = prlsdkapi.Server()
login_job=server.login_local()
login_job.wait()
return server
##
def connect(server, vm_name):
vm_list_job = server.get_vm_list()
result = vm_list_job.wait()
vm_list = [result.get_param_by_index(i) for i in range(result.get_params_count())]
vm = [vm for vm in vm_list if vm.get_name() == vm_name]
if not vm:
vm_names = [vm.get_name() for vm in vm_list]
raise Exception("%s: No such VM. Available VM's are:\n%s" % (vm_name, "\n".join(vm_names)))
vm = vm[0]
vm_io = prlsdkapi.VmIO()
vm_io.connect_to_vm(vm).wait()
return (vm, vm_io)
##
def disconnect(server, vm, vm_io):
if vm and vm_io:
vm_io.disconnect_from_vm(vm)
if server:
server.logoff()
prlsdkapi.deinit_sdk
##
def send(scancodes, vm, vm_io):
timeout = 10
consts = prlsdkapi.prlsdk.consts
for scancode in scancodes:
c = int(scancode, 16)
if (c < 128):
vm_io.send_key_event(vm, (c,), consts.PKE_PRESS, timeout)
else:
vm_io.send_key_event(vm, (c - 128,) , consts.PKE_RELEASE, timeout)
##
if __name__ == "__main__":
main()
`
......@@ -20,8 +20,8 @@ type bootCommandTemplateData struct {
Name string
}
// This step "types" the boot command into the VM via prltype, built on the
// Parallels Virtualization SDK - C API.
// This step "types" the boot command into the VM via the prltype script, built on the
// Parallels Virtualization SDK - Python API.
//
// Uses:
// driver Driver
......
......@@ -212,11 +212,11 @@ As documented above, the `boot_command` is an array of strings. The
strings are all typed in sequence. It is an array only to improve readability
within the template.
The boot command is "typed" character for character using the `prltype` (part
of prl-utils, see [Parallels Builder](/docs/builders/parallels.html))
command connected to the machine, simulating a human actually typing the
keyboard. There are a set of special keys available. If these are in your
boot command, they will be replaced by the proper key:
The boot command is "typed" character for character (using the Parallels
Virtualization SDK, see [Parallels Builder](/docs/builders/parallels.html))
simulating a human actually typing the keyboard. There are a set of special
keys available. If these are in your boot command, they will be replaced by
the proper key:
* `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress.
......
......@@ -161,11 +161,11 @@ As documented above, the `boot_command` is an array of strings. The
strings are all typed in sequence. It is an array only to improve readability
within the template.
The boot command is "typed" character for character using the `prltype` (part
of prl-utils, see [Parallels Builder](/docs/builders/parallels.html))
command connected to the machine, simulating a human actually typing the
keyboard. There are a set of special keys available. If these are in your
boot command, they will be replaced by the proper key:
The boot command is "typed" character for character (using the Parallels
Virtualization SDK, see [Parallels Builder](/docs/builders/parallels.html))
simulating a human actually typing the keyboard. There are a set of special
keys available. If these are in your boot command, they will be replaced by
the proper key:
* `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress.
......
......@@ -26,14 +26,7 @@ Packer supports the following Parallels builders:
## Requirements
In addition to [Parallels Desktop for Mac](http://www.parallels.com/products/desktop/) this requires:
In addition to [Parallels Desktop for Mac](http://www.parallels.com/products/desktop/) this requires the
[Parallels Virtualization SDK](http://www.parallels.com/downloads/desktop/).
- [Parallels Virtualization SDK 9 for Mac](http://download.parallels.com//desktop/v9/pde.hf1/ParallelsVirtualizationSDK-9.0.24172.951362.dmg)
- [prl-utils](https://github.com/rickard-von-essen/prl-utils/)
The SDK can be installed by downloading and following the instructions in the dmg. The easiest way to install _prl-utils_ is using [Homebrew](http://brew.sh/)
```
brew tap rickard-von-essen/homebrew-formulae
brew install --HEAD prl-utils
```
The SDK can be installed by downloading and following the instructions in the dmg.
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