瀏覽代碼

utmctl: support booting into recovery mode

user 4 月之前
父節點
當前提交
d5402b7735
共有 4 個文件被更改,包括 22 次插入4 次删除
  1. 3 0
      Scripting/UTM.sdef
  2. 1 1
      Scripting/UTMScripting.swift
  3. 13 1
      Scripting/UTMScriptingVirtualMachineImpl.swift
  4. 5 2
      utmctl/UTMCtl.swift

+ 3 - 0
Scripting/UTM.sdef

@@ -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">
           <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"/>
             <cocoa key="saveFlag"/>
           </parameter>
           </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>
         
         
         <command name="suspend" code="UTMvsusp" description="Suspend a running virtual machine to memory.">
         <command name="suspend" code="UTMvsusp" description="Suspend a running virtual machine to memory.">

+ 1 - 1
Scripting/UTMScripting.swift

@@ -210,7 +210,7 @@ extension SBObject: UTMScriptingWindow {}
     @objc optional var name: String { get } // The name of the VM.
     @objc optional var name: String { get } // The name of the VM.
     @objc optional var backend: UTMScriptingBackend { get } // Emulation/virtualization engine used.
     @objc optional var backend: UTMScriptingBackend { get } // Emulation/virtualization engine used.
     @objc optional var status: UTMScriptingStatus { get } // Current running status.
     @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 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 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!
     @objc optional func delete() // Delete a virtual machine. All data will be deleted, there is no confirmation!

+ 13 - 1
Scripting/UTMScriptingVirtualMachineImpl.swift

@@ -111,15 +111,27 @@ class UTMScriptingVirtualMachineImpl: NSObject, UTMScriptable {
     
     
     @objc func start(_ command: NSScriptCommand) {
     @objc func start(_ command: NSScriptCommand) {
         let shouldSaveState = command.evaluatedArguments?["saveFlag"] as? Bool ?? true
         let shouldSaveState = command.evaluatedArguments?["saveFlag"] as? Bool ?? true
+        let bootRecoveryMode = command.evaluatedArguments?["bootRecoveryFlag"] as? Bool ?? false
+
         withScriptCommand(command) { [self] in
         withScriptCommand(command) { [self] in
+            var options: UTMVirtualMachineStartOptions = []
+
             if !shouldSaveState {
             if !shouldSaveState {
                 guard type(of: vm).capabilities.supportsDisposibleMode else {
                 guard type(of: vm).capabilities.supportsDisposibleMode else {
                     throw ScriptingError.operationNotSupported
                     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)
             data.run(vm: box, startImmediately: false)
             if vm.state == .stopped {
             if vm.state == .stopped {
-                try await vm.start(options: shouldSaveState ? [] : .bootDisposibleMode)
+                try await vm.start(options: options)
             } else if vm.state == .paused {
             } else if vm.state == .paused {
                 try await vm.resume()
                 try await vm.resume()
             } else {
             } else {

+ 5 - 2
utmctl/UTMCtl.swift

@@ -226,10 +226,13 @@ extension UTMCtl {
         
         
         @Flag(help: "Run VM as a snapshot and do not save changes to disk.")
         @Flag(help: "Run VM as a snapshot and do not save changes to disk.")
         var disposable: Bool = false
         var disposable: Bool = false
-        
+
+        @Flag(help: "Boot a VM in recovery mode.")
+        var recovery: Bool = false
+
         func run(with application: UTMScriptingApplication) throws {
         func run(with application: UTMScriptingApplication) throws {
             let vm = try virtualMachine(forIdentifier: identifer, in: application)
             let vm = try virtualMachine(forIdentifier: identifer, in: application)
-            vm.startSaving!(!disposable)
+            vm.startSaving!(!disposable, recovery: recovery)
             if attach {
             if attach {
                 print("WARNING: attach command is not implemented yet!")
                 print("WARNING: attach command is not implemented yet!")
             }
             }