11import Foundation
22import ArgumentParser
3- import SotoS3
43import prlctl
54import libhostmgr
65
7- struct SyncVMImagesCommand : ParsableCommand , FollowsCommandPolicies {
6+ struct SyncVMImagesCommand : AsyncParsableCommand , FollowsCommandPolicies {
87
98 static let configuration = CommandConfiguration (
10- commandName: " vm_images " ,
11- abstract: " Sync this machine's VM images with those avaiable remotely "
9+ commandName: Configuration . SchedulableSyncCommand . vmImages . rawValue ,
10+ abstract: " Sync this machine's VM images with those available remotely "
1211 )
1312
1413 @OptionGroup
@@ -22,19 +21,19 @@ struct SyncVMImagesCommand: ParsableCommand, FollowsCommandPolicies {
2221 . scheduled( every: 3600 )
2322 ]
2423
25- func run( ) throws {
24+ func run( ) async throws {
2625 try to ( evaluateCommandPolicies ( ) , unless: options. force)
2726
2827 /// The manifest defines which images should be distributed to VM hosts
29- let manifest = try VMRemoteImageManager ( ) . getManifest ( )
30- logger. debug ( " Downloaded manifest: \n \( manifest) " )
28+ let manifest = try await RemoteVMRepository ( ) . getManifest ( )
29+ logger. info ( " Downloaded manifest: \n \( manifest) " )
3130
3231 /// Candidate images are any that the manifest says *could* be installed on this VM host
33- let candidateImages = try VMRemoteImageManager ( ) . list ( ) . filter { manifest. contains ( $0. basename) }
34- logger. debug ( " Available remote images: \n \( candidateImages) " )
32+ let candidateImages = try await RemoteVMRepository ( ) . listImages ( ) . filter { manifest. contains ( $0. basename) }
33+ logger. info ( " Available remote images: \n \( candidateImages) " )
3534
3635 let localImages = try VMLocalImageManager ( ) . list ( )
37- logger. debug ( " Local Images: \( localImages) " )
36+ logger. info ( " Local Images: \( localImages) " )
3837
3938 let imagesToDownload = candidateImages. filter { !localImages. contains ( $0. basename) }
4039 let imagesToDelete = localImages
@@ -46,27 +45,25 @@ struct SyncVMImagesCommand: ParsableCommand, FollowsCommandPolicies {
4645 logger. info ( " Deleting local images: \( imagesToDelete) " )
4746 try VMLocalImageManager ( ) . delete ( images: imagesToDelete)
4847
49- try imagesToDownload. forEach {
50- try download ( image: $0 )
48+ for image in imagesToDownload {
49+ try await download ( image: image )
5150 }
5251
5352 try recordLastRun ( )
5453 }
5554
56- private func download( image: VMRemoteImageManager . RemoteImage ) throws {
55+ private func download( image: RemoteVMImage ) async throws {
5756 let storageDirectory = Configuration . shared. vmStorageDirectory
5857 let destination = storageDirectory. appendingPathComponent ( image. fileName)
5958
60- logger. info ( " Downloading the VM – this will take a few minutes " )
61- logger. trace ( " Downloading \( image. basename) to \( destination) " )
59+ logger. info ( " Downloading \( image. basename) to \( destination) – this will take a few minutes " )
6260
6361 let limiter = Limiter ( policy: . throttle, operationsPerSecond: 1 )
6462
65- try VMRemoteImageManager ( ) . download ( image: image, to: destination) { _ , downloaded , total in
63+ try await RemoteVMRepository ( ) . download ( image: image, to: destination) { progress in
6664 limiter. perform {
6765 try ? recordHeartbeat ( )
68- let percent = String ( format: " %.2f " , Double ( downloaded) / Double( total) * 100 )
69- logger. trace ( " \( percent) % complete " )
66+ logger. info ( " \( progress. decimalPercent) % complete " )
7067 }
7168 }
7269
@@ -87,6 +84,5 @@ struct SyncVMImagesCommand: ParsableCommand, FollowsCommandPolicies {
8784 logger. info ( " Imported Complete " )
8885 logger. info ( " \t Name: \t \( vmToImport. name) " )
8986 logger. info ( " \t UUID: \t \( vmToImport. uuid) " )
90-
9187 }
9288}
0 commit comments