package org.jenkinsci.plugins.dockerbuildstep.cmd;
import hudson.AbortException;
import hudson.DescriptorExtensionList;
import hudson.ExtensionPoint;
import hudson.model.Describable;
import hudson.model.AbstractBuild;
import hudson.model.Descriptor;
import hudson.model.Job;
import java.io.IOException;
import jenkins.model.Jenkins;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.Charsets;
import org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryToken;
import org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint;
import org.jenkinsci.plugins.dockerbuildstep.DockerBuilder;
import org.jenkinsci.plugins.dockerbuildstep.DockerCredConfig;
import org.jenkinsci.plugins.dockerbuildstep.action.DockerContainerConsoleAction;
import org.jenkinsci.plugins.dockerbuildstep.log.ConsoleLogger;
import com.cloudbees.plugins.credentials.CredentialsMatcher;
import com.cloudbees.plugins.credentials.CredentialsMatchers;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.model.AuthConfig;
import com.google.common.base.Strings;
/**
* Parent class of all Docker commands.
*
* @author vjuranek
*
*/
public abstract class DockerCommand implements Describable<DockerCommand>, ExtensionPoint {
private DockerRegistryEndpoint dockerRegistryEndpoint;
@Deprecated
private DockerCredConfig dockerCredentials;
public DockerCommand() {
this(null);
}
public DockerCommand(DockerRegistryEndpoint dockerRegistryEndpoint) {
this.dockerRegistryEndpoint = dockerRegistryEndpoint;
}
public DockerRegistryEndpoint getDockerRegistryEndpoint() {
return dockerRegistryEndpoint;
}
@SuppressWarnings("deprecation")
protected Object readResolve() {
if (dockerCredentials != null) {
this.dockerRegistryEndpoint = new DockerRegistryEndpoint(dockerCredentials.getServerAddress(),
dockerCredentials.getCredentialsId());
this.dockerCredentials = null;
}
return this;
}
public AuthConfig getAuthConfig(Job<?, ?> project) {
if (dockerRegistryEndpoint == null || Strings.isNullOrEmpty(dockerRegistryEndpoint.getCredentialsId())) {
return null;
}
AuthConfig authConfig = new AuthConfig();
authConfig.withRegistryAddress(dockerRegistryEndpoint.getUrl());
DockerRegistryToken token = this.dockerRegistryEndpoint.getToken(project);
if (token != null) {
String credentials = new String(Base64.decodeBase64(token.getToken()), Charsets.UTF_8);
String[] usernamePassword = credentials.split(":");
authConfig.withUsername(usernamePassword[0]);
authConfig.withPassword(usernamePassword[1]);
authConfig.withEmail(token.getEmail());
}
return authConfig;
}
public static CredentialsMatcher CREDENTIALS_MATCHER = CredentialsMatchers.anyOf(CredentialsMatchers
.instanceOf(StandardUsernamePasswordCredentials.class));
public abstract void execute(@SuppressWarnings("rawtypes") AbstractBuild build, ConsoleLogger console)
throws DockerException, AbortException;
protected static DockerClient getClient(AbstractBuild<?,?> build, AuthConfig authConfig) {
return ((DockerBuilder.DescriptorImpl) Jenkins.getInstance().getDescriptor(DockerBuilder.class))
.getDockerClient(build, authConfig);
}
public DockerCommandDescriptor getDescriptor() {
return (DockerCommandDescriptor) Jenkins.getInstance().getDescriptor(getClass());
}
public static DescriptorExtensionList<DockerCommand, DockerCommandDescriptor> all() {
return Jenkins.getInstance().<DockerCommand, DockerCommandDescriptor> getDescriptorList(DockerCommand.class);
}
public String getInfoString() {
return "Info from DockerCommand";
}
/**
* Only the first container started is attached!
*/
protected static DockerContainerConsoleAction attachContainerOutput(
@SuppressWarnings("rawtypes") AbstractBuild build, String containerId) throws DockerException {
try {
DockerContainerConsoleAction outAction = new DockerContainerConsoleAction(build, containerId).start();
build.addAction(outAction);
return outAction;
} catch (IOException e) {
throw new DockerException(e.getMessage(), 0);
}
}
public abstract static class DockerCommandDescriptor extends Descriptor<DockerCommand> {
protected DockerCommandDescriptor(Class<? extends DockerCommand> clazz) {
super(clazz);
}
protected DockerCommandDescriptor() {
}
public DockerRegistryEndpoint.DescriptorImpl getDockerRegistryEndpointDescriptor() {
return (DockerRegistryEndpoint.DescriptorImpl) Jenkins.getInstance().getDescriptor(
DockerRegistryEndpoint.class);
}
public String getInfoString() {
return "Info from DockerCommand.DockerCommandDescriptor";
}
// To make a subclass docker command support credentials, do the following steps:
// 1. In command's subclass, add DockerRegistryEndpoint dockerRegistryEndpoint to its
// data bound constructor, then call super(dockerRegistryEndpoint).
// 2. In command's subclass' descriptor, override showCredentials() and return true
// 3. In command's subclass' exectue(...), do:
// subclassCmd.withAuthconfig(getAuthConfig(build.getParent())
public boolean showCredentials() {
return false;
}
}
}