From ce58c79e34c9dd43dc16627521197f317640c880 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Thu, 20 Sep 2018 12:04:12 -0400 Subject: [PATCH 1/2] Keep duplicate layers to match history --- .../cloud/tools/jib/cache/CacheMetadata.java | 2 +- .../cloud/tools/jib/image/ImageLayers.java | 34 +++++++++++++++---- .../tools/jib/image/ImageLayersTest.java | 27 ++++++++++++++- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheMetadata.java b/jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheMetadata.java index 535a5be1f4..f502e6369d 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheMetadata.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheMetadata.java @@ -34,7 +34,7 @@ class CacheMetadata { static class Builder { private final ImageLayers.Builder layersBuilder = - ImageLayers.builder(); + ImageLayers.builder().removeDuplicates(); private Builder(ImageLayers initialLayers) { layersBuilder.addAll(initialLayers); diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java index bd92686353..36f8620831 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java @@ -18,18 +18,23 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import javax.annotation.Nullable; -/** Holds the layers for an image. Makes sure that there are no duplicate layers. */ +/** Holds the layers for an image. */ public class ImageLayers implements Iterable { public static class Builder { - private final LinkedHashSet layers = new LinkedHashSet<>(); + private final List layers = new ArrayList<>(); private final ImmutableSet.Builder layerDigestsBuilder = ImmutableSet.builder(); + private boolean removeDuplicates = false; /** * Adds a layer. Removes any prior occurrences of the same layer. @@ -43,11 +48,7 @@ public static class Builder { */ public Builder add(T layer) throws LayerPropertyNotFoundException { layerDigestsBuilder.add(layer.getBlobDescriptor().getDigest()); - - // Remove necessary to move layer to the end of the LinkedHashSet. - layers.remove(layer); layers.add(layer); - return this; } @@ -67,8 +68,27 @@ public Builder addAll(ImageLayers layers) return this; } + /** + * Remove any duplicate layers, keeping the last occurrence of the layer. + * + * @return this + */ + public Builder removeDuplicates() { + removeDuplicates = true; + return this; + } + public ImageLayers build() { - return new ImageLayers<>(ImmutableList.copyOf(layers), layerDigestsBuilder.build()); + ImmutableList layers; + if (removeDuplicates) { + // keep last occurrence of each layer by adding in reverse order, + // and then reversing the result + Set dedupedButReversed = new LinkedHashSet(Lists.reverse(this.layers)); + layers = ImmutableList.copyOf(dedupedButReversed).reverse(); + } else { + layers = ImmutableList.copyOf(this.layers); + } + return new ImageLayers<>(layers, layerDigestsBuilder.build()); } } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageLayersTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageLayersTest.java index 497745e110..3346f786ba 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageLayersTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageLayersTest.java @@ -74,12 +74,37 @@ public void testAddLayer_success() throws LayerPropertyNotFoundException { } @Test - public void testAddLayer_sameAsLastLayer() throws LayerPropertyNotFoundException { + public void testAddLayer_maintainDuplicates() throws LayerPropertyNotFoundException { + // must maintain duplicate + List expectedLayers = + Arrays.asList( + mockCachedLayer, + mockReferenceLayer, + mockDigestOnlyLayer, + mockUnwrittenLayer, + mockCachedLayer); + + ImageLayers imageLayers = + ImageLayers.builder() + .add(mockCachedLayer) + .add(mockReferenceLayer) + .add(mockDigestOnlyLayer) + .add(mockUnwrittenLayer) + .add(mockCachedLayer) + .build(); + + Assert.assertEquals(expectedLayers, imageLayers.getLayers()); + } + + @Test + public void testAddLayer_removeDuplicates() throws LayerPropertyNotFoundException { + // remove duplicates: last layer should be kept List expectedLayers = Arrays.asList(mockReferenceLayer, mockDigestOnlyLayer, mockUnwrittenLayer, mockCachedLayer); ImageLayers imageLayers = ImageLayers.builder() + .removeDuplicates() .add(mockCachedLayer) .add(mockReferenceLayer) .add(mockDigestOnlyLayer) From 8e32a363eea8f17c19e4213741fff504359e7141 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Thu, 20 Sep 2018 13:42:43 -0400 Subject: [PATCH 2/2] rework and changelog --- .../cloud/tools/jib/image/ImageLayers.java | 17 ++++++++--------- jib-gradle-plugin/CHANGELOG.md | 2 ++ jib-maven-plugin/CHANGELOG.md | 2 ++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java index 36f8620831..18c165b9d2 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/image/ImageLayers.java @@ -79,16 +79,15 @@ public Builder removeDuplicates() { } public ImageLayers build() { - ImmutableList layers; - if (removeDuplicates) { - // keep last occurrence of each layer by adding in reverse order, - // and then reversing the result - Set dedupedButReversed = new LinkedHashSet(Lists.reverse(this.layers)); - layers = ImmutableList.copyOf(dedupedButReversed).reverse(); - } else { - layers = ImmutableList.copyOf(this.layers); + if (!removeDuplicates) { + return new ImageLayers<>(ImmutableList.copyOf(layers), layerDigestsBuilder.build()); } - return new ImageLayers<>(layers, layerDigestsBuilder.build()); + + // LinkedHashSet maintains the order but keeps the first occurrence. Keep last occurrence by + // adding elements in reverse, and then reversing the result + Set dedupedButReversed = new LinkedHashSet(Lists.reverse(this.layers)); + ImmutableList deduped = ImmutableList.copyOf(dedupedButReversed).reverse(); + return new ImageLayers<>(deduped, layerDigestsBuilder.build()); } } diff --git a/jib-gradle-plugin/CHANGELOG.md b/jib-gradle-plugin/CHANGELOG.md index 126b1bf107..b34c342a41 100644 --- a/jib-gradle-plugin/CHANGELOG.md +++ b/jib-gradle-plugin/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. ### Fixed +- Keep duplicate layers to match container history ([#1017](https://github.com/GoogleContainerTools/jib/pull/1017)) + ## 0.9.10 ### Added diff --git a/jib-maven-plugin/CHANGELOG.md b/jib-maven-plugin/CHANGELOG.md index d61c54e7de..1e6fbcc127 100644 --- a/jib-maven-plugin/CHANGELOG.md +++ b/jib-maven-plugin/CHANGELOG.md @@ -13,6 +13,8 @@ All notable changes to this project will be documented in this file. ### Fixed +- Keep duplicate layers to match container history ([#1017](https://github.com/GoogleContainerTools/jib/pull/1017)) + ## 0.9.10 ### Added