diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesTask.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesTask.kt index 269b9d12..33b5fc82 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesTask.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesTask.kt @@ -28,7 +28,7 @@ data class OciVariantInput( @get:InputFiles @get:PathSensitive(PathSensitivity.NONE) val layerFiles: List, ) -internal class OciMultiArchImage( +internal class OciMultiPlatformImage( val index: OciData, val platformToImage: Map, ) @@ -71,16 +71,16 @@ abstract class OciImagesTask : DefaultTask() { protected fun run() { val imageInputs: Set = images.get() val imageAndReferencesPairs = createImageAndReferencesPairs(imageInputs) - val multiArchImageAndReferencesPairs = createMultiArchImageAndReferencesPairs(imageAndReferencesPairs) + val multiPlatformImageAndReferencesPairs = createMultiPlatformImageAndReferencesPairs(imageAndReferencesPairs) val images = imageAndReferencesPairs.map { it.first } val digestToLayerFile = collectDigestToLayerFile(images) - run(digestToLayerFile, images, multiArchImageAndReferencesPairs) + run(digestToLayerFile, images, multiPlatformImageAndReferencesPairs) } internal abstract fun run( // TODO internal? protected? digestToLayerFile: Map, images: List, - multiArchImageAndReferencesPairs: List>>, + multiPlatformImageAndReferencesPairs: List>>, ) private fun createImageAndReferencesPairs( @@ -124,9 +124,9 @@ abstract class OciImagesTask : DefaultTask() { return OciVariant(metadata, layers) } - private fun createMultiArchImageAndReferencesPairs( + private fun createMultiPlatformImageAndReferencesPairs( imageAndReferencesPairs: Iterable>>, - ): List>> { + ): List>> { // referenceToPlatformToImage map is linked because it will be iterated // platformToImage map is linked to preserve the platform order val referenceToPlatformToImage = LinkedHashMap>() @@ -140,19 +140,19 @@ abstract class OciImagesTask : DefaultTask() { } } } - // multiArchImageAndReferencesPairMap is linked because it will be iterated - val multiArchImageAndReferencesPairMap = - LinkedHashMap, Pair>>() // TODO reference non multi arch images? + // multiPlatformImageAndReferencesPairMap is linked because it will be iterated + val multiPlatformImageAndReferencesPairMap = + LinkedHashMap, Pair>>() // TODO reference non multi arch images? for ((reference, platformToImage) in referenceToPlatformToImage) { - var multiArchImageAndReferencesPair = multiArchImageAndReferencesPairMap[platformToImage] - if (multiArchImageAndReferencesPair == null) { + var multiPlatformImageAndReferencesPair = multiPlatformImageAndReferencesPairMap[platformToImage] + if (multiPlatformImageAndReferencesPair == null) { val index = createIndex(platformToImage) - multiArchImageAndReferencesPair = Pair(OciMultiArchImage(index, platformToImage), ArrayList()) // TODO ArrayList - multiArchImageAndReferencesPairMap[platformToImage] = multiArchImageAndReferencesPair + multiPlatformImageAndReferencesPair = Pair(OciMultiPlatformImage(index, platformToImage), ArrayList()) // TODO ArrayList + multiPlatformImageAndReferencesPairMap[platformToImage] = multiPlatformImageAndReferencesPair } - multiArchImageAndReferencesPair.second += reference + multiPlatformImageAndReferencesPair.second += reference } - return multiArchImageAndReferencesPairMap.values.toList() + return multiPlatformImageAndReferencesPairMap.values.toList() } private fun collectDigestToLayerFile(images: List): Map { diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPushTask.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPushTask.kt index 9d75cdc3..70be7517 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPushTask.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciPushTask.kt @@ -88,10 +88,10 @@ abstract class OciPushTask @Inject constructor(private val workerExecutor: Worke protected fun setRegistryCredentialsId(credentialsId: String) = registry.credentials.set(project.providers.passwordCredentials(credentialsId)) - override fun run( + final override fun run( digestToLayerFile: Map, images: List, - multiArchImageAndReferencesPairs: List>>, + multiPlatformImageAndReferencesPairs: List>>, ) { val context = Context( pushService, @@ -102,10 +102,10 @@ abstract class OciPushTask @Inject constructor(private val workerExecutor: Worke ) val blobs = HashMap() - for ((multiArchImage, imageReferences) in multiArchImageAndReferencesPairs) { + for ((multiPlatformImage, imageReferences) in multiPlatformImageAndReferencesPairs) { for ((imageName, tags) in imageReferences.groupByTo(HashMap(), { it.name }, { it.tag })) { val manifestFutures = mutableListOf>() - for (image in multiArchImage.platformToImage.values) { + for (image in multiPlatformImage.platformToImage.values) { val blobFutures = mutableListOf>() for (variant in image.variants) { for (layer in variant.layers) { @@ -171,7 +171,7 @@ abstract class OciPushTask @Inject constructor(private val workerExecutor: Worke ) } } - val index = multiArchImage.index + val index = multiPlatformImage.index for (tag in tags) { CompletableFuture.allOf(*manifestFutures.toTypedArray()).thenRun { context.pushService.get() diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciRegistryDataTask.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciRegistryDataTask.kt index bb36e1b0..e0d20fa7 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciRegistryDataTask.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciRegistryDataTask.kt @@ -20,10 +20,10 @@ abstract class OciRegistryDataTask : OciImagesTask() { @get:OutputDirectory val registryDataDirectory: DirectoryProperty = project.objects.directoryProperty() - override fun run( + final override fun run( digestToLayerFile: Map, images: List, - multiArchImageAndReferencesPairs: List>>, + multiPlatformImageAndReferencesPairs: List>>, ) { val registryDataDirectory = registryDataDirectory.get().asFile.toPath().ensureEmptyDirectory() val blobsDirectory = registryDataDirectory.resolve("blobs").createDirectory() @@ -35,15 +35,15 @@ abstract class OciRegistryDataTask : OciImagesTask() { blobsDirectory.writeDigestData(image.config.data) blobsDirectory.writeDigestData(image.manifest.data) } - for ((multiArchImage, imageReferences) in multiArchImageAndReferencesPairs) { - blobsDirectory.writeDigestData(multiArchImage.index) + for ((multiPlatformImage, imageReferences) in multiPlatformImageAndReferencesPairs) { + blobsDirectory.writeDigestData(multiPlatformImage.index) for ((name, tags) in imageReferences.groupBy({ it.name }, { it.tag })) { val repositoryDirectory = repositoriesDirectory.resolve(name).createDirectories() val layersDirectory = repositoryDirectory.resolve("_layers").createDirectories() val manifestsDirectory = repositoryDirectory.resolve("_manifests").createDirectories() val manifestRevisionsDirectory = manifestsDirectory.resolve("revisions").createDirectories() val blobDigests = LinkedHashSet() - for (image in multiArchImage.platformToImage.values) { + for (image in multiPlatformImage.platformToImage.values) { manifestRevisionsDirectory.writeDigestLink(image.manifest.digest) blobDigests += image.config.digest for (variant in image.variants) { @@ -55,7 +55,7 @@ abstract class OciRegistryDataTask : OciImagesTask() { for (blobDigest in blobDigests) { layersDirectory.writeDigestLink(blobDigest) } - val indexDigest = multiArchImage.index.digest + val indexDigest = multiPlatformImage.index.digest manifestRevisionsDirectory.writeDigestLink(indexDigest) for (tag in tags) { val tagDirectory = manifestsDirectory.resolve("tags").resolve(tag).createDirectories() diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt index 5d97fe61..8eef2871 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt @@ -13,39 +13,39 @@ import java.util.* */ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { - fun pullMultiArchImageMetadata( + fun pullMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, credentials: Credentials?, - ): Mono = + ): Mono = registryApi.pullManifest(registry, imageReference.name, imageReference.tag.replaceFirst('!', ':'), credentials) - .transformToMultiArchImageMetadata(registry, imageReference, credentials) + .transformToMultiPlatformImageMetadata(registry, imageReference, credentials) - fun pullMultiArchImageMetadata( + fun pullMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, digest: OciDigest, size: Int, credentials: Credentials?, - ): Mono = + ): Mono = registryApi.pullManifest(registry, imageReference.name, digest, size, credentials) - .transformToMultiArchImageMetadata(registry, imageReference, credentials) + .transformToMultiPlatformImageMetadata(registry, imageReference, credentials) - private fun Mono.transformToMultiArchImageMetadata( + private fun Mono.transformToMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, credentials: Credentials?, - ): Mono = flatMap { manifest -> - transformToMultiArchImageMetadata(registry, imageReference, manifest, credentials) + ): Mono = flatMap { manifest -> + transformToMultiPlatformImageMetadata(registry, imageReference, manifest, credentials) } - private fun transformToMultiArchImageMetadata( + private fun transformToMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, manifest: OciData, credentials: Credentials?, - ): Mono = when (manifest.mediaType) { - INDEX_MEDIA_TYPE -> transformIndexToMultiArchImageMetadata( + ): Mono = when (manifest.mediaType) { + INDEX_MEDIA_TYPE -> transformIndexToMultiPlatformImageMetadata( registry, imageReference, manifest, @@ -55,7 +55,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { LAYER_MEDIA_TYPE_PREFIX, ) - MANIFEST_MEDIA_TYPE -> transformManifestToMultiArchImageMetadata( + MANIFEST_MEDIA_TYPE -> transformManifestToMultiPlatformImageMetadata( registry, imageReference, manifest, @@ -64,7 +64,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { LAYER_MEDIA_TYPE_PREFIX, ) - DOCKER_MANIFEST_LIST_MEDIA_TYPE -> transformIndexToMultiArchImageMetadata( + DOCKER_MANIFEST_LIST_MEDIA_TYPE -> transformIndexToMultiPlatformImageMetadata( registry, imageReference, manifest, @@ -74,7 +74,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { DOCKER_LAYER_MEDIA_TYPE, ) - DOCKER_MANIFEST_MEDIA_TYPE -> transformManifestToMultiArchImageMetadata( + DOCKER_MANIFEST_MEDIA_TYPE -> transformManifestToMultiPlatformImageMetadata( registry, imageReference, manifest, @@ -86,7 +86,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { else -> throw IllegalStateException("unsupported manifest media type '${manifest.mediaType}'") } - private fun transformIndexToMultiArchImageMetadata( + private fun transformIndexToMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, index: OciData, @@ -94,7 +94,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { manifestMediaType: String, configMediaType: String, layerMediaTypePrefix: String, - ): Mono { + ): Mono { val indexJsonObject = jsonObject(String(index.bytes)) val indexAnnotations = indexJsonObject.getStringMapOrEmpty("annotations") val metadataMonoList = indexJsonObject.get("manifests") { @@ -141,17 +141,17 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { throw IllegalStateException("duplicate platform in image index: $platform") } } - .map { OciMultiArchImageMetadata(it, index.digest, index.bytes.size) } + .map { OciMultiPlatformImageMetadata(it, index.digest, index.bytes.size) } } - private fun transformManifestToMultiArchImageMetadata( + private fun transformManifestToMultiPlatformImageMetadata( registry: String, imageReference: OciImageReference, manifest: OciData, credentials: Credentials?, configMediaType: String, layerMediaTypePrefix: String, - ): Mono = transformManifestToImageMetadata( + ): Mono = transformManifestToImageMetadata( registry, imageReference, manifest, @@ -160,7 +160,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { credentials, configMediaType, layerMediaTypePrefix, - ).map { OciMultiArchImageMetadata(mapOf(it), manifest.digest, manifest.bytes.size) } + ).map { OciMultiPlatformImageMetadata(mapOf(it), manifest.digest, manifest.bytes.size) } private fun transformManifestToImageMetadata( registry: String, @@ -358,7 +358,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { } } -internal class OciMultiArchImageMetadata( +internal class OciMultiPlatformImageMetadata( val platformToMetadata: Map, val digest: OciDigest, val size: Int, diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt index 695ddd67..bebfbd7b 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt @@ -52,7 +52,7 @@ internal class OciRepositoryHandler( private val credentials: Credentials?, ) : BiFunction> { - private val imageMetadataCache: AsyncCache = + private val imageMetadataCache: AsyncCache = Caffeine.newBuilder().maximumSize(100).expireAfterAccess(1, TimeUnit.MINUTES).buildAsync() private data class ImageMetadataCacheKey( @@ -120,7 +120,7 @@ internal class OciRepositoryHandler( ) val componentId = ociImageComponent.componentId val variantsMetadataMonoList = ociImageComponent.features.map { (featureName, feature) -> - getMultiArchImageMetadata(registryUri, feature.imageReference, credentials).map { + getMultiPlatformImageMetadata(registryUri, feature.imageReference, credentials).map { OciVariantsMetadata(featureName, feature.capabilities, it.platformToMetadata, it.digest, it.size) } } @@ -235,7 +235,7 @@ internal class OciRepositoryHandler( return response.sendBadRequest() } val metadataJsonMono = - getMultiArchImageMetadata(registryUri, imageReference, digest, size, credentials).handle { it, sink -> + getMultiPlatformImageMetadata(registryUri, imageReference, digest, size, credentials).handle { it, sink -> val metadata = it.platformToMetadata[platform] if (metadata == null) { response.status(400) @@ -280,15 +280,15 @@ internal class OciRepositoryHandler( } } - private fun getMultiArchImageMetadata( + private fun getMultiPlatformImageMetadata( registryUri: URI, imageReference: OciImageReference, credentials: Credentials?, - ): Mono { + ): Mono { return imageMetadataCache.getMono( ImageMetadataCacheKey(registryUri.toString(), imageReference, null, -1, credentials?.hashed()) ) { key -> - imageMetadataRegistry.pullMultiArchImageMetadata(key.registry, key.imageReference, credentials).doOnNext { + imageMetadataRegistry.pullMultiPlatformImageMetadata(key.registry, key.imageReference, credentials).doOnNext { imageMetadataCache.asMap().putIfAbsent( key.copy(digest = it.digest, size = it.size), CompletableFuture.completedFuture(it), @@ -297,17 +297,17 @@ internal class OciRepositoryHandler( } } - private fun getMultiArchImageMetadata( + private fun getMultiPlatformImageMetadata( registryUri: URI, imageReference: OciImageReference, digest: OciDigest, size: Int, credentials: Credentials?, - ): Mono { + ): Mono { return imageMetadataCache.getMono( ImageMetadataCacheKey(registryUri.toString(), imageReference, digest, size, credentials?.hashed()) ) { (registry, imageReference) -> - imageMetadataRegistry.pullMultiArchImageMetadata(registry, imageReference, digest, size, credentials) + imageMetadataRegistry.pullMultiPlatformImageMetadata(registry, imageReference, digest, size, credentials) } }