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

Add imagePushed field to jib-image.json #3641

Merged
merged 7 commits into from May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -270,6 +270,10 @@ public void testSteps_forBuildToDockerRegistry_skipExistingDigest()
// Test that both images have the same properties.
Assert.assertEquals(image1.getDigest(), image2.getDigest());
Assert.assertEquals(image1.getImageId(), image2.getImageId());

// Test that the first image was pushed while the second one was skipped
Assert.assertTrue(image1.isImagePushed());
Assert.assertFalse(image2.isImagePushed());
}

@Test
Expand Down
Expand Up @@ -29,25 +29,28 @@ public class JibContainer {
private final DescriptorDigest imageDigest;
private final DescriptorDigest imageId;
private final Set<String> tags;
private final boolean imagePushed;

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

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

/**
Expand All @@ -59,6 +62,15 @@ public ImageReference getTargetImage() {
return targetImage;
}

/**
* Returns true if we pushed this image all the way to a registry.
*
* @return true if pushed.
*/
public boolean isImagePushed() {
return imagePushed;
}

/**
* Gets the digest of the registry image manifest built by Jib. This digest can be used to fetch a
* specific image from the registry in the form {@code myregistry/myimage@digest}.
Expand Down Expand Up @@ -89,7 +101,7 @@ public Set<String> getTags() {

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

@Override
Expand All @@ -104,6 +116,7 @@ public boolean equals(Object other) {
return targetImage.equals(otherContainer.targetImage)
&& imageDigest.equals(otherContainer.imageDigest)
&& imageId.equals(otherContainer.imageId)
&& tags.equals(otherContainer.tags);
&& tags.equals(otherContainer.tags)
&& imagePushed == otherContainer.imagePushed;
}
}
Expand Up @@ -46,15 +46,17 @@ static BuildResult fromImage(Image image, Class<? extends BuildableManifestTempl
targetFormat, containerConfigurationBlobDescriptor);
DescriptorDigest imageDigest = Digests.computeJsonDigest(manifestTemplate);
DescriptorDigest imageId = containerConfigurationBlobDescriptor.getDigest();
return new BuildResult(imageDigest, imageId);
return new BuildResult(imageDigest, imageId, false);
}

private final DescriptorDigest imageDigest;
private final DescriptorDigest imageId;
private final Boolean imagePushed;

BuildResult(DescriptorDigest imageDigest, DescriptorDigest imageId) {
BuildResult(DescriptorDigest imageDigest, DescriptorDigest imageId, boolean imagePushed) {
this.imageDigest = imageDigest;
this.imageId = imageId;
this.imagePushed = imagePushed;
}

public DescriptorDigest getImageDigest() {
Expand All @@ -65,6 +67,10 @@ public DescriptorDigest getImageId() {
return imageId;
}

public boolean isImagePushed() {
return imagePushed;
}

@Override
public int hashCode() {
return Objects.hash(imageDigest, imageId);
Expand All @@ -80,6 +86,7 @@ public boolean equals(Object other) {
}
BuildResult otherBuildResult = (BuildResult) other;
return imageDigest.equals(otherBuildResult.imageDigest)
&& imageId.equals(otherBuildResult.imageId);
&& imageId.equals(otherBuildResult.imageId)
wwadge marked this conversation as resolved.
Show resolved Hide resolved
&& imagePushed.equals(otherBuildResult.imagePushed);
}
}
Expand Up @@ -180,7 +180,7 @@ public BuildResult call() throws IOException, RegistryException {
eventHandlers.dispatch(LogEvent.info("Pushing manifest for " + imageQualifier + "..."));

registryClient.pushManifest(manifestTemplate, imageQualifier);
return new BuildResult(imageDigest, imageId);
return new BuildResult(imageDigest, imageId, true);
}
}
}
Expand Up @@ -573,15 +573,23 @@ private Future<BuildResult> pushImage(
results.manifestCheckResult.get().isPresent()));

realizeFutures(manifestPushResults);

return manifestPushResults.isEmpty()
? new BuildResult(
results.manifestCheckResult.get().get().getDigest(),
Verify.verifyNotNull(containerConfigPushResult).get().getDigest())
Verify.verifyNotNull(containerConfigPushResult).get().getDigest(),
isImagePushed(results.manifestCheckResult.get()))
// Manifest pushers return the same BuildResult.
: manifestPushResults.get(0).get();
});
}

@VisibleForTesting
boolean isImagePushed(Optional<ManifestAndDigest<ManifestTemplate>> manifestResult) {

return !(JibSystemProperties.skipExistingImages() && manifestResult.isPresent());
}

private void pushManifestList(ProgressEventDispatcher.Factory progressDispatcherFactory) {
results.buildResult =
executorService.submit(
Expand Down
Expand Up @@ -16,6 +16,11 @@

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

import static org.mockito.Mockito.when;

import com.google.cloud.tools.jib.builder.steps.BuildResult;
import com.google.cloud.tools.jib.configuration.BuildContext;
import com.google.cloud.tools.jib.configuration.ImageConfiguration;
import com.google.common.collect.ImmutableSet;
import java.security.DigestException;
import java.util.Set;
Expand All @@ -24,6 +29,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;

/** Tests for {@link JibContainer}. */
public class JibContainerTest {
Expand Down Expand Up @@ -53,56 +59,87 @@ public void setUp() throws DigestException, InvalidImageReferenceException {

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

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

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

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);
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2, tags1, true);
JibContainer container2 = new JibContainer(targetImage2, digest1, digest2, tags1, true);

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);
JibContainer container1 = new JibContainer(targetImage1, digest1, digest2, tags1, true);
JibContainer container2 = new JibContainer(targetImage1, digest2, digest2, tags1, true);

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);
JibContainer container1 = new JibContainer(targetImage1, digest1, digest1, tags1, true);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest2, tags1, true);

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

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

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

@Test
public void testEquality_differentImagePushed() {
JibContainer container1 = new JibContainer(targetImage1, digest1, digest1, tags1, true);
JibContainer container2 = new JibContainer(targetImage1, digest1, digest1, tags1, false);

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

@Test
public void testCreation_withBuildContextAndBuildResult() {
BuildResult buildResult = Mockito.mock(BuildResult.class);
BuildContext buildContext = Mockito.mock(BuildContext.class);
ImageConfiguration mockTargetConfiguration = Mockito.mock(ImageConfiguration.class);

when(buildResult.getImageDigest()).thenReturn(digest1);
when(buildResult.getImageId()).thenReturn(digest1);
when(buildResult.isImagePushed()).thenReturn(true);
when(mockTargetConfiguration.getImage()).thenReturn(targetImage1);
when(buildContext.getTargetImageConfiguration()).thenReturn(mockTargetConfiguration);
when(buildContext.getAllTargetImageTags()).thenReturn(ImmutableSet.copyOf(tags1));

JibContainer container = JibContainer.from(buildContext, buildResult);
Assert.assertEquals(targetImage1, container.getTargetImage());
Assert.assertEquals(digest1, container.getDigest());
Assert.assertEquals(digest1, container.getImageId());
Assert.assertEquals(tags1, container.getTags());
Assert.assertTrue(container.isImagePushed());
}
}
Expand Up @@ -31,6 +31,7 @@ public class BuildResultTest {
private DescriptorDigest digest1;
private DescriptorDigest digest2;
private DescriptorDigest id;
private DescriptorDigest id2;

@Before
public void setUp() throws DigestException {
Expand All @@ -43,24 +44,37 @@ public void setUp() throws DigestException {
id =
DescriptorDigest.fromDigest(
"sha256:9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba");

id2 =
DescriptorDigest.fromDigest(
"sha256:1234543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba");
}

@Test
public void testCreated() {
BuildResult container = new BuildResult(digest1, id);
BuildResult container = new BuildResult(digest1, id, true);
Assert.assertEquals(digest1, container.getImageDigest());
Assert.assertEquals(id, container.getImageId());
Assert.assertTrue(container.isImagePushed());
}

@Test
public void testEquality() {
BuildResult container1 = new BuildResult(digest1, id);
BuildResult container2 = new BuildResult(digest1, id);
BuildResult container3 = new BuildResult(digest2, id);
BuildResult container1 = new BuildResult(digest1, id, true);
BuildResult container2 = new BuildResult(digest1, id, true);
BuildResult container3 = new BuildResult(digest2, id, true);
BuildResult container4 = new BuildResult(digest1, id, false);
BuildResult container5 = new BuildResult(digest1, id2, false);

Assert.assertEquals(container1, container2);
Assert.assertEquals(container1, container1);
Assert.assertNotEquals(container1, container5);
Assert.assertNotEquals(container1, new Object());

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

@Test
Expand Down
Expand Up @@ -20,8 +20,11 @@
import com.google.cloud.tools.jib.builder.ProgressEventDispatcher;
import com.google.cloud.tools.jib.builder.steps.PullBaseImageStep.ImagesAndRegistryClient;
import com.google.cloud.tools.jib.configuration.BuildContext;
import com.google.cloud.tools.jib.global.JibSystemProperties;
import com.google.cloud.tools.jib.image.DigestOnlyLayer;
import com.google.cloud.tools.jib.image.Image;
import com.google.cloud.tools.jib.image.json.ManifestTemplate;
import com.google.cloud.tools.jib.registry.ManifestAndDigest;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ForwardingExecutorService;
import com.google.common.util.concurrent.Futures;
Expand All @@ -30,6 +33,7 @@
import java.security.DigestException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
Expand Down Expand Up @@ -148,4 +152,30 @@ public void testObtainBaseImageLayers_skipObtainingDuplicateLayers()
Mockito.verify(executorService, Mockito.times(3))
.submit(Mockito.any(ObtainBaseImageLayerStep.class));
}

@Test
public void testIsImagePushed_skipExistingEnabledAndManifestPresent() {
Optional<ManifestAndDigest<ManifestTemplate>> manifestResult = Mockito.mock(Optional.class);
Mockito.when(manifestResult.isPresent()).thenReturn(true);
System.setProperty(JibSystemProperties.SKIP_EXISTING_IMAGES, "true");

Assert.assertFalse(stepsRunner.isImagePushed(manifestResult));
}

@Test
public void testIsImagePushed_skipExistingImageDisabledAndManifestPresent() {
Optional<ManifestAndDigest<ManifestTemplate>> manifestResult = Mockito.mock(Optional.class);
System.setProperty(JibSystemProperties.SKIP_EXISTING_IMAGES, "false");

Assert.assertTrue(stepsRunner.isImagePushed(manifestResult));
}

@Test
public void testIsImagePushed_skipExistingImageEnabledAndManifestNotPresent() {
Optional<ManifestAndDigest<ManifestTemplate>> manifestResult = Mockito.mock(Optional.class);
System.setProperty(JibSystemProperties.SKIP_EXISTING_IMAGES, "true");
Mockito.when(manifestResult.isPresent()).thenReturn(false);

Assert.assertTrue(stepsRunner.isImagePushed(manifestResult));
}
}