Skip to content

Commit

Permalink
Add OciData
Browse files Browse the repository at this point in the history
Replace OciRegistryApi.Metadata with OciData
Refactor OciDataDescriptor
  • Loading branch information
SgtSilvio committed Jul 10, 2024
1 parent ad71b1e commit 1e2a7f4
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal val DEFAULT_OCI_REFERENCE_SPEC = OciImageReferenceSpec(null, null)

internal class OciLayer( // TODO internal?
val descriptor: OciMetadata.Layer.Descriptor,
val file: File
val file: File,
)

internal class OciVariant(
Expand All @@ -61,7 +61,7 @@ internal class OciImage(
)

internal class OciMultiArchImage(
val index: OciDataDescriptor,
val index: OciData,
val platformToImage: Map<Platform, OciImage>,
)

Expand Down
15 changes: 8 additions & 7 deletions src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPushTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ abstract class OciPushTask @Inject constructor(
val configDigest = config.digest
val sourceBlob = blobs[configDigest]
blobFutures += if (sourceBlob == null) {
val size = config.data.size.toLong()
val sender: NettyOutbound.() -> Publisher<Void> = { sendByteArray(config.data.toMono()) }
val bytes = config.data.bytes
val sender: NettyOutbound.() -> Publisher<Void> = { sendByteArray(bytes.toMono()) }
val future = CompletableFuture<Unit>()
blobs[configDigest] = Blob(configDigest, size, sender, imageName, imageName, future)
blobs[configDigest] = Blob(configDigest, config.size, sender, imageName, imageName, future)
future
} else if (sourceBlob.imageName == imageName) {
sourceBlob.future
Expand All @@ -161,7 +161,7 @@ abstract class OciPushTask @Inject constructor(
val manifest = image.manifest
val manifestDigest = manifest.digest
val manifestMediaType = manifest.mediaType
val manifestData = manifest.data
val manifestBytes = manifest.data.bytes
val manifestFuture = CompletableFuture<Unit>()
manifestFutures += manifestFuture
CompletableFuture.allOf(*blobFutures.toTypedArray()).thenRun {
Expand All @@ -170,17 +170,18 @@ abstract class OciPushTask @Inject constructor(
imageName,
manifestDigest.toString(),
manifestMediaType,
manifestData,
manifestBytes,
manifestFuture,
)
}
}
val index = multiArchImage.index
for (tag in tags) {
val indexMediaType = index.mediaType
val indexData = index.data
val indexBytes = index.bytes
CompletableFuture.allOf(*manifestFutures.toTypedArray()).thenRun {
context.pushService.get().pushManifest(context, imageName, tag, indexMediaType, indexData, null)
context.pushService.get()
.pushManifest(context, imageName, tag, indexMediaType, indexBytes, null)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.sgtsilvio.gradle.oci

import io.github.sgtsilvio.gradle.oci.metadata.OciDataDescriptor
import io.github.sgtsilvio.gradle.oci.metadata.OciData
import io.github.sgtsilvio.gradle.oci.metadata.OciDigest
import io.github.sgtsilvio.gradle.oci.metadata.OciImageReference
import org.gradle.api.file.DirectoryProperty
Expand Down Expand Up @@ -32,8 +32,8 @@ abstract class OciRegistryDataTask : OciImagesInputTask() {
blobsDirectory.resolveDigestDataFile(digest).createLinkPointingTo(layerFile.toPath())
}
for (image in images) {
blobsDirectory.writeDigestData(image.config)
blobsDirectory.writeDigestData(image.manifest)
blobsDirectory.writeDigestData(image.config.data)
blobsDirectory.writeDigestData(image.manifest.data)
}
for ((multiArchImage, imageReferences) in multiArchImageAndReferencesPairs) {
blobsDirectory.writeDigestData(multiArchImage.index)
Expand Down Expand Up @@ -74,13 +74,13 @@ abstract class OciRegistryDataTask : OciImagesInputTask() {
.resolve("data")
}

private fun Path.writeDigestData(dataDescriptor: OciDataDescriptor) {
val digestDataFile = resolveDigestDataFile(dataDescriptor.digest)
private fun Path.writeDigestData(data: OciData) {
val digestDataFile = resolveDigestDataFile(data.digest)
try {
digestDataFile.writeBytes(dataDescriptor.data, StandardOpenOption.CREATE_NEW)
digestDataFile.writeBytes(data.bytes, StandardOpenOption.CREATE_NEW)
} catch (e: FileAlreadyExistsException) {
if (!dataDescriptor.data.contentEquals(digestDataFile.readBytes())) {
throw IllegalStateException("hash collision for digest ${dataDescriptor.digest}: expected file content of $digestDataFile to be the same as ${dataDescriptor.data.contentToString()}")
if (!data.bytes.contentEquals(digestDataFile.readBytes())) {
throw IllegalStateException("hash collision for digest ${data.digest}: expected file content of $digestDataFile to be the same as ${data.bytes.contentToString()}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
): Mono<List<Metadata>> = registryApi.pullManifest(registry, imageReference.name, digest, size, credentials)
.transformToMetadataList(registry, imageReference, credentials)

private fun Mono<OciRegistryApi.Manifest>.transformToMetadataList(
private fun Mono<OciData>.transformToMetadataList(
registry: String,
imageReference: OciImageReference,
credentials: Credentials?,
Expand All @@ -43,7 +43,7 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
private fun transformToMetadataList(
registry: String,
imageReference: OciImageReference,
manifest: OciRegistryApi.Manifest,
manifest: OciData,
credentials: Credentials?,
): Mono<List<Metadata>> = when (manifest.mediaType) {
INDEX_MEDIA_TYPE -> transformIndexToMetadataList(
Expand Down Expand Up @@ -90,13 +90,13 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
private fun transformIndexToMetadataList(
registry: String,
imageReference: OciImageReference,
index: OciRegistryApi.Manifest,
index: OciData,
credentials: Credentials?,
manifestMediaType: String,
configMediaType: String,
layerMediaTypePrefix: String,
): Mono<List<Metadata>> {
val indexJsonObject = jsonObject(String(index.data))
val indexJsonObject = jsonObject(String(index.bytes))
val indexAnnotations = indexJsonObject.getStringMapOrEmpty("annotations")
val metadataMonoList = indexJsonObject.get("manifests") {
asArray().toList {
Expand Down Expand Up @@ -142,7 +142,7 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
private fun transformManifestToMetadataList(
registry: String,
imageReference: OciImageReference,
manifest: OciRegistryApi.Manifest,
manifest: OciData,
credentials: Credentials?,
configMediaType: String,
layerMediaTypePrefix: String,
Expand All @@ -160,14 +160,14 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
private fun transformManifestToMetadata(
registry: String,
imageReference: OciImageReference,
manifest: OciRegistryApi.Manifest,
manifest: OciData,
manifestDescriptorAnnotations: SortedMap<String, String>,
indexAnnotations: SortedMap<String, String>,
credentials: Credentials?,
configMediaType: String,
layerMediaTypePrefix: String,
): Mono<Metadata> {
val manifestJsonObject = jsonObject(String(manifest.data))
val manifestJsonObject = jsonObject(String(manifest.bytes))
val manifestAnnotations = manifestJsonObject.getStringMapOrEmpty("annotations")
val configDescriptor = manifestJsonObject.get("config") { asObject().decodeOciDescriptor() }
val layerDescriptors =
Expand Down Expand Up @@ -294,7 +294,7 @@ internal class OciMetadataRegistry(val registryApi: OciRegistryApi) {
),
Platform(os, architecture, variant, osVersion, osFeatures),
manifest.digest,
manifest.data.size,
manifest.bytes.size,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,12 @@ internal class OciRegistryApi(httpClient: HttpClient) {
) = currentDuration
}

class Manifest(val mediaType: String, val data: ByteArray, val digest: OciDigest)

private fun pullManifestInternal(
registry: String,
imageName: String,
reference: String,
credentials: Credentials?,
): Mono<Manifest> {
): Mono<OciData> {
return send(
registry,
imageName,
Expand All @@ -125,7 +123,7 @@ internal class OciRegistryApi(httpClient: HttpClient) {
val digestAlgorithm =
response.responseHeaders()["docker-content-digest"]?.toOciDigest()?.algorithm
?: OciDigestAlgorithm.SHA_256
Manifest(contentType, data, data.calculateOciDigest(digestAlgorithm))
OciData(contentType, data, digestAlgorithm)
}
} ?: createError(response, body.aggregate())

Expand All @@ -139,7 +137,7 @@ internal class OciRegistryApi(httpClient: HttpClient) {
imageName: String,
reference: String,
credentials: Credentials?,
): Mono<Manifest> = when {
): Mono<OciData> = when {
':' in reference -> pullManifest(registry, imageName, reference.toOciDigest(), -1, credentials)
else -> pullManifestInternal(registry, imageName, reference, credentials)
}
Expand All @@ -150,8 +148,8 @@ internal class OciRegistryApi(httpClient: HttpClient) {
digest: OciDigest,
size: Int,
credentials: Credentials?,
): Mono<Manifest> = pullManifestInternal(registry, imageName, digest.toString(), credentials).map { manifest ->
val manifestBytes = manifest.data
): Mono<OciData> = pullManifestInternal(registry, imageName, digest.toString(), credentials).map { manifest ->
val manifestBytes = manifest.bytes
if ((size != -1) && (size != manifestBytes.size)) {
throw sizeMismatchException(size.toLong(), manifestBytes.size.toLong())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ internal data class OciDescriptorImpl(
override val annotations: SortedMap<String, String>,
) : OciDescriptor

internal class OciDataDescriptor(
override val mediaType: String,
val data: ByteArray,
internal class OciData(
val mediaType: String,
val bytes: ByteArray,
digestAlgorithm: OciDigestAlgorithm,
) {
val digest = bytes.calculateOciDigest(digestAlgorithm)
}

internal class OciDataDescriptor(
val data: OciData,
override val annotations: SortedMap<String, String>,
) : OciDescriptor {
override val digest = data.calculateOciDigest(digestAlgorithm)
override val size get() = data.size.toLong()
override val mediaType get() = data.mediaType
override val digest get() = data.digest
override val size get() = data.bytes.size.toLong()
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ internal fun createConfig(platform: Platform, variants: List<OciVariant>): OciDa
addStringIfNotEmpty("variant", platform.variant)
}.toByteArray()
return OciDataDescriptor(
CONFIG_MEDIA_TYPE,
data,
OciDigestAlgorithm.SHA_256,
OciData(CONFIG_MEDIA_TYPE, data, OciDigestAlgorithm.SHA_256),
lastVariantMetadata.configDescriptorAnnotations, // TODO lastVariantMetadata?
)
}
Expand All @@ -106,14 +104,12 @@ internal fun createManifest(configDescriptor: OciDescriptor, variants: List<OciV
addNumber("schemaVersion", 2)
}.toByteArray()
return OciDataDescriptor(
MANIFEST_MEDIA_TYPE,
data,
OciDigestAlgorithm.SHA_256,
OciData(MANIFEST_MEDIA_TYPE, data, OciDigestAlgorithm.SHA_256),
lastVariantMetadata.manifestDescriptorAnnotations, // TODO lastVariantMetadata?
)
}

internal fun createIndex(platformToImage: Map<Platform, OciImage>): OciDataDescriptor {
internal fun createIndex(platformToImage: Map<Platform, OciImage>): OciData {
val indexAnnotations = TreeMap<String, String>()
val images = platformToImage.values
if (images.isNotEmpty()) {
Expand All @@ -134,7 +130,7 @@ internal fun createIndex(platformToImage: Map<Platform, OciImage>): OciDataDescr
addString("mediaType", INDEX_MEDIA_TYPE)
addNumber("schemaVersion", 2)
}.toByteArray()
return OciDataDescriptor(INDEX_MEDIA_TYPE, data, OciDigestAlgorithm.SHA_256, TreeMap())
return OciData(INDEX_MEDIA_TYPE, data, OciDigestAlgorithm.SHA_256)
}

private fun JsonObjectStringBuilder.encodeOciDescriptor(descriptor: OciDescriptor) {
Expand Down

0 comments on commit 1e2a7f4

Please sign in to comment.