mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 16:22:03 +01:00 
			
		
		
		
	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()
 | |
|     }
 | |
| }
 | |
| 
 |