utmctl: support booting into recovery mode

This commit is contained in:
user
2025-04-16 12:16:49 +02:00
parent 098e2e27d8
commit d5402b7735
4 changed files with 22 additions and 4 deletions
+3
View File
@@ -61,6 +61,9 @@
<parameter name="saving" code="SaVe" description="When false, do not save the VM changes to disk. Default value is true." type="boolean" optional="yes">
<cocoa key="saveFlag"/>
</parameter>
<parameter name="recovery" code="ReCo" description="When true, start the VM in recovery mode. Default value is false." type="boolean" optional="yes">
<cocoa key="bootRecoveryFlag"/>
</parameter>
</command>
<command name="suspend" code="UTMvsusp" description="Suspend a running virtual machine to memory.">
+1 -1
View File
@@ -210,7 +210,7 @@ extension SBObject: UTMScriptingWindow {}
@objc optional var name: String { get } // The name of the VM.
@objc optional var backend: UTMScriptingBackend { get } // Emulation/virtualization engine used.
@objc optional var status: UTMScriptingStatus { get } // Current running status.
@objc optional func startSaving(_ saving: Bool) // Start a virtual machine or resume a suspended virtual machine.
@objc optional func startSaving(_ saving: Bool, recovery: Bool) // Start a virtual machine or resume a suspended virtual machine.
@objc optional func suspendSaving(_ saving: Bool) // Suspend a running virtual machine to memory.
@objc optional func stopBy(_ by: UTMScriptingStopMethod) // Shuts down a running virtual machine.
@objc optional func delete() // Delete a virtual machine. All data will be deleted, there is no confirmation!
+13 -1
View File
@@ -111,15 +111,27 @@ class UTMScriptingVirtualMachineImpl: NSObject, UTMScriptable {
@objc func start(_ command: NSScriptCommand) {
let shouldSaveState = command.evaluatedArguments?["saveFlag"] as? Bool ?? true
let bootRecoveryMode = command.evaluatedArguments?["bootRecoveryFlag"] as? Bool ?? false
withScriptCommand(command) { [self] in
var options: UTMVirtualMachineStartOptions = []
if !shouldSaveState {
guard type(of: vm).capabilities.supportsDisposibleMode else {
throw ScriptingError.operationNotSupported
}
options.insert(.bootDisposibleMode)
}
if bootRecoveryMode {
guard type(of: vm).capabilities.supportsRecoveryMode else {
throw ScriptingError.operationNotSupported
}
options.insert(.bootRecovery)
}
data.run(vm: box, startImmediately: false)
if vm.state == .stopped {
try await vm.start(options: shouldSaveState ? [] : .bootDisposibleMode)
try await vm.start(options: options)
} else if vm.state == .paused {
try await vm.resume()
} else {
+5 -2
View File
@@ -226,10 +226,13 @@ extension UTMCtl {
@Flag(help: "Run VM as a snapshot and do not save changes to disk.")
var disposable: Bool = false
@Flag(help: "Boot a VM in recovery mode.")
var recovery: Bool = false
func run(with application: UTMScriptingApplication) throws {
let vm = try virtualMachine(forIdentifier: identifer, in: application)
vm.startSaving!(!disposable)
vm.startSaving!(!disposable, recovery: recovery)
if attach {
print("WARNING: attach command is not implemented yet!")
}