Skip to content

Commit

Permalink
conformance tests: don't break on trailing zeroes in layer blobs
Browse files Browse the repository at this point in the history
When analyzing a layer blob's contents, don't break if the blob has more
zeroes padding it out even after the tar reader thinks it's hit the end
of the archive.

Add more detail to the diagnostic error we print when there's a digest
or length mismatch, too, in case it's triggered by something other than
zero padding.

Don't ignore errors which might be encountered when we try to use skopeo
to copy an image to a directory.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
  • Loading branch information
nalind committed Mar 6, 2024
1 parent 204cbdb commit b2504c2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
3 changes: 1 addition & 2 deletions tests/blobcache.bats
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ function _check_matches() {
run_buildah login --tls-verify=false --authfile ${TEST_SCRATCH_DIR}/test.auth --username testuser --password testpassword localhost:${REGISTRY_PORT}
outputdir=${TEST_SCRATCH_DIR}/outputdir
mkdir -p ${outputdir}
run podman run --rm --mount type=bind,src=${TEST_SCRATCH_DIR}/test.auth,target=/test.auth,Z --mount type=bind,src=${outputdir},target=/output,Z --net host quay.io/skopeo/stable copy --preserve-digests --authfile=/test.auth --tls-verify=false docker://registry.fedoraproject.org/fedora-minimal dir:/output

podman run --rm --mount type=bind,src=${TEST_SCRATCH_DIR}/test.auth,target=/test.auth,Z --mount type=bind,src=${outputdir},target=/output,Z --net host quay.io/skopeo/stable copy --preserve-digests --authfile=/test.auth --tls-verify=false docker://registry.fedoraproject.org/fedora-minimal dir:/output
run_buildah rmi --all -f
run_buildah pull dir:${outputdir}
run_buildah images -a --format '{{.ID}}'
Expand Down
21 changes: 18 additions & 3 deletions tests/conformance/conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/reexec"
dockertypes "github.com/docker/docker/api/types"
dockerdockerclient "github.com/docker/docker/client"
Expand Down Expand Up @@ -934,11 +935,15 @@ func saveReport(ctx context.Context, t *testing.T, ref types.ImageReference, dir
// summarizeLayer reads a blob and returns a summary of the parts of its contents that we care about
func summarizeLayer(t *testing.T, imageName string, blobInfo types.BlobInfo, reader io.Reader) (layer Layer) {
compressedDigest := digest.Canonical.Digester()
uncompressedBlob, _, err := compression.AutoDecompress(io.TeeReader(reader, compressedDigest.Hash()))
counter := ioutils.NewWriteCounter(compressedDigest.Hash())
compressionAlgorithm, _, reader, err := compression.DetectCompressionFormat(reader)
require.NoErrorf(t, err, "error checking if blob %+v for image %q is compressed", blobInfo, imageName)
uncompressedBlob, wasCompressed, err := compression.AutoDecompress(io.TeeReader(reader, counter))
require.NoErrorf(t, err, "error decompressing blob %+v for image %q", blobInfo, imageName)
defer uncompressedBlob.Close()
uncompressedDigest := digest.Canonical.Digester()
tr := tar.NewReader(io.TeeReader(uncompressedBlob, uncompressedDigest.Hash()))
tarToRead := io.TeeReader(uncompressedBlob, uncompressedDigest.Hash())
tr := tar.NewReader(tarToRead)
hdr, err := tr.Next()
for err == nil {
header := fsHeaderForEntry(hdr)
Expand All @@ -953,8 +958,18 @@ func summarizeLayer(t *testing.T, imageName string, blobInfo types.BlobInfo, rea
hdr, err = tr.Next()
}
require.Equal(t, io.EOF, err, "unexpected error reading layer contents %+v for image %q", blobInfo, imageName)
_, err = io.Copy(io.Discard, tarToRead)
require.NoError(t, err, "reading out any not-usually-present zero padding at the end")
layer.CompressedDigest = compressedDigest.Digest()
require.Equal(t, blobInfo.Digest, layer.CompressedDigest, "calculated digest of compressed blob didn't match expected digest")
blobFormatDescription := "uncompressed"
if wasCompressed {
if compressionAlgorithm.Name() != "" {
blobFormatDescription = "compressed with " + compressionAlgorithm.Name()
} else {
blobFormatDescription = "compressed (?)"
}
}
require.Equalf(t, blobInfo.Digest, layer.CompressedDigest, "calculated digest of %s blob didn't match expected digest (expected length %d, actual length %d)", blobFormatDescription, blobInfo.Size, counter.Count)
layer.UncompressedDigest = uncompressedDigest.Digest()
return layer
}
Expand Down

0 comments on commit b2504c2

Please sign in to comment.