Skip to content

jib-core: ReproducibleLayerBuilder blob improperly closes the output stream #4505

@scottjasso

Description

@scottjasso

Environment:

  • Jib version: jib-core: 0.28.1
  • Build tool: gradle
  • OS: Mac (irrelevant)

Description of the issue:
ReproducibleLayerBuilder builds a blob that first calls close on the underlying OutputStream (contrary to the javadoc), and then later calls flush, causing many OutputStream implementations to throw.

  1. ReproducibleLayerBuilder uses TarStreamBuilder under the hood. It returns Blobs.from(tarStreamBuilder::writeAsTarArchiveTo, false), which creates a WriteableContentsBlob.
  2. TarStreamBuilder.writeAsTarArchiveTo uses try-with-resources, which closes the underlying OutputStream when finished.
  3. WriteableContentsBlob.writeTo uses Digests.computeDigest(writableContents, outputStream), which does this:
    CountingDigestOutputStream digestOutStream = new CountingDigestOutputStream(outStream);
    contents.writeTo(digestOutStream);
    digestOutStream.flush();
    return digestOutStream.computeDigest();

Line 2 closes the digestOutputStream (because of writeAsTarArchiveTo), so then line 3 flushes after close.

Expected behavior:

Blob.writeTo should never call close on the OutputStream. You should be able to use any OutputStream.

TarStreamBuilder should not close the output stream passed to it.

Steps to reproduce:

ReproducibleLayerBuilder blob = new ReproducibleLayerBuilder(ImmutableList.of()).build();
// this causes ZstdOutputStream to throw IOException: StreamClosed
blob.writeTo(new ZstdOutputStream(new ByteArrayOutputStream()));

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions