From 99c91cbf878e6dbaed05ef189ad2f5d41c30af8a Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Thu, 11 Apr 2024 15:20:58 +0200 Subject: [PATCH] Allow mounting NBD disks (#786) * Allow mounting NBD disks Fixes #759 * Apply suggestions from code review Co-authored-by: Nikolay Edigaryev * Removed unnecessary docs --------- Co-authored-by: Nikolay Edigaryev --- Sources/tart/Commands/Run.swift | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Sources/tart/Commands/Run.swift b/Sources/tart/Commands/Run.swift index 9369b75..510f415 100644 --- a/Sources/tart/Commands/Run.swift +++ b/Sources/tart/Commands/Run.swift @@ -61,9 +61,9 @@ struct Run: AsyncParsableCommand { var vncExperimental: Bool = false @Option(help: ArgumentHelp(""" - Additional disk attachments with an optional read-only specifier\n(e.g. --disk=\"disk.bin\" --disk=\"ubuntu.iso:ro\" --disk=\"/dev/disk0\") + Additional disk attachments with an optional read-only specifier\n(e.g. --disk=\"disk.bin\" --disk=\"ubuntu.iso:ro\" --disk=\"/dev/disk0\" --disk=\"nbd://localhost:10809/myDisk\") """, discussion: """ - Can be either a disk image file or a block device like a local SSD on AWS EC2 Mac instances. + Can be either a disk image file, a block device like a local SSD on AWS EC2 Mac instances or a Network Block Device (NBD). Learn how to create a disk image using Disk Utility here: https://support.apple.com/en-gb/guide/disk-utility/dskutl11888/mac @@ -429,6 +429,24 @@ struct Run: AsyncParsableCommand { for rawDisk in expandedDiskPaths { let diskReadOnly = rawDisk.hasSuffix(readOnlySuffix) let diskPath = diskReadOnly ? String(rawDisk.prefix(rawDisk.count - readOnlySuffix.count)) : rawDisk + + if (diskPath.starts(with: "nbd://")) { + guard #available(macOS 14, *) else { + throw UnsupportedOSError("attaching Network Block Devices", "are") + } + guard let nbdURL = URL(string: diskPath) else { + throw RuntimeError.VMConfigurationError("invalid NBD URL: \(diskPath)") + } + let nbdAttachment = try VZNetworkBlockDeviceStorageDeviceAttachment( + url: nbdURL, + timeout: 30, + isForcedReadOnly: diskReadOnly, + synchronizationMode: VZDiskSynchronizationMode.none + ) + result.append(VZVirtioBlockDeviceConfiguration(attachment: nbdAttachment)) + continue + } + let diskURL = URL(fileURLWithPath: diskPath) // check if `diskPath` is a block device or a directory