1212//
1313//===----------------------------------------------------------------------===//
1414
15- import ArgumentParser
1615import Foundation
17- import ContainerRegistry
18- import Tar
16+ import ArgumentParser
1917import Basics
18+ import ContainerRegistry
2019
2120extension Swift . String : Swift . Error { }
2221
@@ -216,10 +215,11 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
216215
217216 // MARK: Build the image
218217
219- let finalImage = try await destination . publishContainerImage (
218+ let finalImage = try await publishContainerImage (
220219 baseImage: baseImage,
221220 destinationImage: destinationImage,
222221 source: source,
222+ destination: destination,
223223 architecture: architecture,
224224 os: os,
225225 resources: imageBuildOptions. resources,
@@ -231,166 +231,3 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
231231 print ( finalImage)
232232 }
233233}
234-
235- extension RegistryClient {
236- func publishContainerImage(
237- baseImage: ImageReference ,
238- destinationImage: ImageReference ,
239- source: RegistryClient ? ,
240- architecture: String ,
241- os: String ,
242- resources: [ String ] ,
243- tag: String ? ,
244- verbose: Bool ,
245- executableURL: URL
246- ) async throws -> ImageReference {
247-
248- // MARK: Find the base image
249-
250- let baseImageManifest : ImageManifest
251- let baseImageConfiguration : ImageConfiguration
252- let baseImageDescriptor : ContentDescriptor
253- if let source {
254- ( baseImageManifest, baseImageDescriptor) = try await source. getImageManifest (
255- forImage: baseImage,
256- architecture: architecture
257- )
258- try log ( " Found base image manifest: \( ImageReference . Digest ( baseImageDescriptor. digest) ) " )
259-
260- baseImageConfiguration = try await source. getImageConfiguration (
261- forImage: baseImage,
262- digest: ImageReference . Digest ( baseImageManifest. config. digest)
263- )
264- log ( " Found base image configuration: \( baseImageManifest. config. digest) " )
265- } else {
266- baseImageManifest = . init(
267- schemaVersion: 2 ,
268- config: . init( mediaType: " scratch " , digest: " scratch " , size: 0 ) ,
269- layers: [ ]
270- )
271- baseImageConfiguration = . init(
272- architecture: architecture,
273- os: os,
274- rootfs: . init( _type: " layers " , diff_ids: [ ] )
275- )
276- if verbose { log ( " Using scratch as base image " ) }
277- }
278-
279- // MARK: Upload resource layers
280-
281- var resourceLayers : [ RegistryClient . ImageLayer ] = [ ]
282- for resourceDir in resources {
283- let resourceTardiff = try Archive ( ) . appendingRecursively ( atPath: resourceDir) . bytes
284- let resourceLayer = try await self . uploadLayer (
285- repository: destinationImage. repository,
286- contents: resourceTardiff
287- )
288-
289- if verbose {
290- log ( " resource layer: \( resourceLayer. descriptor. digest) ( \( resourceLayer. descriptor. size) bytes) " )
291- }
292-
293- resourceLayers. append ( resourceLayer)
294- }
295-
296- // MARK: Upload the application layer
297-
298- let applicationLayer = try await self . uploadLayer (
299- repository: destinationImage. repository,
300- contents: try Archive ( ) . appendingFile ( at: executableURL) . bytes
301- )
302- if verbose {
303- log ( " application layer: \( applicationLayer. descriptor. digest) ( \( applicationLayer. descriptor. size) bytes) " )
304- }
305-
306- // MARK: Create the application configuration
307-
308- let timestamp = Date ( timeIntervalSince1970: 0 ) . ISO8601Format ( )
309-
310- // Inherit the configuration of the base image - UID, GID, environment etc -
311- // and override the entrypoint.
312- var inheritedConfiguration = baseImageConfiguration. config ?? . init( )
313- inheritedConfiguration. Entrypoint = [ " / \( executableURL. lastPathComponent) " ]
314- inheritedConfiguration. Cmd = [ ]
315- inheritedConfiguration. WorkingDir = " / "
316-
317- let configuration = ImageConfiguration (
318- created: timestamp,
319- architecture: architecture,
320- os: os,
321- config: inheritedConfiguration,
322- rootfs: . init(
323- _type: " layers " ,
324- // The diff_id is the digest of the _uncompressed_ layer archive.
325- // It is used by the runtime, which might not store the layers in
326- // the compressed form in which it received them from the registry.
327- diff_ids: baseImageConfiguration. rootfs. diff_ids
328- + resourceLayers. map { " \( $0. diffID) " }
329- + [ " \( applicationLayer. diffID) " ]
330- ) ,
331- history: [ . init( created: timestamp, created_by: " containertool " ) ]
332- )
333-
334- let configurationBlobReference = try await self . putImageConfiguration (
335- forImage: destinationImage,
336- configuration: configuration
337- )
338-
339- if verbose {
340- log ( " image configuration: \( configurationBlobReference. digest) ( \( configurationBlobReference. size) bytes) " )
341- }
342-
343- // MARK: Create application manifest
344-
345- let manifest = ImageManifest (
346- schemaVersion: 2 ,
347- mediaType: " application/vnd.oci.image.manifest.v1+json " ,
348- config: configurationBlobReference,
349- layers: baseImageManifest. layers
350- + resourceLayers. map { $0. descriptor }
351- + [ applicationLayer. descriptor]
352- )
353-
354- // MARK: Upload base image
355-
356- // Copy the base image layers to the destination repository
357- // Layers could be checked and uploaded concurrently
358- // This could also happen in parallel with the application image build
359- if let source {
360- for layer in baseImageManifest. layers {
361- try await source. copyBlob (
362- digest: ImageReference . Digest ( layer. digest) ,
363- fromRepository: baseImage. repository,
364- toClient: self ,
365- toRepository: destinationImage. repository
366- )
367- }
368- }
369-
370- // MARK: Upload application manifest
371-
372- let manifestDescriptor = try await self . putManifest (
373- repository: destinationImage. repository,
374- reference: destinationImage. reference,
375- manifest: manifest
376- )
377-
378- if verbose {
379- log ( " manifest: \( manifestDescriptor. digest) ( \( manifestDescriptor. size) bytes) " )
380- }
381-
382- // Use the manifest's digest if the user did not provide a human-readable tag
383- // To support multiarch images, we should also create an an index pointing to
384- // this manifest.
385- let reference : ImageReference . Reference
386- if let tag {
387- reference = try ImageReference . Tag ( tag)
388- } else {
389- reference = try ImageReference . Digest ( manifestDescriptor. digest)
390- }
391-
392- var result = destinationImage
393- result. reference = reference
394- return result
395- }
396- }
0 commit comments