package org.openslx.dozmod.util; import com.google.gson.JsonArray; import com.google.gson.JsonParser; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.thrift.TException; 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.GridManager; import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.cache.ImageCache; import org.openslx.dozmod.thrift.cache.LectureCache; import org.openslx.thrifthelper.TConst; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.ThriftUtil; import org.openslx.util.Util; import org.openslx.util.TarArchiveUtil.TarArchiveReader; import org.openslx.virtualization.configuration.container.ContainerMeta; import javax.swing.*; import java.awt.*; import java.io.*; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; /** * Class with some temporally Helper Functions. */ public class ContainerUtils { private static final Logger LOGGER = LogManager.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 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 boolean isDataContainer(ImageSummaryRead image) { if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER)) { ContainerDefinition containerDefinition = getContainerDefinition(Session.getSatelliteToken(), image.getImageName(), image.getLatestVersionId()); if (containerDefinition.getContainerMeta().getImageType() == ContainerMeta.ContainerImageType.DATA) { return true; } } return false; } public static List getDataContainerImages() { String satelliteToken = Session.getSatelliteToken(); List images = ImageCache.get(true); List dataContainerImages = new ArrayList<>(); for (ImageSummaryRead image : images) { if (image.getVirtId().equals(TConst.VIRT_DOCKER)) { ContainerDefinition containerDefinition = getContainerDefinition(satelliteToken, image.getImageName(), image.getLatestVersionId()); if (containerDefinition != null && containerDefinition.getContainerMeta().getImageType() == ContainerMeta.ContainerImageType.DATA) dataContainerImages.add(image); } } return dataContainerImages; } public static void showWarning(Component c, String message, Logger logger) { Gui.showMessageBox(c, message, MessageType.WARNING, logger, null); } public static ContainerDefinition getContainerDefinition(String satelliteToken, String imageName, String latestVersionId) { byte[] rawVirtConfig = null; if (latestVersionId == null) return null; try { ByteBuffer byteBuffer = ThriftManager.getSatClient().getImageVersionVirtConfig(satelliteToken, latestVersionId); rawVirtConfig = ThriftUtil.unwrapByteBuffer(byteBuffer); } catch (TException e) { LOGGER.error(String.format(" Failed to retrieve virtualizer config for image '%s' with image version '%s', see trace:", imageName, latestVersionId), e); return null; } return ContainerDefinition.fromByteArray(rawVirtConfig); } /** * 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 { TarArchiveReader tarReader = new TarArchiveReader(new FileInputStream(tarFile)); while (tarReader.hasNextEntry()) { if (tarReader.getEntryName().equals("manifest.json")) { containsManifest = true; manifestJson = JsonParser.parseString(new String(tarReader.readCurrentEntry(), StandardCharsets.UTF_8)) .getAsJsonArray(); } if (tarReader.getEntryName().equals("repositories")) { containsRepositories = true; // just check if the file exists } if (containsManifest && containsRepositories) break; } Util.safeClose(tarReader); } catch (IOException e) { LOGGER.error("IOError while processing tar file", e); } // check the json files inside the tar file try { if (containsManifest && containsRepositories && manifestJson.isJsonArray() && manifestJson.size() == 1) { isValid = true; JsonArray jRepoTags = manifestJson.get(0).getAsJsonObject().getAsJsonArray("RepoTags"); if (jRepoTags.isEmpty()) LOGGER.info("Valid Docker-Archive with no repoTags recognized"); else LOGGER.info(String.format("Valid Docker-Archive with repoTag=%s recognized", jRepoTags.get(0).toString())); } 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 (IllegalStateException e) { Gui.showMessageBox("An error occurred while checking the Docker archive!", MessageType.ERROR, LOGGER, null); isValid=false; } return isValid; } public static JPanel createDownloadContainerInfo(String imageRepo, String infoText) { JPanel pnlUserInfo = new JPanel(); GridManager grid = new GridManager(pnlUserInfo, 1, true); JTextArea txtInfoText = new JTextArea(); txtInfoText.setBorder(BorderFactory.createTitledBorder(I18n.PAGE_LAYOUT.getString("Info"))); txtInfoText.setLineWrap(true); txtInfoText.setWrapStyleWord(true); txtInfoText.setEditable(false); txtInfoText.setFocusable(false); txtInfoText.setOpaque(false); txtInfoText.setText(infoText); grid.add(txtInfoText).fill(true, true); grid.nextRow(); JTextField txtUserInfo = new JTextField(); txtUserInfo.setText(imageRepo); grid.add(txtUserInfo).fill(true, true); grid.finish(true); return pnlUserInfo; } public static String getImageNameByBaseId(String imageBaseId) { List images = ImageCache.get(true); for (ImageSummaryRead image : images) { if (image.imageBaseId.equals(imageBaseId)) return image.getImageName(); } return imageBaseId; } }