Skip to content

Commit c941ef6

Browse files
committed
ContainerRegistry: publishContainerImage should not be a method of RegistryClient
1 parent 935912e commit c941ef6

File tree

1 file changed

+140
-140
lines changed

1 file changed

+140
-140
lines changed

Sources/containertool/containertool.swift

Lines changed: 140 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,11 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
216216

217217
// MARK: Build the image
218218

219-
let finalImage = try await destination.publishContainerImage(
219+
let finalImage = try await publishContainerImage(
220220
baseImage: baseImage,
221221
destinationImage: destinationImage,
222222
source: source,
223+
destination: destination,
223224
architecture: architecture,
224225
os: os,
225226
resources: imageBuildOptions.resources,
@@ -232,165 +233,164 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
232233
}
233234
}
234235

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-
}
236+
func publishContainerImage(
237+
baseImage: ImageReference,
238+
destinationImage: ImageReference,
239+
source: RegistryClient?,
240+
destination: RegistryClient,
241+
architecture: String,
242+
os: String,
243+
resources: [String],
244+
tag: String?,
245+
verbose: Bool,
246+
executableURL: URL
247+
) async throws -> ImageReference {
248+
249+
// MARK: Find the base image
250+
251+
let baseImageManifest: ImageManifest
252+
let baseImageConfiguration: ImageConfiguration
253+
let baseImageDescriptor: ContentDescriptor
254+
if let source {
255+
(baseImageManifest, baseImageDescriptor) = try await source.getImageManifest(
256+
forImage: baseImage,
257+
architecture: architecture
258+
)
259+
try log("Found base image manifest: \(ImageReference.Digest(baseImageDescriptor.digest))")
292260

293-
resourceLayers.append(resourceLayer)
294-
}
261+
baseImageConfiguration = try await source.getImageConfiguration(
262+
forImage: baseImage,
263+
digest: ImageReference.Digest(baseImageManifest.config.digest)
264+
)
265+
log("Found base image configuration: \(baseImageManifest.config.digest)")
266+
} else {
267+
baseImageManifest = .init(
268+
schemaVersion: 2,
269+
config: .init(mediaType: "scratch", digest: "scratch", size: 0),
270+
layers: []
271+
)
272+
baseImageConfiguration = .init(
273+
architecture: architecture,
274+
os: os,
275+
rootfs: .init(_type: "layers", diff_ids: [])
276+
)
277+
if verbose { log("Using scratch as base image") }
278+
}
295279

296-
// MARK: Upload the application layer
280+
// MARK: Upload resource layers
297281

298-
let applicationLayer = try await self.uploadLayer(
282+
var resourceLayers: [RegistryClient.ImageLayer] = []
283+
for resourceDir in resources {
284+
let resourceTardiff = try Archive().appendingRecursively(atPath: resourceDir).bytes
285+
let resourceLayer = try await destination.uploadLayer(
299286
repository: destinationImage.repository,
300-
contents: try Archive().appendingFile(at: executableURL).bytes
287+
contents: resourceTardiff
301288
)
289+
302290
if verbose {
303-
log("application layer: \(applicationLayer.descriptor.digest) (\(applicationLayer.descriptor.size) bytes)")
291+
log("resource layer: \(resourceLayer.descriptor.digest) (\(resourceLayer.descriptor.size) bytes)")
304292
}
305293

306-
// MARK: Create the application configuration
294+
resourceLayers.append(resourceLayer)
295+
}
307296

308-
let timestamp = Date(timeIntervalSince1970: 0).ISO8601Format()
297+
// MARK: Upload the application layer
309298

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 = "/"
299+
let applicationLayer = try await destination.uploadLayer(
300+
repository: destinationImage.repository,
301+
contents: try Archive().appendingFile(at: executableURL).bytes
302+
)
303+
if verbose {
304+
log("application layer: \(applicationLayer.descriptor.digest) (\(applicationLayer.descriptor.size) bytes)")
305+
}
316306

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-
)
307+
// MARK: Create the application configuration
308+
309+
let timestamp = Date(timeIntervalSince1970: 0).ISO8601Format()
310+
311+
// Inherit the configuration of the base image - UID, GID, environment etc -
312+
// and override the entrypoint.
313+
var inheritedConfiguration = baseImageConfiguration.config ?? .init()
314+
inheritedConfiguration.Entrypoint = ["/\(executableURL.lastPathComponent)"]
315+
inheritedConfiguration.Cmd = []
316+
inheritedConfiguration.WorkingDir = "/"
317+
318+
let configuration = ImageConfiguration(
319+
created: timestamp,
320+
architecture: architecture,
321+
os: os,
322+
config: inheritedConfiguration,
323+
rootfs: .init(
324+
_type: "layers",
325+
// The diff_id is the digest of the _uncompressed_ layer archive.
326+
// It is used by the runtime, which might not store the layers in
327+
// the compressed form in which it received them from the registry.
328+
diff_ids: baseImageConfiguration.rootfs.diff_ids
329+
+ resourceLayers.map { "\($0.diffID)" }
330+
+ ["\(applicationLayer.diffID)"]
331+
),
332+
history: [.init(created: timestamp, created_by: "containertool")]
333+
)
333334

334-
let configurationBlobReference = try await self.putImageConfiguration(
335-
forImage: destinationImage,
336-
configuration: configuration
337-
)
335+
let configurationBlobReference = try await destination.putImageConfiguration(
336+
forImage: destinationImage,
337+
configuration: configuration
338+
)
338339

339-
if verbose {
340-
log("image configuration: \(configurationBlobReference.digest) (\(configurationBlobReference.size) bytes)")
341-
}
340+
if verbose {
341+
log("image configuration: \(configurationBlobReference.digest) (\(configurationBlobReference.size) bytes)")
342+
}
342343

343-
// MARK: Create application manifest
344+
// MARK: Create application manifest
344345

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-
)
346+
let manifest = ImageManifest(
347+
schemaVersion: 2,
348+
mediaType: "application/vnd.oci.image.manifest.v1+json",
349+
config: configurationBlobReference,
350+
layers: baseImageManifest.layers
351+
+ resourceLayers.map { $0.descriptor }
352+
+ [applicationLayer.descriptor]
353+
)
353354

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-
}
355+
// MARK: Upload base image
356+
357+
// Copy the base image layers to the destination repository
358+
// Layers could be checked and uploaded concurrently
359+
// This could also happen in parallel with the application image build
360+
if let source {
361+
for layer in baseImageManifest.layers {
362+
try await source.copyBlob(
363+
digest: ImageReference.Digest(layer.digest),
364+
fromRepository: baseImage.repository,
365+
toClient: destination,
366+
toRepository: destinationImage.repository
367+
)
368368
}
369+
}
369370

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-
)
371+
// MARK: Upload application manifest
377372

378-
if verbose {
379-
log("manifest: \(manifestDescriptor.digest) (\(manifestDescriptor.size) bytes)")
380-
}
373+
let manifestDescriptor = try await destination.putManifest(
374+
repository: destinationImage.repository,
375+
reference: destinationImage.reference,
376+
manifest: manifest
377+
)
381378

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-
}
379+
if verbose {
380+
log("manifest: \(manifestDescriptor.digest) (\(manifestDescriptor.size) bytes)")
381+
}
391382

392-
var result = destinationImage
393-
result.reference = reference
394-
return result
383+
// Use the manifest's digest if the user did not provide a human-readable tag
384+
// To support multiarch images, we should also create an an index pointing to
385+
// this manifest.
386+
let reference: ImageReference.Reference
387+
if let tag {
388+
reference = try ImageReference.Tag(tag)
389+
} else {
390+
reference = try ImageReference.Digest(manifestDescriptor.digest)
395391
}
392+
393+
var result = destinationImage
394+
result.reference = reference
395+
return result
396396
}

0 commit comments

Comments
 (0)