Skip to content
This repository has been archived by the owner on Mar 31, 2022. It is now read-only.

Adding support for exporting an image as a tar archive. #330

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
30 changes: 28 additions & 2 deletions plugin/src/main/java/com/spotify/plugin/dockerfile/BuildMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@
import com.spotify.docker.client.exceptions.ImageNotFoundException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -114,6 +117,12 @@ public class BuildMojo extends AbstractDockerMojo {

@Parameter(property = "dockerfile.build.squash", defaultValue = "false")
private boolean squash;

/**
* File path to save image as a tar archive after it is built.
*/
@Parameter(property = "dockerfile.build.saveImageToTarArchive")
private String saveImageToTarArchive;

@Override
public void execute(DockerClient dockerClient)
Expand Down Expand Up @@ -149,7 +158,24 @@ public void execute(DockerClient dockerClient)
}

writeMetadata(log);


if (saveImageToTarArchive != null && imageId != null) {
try {
log.info(MessageFormat.format("Image will be saved as a file {0}",
Paths.get(saveImageToTarArchive).toString()));
final InputStream is = dockerClient.save(imageId);
java.nio.file.Files.copy(is, Paths.get(saveImageToTarArchive),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
log.warn("IOException thrown while trying to write the image archive.");
} catch (DockerException e) {
log.warn("Docker threw an exception while trying to write the image archive: "
+ e.getMessage());
} catch (InterruptedException e) {
log.warn("InterruptedException thrown while trying to write the image archive.");
}
}
Comment on lines +169 to +177
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about the error handling here. It seems like if an exception was thrown by dockerClient.save() (or the file copy) then the plugin execution will continue, and probably print a BUILD SUCCESS message from Maven, but with a warning message that saving the image archive to a tarball failed.

How about failing the build in those cases? I'd assume that if someone configured the build to save the image archive to a file, they'd want the build to fail if that action failed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes perfect sense to me. I already found one case where an exception occurs: running the basic integration test, The image has scratch as a base so the tar archive is 0 bytes and an exception is thrown.

Do you think an extra integration test is needed to test the archive export
as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think an extra integration test is needed to test the archive export
as well?

I think that would be nice to have but not necessary


if (repository == null) {
log.info(MessageFormat.format("Successfully built {0}", imageId));
} else {
Expand Down Expand Up @@ -220,7 +246,7 @@ static String buildImage(@Nonnull DockerClient dockerClient,
if (squash) {
buildParameters.add(new DockerClient.BuildParam("squash", encodeBuildParam(squash)));
}

final DockerClient.BuildParam[] buildParametersArray =
buildParameters.toArray(new DockerClient.BuildParam[buildParameters.size()]);

Expand Down