Merge pull request #1499 from JessThrysoee/python_prltype

builder/parallels: Bundle python version of prltype
This commit is contained in:
Rickard von Essen 2014-09-27 11:10:37 +02:00
commit dc3f156f02
7 changed files with 113 additions and 25 deletions

View File

@ -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

View File

@ -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())

View File

@ -0,0 +1,76 @@
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()
`

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.