diff options
author | ralph isenmann | 2020-09-24 16:20:33 +0200 |
---|---|---|
committer | ralph isenmann | 2020-09-24 16:20:33 +0200 |
commit | f776e49d80f5d2df632ec17578c5783c1a4408c1 (patch) | |
tree | 887c363737d327978c93e3200aac6c10150dd1f4 | |
parent | [client] more refactoring (diff) | |
download | tutor-module-f776e49d80f5d2df632ec17578c5783c1a4408c1.tar.gz tutor-module-f776e49d80f5d2df632ec17578c5783c1a4408c1.tar.xz tutor-module-f776e49d80f5d2df632ec17578c5783c1a4408c1.zip |
[client] update download behavior for container definitions
- downloading a container entry will now result in two files in target directory: dockerfile and container_meta.json
- TODO: Do not download the container image in the container context, it will be deleted immediately.
3 files changed, 86 insertions, 104 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java index 7784ce86..0b378ea6 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java @@ -21,6 +21,10 @@ import java.util.zip.GZIPOutputStream; public class ContainerDefinition { private static final Logger LOGGER = Logger.getLogger(ContainerDefinition.class); + + private static final String CONTAINER_FILE = "dockerfile"; + private static final String CONTAINER_META_FILE = "container_meta.json"; + /** * The file to construct a real container, could be an dockerfile or a singularity recipe. */ @@ -92,9 +96,9 @@ public class ContainerDefinition { byte[] rawData = new byte[size]; tis.read(rawData, 0, size); - if (entry.getName().equals("dockerfile")) + if (entry.getName().equals(CONTAINER_FILE)) containerDef.setContainerDescription(rawData); - if (entry.getName().equals("container_meta.json")) + if (entry.getName().equals(CONTAINER_META_FILE)) containerDef.setContainerMeta(rawData); } @@ -119,10 +123,8 @@ public class ContainerDefinition { TarOutputStream output = new TarOutputStream(new GZIPOutputStream(baos)); Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - TarArchiveUtil.tarPutFile(output, "container_meta.json", gson.toJson(containerMeta)); - TarArchiveUtil.tarPutFile(output, "dockerfile", containerDescription); - + TarArchiveUtil.tarPutFile(output, CONTAINER_META_FILE, gson.toJson(containerMeta)); + TarArchiveUtil.tarPutFile(output, CONTAINER_FILE, containerDescription); output.close(); containerDef = ByteBuffer.wrap(baos.toByteArray()); @@ -151,6 +153,27 @@ public class ContainerDefinition { return new String(containerRecipe, StandardCharsets.UTF_8); } + public void saveLocal(File destDir) { + + writeFile(destDir, containerDescription, CONTAINER_FILE); + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + writeFile(destDir, gson.toJson(containerMeta), CONTAINER_META_FILE); + } + + private void writeFile(File destDir, String fileContent, String filename) { + File output = new File(destDir, filename); + try { + FileWriter fw = new FileWriter(output); + fw.write(fileContent); + fw.flush(); + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + LOGGER.error("Could not write File", e); + } + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java index 8c51b75f..27a77322 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java @@ -15,24 +15,8 @@ import javax.swing.JFileChooser; import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransportException; -import org.openslx.bwlp.thrift.iface.ImageBaseWrite; -import org.openslx.bwlp.thrift.iface.ImageDetailsRead; -import org.openslx.bwlp.thrift.iface.ImagePermissions; -import org.openslx.bwlp.thrift.iface.ImagePublishData; -import org.openslx.bwlp.thrift.iface.ImageVersionDetails; -import org.openslx.bwlp.thrift.iface.ImageVersionWrite; -import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.bwlp.thrift.iface.LectureRead; -import org.openslx.bwlp.thrift.iface.LectureSummary; -import org.openslx.bwlp.thrift.iface.LectureWrite; -import org.openslx.bwlp.thrift.iface.Satellite; +import org.openslx.bwlp.thrift.iface.*; import org.openslx.bwlp.thrift.iface.SatelliteServer.Client; -import org.openslx.bwlp.thrift.iface.TAuthorizationException; -import org.openslx.bwlp.thrift.iface.TInvocationException; -import org.openslx.bwlp.thrift.iface.TNotFoundException; -import org.openslx.bwlp.thrift.iface.TransferInformation; -import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.bwlp.thrift.iface.WhoamiInfo; import org.openslx.dozmod.App; import org.openslx.dozmod.Config; import org.openslx.dozmod.Config.SavedSession; @@ -466,8 +450,10 @@ public class ThriftActions { dlTask.addListener(new TransferEventListener() { @Override public void update(TransferEvent event) { - ImageWrapper.unpack(event, virtualizerId, tmpDiskFile, imageName, destDir, osId, - fTransInf); + if (event.state != TransferState.FINISHED) + return; + ImageWrapper.unpack(virtualizerId, tmpDiskFile, imageName, destDir, osId, + fTransInf.getMachineDescription()); } }); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java index c8ca7746..c86ddfa9 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java @@ -1,17 +1,15 @@ package org.openslx.dozmod.util; import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.TransferInformation; -import org.openslx.bwlp.thrift.iface.TransferState; + import org.openslx.dozmod.Branding; -import org.openslx.dozmod.filetransfer.TransferEvent; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.thrifthelper.TConst; import org.openslx.util.vm.DiskImage; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; @@ -19,102 +17,77 @@ public class ImageWrapper { private static final Logger LOGGER = Logger.getLogger(ImageWrapper.class); - - public static void unpack(TransferEvent event, String virtualizerId, File tmpDiskFile, String imageName, - File destDir, int osId, TransferInformation fTransInf) { + /** + * @param virtualizerId string constant defined in @link org.openslx.thrifthelper.TConst + * @param tmpDiskFile dont no! + * @param imageName The name of that image in the list. + * @param destDir Destination directory on the local host. + * @param osId Operating system identifier of the selected image. + * @param virtualizerConfig raw byte array of virtualizerconfig in imageversion table. Only the Image knows + * how to use it. + */ + public static void unpack(String virtualizerId, File tmpDiskFile, String imageName, File destDir, + int osId, byte[] virtualizerConfig) { // after the whole image is downloaded and persisted as a .part file, // this will be executed to unpack it. // TODO Move into new Class (implements TransferEventListener) - /* - * It seems only the diskfile of UploadWizardState will be downloaded. - * In Context of Container this would be a Container Image. - * - */ - if (event.state != TransferState.FINISHED) - return; DiskImage diskImage = null; String ext = virtualizerId; - // TODO: Currently when downloading a Docker Image, the dockerfile will be downloaded - // just rename the .part file to dockerfile - + // unwrap each image individually + // TODO In future maybe this is a check to distinguish between VM-Image and Container Image if (virtualizerId.equals(TConst.VIRT_DOCKER)) { - // - File destImage = new File(destDir.getAbsolutePath(),"dockerfile"); - try { - // TODO: (RALPH) dockerfile == virtualizerconfig(table imageversion) ... maybe not a goot solution! - writeDockerfile(destDir, fTransInf.getMachineDescription()); + ContainerDefinition conDef = ContainerDefinition.fromByteArray(virtualizerConfig); + conDef.saveLocal(destDir); - // delete image file because thats also the dockerfile + try { + // delete image file, unused in container Context. Files.delete(tmpDiskFile.toPath()); - // use move(..) because of platform independence - /*Files.move(tmpDiskFile.toPath(), - destImage.toPath(), - StandardCopyOption.REPLACE_EXISTING - );*/ - } catch (IOException e) { - Gui.asyncMessageBox("Konnte dockerfile nicht an Ziel kopieren", - MessageType.WARNING, LOGGER, e); + Gui.asyncMessageBox("Konnte temporäre Download Datei nicht löschen", MessageType.WARNING, LOGGER, + e); } - return; - } - // TODO: Container images have currently no diskImage, prevent creating one - try { - diskImage = new DiskImage(tmpDiskFile); - } catch (IOException | DiskImage.UnknownImageFormatException e) { - LOGGER.warn("Could not open downloaded image for analyze step", e); - } - if (diskImage != null) { - if (diskImage.format != null) { - ext = diskImage.format.extension; + } else { + try { + diskImage = new DiskImage(tmpDiskFile); + } catch (IOException | DiskImage.UnknownImageFormatException e) { + LOGGER.warn("Could not open downloaded image for analyze step", e); } - if (diskImage.isCompressed) { - String msg = "<html>Die heruntergeladene VM '" + imageName + "' ist ein komprimiertes " - + "Abbild.<br>Sie müssen das Abbild dekomprimieren, bevor Sie es verändern " - + "können.<br> Die VM wird lokal voraussichtlich nicht startfähig sein!" - + "<br><br>Bitte lesen Sie die Hinweise unter " - + "<a href=\"" + Branding.getServiceFAQWebsite() + "\">" - + "VMDK Disk Types</a>"; - - Gui.asyncMessageBox(msg, MessageType.WARNING, null, - null); + + if (diskImage != null) { + if (diskImage.format != null) { + ext = diskImage.format.extension; + } + if (diskImage.isCompressed) { + String msg = "<html>Die heruntergeladene VM '" + imageName + "' ist ein komprimiertes " + + "Abbild.<br>Sie müssen das Abbild dekomprimieren, bevor Sie es verändern " + + "können.<br> Die VM wird lokal voraussichtlich nicht startfähig sein!" + + "<br><br>Bitte lesen Sie die Hinweise unter " + "<a href=\"" + + Branding.getServiceFAQWebsite() + "\">" + "VMDK Disk Types</a>"; + + Gui.asyncMessageBox(msg, MessageType.WARNING, null, null); + } } - } - File destImage = new File(destDir.getAbsolutePath(), VmWrapper.generateFilename( - imageName, ext)); + File destImage = new File(destDir.getAbsolutePath(), VmWrapper.generateFilename(imageName, ext)); - destImage.delete(); + destImage.delete(); - if (!tmpDiskFile.renameTo(destImage)) { - destImage = tmpDiskFile; // Must be Windows... - } - try { - VmWrapper.wrapVm(destImage, imageName, fTransInf.getMachineDescription(), - virtualizerId, osId, diskImage); - - } catch (VmWrapper.MetaDataMissingException | IOException e) { - Gui.asyncMessageBox( - "Zur heruntergeladenen VM konnte keine vmx-Datei angelegt werden." - + "\nSie können versuchen, das Abbild manuell in den VMWare-Player zu importieren.", - MessageType.WARNING, LOGGER, e); - } - } + if (!tmpDiskFile.renameTo(destImage)) { + destImage = tmpDiskFile; // Must be Windows... + } + try { + VmWrapper.wrapVm(destImage, imageName, virtualizerConfig, virtualizerId, osId, diskImage); - private static void writeDockerfile(File destDir, byte[] dockerfile_b) { - String filename = "dockerfile"; - File dockerfile = new File(destDir,filename); - try { - FileOutputStream fos = new FileOutputStream(dockerfile); - fos.write(dockerfile_b); - fos.close(); - } catch (IOException e) { - LOGGER.error("could not write dockerfile", e); + } catch (VmWrapper.MetaDataMissingException | IOException e) { + Gui.asyncMessageBox("Zur heruntergeladenen VM konnte keine vmx-Datei angelegt werden." + + "\nSie können versuchen, das Abbild manuell in den VMWare-Player zu importieren.", + MessageType.WARNING, LOGGER, e); + } } } } |