summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java
blob: 62e5dd0da3fb247a6ef09f9783aced308b0be5d0 (plain) (blame)
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
package org.openslx.dozmod.util;

import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import org.apache.log4j.Logger;
import org.kamranzafar.jtar.TarEntry;
import org.kamranzafar.jtar.TarHeader;
import org.kamranzafar.jtar.TarInputStream;
import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.I18n;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.thrift.cache.LectureCache;
import org.openslx.thrifthelper.TConst;

import java.awt.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * Class with some temporally Helper Functions.
 */
public class ContainerUtils {

	private static final Logger LOGGER = Logger.getLogger(ContainerUtils.class);
	/**
	 * Checks ImageBaseId of image if already linked with existing Lectures in LectureCache.
	 *
	 * @param image The image to check.
	 * @return true if the images imageBaseId is already linked with a lecture.
	 */
	public static boolean isContainerImageLinked(ImageSummaryRead image) {
		if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER)) {
			List<LectureSummary> lectureSummaries = LectureCache.get(true);
			for (LectureSummary lecture : lectureSummaries) {
				// lecture.imageBaseId is null when no image linked to it -> NullPointer on equals
				if (image.imageBaseId.equals(lecture.imageBaseId)) {
					return true;
				}
			}
		}
		return false;
	}

	public static void showWarning(Component c, Logger logger) {
		Gui.showMessageBox(c, I18n.WINDOW.getString("LectureDetails.Message.error.containerLinkedWithLecture"),
				MessageType.WARNING, logger, null);
	}

	/**
	 * Check if a provided tar file contains information about a single docker image.
	 * To check the validity of the file, the existence of two JSON files is checked
	 * and one of the files must only contain information for one image.
	 *
	 * The tar file have to be created by the 'docker save ...' command.
	 *
	 * @param tarFile the user selected tar file.
	 * @return true if the images imageBaseId is already linked with a lecture.
	 */
	public static boolean isValidTar(File tarFile) {

		boolean isValid = false;
		boolean containsManifest = false;
		boolean containsRepositories = false;
		JsonArray manifestJson = null;

		try {
			TarInputStream tis = new TarInputStream(new FileInputStream(tarFile));
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] rawData = new byte[1024];
			TarEntry entry;

			// setDefaultSkip seems to fasten things up while processing the file,
			// because we want only to check manifest.json and repositories file
			tis.setDefaultSkip(true);
			while ((entry = tis.getNextEntry()) != null) {
				if(!TarHeader.USTAR_MAGIC.equals(entry.getHeader().magic.toString()))
					break;
				Arrays.fill(rawData, (byte) 0);
				output.reset();
				int count = 0;

				if (entry.getName().equals("manifest.json")) {
					containsManifest = true;
					while ((count = tis.read(rawData)) != -1) {
						output.write(rawData, 0, count);
					}
					manifestJson = new JsonParser().parse(
							new String(output.toByteArray(), StandardCharsets.UTF_8)).getAsJsonArray();
				}

				if (entry.getName().equals("repositories")) {
					containsRepositories = true;
					// dont read the file, no checks for the Content
				}

				if (containsManifest && containsRepositories)
					break;
			}
			tis.close();
			// check the json files inside the tar file
			if (containsManifest && containsRepositories && manifestJson.isJsonArray()
					&& manifestJson.size() == 1) {
				isValid = true;
				String repoTag = manifestJson.get(0).getAsJsonObject().get("RepoTags").getAsString();
				LOGGER.info(String.format("Tar File contains Docker Image with repoTag=%s", repoTag));
			} else if (containsManifest && containsRepositories && manifestJson.isJsonArray()
					&& manifestJson.size() > 1) {
				Gui.showMessageBox("Tar File container more then one Images!", MessageType.ERROR,
						LOGGER,
						null);
			} else {
				Gui.showMessageBox("No valid Tar File with Images provided!", MessageType.ERROR,
						LOGGER,
						null);
			}

		} catch (IOException e) {
			LOGGER.error("IOError while processing tar file", e);
		}
		return isValid;
	}
}