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 extra tags to tar image #2054

Merged
merged 5 commits into from
Oct 14, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jib-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
### Fixed

- Fixed temporary directory cleanup during builds using local base images. ([#2016](https:/GoogleContainerTools/jib/issues/2016))
- Fixed additional tags being ignored when building to a tarball. ([#2043](https:/GoogleContainerTools/jib/issues/2043))

## 0.11.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.google.common.io.CharStreams;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand Down Expand Up @@ -111,26 +110,22 @@ public void testTarballStructure() throws IOException {

@Test
public void testManifest() throws IOException {
try (InputStream input = Files.newInputStream(imageTar.toPath())) {
String exectedManifest =
"[{\"config\":\"config.json\",\"repoTags\":[\"jib-core/reproducible:latest\"],"
+ "\"layers\":[\"c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz\",\"6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz\",\"530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz\"]}]";
String generatedManifest = extractFromTarFileAsString(imageTar, "manifest.json");
Assert.assertEquals(exectedManifest, generatedManifest);
}
String exectedManifest =
"[{\"config\":\"config.json\",\"repoTags\":[\"jib-core/reproducible:latest\"],"
+ "\"layers\":[\"c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz\",\"6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz\",\"530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz\"]}]";
String generatedManifest = extractFromTarFileAsString(imageTar, "manifest.json");
Assert.assertEquals(exectedManifest, generatedManifest);
}

@Test
public void testConfiguration() throws IOException {
try (InputStream input = Files.newInputStream(imageTar.toPath())) {
String exectedConfig =
"{\"created\":\"1970-01-01T00:00:00Z\",\"architecture\":\"amd64\",\"os\":\"linux\","
+ "\"config\":{\"Env\":[],\"Entrypoint\":[\"echo\",\"Hello World\"],\"ExposedPorts\":{},\"Labels\":{},\"Volumes\":{}},"
+ "\"history\":[{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"},{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"},{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"}],"
+ "\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:18e4f44e6d1835bd968339b166057bd17ab7d4cbb56dc7262a5cafea7cf8d405\",\"sha256:13369c34f073f2b9c1fa6431e23d925f1a8eac65b1726c8cc8fcc2596c69b414\",\"sha256:4f92c507112d7880ca0f504ef8272b7fdee107263270125036a260a741565923\"]}}";
String generatedConfig = extractFromTarFileAsString(imageTar, "config.json");
Assert.assertEquals(exectedConfig, generatedConfig);
}
String exectedConfig =
"{\"created\":\"1970-01-01T00:00:00Z\",\"architecture\":\"amd64\",\"os\":\"linux\","
+ "\"config\":{\"Env\":[],\"Entrypoint\":[\"echo\",\"Hello World\"],\"ExposedPorts\":{},\"Labels\":{},\"Volumes\":{}},"
+ "\"history\":[{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"},{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"},{\"created\":\"1970-01-01T00:00:00Z\",\"author\":\"Jib\",\"created_by\":\"jib-core:null\",\"comment\":\"\"}],"
+ "\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:18e4f44e6d1835bd968339b166057bd17ab7d4cbb56dc7262a5cafea7cf8d405\",\"sha256:13369c34f073f2b9c1fa6431e23d925f1a8eac65b1726c8cc8fcc2596c69b414\",\"sha256:4f92c507112d7880ca0f504ef8272b7fdee107263270125036a260a741565923\"]}}";
String generatedConfig = extractFromTarFileAsString(imageTar, "config.json");
Assert.assertEquals(exectedConfig, generatedConfig);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.google.cloud.tools.jib.builder.steps;

import com.google.cloud.tools.jib.api.ImageReference;
import com.google.cloud.tools.jib.api.LogEvent;
import com.google.cloud.tools.jib.builder.ProgressEventDispatcher;
import com.google.cloud.tools.jib.builder.TimerEventDispatcher;
Expand Down Expand Up @@ -55,10 +54,11 @@ public BuildResult call() throws InterruptedException, IOException {
try (TimerEventDispatcher ignored =
new TimerEventDispatcher(eventHandlers, "Loading to Docker daemon")) {
eventHandlers.dispatch(LogEvent.progress("Loading to Docker daemon..."));

ImageReference targetImageReference =
buildConfiguration.getTargetImageConfiguration().getImage();
ImageTarball imageTarball = new ImageTarball(builtImage, targetImageReference);
ImageTarball imageTarball =
new ImageTarball(
builtImage,
buildConfiguration.getTargetImageConfiguration().getImage(),
buildConfiguration.getAllTargetImageTags());

// Note: The progress reported here is not entirely accurate. The total allocation units is
// the size of the layers, but the progress being reported includes the config and manifest
Expand All @@ -73,16 +73,6 @@ public BuildResult call() throws InterruptedException, IOException {
eventHandlers.dispatch(
LogEvent.debug(dockerClient.load(imageTarball, throttledProgressReporter)));

// Tags the image with all the additional tags, skipping the one 'docker load' already
// loaded.
for (String tag : buildConfiguration.getAllTargetImageTags()) {
if (tag.equals(targetImageReference.getTag())) {
continue;
}

dockerClient.tag(targetImageReference, targetImageReference.withTag(tag));
}

return BuildResult.fromImage(builtImage, buildConfiguration.getTargetFormat());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

public class WriteTarFileStep implements Callable<BuildResult> {

Expand All @@ -50,7 +49,7 @@ public class WriteTarFileStep implements Callable<BuildResult> {
}

@Override
public BuildResult call() throws ExecutionException, InterruptedException, IOException {
public BuildResult call() throws IOException {
buildConfiguration
.getEventHandlers()
.dispatch(LogEvent.progress("Building image to tar file..."));
Expand All @@ -63,7 +62,10 @@ public BuildResult call() throws ExecutionException, InterruptedException, IOExc
}
try (OutputStream outputStream =
new BufferedOutputStream(FileOperations.newLockingOutputStream(outputPath))) {
new ImageTarball(builtImage, buildConfiguration.getTargetImageConfiguration().getImage())
new ImageTarball(
builtImage,
buildConfiguration.getTargetImageConfiguration().getImage(),
buildConfiguration.getAllTargetImageTags())
.writeTo(outputStream);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,28 +243,6 @@ public void save(
}
}

/**
* Tags the image referenced by {@code originalImageReference} with a new image reference {@code
* newImageReference}.
*
* @param originalImageReference the existing image reference on the Docker daemon
* @param newImageReference the new image reference
* @see <a
* href="https://docs.docker.com/engine/reference/commandline/tag/">https://docs.docker.com/engine/reference/commandline/tag/</a>
* @throws InterruptedException if the 'docker tag' process is interrupted
* @throws IOException if an I/O exception occurs or {@code docker tag} failed
*/
public void tag(ImageReference originalImageReference, ImageReference newImageReference)
throws IOException, InterruptedException {
// Runs 'docker tag'.
Process dockerProcess =
docker("tag", originalImageReference.toString(), newImageReference.toString());
if (dockerProcess.waitFor() != 0) {
throw new IOException(
"'docker tag' command failed with error: " + getStderrOutput(dockerProcess));
}
}

/**
* Gets the size, image ID, and diff IDs of an image in the Docker daemon.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.cloud.tools.jib.json.JsonTemplate;
import com.google.cloud.tools.jib.json.JsonTemplateMapper;
import com.google.cloud.tools.jib.tar.TarStreamBuilder;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
Expand All @@ -42,16 +43,21 @@ public class ImageTarball {

private final Image image;
private final ImageReference imageReference;
private final ImmutableSet<String> allTargetImageTags;

/**
* Instantiate with an {@link Image}.
*
* @param image the image to convert into a tarball
* @param imageReference image reference to set in the manifest
* @param imageReference image reference to set in the manifest (note that the tag portion of the
* image reference is ignored)
* @param allTargetImageTags the tags to tag the image with
*/
public ImageTarball(Image image, ImageReference imageReference) {
public ImageTarball(
Image image, ImageReference imageReference, ImmutableSet<String> allTargetImageTags) {
this.image = image;
this.imageReference = imageReference;
this.allTargetImageTags = allTargetImageTags;
}

public void writeTo(OutputStream out) throws IOException {
Expand All @@ -75,7 +81,9 @@ public void writeTo(OutputStream out) throws IOException {
CONTAINER_CONFIGURATION_JSON_FILE_NAME);

// Adds the manifest to tarball.
manifestTemplate.setRepoTags(imageReference.toStringWithTag());
for (String tag : allTargetImageTags) {
manifestTemplate.addRepoTag(imageReference.withTag(tag).toStringWithTag());
}
tarStreamBuilder.addByteEntry(
JsonTemplateMapper.toByteArray(Collections.singletonList(manifestTemplate)),
MANIFEST_JSON_FILE_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package com.google.cloud.tools.jib.docker.json;

import com.google.cloud.tools.jib.json.JsonTemplate;
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
Expand Down Expand Up @@ -48,15 +48,15 @@
public class DockerManifestEntryTemplate implements JsonTemplate {

private String config = "config.json";
private List<String> repoTags = Collections.singletonList(null);
private final List<String> repoTags = new ArrayList<>();
private final List<String> layers = new ArrayList<>();

public void setConfig(String config) {
this.config = config;
}

public void setRepoTags(String repoTags) {
this.repoTags = Collections.singletonList(repoTags);
public void addRepoTag(String repoTag) {
chanseokoh marked this conversation as resolved.
Show resolved Hide resolved
repoTags.add(repoTag);
}

public void addLayerFile(String layer) {
Expand All @@ -70,4 +70,9 @@ public String getConfig() {
public List<String> getLayerFiles() {
return layers;
}

@VisibleForTesting
public List<String> getRepoTags() {
return repoTags;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.google.cloud.tools.jib.api.DescriptorDigest;
import com.google.cloud.tools.jib.api.ImageReference;
import com.google.cloud.tools.jib.api.InvalidImageReferenceException;
import com.google.cloud.tools.jib.docker.DockerClient.DockerImageDetails;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
Expand Down Expand Up @@ -209,19 +208,6 @@ public void testSave_fail() throws InterruptedException {
}
}

@Test
public void testTag() throws InterruptedException, IOException, InvalidImageReferenceException {
DockerClient testDockerClient =
new DockerClient(
subcommand -> {
Assert.assertEquals(Arrays.asList("tag", "original", "new"), subcommand);
return mockProcessBuilder;
});
Mockito.when(mockProcess.waitFor()).thenReturn(0);

testDockerClient.tag(ImageReference.of(null, "original", null), ImageReference.parse("new"));
}

@Test
public void testDefaultProcessorBuilderFactory_customExecutable() {
ProcessBuilder processBuilder =
Expand All @@ -247,28 +233,6 @@ public void testDefaultProcessorBuilderFactory_customEnvironment() {
Assert.assertEquals(expectedEnvironment, processBuilder.environment());
}

@Test
public void testTag_fail() throws InterruptedException, InvalidImageReferenceException {
DockerClient testDockerClient =
new DockerClient(
subcommand -> {
Assert.assertEquals(Arrays.asList("tag", "original", "new"), subcommand);
return mockProcessBuilder;
});
Mockito.when(mockProcess.waitFor()).thenReturn(1);

Mockito.when(mockProcess.getErrorStream())
.thenReturn(new ByteArrayInputStream("error".getBytes(StandardCharsets.UTF_8)));

try {
testDockerClient.tag(ImageReference.of(null, "original", null), ImageReference.parse("new"));
Assert.fail("docker tag should have failed");

} catch (IOException ex) {
Assert.assertEquals("'docker tag' command failed with error: error", ex.getMessage());
}
}

@Test
public void testSize_fail() throws InterruptedException {
DockerClient testDockerClient =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import com.google.cloud.tools.jib.image.json.ContainerConfigurationTemplate;
import com.google.cloud.tools.jib.image.json.V22ManifestTemplate;
import com.google.cloud.tools.jib.json.JsonTemplateMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.CharStreams;
import com.google.common.io.Resources;
import java.io.ByteArrayInputStream;
Expand Down Expand Up @@ -82,8 +84,11 @@ public void testWriteTo()
Mockito.when(mockLayer2.getDiffId()).thenReturn(fakeDigestB);
Image testImage =
Image.builder(V22ManifestTemplate.class).addLayer(mockLayer1).addLayer(mockLayer2).build();

ImageTarball imageToTarball = new ImageTarball(testImage, ImageReference.parse("my/image:tag"));
ImageTarball imageToTarball =
new ImageTarball(
testImage,
ImageReference.parse("my/image:tag"),
ImmutableSet.of("tag", "another-tag", "tag3"));

ByteArrayOutputStream out = new ByteArrayOutputStream();
imageToTarball.writeTo(out);
Expand Down Expand Up @@ -120,7 +125,11 @@ public void testWriteTo()
String manifestJson =
CharStreams.toString(
new InputStreamReader(tarArchiveInputStream, StandardCharsets.UTF_8));
JsonTemplateMapper.readListOfJson(manifestJson, DockerManifestEntryTemplate.class);
DockerManifestEntryTemplate manifest =
JsonTemplateMapper.readListOfJson(manifestJson, DockerManifestEntryTemplate.class).get(0);
Assert.assertEquals(
ImmutableList.of("my/image:tag", "my/image:another-tag", "my/image:tag3"),
manifest.getRepoTags());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.junit.Test;

/** Tests for {@link DockerManifestEntryTemplate}. */
public class DockerManifestTemplateTest {
public class DockerManifestEntryTemplateTest {

@Test
public void testToJson() throws URISyntaxException, IOException {
Expand All @@ -42,8 +42,7 @@ public void testToJson() throws URISyntaxException, IOException {
String expectedJson = new String(Files.readAllBytes(jsonFile), StandardCharsets.UTF_8);

DockerManifestEntryTemplate template = new DockerManifestEntryTemplate();
template.setRepoTags(
ImageReference.of("testregistry", "testrepo", "testtag").toStringWithTag());
template.addRepoTag(ImageReference.of("testregistry", "testrepo", "testtag").toStringWithTag());
template.addLayerFile("layer1.tar.gz");
template.addLayerFile("layer2.tar.gz");
template.addLayerFile("layer3.tar.gz");
Expand Down
1 change: 1 addition & 0 deletions jib-gradle-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Fixed

- Fixed temporary directory cleanup during builds using local base images. ([#2016](https:/GoogleContainerTools/jib/issues/2016))
- Fixed additional tags being ignored when building to a tarball. ([#2043](https:/GoogleContainerTools/jib/issues/2043))

## 1.6.1

Expand Down
1 change: 1 addition & 0 deletions jib-maven-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Fixed

- Fixed temporary directory cleanup during builds using local base images. ([#2016](https:/GoogleContainerTools/jib/issues/2016))
- Fixed additional tags being ignored when building to a tarball. ([#2043](https:/GoogleContainerTools/jib/issues/2043))

## 1.6.1

Expand Down