소스 검색

config(qemu): show progress indicator for reclaim operations

osy 1 년 전
부모
커밋
0008112d02
3개의 변경된 파일47개의 추가작업 그리고 5개의 파일을 삭제
  1. 9 1
      Platform/UTMData.swift
  2. 36 2
      Services/UTMQemuImage.swift
  3. 2 2
      UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+ 9 - 1
Platform/UTMData.swift

@@ -776,7 +776,15 @@ struct AlertMessage: Identifiable {
     func reclaimSpace(for driveUrl: URL, withCompression isCompressed: Bool = false) async throws {
         let baseUrl = driveUrl.deletingLastPathComponent()
         let dstUrl = Self.newImage(from: driveUrl, to: baseUrl, withExtension: "qcow2")
-        try await UTMQemuImage.convert(from: driveUrl, toQcow2: dstUrl, withCompression: isCompressed)
+        defer {
+            busyProgress = nil
+        }
+        try await UTMQemuImage.convert(from: driveUrl, toQcow2: dstUrl, withCompression: isCompressed) { progress in
+            Task { @MainActor in
+                self.busyProgress = progress / 100
+            }
+        }
+        busyProgress = nil
         do {
             try fileManager.replaceItem(at: driveUrl, withItemAt: dstUrl, backupItemName: nil, resultingItemURL: nil)
         } catch {

+ 36 - 2
Services/UTMQemuImage.swift

@@ -18,9 +18,12 @@ import Foundation
 import QEMUKitInternal
 
 @objc class UTMQemuImage: UTMProcess {
+    typealias ProgressCallback = (Float) -> Void
+
     private var logOutput: String = ""
     private var processExitContinuation: CheckedContinuation<Void, any Error>?
-    
+    private var onProgress: ProgressCallback?
+
     private init() {
         super.init(arguments: [])
     }
@@ -52,11 +55,14 @@ import QEMUKitInternal
         }
     }
     
-    static func convert(from url: URL, toQcow2 dest: URL, withCompression compressed: Bool = false) async throws {
+    static func convert(from url: URL, toQcow2 dest: URL, withCompression compressed: Bool = false, onProgress: ProgressCallback? = nil) async throws {
         let qemuImg = UTMQemuImage()
         let srcBookmark = try url.bookmarkData()
         let dstBookmark = try dest.deletingLastPathComponent().bookmarkData()
         qemuImg.pushArgv("convert")
+        if onProgress != nil {
+            qemuImg.pushArgv("-p")
+        }
         if compressed {
             qemuImg.pushArgv("-c")
             qemuImg.pushArgv("-o")
@@ -69,8 +75,10 @@ import QEMUKitInternal
         qemuImg.accessData(withBookmark: dstBookmark)
         qemuImg.pushArgv(dest.path)
         let logging = QEMULogging()
+        logging.delegate = qemuImg
         qemuImg.standardOutput = logging.standardOutput
         qemuImg.standardError = logging.standardError
+        qemuImg.onProgress = onProgress
         try await qemuImg.start()
     }
     
@@ -175,8 +183,34 @@ extension UTMQemuImageError: LocalizedError {
 extension UTMQemuImage: QEMULoggingDelegate {
     func logging(_ logging: QEMULogging, didRecieveOutputLine line: String) {
         logOutput += line
+        if let onProgress = onProgress, line.contains("100%") {
+            if let progress = parseProgress(line) {
+                onProgress(progress)
+            }
+        }
     }
     
     func logging(_ logging: QEMULogging, didRecieveErrorLine line: String) {
     }
 }
+
+extension UTMQemuImage {
+    private func parseProgress(_ line: String) -> Float? {
+        let pattern = "\\(([0-9]+\\.[0-9]+)/100\\%\\)"
+        do {
+            let regex = try NSRegularExpression(pattern: pattern)
+            if let match = regex.firstMatch(in: line, range: NSRange(location: 0, length: line.count)) {
+                let range = match.range(at: 1)
+                if let swiftRange = Range(range, in: line) {
+                    let floatValueString = line[swiftRange]
+                    if let floatValue = Float(floatValueString) {
+                        return floatValue
+                    }
+                }
+            }
+        } catch {
+
+        }
+        return nil
+    }
+}

+ 2 - 2
UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -1,5 +1,5 @@
 {
-  "originHash" : "7b5e2ff74c08d3efce9babb7649d891f7ad18d9c868e75db7d9e26ce542055cc",
+  "originHash" : "c9482d61e795c27df5a7c772a0750aefc9164d93bd871138a9b229c9f08c6fab",
   "pins" : [
     {
       "identity" : "altkit",
@@ -52,7 +52,7 @@
       "location" : "https://github.com/utmapp/QEMUKit.git",
       "state" : {
         "branch" : "main",
-        "revision" : "06b806f61aeeea8efff99a98b058defcf3632e2e"
+        "revision" : "1019ed76278a1d5cbe871ff5e51c62b5d8c9a032"
       }
     },
     {