Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write out the image metadata to a file after build. #2227

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,34 @@
import com.google.cloud.tools.jib.configuration.BuildContext;
import com.google.common.annotations.VisibleForTesting;
import java.util.Objects;
import java.util.Set;

/** The container built by Jib. */
public class JibContainer {

private final ImageReference targetImage;
private final DescriptorDigest imageDigest;
private final DescriptorDigest imageId;
private final Set<String> tags;

@VisibleForTesting
JibContainer(ImageReference targetImage, DescriptorDigest imageDigest, DescriptorDigest imageId) {
JibContainer(
ImageReference targetImage,
DescriptorDigest imageDigest,
DescriptorDigest imageId,
Set<String> tags) {
this.targetImage = targetImage;
this.imageDigest = imageDigest;
this.imageId = imageId;
this.tags = tags;
}

static JibContainer from(BuildContext buildContext, BuildResult buildResult) {
ImageReference targetImage = buildContext.getTargetImageConfiguration().getImage();
DescriptorDigest imageDigest = buildResult.getImageDigest();
DescriptorDigest imageId = buildResult.getImageId();
return new JibContainer(targetImage, imageDigest, imageId);
Set<String> tags = buildContext.getAllTargetImageTags();
return new JibContainer(targetImage, imageDigest, imageId, tags);
}

/**
Expand Down Expand Up @@ -70,9 +78,18 @@ public DescriptorDigest getImageId() {
return imageId;
}

/**
* Get the tags applied to the container.
*
* @return the set of all tags
*/
public Set<String> getTags() {
return tags;
}

@Override
public int hashCode() {
return Objects.hash(targetImage, imageDigest, imageId);
return Objects.hash(targetImage, imageDigest, imageId, tags);
}

@Override
Expand All @@ -86,6 +103,7 @@ public boolean equals(Object other) {
JibContainer otherContainer = (JibContainer) other;
return targetImage.equals(otherContainer.targetImage)
&& imageDigest.equals(otherContainer.imageDigest)
&& imageId.equals(otherContainer.imageId);
&& imageId.equals(otherContainer.imageId)
&& tags.equals(otherContainer.tags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

package com.google.cloud.tools.jib.api;

import com.google.common.collect.ImmutableSet;
import java.security.DigestException;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
Expand All @@ -32,7 +34,8 @@ public class JibContainerTest {
private ImageReference targetImage2;
private DescriptorDigest digest1;
private DescriptorDigest digest2;
private DescriptorDigest digest3;
private Set<String> tags1;
private Set<String> tags2;

@Before
public void setUp() throws DigestException, InvalidImageReferenceException {
Expand All @@ -44,34 +47,62 @@ public void setUp() throws DigestException, InvalidImageReferenceException {
digest2 =
DescriptorDigest.fromDigest(
"sha256:9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba");
digest3 =
DescriptorDigest.fromDigest(
"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
tags1 = ImmutableSet.of("latest", "custom-tag");
tags2 = ImmutableSet.of("latest");
}

@Test
public void testCreation() {
JibContainer container = new JibContainer(targetImage1, digest1, digest2);
JibContainer container = new JibContainer(targetImage1, digest1, digest2, tags1);

Assert.assertEquals(targetImage1, container.getTargetImage());
Assert.assertEquals(digest1, container.getDigest());
Assert.assertEquals(digest2, container.getImageId());
Assert.assertEquals(tags1, container.getTags());
}

@Test
public void testEquality() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest2);
JibContainer container3 = new JibContainer(targetImage1, digest2, digest3);
JibContainer container4 = new JibContainer(targetImage2, digest2, digest3);
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2, tags1);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest2, tags1);

Assert.assertEquals(container1, container2);
Assert.assertEquals(container1.hashCode(), container2.hashCode());
}

@Test
public void testEquality_differentTargetImage() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2, tags1);
JibContainer container2 = new JibContainer(targetImage2, digest1, digest2, tags1);

Assert.assertNotEquals(container1, container2);
Assert.assertNotEquals(container1.hashCode(), container2.hashCode());
}

@Test
public void testEquality_differentImageDigest() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2, tags1);
JibContainer container2 = new JibContainer(targetImage1, digest2, digest2, tags1);

Assert.assertNotEquals(container1, container3);
Assert.assertNotEquals(container1.hashCode(), container3.hashCode());
Assert.assertNotEquals(container1, container2);
Assert.assertNotEquals(container1.hashCode(), container2.hashCode());
}

@Test
public void testEquality_differentImageId() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest1, tags1);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest2, tags1);

Assert.assertNotEquals(container1, container2);
Assert.assertNotEquals(container1.hashCode(), container2.hashCode());
}
briandealwis marked this conversation as resolved.
Show resolved Hide resolved

@Test
public void testEquality_differentTags() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest1, tags1);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest1, tags2);

Assert.assertNotEquals(container3, container4);
Assert.assertNotEquals(container3.hashCode(), container4.hashCode());
Assert.assertNotEquals(container1, container2);
Assert.assertNotEquals(container1.hashCode(), container2.hashCode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.google.cloud.tools.jib.json.JsonTemplateMapper;
import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
* Builds a JSON string containing metadata about a {@link JibContainer} from a build.
Expand All @@ -31,9 +33,10 @@
*
* <pre>{@code
* {
* "image":"gcr.io/project/image:tag",
* "image": "gcr.io/project/image:tag",
* "imageId": "sha256:61bb3ec31a47cb730eb58a38bbfa813761a51dca69d10e39c24c3d00a7b2c7a9",
* "imageDigest": "sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6f"
* "imageDigest": "sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6f",
* "tags": ["latest", "tag"]
* }
* }</pre>
*/
Expand All @@ -42,15 +45,18 @@ public class ImageMetadataOutput implements JsonTemplate {
private final String image;
private final String imageId;
private final String imageDigest;
private final List<String> tags;

@JsonCreator
ImageMetadataOutput(
@JsonProperty(value = "image", required = true) String image,
@JsonProperty(value = "imageId", required = true) String imageId,
@JsonProperty(value = "imageDigest", required = true) String imageDigest) {
@JsonProperty(value = "imageDigest", required = true) String imageDigest,
@JsonProperty(value = "tags", required = true) List<String> tags) {
this.image = image;
this.imageId = imageId;
this.imageDigest = imageDigest;
this.tags = tags;
}

@VisibleForTesting
Expand All @@ -62,7 +68,11 @@ public static ImageMetadataOutput fromJibContainer(JibContainer jibContainer) {
String image = jibContainer.getTargetImage().toString();
String imageId = jibContainer.getImageId().toString();
String imageDigest = jibContainer.getDigest().toString();
return new ImageMetadataOutput(image, imageId, imageDigest);

// Make sure tags always appear in a predictable way, by sorting them into a list
List<String> tags = jibContainer.getTags().stream().sorted().collect(Collectors.toList());
mbruggmann marked this conversation as resolved.
Show resolved Hide resolved

return new ImageMetadataOutput(image, imageId, imageDigest, tags);
}

public String getImage() {
Expand All @@ -77,6 +87,10 @@ public String getImageDigest() {
return imageDigest;
}

public List<String> getTags() {
return tags;
}

public String toJson() throws IOException {
return JsonTemplateMapper.toUtf8String(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.cloud.tools.jib.plugins.common;

import com.google.common.collect.ImmutableList;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
Expand All @@ -28,7 +29,9 @@ public class ImageMetadataOutputTest {
+ "\"imageId\":"
+ "\"sha256:61bb3ec31a47cb730eb58a38bbfa813761a51dca69d10e39c24c3d00a7b2c7a9\","
+ "\"imageDigest\":"
+ "\"sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6fc\"}";
+ "\"sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6fc\","
+ "\"tags\":[\"latest\",\"tag\"]"
+ "}";

@Test
public void testFromJson() throws IOException {
Expand All @@ -40,6 +43,8 @@ public void testFromJson() throws IOException {
Assert.assertEquals(
"sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6fc",
output.getImageDigest());

Assert.assertEquals(ImmutableList.of("latest", "tag"), output.getTags());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@
import com.google.cloud.tools.jib.api.RegistryException;
import com.google.cloud.tools.jib.api.RegistryUnauthorizedException;
import com.google.cloud.tools.jib.registry.RegistryCredentialsNotSentException;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.apache.http.conn.HttpHostConnectException;
import org.junit.Assert;
Expand Down Expand Up @@ -229,12 +231,14 @@ public void testBuildImage_writesImageJson() throws Exception {
final String imageId =
"sha256:61bb3ec31a47cb730eb58a38bbfa813761a51dca69d10e39c24c3d00a7b2c7a9";
final String digest = "sha256:3f1be7e19129edb202c071a659a4db35280ab2bb1a16f223bfd5d1948657b6fc";
final Set<String> tags = ImmutableSet.of("latest", "0.1.41-69d10e-20200116T101403");

final Path outputPath = temporaryFolder.newFile("jib-image.json").toPath();

Mockito.when(mockJibContainer.getTargetImage()).thenReturn(targetImageReference);
Mockito.when(mockJibContainer.getImageId()).thenReturn(DescriptorDigest.fromDigest(imageId));
Mockito.when(mockJibContainer.getDigest()).thenReturn(DescriptorDigest.fromDigest(digest));
Mockito.when(mockJibContainer.getTags()).thenReturn(tags);
Mockito.when(mockJibContainerBuilder.containerize(mockContainerizer))
.thenReturn(mockJibContainer);
testJibBuildRunner.writeImageJson(outputPath).runBuild();
Expand All @@ -244,5 +248,6 @@ public void testBuildImage_writesImageJson() throws Exception {
Assert.assertEquals(targetImageReference.toString(), metadataOutput.getImage());
Assert.assertEquals(imageId, metadataOutput.getImageId());
Assert.assertEquals(digest, metadataOutput.getImageDigest());
Assert.assertEquals(tags, ImmutableSet.copyOf(metadataOutput.getTags()));
}
}