summaryrefslogtreecommitdiffstats
path: root/src/main/java/net/libertacasa/pubsh/web/Docker.java
blob: b150fdc13585f770b6122365033a4bec53601168 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
package net.libertacasa.pubsh.web;

import java.io.File;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.BuildImageResultCallback;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.ListContainersCmd;
import com.github.dockerjava.api.command.ListImagesCmd;
import com.github.dockerjava.api.command.WaitContainerResultCallback;
import com.github.dockerjava.api.model.Image;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;

public class Docker {
	
	static DockerClientConfig DockerConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
		    //.withDockerHost("tcp://sweetsuse:2375")
			.withDockerHost("tcp://sweetsuse:8085")
		    .withDockerTlsVerify(false)
		    .build();	
	
	static DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
		    .dockerHost(DockerConfig.getDockerHost())
		    .sslConfig(DockerConfig.getSSLConfig())
		    .maxConnections(100)
		    .connectionTimeout(Duration.ofSeconds(30))
		    .responseTimeout(Duration.ofSeconds(45))
		    .build();
	
	static DockerClient dockerClient = DockerClientImpl.getInstance(DockerConfig, httpClient);
	
	public static List<String> getImageChecksums() {
		List<Image> imageQuery;
		List<String> imageList;
		imageQuery = dockerClient.listImagesCmd().exec();
		imageList = imageQuery.stream().map(Image::getId).collect(Collectors.toList());
		return imageList;
	}
	
	public static List<Image> getImages(String name) {		
		List<Image> imageQuery;
		ListImagesCmd imageQueryCmd = dockerClient.listImagesCmd();
				
		if (name != null) {
			imageQueryCmd.getFilters().put("reference", Arrays.asList(name + "*")); //to-do: filter by nameshX instead
		}
		
		imageQuery = imageQueryCmd.exec();
		return imageQuery;
	}
	
	public static List<com.github.dockerjava.api.model.Container> getContainers(String name) {
		List<com.github.dockerjava.api.model.Container> containerQuery;	
		ListContainersCmd containerQueryCmd = dockerClient.listContainersCmd();
		
		if (name != null) {
			containerQueryCmd.getFilters().put("name", Arrays.asList(name + "*"));
		}
		
		containerQuery = containerQueryCmd.withShowAll(true).exec();
		
		return containerQuery;
	}
	
	public static void deleteContainer(String id) {
		Collection<String> stringifiedId = Arrays.asList(id);
		//System.out.println(id);
		System.out.println(stringifiedId);
		List<com.github.dockerjava.api.model.Container> containerQuery = dockerClient.listContainersCmd().withShowAll(false).withIdFilter(stringifiedId).exec();
		//apparently listContainersCmd returns a bunch of garbled crap, hence the less ideal toString/contains
		if(! containerQuery.toString().contains(id)) {
			System.out.println("Not found in running containers ...");
			List<com.github.dockerjava.api.model.Container> containerQueryAll = dockerClient.listContainersCmd().withShowAll(true).withIdFilter(stringifiedId).exec();
			if(containerQueryAll.toString().contains(id)) {
				System.out.println("Found in stopped containers ...");
			}
			if(! containerQueryAll.toString().contains(id)) {
				System.out.println("Not found at all. The fuck.");
			}
		}
		if(containerQuery.toString().contains(id)) {
			System.out.println("Found in running containers, stopping ...");
			dockerClient.stopContainerCmd(id).exec();
		}

		dockerClient.removeContainerCmd(id).exec();
	}
	
	public static String buildImage(String targetUser, String osChoice, Integer count) {
		String dockerfile = "/home/georg/tmp/docker/Dockerfile_" + osChoice;
		String tag = targetUser + ":" + osChoice + count;
		if (! new File(dockerfile).exists()) {
			System.out.printf("Invalid Dockerfile: %s\n", dockerfile);
		}
		Set<String> tags = new HashSet<String>();
		tags.add(tag);
		String imgid = dockerClient.buildImageCmd()
				.withDockerfile(new File(dockerfile))
				.withPull(false).withNoCache(false).withTags(tags)
				.exec(new BuildImageResultCallback()).awaitImageId();
		
		System.out.printf("Built image with ID %s\n", imgid);
		return(imgid);
	}
	
	public static void deleteImage(String id) {
		List<Image> imagequery = Docker.getImages(null);

		if (imagequery.toString().contains(id)) {
			try {
				System.out.printf("Found image ID %s, deleting ...\n", id);
				dockerClient.removeImageCmd(id).withImageId(id).exec();
			} catch (com.github.dockerjava.api.exception.ConflictException exception) {
				System.out.println("Image is still being used by a container.");
				throw exception;
			}
			//needs to wait for callback, but there is none
			//System.out.printf("%s", removeQuery);

		}
		if (! imagequery.toString().contains(id)) {
			System.out.printf("Image ID %s not found.\n", id);
		}
		
	}
	
	public static String createContainer(String name, String imgid) {
		//String containerid = dockerClient.createContainerCmd(imgid).exec();
		WaitContainerResultCallback resultCallback = new WaitContainerResultCallback();
		CreateContainerResponse createContainerResponse = dockerClient
				.createContainerCmd(imgid)
				.withName(name)
				.withTty(true)
				.withAttachStdin(true)
				.exec();
		dockerClient.waitContainerCmd(createContainerResponse.getId()).exec(resultCallback);
		try {
			resultCallback.awaitCompletion();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String containerid = createContainerResponse.getId();
		//System.out.println(dockerClient.infoCmd().exec());
			
		System.out.printf("Created container with ID %s from image ID %s\n", containerid, imgid);
		return(containerid);
	}
	
	public static String createShell(String user, String os, Integer count) {
		String name1 = user + "_" + os;
		String name = name1 + "_" + count;
		String imageid = null;
		List<Image> imageQuery = Docker.getImages(user + ":" + os);

		System.out.printf("Image query: %s\n", imageQuery);
		
		if (imageQuery.isEmpty()) {
			System.out.println("No result, building new image.\n");
			imageid = Docker.buildImage(user, os, count);
		}		
		if (! imageQuery.isEmpty()) {
			System.out.println("Found existing image.\n");
			Image image = imageQuery.get(0);
			imageid = image.getId();
		}				

		String containerid = createContainer(name, imageid);
		System.out.printf("Initialized shell with image ID %s and container ID %s\n", imageid, containerid);
		return(containerid);
	}
	
	public static Integer deleteShell(String user, String id) {
		Docker.deleteContainer(id);
		List<Image> images = Docker.getImages(user);
		for (Image image : images) {
			String imageid = image.getId();
			System.out.println(imageid);
			try {
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Docker.deleteImage(imageid);
				System.out.println("Removed.");
			} catch (com.github.dockerjava.api.exception.ConflictException exception) {
				System.out.println("Still being used, skipping.");
			}
		}
		return(null);
	}

}