Skip to content

Commit

Permalink
fix: Fix V22ManifestListTemplate cast when pulling an oci index manif…
Browse files Browse the repository at this point in the history
…est (GoogleContainerTools#3974)

* Since there's no more downcast in PullBaseImageStep of manifest lists actual implementation, use the parent class in the unit tests.
* Add an integration-test case of building a multi-platform image from a base oci index manifest.
* Also update jib-core gradle example to compile with 0.23.0.
  • Loading branch information
rquinio authored Apr 11, 2023
1 parent 8f99f9e commit 9f2d0ba
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 17 deletions.
7 changes: 5 additions & 2 deletions jib-core/examples/build.gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ For example, the following snippet is a simple example that creates a Gradle tas
// Imports Jib Core as a library to use in this build script.
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:jib-core:0.20.0'
classpath 'com.google.cloud.tools:jib-core:0.23.0'
}
}
Expand Down Expand Up @@ -41,7 +42,9 @@ task('dojib') {
// Tells Jib to get registry credentials from a Docker config.
.addCredentialRetriever(
CredentialRetrieverFactory
.forImage(ImageReference.parse(targetImage))
.forImage(
ImageReference.parse(targetImage),
logEvent -> logger.log(LogLevel.valueOf(logEvent.getLevel().name()), logEvent.getMessage()))
.dockerConfig())))
println 'done'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
/** Integration tests for {@link Jib}. */
public class JibIntegrationTest {

/** A known oci index sha for gcr.io/distroless/base. */
public static final String KNOWN_OCI_INDEX_SHA =
"sha256:2c50b819aa3bfaf6ae72e47682f6c5abc0f647cf3f4224a4a9be97dd30433909";

@ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5000);

@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
Expand All @@ -64,6 +68,14 @@ public class JibIntegrationTest {
new FailoverHttpClient(true, true, ignored -> {}))
.newRegistryClient();

private final RegistryClient distrolessRegistryClient =
RegistryClient.factory(
EventHandlers.NONE,
dockerHost + ":5000",
"jib-distroless",
new FailoverHttpClient(true, true, ignored -> {}))
.newRegistryClient();

/**
* Pulls a built image and attempts to run it.
*
Expand Down Expand Up @@ -292,6 +304,33 @@ public void testScratch_multiPlatform()
Assert.assertEquals("windows", platform2.getOs());
}

@Test
public void testDistroless_ociManifest()
throws IOException, InterruptedException, ExecutionException, RegistryException,
CacheDirectoryCreationException, InvalidImageReferenceException {
Jib.from("gcr.io/distroless/base@" + KNOWN_OCI_INDEX_SHA)
.setPlatforms(
ImmutableSet.of(new Platform("arm64", "linux"), new Platform("amd64", "linux")))
.containerize(
Containerizer.to(
RegistryImage.named(dockerHost + ":5000/jib-distroless:multi-platform"))
.setAllowInsecureRegistries(true));

V22ManifestListTemplate manifestList =
(V22ManifestListTemplate)
distrolessRegistryClient.pullManifest("multi-platform").getManifest();
Assert.assertEquals(2, manifestList.getManifests().size());
ManifestDescriptorTemplate.Platform platform1 =
manifestList.getManifests().get(0).getPlatform();
ManifestDescriptorTemplate.Platform platform2 =
manifestList.getManifests().get(1).getPlatform();

Assert.assertEquals("arm64", platform1.getArchitecture());
Assert.assertEquals("linux", platform1.getOs());
Assert.assertEquals("amd64", platform2.getArchitecture());
Assert.assertEquals("linux", platform2.getOs());
}

@Test
public void testOffline()
throws IOException, InterruptedException, InvalidImageReferenceException, ExecutionException,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import com.google.cloud.tools.jib.image.json.UnknownManifestFormatException;
import com.google.cloud.tools.jib.image.json.UnlistedPlatformInManifestListException;
import com.google.cloud.tools.jib.image.json.V21ManifestTemplate;
import com.google.cloud.tools.jib.image.json.V22ManifestListTemplate;
import com.google.cloud.tools.jib.json.JsonTemplateMapper;
import com.google.cloud.tools.jib.registry.ManifestAndDigest;
import com.google.cloud.tools.jib.registry.RegistryClient;
Expand Down Expand Up @@ -468,7 +467,7 @@ List<Image> getCachedBaseImages()
ImmutableList.Builder<Image> images = ImmutableList.builder();
for (Platform platform : buildContext.getContainerConfiguration().getPlatforms()) {
String manifestDigest =
lookUpPlatformSpecificImageManifest((V22ManifestListTemplate) manifestList, platform);
lookUpPlatformSpecificImageManifest((ManifestListTemplate) manifestList, platform);

Optional<ManifestAndConfigTemplate> manifestAndConfigFound =
manifestsAndConfigs.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
import com.google.cloud.tools.jib.image.LayerCountMismatchException;
import com.google.cloud.tools.jib.image.LayerPropertyNotFoundException;
import com.google.cloud.tools.jib.image.json.BadContainerConfigurationFormatException;
import com.google.cloud.tools.jib.image.json.BuildableManifestTemplate;
import com.google.cloud.tools.jib.image.json.ContainerConfigurationTemplate;
import com.google.cloud.tools.jib.image.json.ImageMetadataTemplate;
import com.google.cloud.tools.jib.image.json.ManifestAndConfigTemplate;
import com.google.cloud.tools.jib.image.json.ManifestListTemplate;
import com.google.cloud.tools.jib.image.json.ManifestTemplate;
import com.google.cloud.tools.jib.image.json.OciIndexTemplate;
import com.google.cloud.tools.jib.image.json.PlatformNotFoundInBaseImageException;
Expand Down Expand Up @@ -350,7 +352,7 @@ public void testGetCachedBaseImages_v21ManifestCached()
}

@Test
public void testGetCachedBaseImages_v22ManifestCached()
public void testGetCachedBaseImages_manifestCached()
throws InvalidImageReferenceException, IOException, CacheCorruptedException,
UnlistedPlatformInManifestListException, BadContainerConfigurationFormatException,
LayerCountMismatchException, PlatformNotFoundInBaseImageException {
Expand All @@ -363,7 +365,7 @@ public void testGetCachedBaseImages_v22ManifestCached()
containerConfigJson.setOs("fat system");
ManifestAndConfigTemplate manifestAndConfig =
new ManifestAndConfigTemplate(
new V22ManifestTemplate(), containerConfigJson, "sha256:digest");
Mockito.mock(BuildableManifestTemplate.class), containerConfigJson, "sha256:digest");
ImageMetadataTemplate imageMetadata =
new ImageMetadataTemplate(null, Arrays.asList(manifestAndConfig));
Mockito.when(cache.retrieveMetadata(imageReference)).thenReturn(Optional.of(imageMetadata));
Expand All @@ -377,7 +379,7 @@ public void testGetCachedBaseImages_v22ManifestCached()
}

@Test
public void testGetCachedBaseImages_v22ManifestListCached()
public void testGetCachedBaseImages_manifestListCached()
throws InvalidImageReferenceException, IOException, CacheCorruptedException,
UnlistedPlatformInManifestListException, BadContainerConfigurationFormatException,
LayerCountMismatchException, PlatformNotFoundInBaseImageException {
Expand All @@ -390,7 +392,7 @@ public void testGetCachedBaseImages_v22ManifestListCached()
containerConfigJson1.setContainerUser("user1");
containerConfigJson2.setContainerUser("user2");

V22ManifestListTemplate manifestList = Mockito.mock(V22ManifestListTemplate.class);
ManifestListTemplate manifestList = Mockito.mock(ManifestListTemplate.class);
Mockito.when(manifestList.getDigestsForPlatform("arch1", "os1"))
.thenReturn(Arrays.asList("sha256:digest1"));
Mockito.when(manifestList.getDigestsForPlatform("arch2", "os2"))
Expand All @@ -401,9 +403,13 @@ public void testGetCachedBaseImages_v22ManifestListCached()
manifestList,
Arrays.asList(
new ManifestAndConfigTemplate(
new V22ManifestTemplate(), containerConfigJson1, "sha256:digest1"),
Mockito.mock(BuildableManifestTemplate.class),
containerConfigJson1,
"sha256:digest1"),
new ManifestAndConfigTemplate(
new V22ManifestTemplate(), containerConfigJson2, "sha256:digest2")));
Mockito.mock(BuildableManifestTemplate.class),
containerConfigJson2,
"sha256:digest2")));
Mockito.when(cache.retrieveMetadata(imageReference)).thenReturn(Optional.of(imageMetadata));
Mockito.when(
cache.areAllLayersCached(imageMetadata.getManifestsAndConfigs().get(0).getManifest()))
Expand All @@ -423,15 +429,15 @@ public void testGetCachedBaseImages_v22ManifestListCached()
}

@Test
public void testGetCachedBaseImages_v22ManifestListCached_partialMatches()
public void testGetCachedBaseImages_manifestListCached_partialMatches()
throws InvalidImageReferenceException, IOException, CacheCorruptedException,
UnlistedPlatformInManifestListException, BadContainerConfigurationFormatException,
LayerCountMismatchException, PlatformNotFoundInBaseImageException {
ImageReference imageReference = ImageReference.parse("cat");
Mockito.when(buildContext.getBaseImageConfiguration())
.thenReturn(ImageConfiguration.builder(imageReference).build());

V22ManifestListTemplate manifestList = Mockito.mock(V22ManifestListTemplate.class);
ManifestListTemplate manifestList = Mockito.mock(ManifestListTemplate.class);
Mockito.when(manifestList.getDigestsForPlatform("arch1", "os1"))
.thenReturn(Arrays.asList("sha256:digest1"));
Mockito.when(manifestList.getDigestsForPlatform("arch2", "os2"))
Expand All @@ -442,7 +448,7 @@ public void testGetCachedBaseImages_v22ManifestListCached_partialMatches()
manifestList,
Arrays.asList(
new ManifestAndConfigTemplate(
new V22ManifestTemplate(),
Mockito.mock(BuildableManifestTemplate.class),
new ContainerConfigurationTemplate(),
"sha256:digest1")));
Mockito.when(cache.retrieveMetadata(imageReference)).thenReturn(Optional.of(imageMetadata));
Expand All @@ -457,15 +463,15 @@ public void testGetCachedBaseImages_v22ManifestListCached_partialMatches()
}

@Test
public void testGetCachedBaseImages_v22ManifestListCached_onlyPlatforms()
public void testGetCachedBaseImages_manifestListCached_onlyPlatforms()
throws InvalidImageReferenceException, IOException, CacheCorruptedException,
UnlistedPlatformInManifestListException, PlatformNotFoundInBaseImageException,
BadContainerConfigurationFormatException, LayerCountMismatchException {
ImageReference imageReference = ImageReference.parse("cat");
Mockito.when(buildContext.getBaseImageConfiguration())
.thenReturn(ImageConfiguration.builder(imageReference).build());

V22ManifestListTemplate manifestList = Mockito.mock(V22ManifestListTemplate.class);
ManifestListTemplate manifestList = Mockito.mock(ManifestListTemplate.class);
Mockito.when(manifestList.getDigestsForPlatform("target-arch", "target-os"))
.thenReturn(Arrays.asList("sha256:target-digest"));

Expand All @@ -474,10 +480,12 @@ public void testGetCachedBaseImages_v22ManifestListCached_onlyPlatforms()

ManifestAndConfigTemplate targetManifestAndConfig =
new ManifestAndConfigTemplate(
new V22ManifestTemplate(), containerConfigJson, "sha256:target-digest");
Mockito.mock(BuildableManifestTemplate.class),
containerConfigJson,
"sha256:target-digest");
ManifestAndConfigTemplate unrelatedManifestAndConfig =
new ManifestAndConfigTemplate(
new V22ManifestTemplate(),
Mockito.mock(BuildableManifestTemplate.class),
new ContainerConfigurationTemplate(),
"sha256:unrelated-digest");

Expand Down

0 comments on commit 9f2d0ba

Please sign in to comment.