package org.jenkinsci.plugins.dockerbuildstep.cmd;
import hudson.Extension;
import hudson.model.AbstractBuild;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.dockerbuildstep.log.ConsoleLogger;
import org.jenkinsci.plugins.dockerbuildstep.util.Resolver;
import org.kohsuke.stapler.DataBoundConstructor;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.exception.NotFoundException;
/**
* This command removes specified Docker container(s).
*
* @see docker save
*
* @author draoullig
*
*/
public class SaveImageCommand extends DockerCommand {
private final String imageName;
private final String imageTag;
private final String destination;
private final String filename;
private final boolean ignoreIfNotFound;
@DataBoundConstructor
public SaveImageCommand(final String imageName, final String imageTag,
final String destination, final String filename,
final boolean ignoreIfNotFound) {
this.imageName = imageName;
this.imageTag = imageTag;
this.destination = destination;
this.filename = filename;
this.ignoreIfNotFound = ignoreIfNotFound;
}
public String getImageName() {
return imageName;
}
public String getImageTag() {
return imageTag;
}
public String getDestination() {
return destination;
}
public String getFilename() {
return filename;
}
public boolean getIgnoreIfNotFound() {
return ignoreIfNotFound;
}
@Override
public void execute(@SuppressWarnings("rawtypes") AbstractBuild build,
ConsoleLogger console) throws DockerException {
if (imageName == null || imageName.isEmpty()) {
throw new IllegalArgumentException("Image Name is not configured");
}
if (imageTag == null || imageTag.isEmpty()) {
throw new IllegalArgumentException("Image Tag is not configured");
}
if (destination == null || destination.isEmpty()) {
throw new IllegalArgumentException(
"Folder Destination is not configured");
}
if (filename == null || filename.isEmpty()) {
throw new IllegalArgumentException("Filename is not configured");
}
final String imageNameRes = Resolver.buildVar(build, imageName);
final String imageTagRes = Resolver.buildVar(build, imageTag);
final String destinationRes = Resolver.buildVar(build, destination);
final String filenameRes = Resolver.buildVar(build, filename);
if (!new File(destinationRes).exists()) {
throw new IllegalArgumentException(
"Destination is not a valid path");
}
final DockerClient client = getClient(build, null);
try {
console.logInfo(String
.format("Started save image '%s' ... ",
imageNameRes + " " + imageTagRes));
final OutputStream output = new FileOutputStream(new File(
destinationRes + "/" + filenameRes));
IOUtils.copy(client.saveImageCmd(imageNameRes + ":" + imageTagRes)
.exec(), output);
IOUtils.closeQuietly(output);
console.logInfo("Finished save image " + imageNameRes + " " + imageTagRes);
} catch (NotFoundException e) {
if (!ignoreIfNotFound) {
console.logError(String.format("image '%s' not found ",
imageNameRes + " " + imageTagRes));
throw e;
} else {
console.logInfo(String
.format("image '%s' not found, but skipping this error is turned on, let's continue ... ",
imageNameRes + " " + imageTagRes));
}
} catch (IOException e) {
console.logError(String.format("Error to save '%s' ", imageNameRes
+ " " + imageTagRes)
+ " " + e.getLocalizedMessage());
throw new DockerException(
String.format("Error to save '%s' ", imageNameRes + " "
+ imageTagRes)
+ " " + e.getLocalizedMessage(),
HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
}
@Extension
public static class RemoveImageCommandDescriptor extends
DockerCommandDescriptor {
@Override
public String getDisplayName() {
return "Save image";
}
}
}