mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 23:07:44 +00:00
tstest/tailmac: add support for mounting host directories in the guest (#13957)
updates tailscale/corp#24197 tailmac run now supports the --share option which will allow you to specify a directory on the host which can be mounted in the guest using mount_virtiofs vmshare <path>. Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
parent
0f9a054cba
commit
aecb0ab76b
@ -14,6 +14,7 @@ class Config: Codable {
|
||||
var mac = "52:cc:cc:cc:cc:01"
|
||||
var ethermac = "52:cc:cc:cc:ce:01"
|
||||
var port: UInt32 = 51009
|
||||
var sharedDir: String?
|
||||
|
||||
// The virtual machines ID. Also double as the directory name under which
|
||||
// we will store configuration, block device, etc.
|
||||
|
@ -141,5 +141,18 @@ struct TailMacConfigHelper {
|
||||
func createKeyboardConfiguration() -> VZKeyboardConfiguration {
|
||||
return VZMacKeyboardConfiguration()
|
||||
}
|
||||
|
||||
func createDirectoryShareConfiguration(tag: String) -> VZDirectorySharingDeviceConfiguration? {
|
||||
guard let dir = config.sharedDir else { return nil }
|
||||
|
||||
let sharedDir = VZSharedDirectory(url: URL(fileURLWithPath: dir), readOnly: false)
|
||||
let share = VZSingleDirectoryShare(directory: sharedDir)
|
||||
|
||||
// Create the VZVirtioFileSystemDeviceConfiguration and assign it a unique tag.
|
||||
let sharingConfiguration = VZVirtioFileSystemDeviceConfiguration(tag: tag)
|
||||
sharingConfiguration.share = share
|
||||
|
||||
return sharingConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,12 @@ var config: Config = Config()
|
||||
extension HostCli {
|
||||
struct Run: ParsableCommand {
|
||||
@Option var id: String
|
||||
@Option var share: String?
|
||||
|
||||
mutating func run() {
|
||||
print("Running vm with identifier \(id)")
|
||||
config = Config(id)
|
||||
config.sharedDir = share
|
||||
print("Running vm with identifier \(id) and sharedDir \(share ?? "<none>")")
|
||||
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +95,13 @@ class VMController: NSObject, VZVirtualMachineDelegate {
|
||||
virtualMachineConfiguration.keyboards = [helper.createKeyboardConfiguration()]
|
||||
virtualMachineConfiguration.socketDevices = [helper.createSocketDeviceConfiguration()]
|
||||
|
||||
if let dir = config.sharedDir, let shareConfig = helper.createDirectoryShareConfiguration(tag: "vmshare") {
|
||||
print("Sharing \(dir) as vmshare. Use: mount_virtiofs vmshare <path> in the guest to mount.")
|
||||
virtualMachineConfiguration.directorySharingDevices = [shareConfig]
|
||||
} else {
|
||||
print("No shared directory created. \(config.sharedDir ?? "none") was requested.")
|
||||
}
|
||||
|
||||
try! virtualMachineConfiguration.validate()
|
||||
try! virtualMachineConfiguration.validateSaveRestoreSupport()
|
||||
|
||||
|
@ -95,6 +95,7 @@ extension Tailmac {
|
||||
extension Tailmac {
|
||||
struct Run: ParsableCommand {
|
||||
@Option(help: "The vm identifier") var id: String
|
||||
@Option(help: "Optional share directory") var share: String?
|
||||
@Flag(help: "Tail the TailMac log output instead of returning immediatly") var tail
|
||||
|
||||
mutating func run() {
|
||||
@ -115,7 +116,12 @@ extension Tailmac {
|
||||
fatalError("Could not find Host.app at \(appPath). This must be co-located with the tailmac utility")
|
||||
}
|
||||
|
||||
process.arguments = ["run", "--id", id]
|
||||
var args = ["run", "--id", id]
|
||||
if let share {
|
||||
args.append("--share")
|
||||
args.append(share)
|
||||
}
|
||||
process.arguments = args
|
||||
|
||||
do {
|
||||
process.standardOutput = stdOutPipe
|
||||
@ -124,26 +130,18 @@ extension Tailmac {
|
||||
fatalError("Unable to launch the vm process")
|
||||
}
|
||||
|
||||
// This doesn't print until we exit which is not ideal, but at least we
|
||||
// get the output
|
||||
if tail != 0 {
|
||||
// (jonathan)TODO: How do we get the process output in real time?
|
||||
// The child process only seems to flush to stdout on completion
|
||||
let outHandle = stdOutPipe.fileHandleForReading
|
||||
|
||||
let queue = OperationQueue()
|
||||
NotificationCenter.default.addObserver(
|
||||
forName: NSNotification.Name.NSFileHandleDataAvailable,
|
||||
object: outHandle, queue: queue)
|
||||
{
|
||||
notification -> Void in
|
||||
let data = outHandle.availableData
|
||||
outHandle.readabilityHandler = { handle in
|
||||
let data = handle.availableData
|
||||
if data.count > 0 {
|
||||
if let str = String(data: data, encoding: String.Encoding.utf8) {
|
||||
print(str)
|
||||
}
|
||||
}
|
||||
outHandle.waitForDataInBackgroundAndNotify()
|
||||
}
|
||||
outHandle.waitForDataInBackgroundAndNotify()
|
||||
process.waitUntilExit()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user