tailscale/tstest/tailmac/Swift/Host/AppDelegate.swift
Jonathan Nobels 8fad8c4b9b
tstest/tailmac: add customized macOS virtualization tooling (#13146)
updates tailcale/corp#22371

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