View Javadoc
1   package io.micronaut.build.services;
2   
3   import com.github.dockerjava.api.DockerClient;
4   import com.github.dockerjava.api.command.BuildImageCmd;
5   import com.github.dockerjava.api.command.BuildImageResultCallback;
6   import com.github.dockerjava.api.command.CreateContainerResponse;
7   import com.github.dockerjava.api.model.BuildResponseItem;
8   import com.github.dockerjava.core.DefaultDockerClientConfig;
9   import com.github.dockerjava.core.DockerClientConfig;
10  import com.github.dockerjava.core.DockerClientImpl;
11  import com.github.dockerjava.transport.DockerHttpClient;
12  import com.github.dockerjava.zerodep.ZerodepDockerHttpClient;
13  import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
14  import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
15  import org.apache.commons.compress.utils.IOUtils;
16  import org.apache.commons.io.FileUtils;
17  import org.apache.commons.lang.StringUtils;
18  import org.apache.maven.project.MavenProject;
19  import org.slf4j.Logger;
20  import org.slf4j.LoggerFactory;
21  
22  import javax.inject.Inject;
23  import javax.inject.Singleton;
24  import java.io.File;
25  import java.io.FileOutputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  
29  /**
30   * Provides methods to work with Docker images
31   *
32   * @author Álvaro Sánchez-Mariscal
33   * @since 1.1
34   */
35  @Singleton
36  public class DockerService {
37  
38      private static final Logger LOG = LoggerFactory.getLogger(DockerService.class);
39  
40      private final DockerClient dockerClient;
41      private final MavenProject mavenProject;
42  
43      @SuppressWarnings("CdiInjectionPointsInspection")
44      @Inject
45      public DockerService(MavenProject mavenProject) {
46          this.mavenProject = mavenProject;
47          DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
48          DockerHttpClient httpClient = new ZerodepDockerHttpClient.Builder()
49                  .dockerHost(config.getDockerHost())
50                  .sslConfig(config.getSSLConfig())
51                  .build();
52          dockerClient = DockerClientImpl.getInstance(config, httpClient);
53      }
54  
55      public BuildImageCmd buildImageCmd(String dockerfileName) throws IOException {
56          return dockerClient.buildImageCmd(loadDockerfileAsResource(dockerfileName));
57      }
58  
59      public BuildImageCmd buildImageCmd() {
60          return dockerClient.buildImageCmd();
61      }
62  
63      public String buildImage(BuildImageCmd builder) {
64          BuildImageResultCallback resultCallback = new BuildImageResultCallback() {
65              @Override
66              public void onNext(BuildResponseItem item) {
67                  super.onNext(item);
68                  if (item.isErrorIndicated()) {
69                      LOG.error(item.getErrorDetail().getMessage());
70                  } else if (item.getStream() != null) {
71                      LOG.info(StringUtils.chomp(item.getStream(), System.lineSeparator()));
72                  }
73              }
74          };
75  
76          return builder
77                  .exec(resultCallback)
78                  .awaitImageId();
79      }
80  
81      public File copyFromContainer(String imageId, String containerPath) {
82          CreateContainerResponse container = dockerClient.createContainerCmd(imageId).exec();
83          dockerClient.startContainerCmd(container.getId());
84          InputStream nativeImage = dockerClient.copyArchiveFromContainerCmd(container.getId(), containerPath).exec();
85  
86          try (TarArchiveInputStream fin = new TarArchiveInputStream(nativeImage)) {
87              TarArchiveEntry tarEntry = fin.getNextTarEntry();
88              File file = new File(mavenProject.getBuild().getDirectory(), tarEntry.getName());
89              IOUtils.copy(fin, new FileOutputStream(file));
90  
91              return file;
92          } catch (IOException e) {
93              e.printStackTrace();
94          }
95          return null;
96      }
97  
98      public File loadDockerfileAsResource(String name) throws IOException {
99          String path = "/dockerfiles/" + name;
100         InputStream stream = getClass().getResourceAsStream(path);
101         if (stream != null) {
102             File dockerfile = new File(mavenProject.getBuild().getDirectory(), "Dockerfile");
103             FileUtils.copyInputStreamToFile(stream, dockerfile);
104             return dockerfile;
105         }
106         return null;
107     }
108 
109 }