diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageTarball.java b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageTarball.java index ce9000aa9f..b87f3a52e7 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageTarball.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageTarball.java @@ -46,10 +46,12 @@ public class ImageTarball { /** File name extension for the layer content files. */ private static final String LAYER_FILE_EXTENSION = ".tar.gz"; + /** Time that entry is set in the tar. */ + private static final Instant TAR_ENTRY_MODIFICATION_TIME = Instant.EPOCH; + private final Image image; private final ImageReference imageReference; private final ImmutableSet allTargetImageTags; - private static final Instant TAR_ENTRY_MODIFICATION_TIME = Instant.EPOCH; /** * Instantiate with an {@link Image}. @@ -91,7 +93,7 @@ private void ociWriteTo(OutputStream out) throws IOException { long size = layer.getBlobDescriptor().getSize(); tarStreamBuilder.addBlobEntry( - layer.getBlob(), size, "blobs/sha256/" + digest.getHash(), creationTime); + layer.getBlob(), size, "blobs/sha256/" + digest.getHash(), TAR_ENTRY_MODIFICATION_TIME); manifest.addLayer(size, digest); } @@ -103,25 +105,25 @@ private void ociWriteTo(OutputStream out) throws IOException { tarStreamBuilder.addByteEntry( JsonTemplateMapper.toByteArray(containerConfiguration), "blobs/sha256/" + configDescriptor.getDigest().getHash(), - creationTime); + TAR_ENTRY_MODIFICATION_TIME); // Adds the manifest to the tarball BlobDescriptor manifestDescriptor = Digests.computeDigest(manifest); tarStreamBuilder.addByteEntry( JsonTemplateMapper.toByteArray(manifest), "blobs/sha256/" + manifestDescriptor.getDigest().getHash(), - creationTime); + TAR_ENTRY_MODIFICATION_TIME); // Adds the oci-layout and index.json tarStreamBuilder.addByteEntry( "{\"imageLayoutVersion\": \"1.0.0\"}".getBytes(StandardCharsets.UTF_8), "oci-layout", - creationTime); + TAR_ENTRY_MODIFICATION_TIME); OciIndexTemplate index = new OciIndexTemplate(); // TODO: figure out how to tag with allTargetImageTags index.addManifest(manifestDescriptor, imageReference.toStringWithQualifier()); tarStreamBuilder.addByteEntry( - JsonTemplateMapper.toByteArray(index), "index.json", creationTime); + JsonTemplateMapper.toByteArray(index), "index.json", TAR_ENTRY_MODIFICATION_TIME); tarStreamBuilder.writeAsTarArchiveTo(out); } @@ -135,7 +137,10 @@ private void dockerWriteTo(OutputStream out) throws IOException { String layerName = layer.getBlobDescriptor().getDigest().getHash() + LAYER_FILE_EXTENSION; tarStreamBuilder.addBlobEntry( - layer.getBlob(), layer.getBlobDescriptor().getSize(), layerName, creationTime); + layer.getBlob(), + layer.getBlobDescriptor().getSize(), + layerName, + TAR_ENTRY_MODIFICATION_TIME); manifestTemplate.addLayerFile(layerName); } @@ -145,7 +150,7 @@ private void dockerWriteTo(OutputStream out) throws IOException { tarStreamBuilder.addByteEntry( JsonTemplateMapper.toByteArray(containerConfiguration), CONTAINER_CONFIGURATION_JSON_FILE_NAME, - creationTime); + TAR_ENTRY_MODIFICATION_TIME); // Adds the manifest to tarball. for (String tag : allTargetImageTags) { @@ -154,7 +159,7 @@ private void dockerWriteTo(OutputStream out) throws IOException { tarStreamBuilder.addByteEntry( JsonTemplateMapper.toByteArray(Collections.singletonList(manifestTemplate)), MANIFEST_JSON_FILE_NAME, - creationTime); + TAR_ENTRY_MODIFICATION_TIME); tarStreamBuilder.writeAsTarArchiveTo(out); } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/tar/TarStreamBuilder.java b/jib-core/src/main/java/com/google/cloud/tools/jib/tar/TarStreamBuilder.java index aff6e769ac..bd579bbde4 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/tar/TarStreamBuilder.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/tar/TarStreamBuilder.java @@ -77,7 +77,7 @@ public void addTarArchiveEntry(TarArchiveEntry entry) { public void addByteEntry(byte[] contents, String name, Instant modificationTime) { TarArchiveEntry entry = new TarArchiveEntry(name); entry.setSize(contents.length); - entry.setModTime(modTime.getEpochSecond()); + entry.setModTime(modificationTime.getEpochSecond()); archiveMap.put(entry, Blobs.from(outputStream -> outputStream.write(contents))); } @@ -88,12 +88,12 @@ public void addByteEntry(byte[] contents, String name, Instant modificationTime) * @param blob the {@link Blob} to add to the tarball * @param size the size (in bytes) of {@code blob} * @param name the name of the entry (i.e. filename) - * @param modTime the time the entry is created + * @param modificationTime the modification time of the entry */ - public void addBlobEntry(Blob blob, long size, String name, Instant modTime) { + public void addBlobEntry(Blob blob, long size, String name, Instant modificationTime) { TarArchiveEntry entry = new TarArchiveEntry(name); entry.setSize(size); - entry.setModTime(modTime.getEpochSecond()); + entry.setModTime(modificationTime.getEpochSecond()); archiveMap.put(entry, blob); } } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/tar/TarStreamBuilderTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/tar/TarStreamBuilderTest.java index 2f61b1c75a..f257d9d8cc 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/tar/TarStreamBuilderTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/tar/TarStreamBuilderTest.java @@ -97,9 +97,10 @@ public void testToBlob_stringsAndTarArchiveEntriesWithCompression() throws IOExc @Test public void testToBlob_multiByte() throws IOException { - testTarStreamBuilder.addByteEntry("日本語".getBytes(StandardCharsets.UTF_8), "test", creationTime); testTarStreamBuilder.addByteEntry( - "asdf".getBytes(StandardCharsets.UTF_8), "crepecake", creationTime); + "日本語".getBytes(StandardCharsets.UTF_8), "test", Instant.EPOCH); + testTarStreamBuilder.addByteEntry( + "asdf".getBytes(StandardCharsets.UTF_8), "crepecake", Instant.EPOCH); testTarStreamBuilder.addBlobEntry( Blobs.from("jib"), "jib".getBytes(StandardCharsets.UTF_8).length, "jib", Instant.EPOCH); @@ -124,11 +125,13 @@ public void testToBlob_multiByte() throws IOException { Assert.assertEquals("crepecake", headerFile.getName()); Assert.assertEquals( "asdf", new String(ByteStreams.toByteArray(tarArchiveInputStream), StandardCharsets.UTF_8)); + Assert.assertEquals(Instant.EPOCH, headerFile.getModTime().toInstant()); headerFile = tarArchiveInputStream.getNextTarEntry(); Assert.assertEquals("jib", headerFile.getName()); Assert.assertEquals( "jib", new String(ByteStreams.toByteArray(tarArchiveInputStream), StandardCharsets.UTF_8)); + Assert.assertEquals(Instant.EPOCH, headerFile.getModTime().toInstant()); Assert.assertNull(tarArchiveInputStream.getNextTarEntry()); } @@ -150,27 +153,27 @@ private void setUpWithTarEntries() { /** Creates a TarStreamBuilder using Strings. */ private void setUpWithStrings() { // Prepares a test TarStreamBuilder. - testTarStreamBuilder.addByteEntry(fileAContents, "some/path/to/resourceFileA", creationTime); - testTarStreamBuilder.addByteEntry(fileBContents, "crepecake", creationTime); + testTarStreamBuilder.addByteEntry(fileAContents, "some/path/to/resourceFileA", Instant.EPOCH); + testTarStreamBuilder.addByteEntry(fileBContents, "crepecake", Instant.EPOCH); testTarStreamBuilder.addTarArchiveEntry( new TarArchiveEntry(directoryA.toFile(), "some/path/to")); testTarStreamBuilder.addByteEntry( fileAContents, "some/really/long/path/that/exceeds/100/characters/abcdefghijklmnopqrstuvwxyz0123456789012345678901234567890", - creationTime); + Instant.EPOCH); } /** Creates a TarStreamBuilder using Strings and TarArchiveEntries. */ private void setUpWithStringsAndTarEntries() { // Prepares a test TarStreamBuilder. - testTarStreamBuilder.addByteEntry(fileAContents, "some/path/to/resourceFileA", creationTime); + testTarStreamBuilder.addByteEntry(fileAContents, "some/path/to/resourceFileA", Instant.EPOCH); testTarStreamBuilder.addTarArchiveEntry(new TarArchiveEntry(fileB.toFile(), "crepecake")); testTarStreamBuilder.addTarArchiveEntry( new TarArchiveEntry(directoryA.toFile(), "some/path/to")); testTarStreamBuilder.addByteEntry( fileAContents, "some/really/long/path/that/exceeds/100/characters/abcdefghijklmnopqrstuvwxyz0123456789012345678901234567890", - creationTime); + Instant.EPOCH); } /** Creates a compressed blob from the TarStreamBuilder and verifies it. */ @@ -215,18 +218,21 @@ private void verifyTarArchive(TarArchiveInputStream tarArchiveInputStream) throw // Verifies fileB was archived correctly. TarArchiveEntry headerFileB = tarArchiveInputStream.getNextTarEntry(); Assert.assertEquals("crepecake", headerFileB.getName()); + Assert.assertEquals(Instant.EPOCH, headerFileB.getModTime().toInstant()); byte[] fileBString = ByteStreams.toByteArray(tarArchiveInputStream); Assert.assertArrayEquals(fileBContents, fileBString); // Verifies directoryA was archived correctly. TarArchiveEntry headerDirectoryA = tarArchiveInputStream.getNextTarEntry(); Assert.assertEquals("some/path/to/", headerDirectoryA.getName()); + Assert.assertEquals(Instant.EPOCH, headerDirectoryA.getModTime().toInstant()); // Verifies the long file was archived correctly. TarArchiveEntry headerFileALong = tarArchiveInputStream.getNextTarEntry(); Assert.assertEquals( "some/really/long/path/that/exceeds/100/characters/abcdefghijklmnopqrstuvwxyz0123456789012345678901234567890", headerFileALong.getName()); + Assert.assertEquals(Instant.EPOCH, headerFileALong); byte[] fileALongString = ByteStreams.toByteArray(tarArchiveInputStream); Assert.assertArrayEquals(fileAContents, fileALongString);