Jonathan Nobels 8fad8c4b9b
tstest/tailmac: add customized macOS virtualization tooling ()
updates 

Adds custom macOS vm tooling.  See the README for
the general gist, but this will spin up VMs with unixgram
capable network interfaces listening to a named socket,
and with a virtio socket device for host-guest communication.

We can add other devices like consoles, serial, etc as needed.

The whole things is buildable with a single make command, and
everything is controllable via the command line using the TailMac
utility.

This should all be generally functional but takes a few shortcuts
with error handling and the like.  The virtio socket device support
has not been tested and may require some refinement.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2024-08-19 15:01:19 -04:00

53 lines
1.7 KiB
Swift

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
import Cocoa
import Foundation
import Virtualization
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow!
@IBOutlet weak var virtualMachineView: VZVirtualMachineView!
var runner: VMController!
func applicationDidFinishLaunching(_ aNotification: Notification) {
DispatchQueue.main.async { [self] in
runner = VMController()
runner.createVirtualMachine()
virtualMachineView.virtualMachine = runner.virtualMachine
virtualMachineView.capturesSystemKeys = true
// Configure the app to automatically respond to changes in the display size.
virtualMachineView.automaticallyReconfiguresDisplay = true
let fileManager = FileManager.default
if fileManager.fileExists(atPath: config.saveFileURL.path) {
print("Restoring virtual machine state from \(config.saveFileURL)")
runner.restoreVirtualMachine()
} else {
print("Restarting virtual machine")
runner.startVirtualMachine()
}
}
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
if runner.virtualMachine.state == .running {
runner.pauseAndSaveVirtualMachine(completionHandler: {
sender.reply(toApplicationShouldTerminate: true)
})
return .terminateLater
}
return .terminateNow
}
}