From 3da91e651804bb2e8814689414ccc28343019567 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Mon, 9 Sep 2024 20:45:59 +0400 Subject: [PATCH] tart run: provide a hint with names of other running VMs (#900) When VM limit gets exceeded. --- Sources/tart/Commands/Run.swift | 30 +++++++++++++++++++++++++++++- Sources/tart/VMStorageHelper.swift | 3 +++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Sources/tart/Commands/Run.swift b/Sources/tart/Commands/Run.swift index cebad86..48af5f4 100644 --- a/Sources/tart/Commands/Run.swift +++ b/Sources/tart/Commands/Run.swift @@ -346,7 +346,35 @@ struct Run: AsyncParsableCommand { } #endif - try await vm!.start(recovery: recovery, resume: resume) + do { + try await vm!.start(recovery: recovery, resume: resume) + } catch let error as VZError { + if error.code == .virtualMachineLimitExceeded { + var hint = "" + + do { + let runningVMs: [String] = try localStorage.list().compactMap { (name, vmDir) in + if try !vmDir.running() { + return nil + } + + return name + } + + if !runningVMs.isEmpty { + let runningVMsJoined = runningVMs.joined(separator: ", ") + + hint = " (other running VMs: \(runningVMsJoined))" + } + } catch { + // we can't provide any hint + } + + throw RuntimeError.VirtualMachineLimitExceeded(hint) + } + + throw error + } if let vncImpl = vncImpl { let vncURL = try await vncImpl.waitForURL(netBridged: !netBridged.isEmpty) diff --git a/Sources/tart/VMStorageHelper.swift b/Sources/tart/VMStorageHelper.swift index c12db27..4774d16 100644 --- a/Sources/tart/VMStorageHelper.swift +++ b/Sources/tart/VMStorageHelper.swift @@ -71,6 +71,7 @@ enum RuntimeError : Error { case OCIUnsupportedDiskFormat(_ format: String) case SuspendFailed(_ message: String) case PullFailed(_ message: String) + case VirtualMachineLimitExceeded(_ hint: String) } protocol HasExitCode { @@ -128,6 +129,8 @@ extension RuntimeError : CustomStringConvertible { return "Failed to suspend the VM: \(message)" case .PullFailed(let message): return message + case .VirtualMachineLimitExceeded(let hint): + return "The number of VMs exceeds the system limit\(hint)" } } }