package com.dianping.paas.repository.docker; import com.dianping.paas.core.config.ConfigManager; import com.dianping.paas.core.dto.request.DockerfileRequest; import com.dianping.paas.core.dto.response.DockerfileResponse; import com.dianping.paas.core.extension.ExtensionLoader; import com.dianping.paas.core.util.FileUtil; import com.dianping.paas.repository.template.TemplateService; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.model.Identifier; import com.github.dockerjava.api.model.PushResponseItem; import com.github.dockerjava.api.model.Repository; import com.github.dockerjava.core.command.BuildImageResultCallback; import com.github.dockerjava.core.command.PushImageResultCallback; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.File; /** * Created by yuchao on 11/23/15. */ @Component public class DockerServiceImpl implements DockerService { private static final Logger logger = LogManager.getLogger(DockerServiceImpl.class); private ConfigManager configManager = ExtensionLoader.getExtension(ConfigManager.class); @Resource @SuppressWarnings("SpringJavaAutowiringInspection") private DockerClient dockerClient; @Resource private TemplateService templateService; public DockerfileResponse buildImageAndPush(DockerfileRequest request) throws Exception { DockerfileResponse response = new DockerfileResponse(); if (buildImage(request, response)) { pushImage(request, response); } return response; } private boolean buildImage(DockerfileRequest request, DockerfileResponse response) throws Exception { logger.info(String.format("begin buildImage: %s", request)); try { File dockerFileTemplate = new File(request.getDockerfileTemplateLocation()); String dockerfileContent = templateService.getContentFromTemplateFile(dockerFileTemplate, request.getDockerfileParams()); response.setDockerfileContent(dockerfileContent); File dockerfile = FileUtil.write(request.getDockerfileLocation(), dockerfileContent); String imageId = dockerClient.buildImageCmd(dockerfile).withTag(buildImageTag(request)).exec(new BuildImageResultCallback()).awaitImageId(); response.setImageId(imageId); response.success(); } catch (Exception e) { response.fail(e.toString()); logger.error(String.format("error buildImage: %s", request), e); } logger.info(String.format("end buildImage: %s", response)); return response.isSuccess(); } private void pushImage(DockerfileRequest request, DockerfileResponse response) { logger.info(String.format("begin pushImage: %s", request)); try { String repositoryName = buildRepositoryName(request); Repository repository = new Repository(repositoryName); Identifier identifier = new Identifier(repository, request.getAppTag()); dockerClient.pushImageCmd(identifier).exec(new PushImageResultCallback() { @Override public void onNext(PushResponseItem item) { super.onNext(item); if (logger.isDebugEnabled()) { logger.debug(item); } } }).awaitSuccess(); response.setRepository(String.format("%s:%s", repositoryName, request.getAppTag())); } catch (Exception e) { response.fail(e.toString()); logger.error(String.format("error pushImage: %s", request), e); } logger.info(String.format("end pushImage: %s", response)); } private String buildImageTag(DockerfileRequest request) { return String.format("%s:%s", buildRepositoryName(request), request.getAppTag()); } private String buildRepositoryName(DockerfileRequest request) { return String.format("%s/%s", configManager.getRepositoryUrl(), request.getAppName()); } }