Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boot_command scancodes warped for macOS guests #5635

Closed
mcandre opened this issue Nov 26, 2017 · 4 comments
Closed

boot_command scancodes warped for macOS guests #5635

mcandre opened this issue Nov 26, 2017 · 4 comments

Comments

@mcandre
Copy link

mcandre commented Nov 26, 2017

macOS guests do not follow Linux keyboard scancodes, but have their own scancode mapping:

https://developer.apple.com/legacy/library/documentation/mac/pdf/MacintoshToolboxEssentials.pdf

Specifically:

https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.6.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h#L267-L315

For example, boot_command: ["<down><wait>"] currently fails to work in macOS guests, as packer attempts to translate <down> into the scancode [0x50 0xd0], which macOS interprets at F19, no such scancode. Rather, for macOS guests, <down> should use scancode [0x30].

Interestingly enough, when the user manually presses the Down arrow key with a macOS guest in VirtualBox, the key is correctly sent to the VM. Even other keys like Command with no boot_command equivalent at all can be sent to the VM when input by a human. It's just when packer tries to formulate scancodes that things get messed up, because the packer codebase hardcodes Linux scancodes instead of dispatching scancode tables based on the guest OS type, or a scancode/keyboard JSON key, or whatever.

Note that scancode selection is probably not needed for builders that send keys via VNC, such as qemu and vmware, nor for builders that do not use boot_command at all, such as docker, lxd, and lxc. I think VNC-based boot_command builders are probably safe, though I'll test my macos box with them just to be sure. Other builders like virtualbox, hyperv, and parallels make the mistake of assuming an IBM keyboard guest, using the wrong scancodes for non-PC VM's.

Some of this hardcoded incorrect scancode tables and duplicated code madness could be improved by abstracting boot_command handling. Right now, each builder appears to implement a lot of code to handle keyboard input, that could be better written in terms of (Go) interfaces. Maybe something like a base keyboardinput.go:

type AbstractKeyboardInput string

const (
	InputSleep AbstractKeyboardInput = "InputSleep"
	InputSleep5 = "InputSleep5"
	InputSleep10 = "InputSleep10"
	InputA = "InputA"
	InputB = "InputB"
	...
	InputDown = "InputDown"
	...
)

type ScancodeSet = string

const (
	IBMScancodeSet ScancodeSet = "IBMScancodeSet"
	AppleScancodeSet = "AppleScancodeSet"
	VNCScancodeSet = "VNCScancodeSet"
)

func parse_boot_command(command string) []AbstractKeyboardInput {
	...
}

type TimedScancodes = (time.Duration, []byte)

// Given an abstract representation of some keyboard input,
// potentially with intermittent sleep timers, and a scancode table;
// Return the appropriate scancode array for the input,
// with an associated delay before the key should be sent.
// Zero indicates no delay, positive indicates a delay.
func translate_input(input AbstractKeyboardInput, sset ScancodeSet) TimedScancodes {
	...
}

type KeyboardHandler interface {
	Execute(ts TimedScancodes)
}

And then each individual builder would implement Execute(input AbstractKeyboardInput) according to the particular hypervisor's details. Now parsing and scancode translation are handled with reusable base code, and the particular sleep commands and keycode byte delivery methods can be implemented with less code for the individual builders.

Could packer offer a JSON key to configure scancode sets? The default could be "scancodes": "ibm", as this represents most modern Linux/Microsoft keyboards. Maybe add a "scancodes": "apple" for Apple keyboards? Of course, builders that send keys via VNC should probably configure this as "scancodes": "vnc", or even reject this configuration entirely.

I realize that macOS guests are obscure in the virtualization community, so it's not always easy to spot these edge cases. For testing purposes, I have a work in progress "macos" branch of my packer-templates project to try to pack a macOS Vagrant box. I managed to generate an installer ISO and issue an <enter> key in boot_command, but then when I try to submit some <down> keys to navigate through the installer UI to Disk Utility, I get this scancode mismatch and I'm scratching my head thinking of ways to hack around it. If I can find a way to space apart VBoxManage commands in vboxmanage, maybe even get the timing right with a packer build -debug trick, then hopefully I can work around this scancode issue while waiting for a fix.

@rickard-von-essen
Copy link
Collaborator

I don't think all of this is entirely accurate. Scan codes are not os dependant in general.

@mwhooker
Copy link
Contributor

I'd still like to understand what's going on here better. my understanding is that macs should understand the scancodes sent by pc-at keyboards. I'd be open to what's proposed here (ie swapping out scancodes), but I am not convinced there is an issue.

@mcandre
Copy link
Author

mcandre commented Apr 19, 2018

The IBM PC scancode set 3 is correctly used for modern OS's. This error behavior turned out to be due to parsing errors in the old scancode system, fixed by #6067 . The new PEG-based boot_command parser should prove much more robust soon.

@ghost
Copy link

ghost commented Apr 1, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants