diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInput.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInput.kt index e4505fea..3207e8bc 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInput.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInput.kt @@ -2,10 +2,7 @@ package io.github.sgtsilvio.gradle.oci import io.github.sgtsilvio.gradle.oci.component.* import io.github.sgtsilvio.gradle.oci.dsl.ResolvableOciImageDependencies -import io.github.sgtsilvio.gradle.oci.metadata.OciDigest -import io.github.sgtsilvio.gradle.oci.metadata.OciDigestAlgorithm -import io.github.sgtsilvio.gradle.oci.metadata.OciImageReference -import io.github.sgtsilvio.gradle.oci.metadata.calculateOciDigests +import io.github.sgtsilvio.gradle.oci.metadata.* import org.apache.commons.io.FileUtils import org.gradle.api.DefaultTask import org.gradle.api.NonExtensible @@ -57,8 +54,8 @@ abstract class OciImagesInputTask : DefaultTask() { } for ((layerDescriptor, layer) in layers) { val prevLayer = digestToLayer.putIfAbsent(layerDescriptor.digest, layer) - if ((prevLayer != null) && (prevLayer != layer) && !FileUtils.contentEquals(prevLayer, layer)) { - throw IllegalStateException("hash collision for digest ${layerDescriptor.digest}: expected file contents of $prevLayer and $layer to be the same") + if (prevLayer != null) { + checkDuplicateLayer(layerDescriptor, prevLayer, layer) } } for ((rootCapability, references) in imagesInput.rootCapabilities.get()) { @@ -212,4 +209,21 @@ abstract class OciImagesInputTask : DefaultTask() { } } } + + private fun checkDuplicateLayer(layerDescriptor: OciComponent.Bundle.Layer.Descriptor, file1: File, file2: File) { + if (file1 != file2) { + if (!FileUtils.contentEquals(file1, file2)) { + throw IllegalStateException("hash collision for digest ${layerDescriptor.digest}: expected file contents of $file1 and $file2 to be the same") + } + if (layerDescriptor.diffId !in EMPTY_LAYER_DIFF_IDS) { + logger.warn("the same layer (${layerDescriptor.digest}) should not be provided by multiple artifacts ($file1, $file2)") + } + } + } } + +// empty tar = 1024 bytes zeros +private val EMPTY_LAYER_DIFF_IDS = setOf( + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef".toOciDigest(), + "sha512:8efb4f73c5655351c444eb109230c556d39e2c7624e9c11abc9e3fb4b9b9254218cc5085b454a9698d085cfa92198491f07a723be4574adc70617b73eb0b6461".toOciDigest(), +)