cirruslabs / tart

macOS and Linux VMs on Apple Silicon to use in CI and other automations
https://tart.run
Other
3.73k stars 104 forks source link

Support pasting clipboard from host #14

Open fkorotkov opened 2 years ago

fkorotkov commented 2 years ago

It seems it's not supported at the moment with the current API according to this comment and based on my research at the time. But let's create a tracking issue.

fkorotkov commented 2 years ago

Yeah, I've poked around the code and didn't find a way to support it. Seems there is no way to get handle on a keyboard to send fake strokes.

A workaround for people might be enabling Screen Sharing and using VNC via running a VM with --no-graphics option and then getting it's IP via tart ip <name> command to use with Screen Sharing.

edigaryev commented 2 years ago

Yeah, I've poked around the code and didn't find a way to support it. Seems there is no way to get handle on a keyboard to send fake strokes.

So, sending CGEvent's is not an option either?

Also, maybe can we manually call methods like keyDown() on an NSResponder?

fkorotkov commented 2 years ago

I haven't found a public API to interact with a keyboard. As far as I understood VZVirtualMachineView will support it at some point:

If the VM configuration includes a keyboard and a pointing device, the view forwards keyboard and mouse events to the VM through those devices.

fkorotkov commented 2 years ago

It seems it will be possible. At least according to a new Linux example (see "Enable copy-and-paste support between the host and the guest" section):

private func createSpiceAgentConsoleDeviceConfiguration() -> VZVirtioConsoleDeviceConfiguration {
    let consoleDevice = VZVirtioConsoleDeviceConfiguration()

    let spiceAgentPort = VZVirtioConsolePortConfiguration()
    spiceAgentPort.name = VZSpiceAgentPortAttachment.spiceAgentPortName
    spiceAgentPort.attachment = VZSpiceAgentPortAttachment()
    consoleDevice.ports[0] = spiceAgentPort

    return consoleDevice
}

Need to verify that it will work in macOS though.

fkorotkov commented 2 years ago

I've tried the above example and a bit different one:

let spiceAgentPortAttachment = VZSpiceAgentPortAttachment()
spiceAgentPortAttachment.sharesClipboard = true
let serialPortConfiguration = VZVirtioConsoleDeviceSerialPortConfiguration()
serialPortConfiguration.attachment = spiceAgentPortAttachment
configuration.serialPorts = [serialPortConfiguration]

with the latest Ventura and it seems not be working. It might be indicating that it only works for Linux. Will need to investigate more.

bootstraponline commented 1 year ago

@fkorotkov Hey, https://github.com/cirruslabs/tart/commit/048a5506df871aaddc412ddfabe2e52bec850e57 doesn't support clipboard sharing on Linux. A spice agent is necessary, similar to what you posted in https://github.com/cirruslabs/tart/issues/14#issuecomment-1147850768

https://github.com/cirruslabs/tart/pull/287 also fixes this issue. Would you prefer a standalone PR for clipboard sharing?

fkorotkov commented 1 year ago

Right. https://github.com/cirruslabs/tart/commit/048a5506df871aaddc412ddfabe2e52bec850e57 was only about trackpad support. @edigaryev had some security concerns as well about enabling clipboard sharing by default. Will be probably better to put the clipboard support under a flag or maybe do similar to what "Screen Sharing" app is doing e.g. only share things copied to clipboard after launching a session. It seems "Screen Sharing" either cleans the clipboard upon session creation or doing something else. Haven't investigated the behaviour in more details.

bootstraponline commented 1 year ago

Right. 048a550 was only about trackpad support.

Ah, the commit message says Support trackpad on macOS and clipboard sharing on Linux

@edigaryev had some security concerns as well about enabling clipboard sharing by default. Will be probably better to put the clipboard support under a flag or maybe do similar to what "Screen Sharing" app is doing e.g. only share things copied to clipboard after launching a session.

I think a flag makes sense. Some users may want an isolated VM with no clipboard support.

Does tart have the concept of a VM description file? In VMWare, there's .vmx files that contain the VM configuration.

What do you think about having a Tart.app with a UI that enables configuring persistent VM settings that are stored on disk? https://github.com/cirruslabs/tart/issues/243#issuecomment-1248355627 mentioned the .app might be required for certain entitlements.

Parallels has a simple UI.

image

The settings could also be available via flag for the command line use case.

fkorotkov commented 1 year ago

Right now config is stored in a JSON file and can be altered via tart set command. We were thinking about a UI similar to your screenshot so you can open Tart.App or run tart run which will display a list of available VMs with an option to change configs. We just have too many other things on our plates to find time for that.

bootstraponline commented 1 year ago

We were thinking about a UI similar to your screenshot so you can open Tart.App or run tart run which will display a list of available VMs with an option to change configs. We just have too many other things on our plates to find time for that.

I looked into this and it seems like Swift Package Manager doesn't play nice with macOS apps. For full SwiftUI support (including view previews), Xcode is expecting an Xcode project.

ThreatLockerAlex commented 1 year ago

with the latest Ventura and it seems not be working. It might be indicating that it only works for Linux. Will need to investigate more.

hey @fkorotkov any breakthroughs here? Just came across this thread trying to help another team at work. Not super familiar with swift but I have modified the VMInstance file of MacVM. There biggest pain point right now is clipboard sharing, hoping to either resolve let them know it is still not currently possible.

edigaryev commented 1 year ago

I've just tried building & running Tart on a macOS 14.0 Sonoma (23A5276g) host with macOS 14.0 Sonoma (23A5276q) guest with the following snippet added to a VM.craftConfiguration()

    // Clipboard sharing
    let spiceAgentPortAttachment = VZSpiceAgentPortAttachment()
    spiceAgentPortAttachment.sharesClipboard = true

    let spiceAgentPort = VZVirtioConsolePortConfiguration()
    spiceAgentPort.name = VZSpiceAgentPortAttachment.spiceAgentPortName
    spiceAgentPort.attachment = spiceAgentPortAttachment

    let consoleDevice = VZVirtioConsoleDeviceConfiguration()
    consoleDevice.ports[0] = spiceAgentPort
    configuration.consoleDevices = [consoleDevice]

With this snippet, tart run boots the VM with an additional device present in ioreg:

    | |   |   | +-o AppleVirtIOPCITransport  <class AppleVirtIOPCITransport, id 0x1000001a7, registered, matched, active, busy 0 (12 ms), retain 7>
    | |   |   |   +-o AppleVirtIOConsole  <class AppleVirtIOConsole, id 0x1000001b1, registered, matched, active, busy 0 (9 ms), retain 10>
    | |   |   |     +-o IOSerialStreamSync  <class IOSerialStreamSync, id 0x1000001c3, registered, matched, active, busy 0 (9 ms), retain 7>
    | |   |   |       +-o IOSerialBSDClient  <class IOSerialBSDClient, id 0x1000001c7, registered, matched, active, busy 0 (0 ms), retain 5>

This device is also present in /dev:

crw-rw-rw-  1 root   wheel      0x9000001 Jun 23 15:51 cu.com.redhat.spice.0
crw-rw-rw-  1 root   wheel      0x9000000 Jun 23 15:51 tty.com.redhat.spice.0

However, when attempting to access either of these devices (e.g. using cat /dev/cu.com.redhat.spice.0) from inside of a VM, the VM exits with the following exception:

guest has stopped the virtual machine due to error: Error Domain=VZErrorDomain Code=1 "The virtual machine stopped unexpectedly." UserInfo={NSLocalizedFailure=Internal Virtualization error., NSLocalizedFailureReason=The virtual machine stopped unexpectedly.}

So I guess it's not ready for macOS yet or I'm doing something wrong.

I've also found a similar issue in another project utilizing Virtualization.Framework: https://github.com/s-u/macosvm/issues/1.

ThreatLockerAlex commented 1 year ago

Thank you for your efforts @fkorotkov

fkorotkov commented 1 year ago

All thanks to @edigaryev for double checking! 🙌

joshuaquek commented 2 months ago

There is another tool like tart that allows MacOS virtualisation as well as copy and pasting - https://github.com/insidegui/VirtualBuddy/pull/144 , where the both the host and guest is running on MacOS

Seems like the solution is to simply have a helper app within the guest VM to allow this.