mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 19:45:35 +00:00
8fad8c4b9b
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>
59 lines
1.9 KiB
Swift
59 lines
1.9 KiB
Swift
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
import Foundation
|
|
import Virtualization
|
|
|
|
class RestoreImage: NSObject {
|
|
private var downloadObserver: NSKeyValueObservation?
|
|
|
|
// MARK: Observe the download progress.
|
|
|
|
var restoreImageURL: URL
|
|
|
|
init(_ dest: URL) {
|
|
restoreImageURL = dest
|
|
}
|
|
|
|
public func download(completionHandler: @escaping () -> Void) {
|
|
print("Attempting to download latest available restore image.")
|
|
VZMacOSRestoreImage.fetchLatestSupported { [self](result: Result<VZMacOSRestoreImage, Error>) in
|
|
switch result {
|
|
case let .failure(error):
|
|
fatalError(error.localizedDescription)
|
|
|
|
case let .success(restoreImage):
|
|
downloadRestoreImage(restoreImage: restoreImage, completionHandler: completionHandler)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func downloadRestoreImage(restoreImage: VZMacOSRestoreImage, completionHandler: @escaping () -> Void) {
|
|
let downloadTask = URLSession.shared.downloadTask(with: restoreImage.url) { localURL, response, error in
|
|
if let error = error {
|
|
fatalError("Download failed. \(error.localizedDescription).")
|
|
}
|
|
|
|
do {
|
|
try FileManager.default.moveItem(at: localURL!, to: self.restoreImageURL)
|
|
} catch {
|
|
fatalError("Failed to move downloaded restore image to \(self.restoreImageURL) \(error).")
|
|
}
|
|
|
|
|
|
completionHandler()
|
|
}
|
|
|
|
var lastPct = 0
|
|
downloadObserver = downloadTask.progress.observe(\.fractionCompleted, options: [.initial, .new]) { (progress, change) in
|
|
let pct = Int(change.newValue! * 100)
|
|
if pct != lastPct {
|
|
print("Restore image download progress: \(pct)%")
|
|
lastPct = pct
|
|
}
|
|
}
|
|
downloadTask.resume()
|
|
}
|
|
}
|
|
|