@@ -47,18 +47,25 @@ extension Application {
4747 @Option ( name: . customLong( " tar " ) , help: " Filesystem path or remote URL to a tar archive containing a kernel file " )
4848 var tarPath : String ? = nil
4949
50+ @Option ( name: . long, help: " Expected digest for the tar archive, for example sha256:<hex>. Required when --tar is a remote URL. " )
51+ var digest : String ? = nil
52+
5053 @OptionGroup
5154 public var logOptions : Flags . Logging
5255
5356 public init ( ) { }
5457
5558 public func run( ) async throws {
56- let containerSystemConfig : ContainerSystemConfig = try await Application . loadContainerSystemConfig ( )
5759 if recommended {
60+ let containerSystemConfig : ContainerSystemConfig = try await Application . loadContainerSystemConfig ( )
5861 let url = containerSystemConfig. kernel. url
5962 let path : String = containerSystemConfig. kernel. binaryPath
6063 log. info ( " Installing the recommended kernel from \( url) ... " )
61- try await Self . downloadAndInstallWithProgressBar ( tarRemoteURL: url, kernelFilePath: path, force: force)
64+ try await Self . downloadAndInstallWithProgressBar (
65+ tarRemoteURL: url,
66+ kernelFilePath: path,
67+ expectedDigest: containerSystemConfig. kernel. digest,
68+ force: force)
6269 return
6370 }
6471 guard tarPath != nil else {
@@ -68,6 +75,9 @@ extension Application {
6875 }
6976
7077 private func setKernelFromBinary( ) async throws {
78+ guard digest == nil else {
79+ throw ArgumentParser . ValidationError ( " '--digest' can only be used with '--tar' " )
80+ }
7181 guard let binaryPath else {
7282 throw ArgumentParser . ValidationError ( " missing argument '--binary' " )
7383 }
@@ -84,16 +94,32 @@ extension Application {
8494 throw ArgumentParser . ValidationError ( " missing argument '--tar " )
8595 }
8696 let platform = try getSystemPlatform ( )
97+ let remoteURL = URL ( string: tarPath)
98+ let remoteScheme = remoteURL? . scheme? . lowercased ( )
99+ let isHTTPURL = remoteScheme == " http " || remoteScheme == " https "
87100 let localTarPath = URL ( fileURLWithPath: tarPath, relativeTo: . currentDirectory( ) ) . path
88101 let fm = FileManager . default
89- if fm. fileExists ( atPath: localTarPath) {
90- try await ClientKernel . installKernelFromTar ( tarFile: localTarPath, kernelFilePath: binaryPath, platform: platform, force: force)
102+ if !isHTTPURL && fm. fileExists ( atPath: localTarPath) {
103+ try await ClientKernel . installKernelFromTar (
104+ tarFile: localTarPath,
105+ kernelFilePath: binaryPath,
106+ platform: platform,
107+ expectedDigest: digest,
108+ force: force)
91109 return
92110 }
93- guard let remoteURL = URL ( string : tarPath ) else {
111+ guard let remoteURL else {
94112 throw ContainerizationError ( . invalidArgument, message: " invalid remote URL ' \( tarPath) ' for argument '--tar'. Missing protocol? " )
95113 }
96- try await Self . downloadAndInstallWithProgressBar ( tarRemoteURL: remoteURL, kernelFilePath: binaryPath, platform: platform, force: force)
114+ guard let digest else {
115+ throw ArgumentParser . ValidationError ( " '--digest' is required when '--tar' is a remote URL " )
116+ }
117+ try await Self . downloadAndInstallWithProgressBar (
118+ tarRemoteURL: remoteURL,
119+ kernelFilePath: binaryPath,
120+ platform: platform,
121+ expectedDigest: digest,
122+ force: force)
97123 }
98124
99125 private func getSystemPlatform( ) throws -> SystemPlatform {
@@ -107,18 +133,29 @@ extension Application {
107133 }
108134 }
109135
110- static func downloadAndInstallWithProgressBar( tarRemoteURL: URL , kernelFilePath: String , platform: SystemPlatform = . current, force: Bool ) async throws {
136+ static func downloadAndInstallWithProgressBar(
137+ tarRemoteURL: URL ,
138+ kernelFilePath: String ,
139+ platform: SystemPlatform = . current,
140+ expectedDigest: String ,
141+ force: Bool
142+ ) async throws {
111143 let progressConfig = try ProgressConfig (
112144 showTasks: true ,
113- totalTasks: 2
145+ totalTasks: 3
114146 )
115147 let progress = ProgressBar ( config: progressConfig)
116148 defer {
117149 progress. finish ( )
118150 }
119151 progress. start ( )
120152 try await ClientKernel . installKernelFromTar (
121- tarFile: tarRemoteURL. absoluteString, kernelFilePath: kernelFilePath, platform: platform, progressUpdate: progress. handler, force: force)
153+ tarFile: tarRemoteURL. absoluteString,
154+ kernelFilePath: kernelFilePath,
155+ platform: platform,
156+ progressUpdate: progress. handler,
157+ expectedDigest: expectedDigest,
158+ force: force)
122159 progress. finish ( )
123160 }
124161
0 commit comments