From 568506424ab62dbc42198940451fb73d46407ff1 Mon Sep 17 00:00:00 2001 From: ralph isenmann Date: Tue, 11 May 2021 09:17:52 +0200 Subject: [client] Allow user to define container with Repository Image (directly from hub.docker) --- .../openslx/dozmod/gui/panel/ContainerPanel.java | 20 +++++++++++----- .../wizard/layout/ContainerUploadPageLayout.java | 27 ++++++++++++++++++---- .../gui/wizard/page/ContainerUploadPage.java | 9 ++++++++ .../dozmod/model/ContainerBuildContextMethod.java | 2 +- .../org/openslx/dozmod/model/ContainerMeta.java | 14 ++++++++++- .../src/main/properties/i18n/page.properties | 1 + .../src/main/properties/i18n/page_de_DE.properties | 2 ++ .../main/properties/i18n/page_layout.properties | 2 ++ .../properties/i18n/page_layout_de_DE.properties | 2 ++ 9 files changed, 66 insertions(+), 13 deletions(-) (limited to 'dozentenmodul/src') diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java index 37008e78..028b9878 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java @@ -103,12 +103,21 @@ public class ContainerPanel extends JPanel { txtContainerImageName.setText(image.imageName); txtContainerImageName.setEnabled(false); - // TODO simplify this mess. ContainerBuildContextMethod is to complex - if (containerDefinition.getBuildContextMethod() == ContainerBuildContextMethod.FILE) { + // TODO simplify this mess. ContainerBuildContextMethod is to complex or useless + switch (containerDefinition.getBuildContextMethod()) + { + case FILE: txtContainerRecipe.setText(containerDefinition.getContainerRecipe()); - } else if (containerDefinition.getBuildContextMethod() - == ContainerBuildContextMethod.GIT_REPOSITORY) { + break; + case IMAGE_REPO: + txtContainerRecipe.setText(containerDefinition.getContainerMeta().getImageRepo()); + break; + case GIT_REPOSITORY: txtContainerRecipe.setText(containerDefinition.getContainerMeta().getBuildContextUrl()); + break; + default: + LOGGER.error("Unknown Build Context"); + break; } if (context.equals(IMAGE_CONTEXT)) { @@ -118,12 +127,11 @@ public class ContainerPanel extends JPanel { } else { LOGGER.error("Container Panel init failed: Please use proper context"); } - } private void initImageDetails() { - // currently do not allow user to change the Dockerfile in the suite. + // currently do not allow user to change the Image Repository or Dockerfile in the suite. txtContainerRecipe.setEnabled(false); lblContainerRunOpt.setVisible(false); txtContainerRun.setVisible(false); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ContainerUploadPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ContainerUploadPageLayout.java index 5fcc6dcd..0496261f 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ContainerUploadPageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ContainerUploadPageLayout.java @@ -24,6 +24,8 @@ public class ContainerUploadPageLayout extends WizardPage { protected final QLabel lblImageName; protected final JTextArea txtInfoText; + protected final JTextField txtImageRepo; + protected final JTabbedPane tpInput; protected final JTextField txtGitRepo; @@ -38,8 +40,24 @@ public class ContainerUploadPageLayout extends WizardPage { setDescription(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.description")); GridManager grid = new GridManager(this, 3, false); + JPanel imageRepoPanel = new JPanel(); + imageRepoPanel.setVisible(true); + GridManager tmpGrid = new GridManager(imageRepoPanel, 2, true, new Insets(5, 0, 5, 0)); + QLabel lblImageRepo = new QLabel( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.DockerFile.label")); + lblImageRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); + txtImageRepo = new JTextField(); + txtImageRepo.setEditable(true); + txtImageRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); + tmpGrid.add(lblImageRepo); + tmpGrid.add(txtImageRepo).fill(true, false).expand(true, false); + tmpGrid.finish(false); + + JPanel p1 = new JPanel(); - p1.setVisible(true); + p1.setVisible(false); GridManager g1 = new GridManager(p1, 3, true, new Insets(5, 0, 5, 0)); QLabel imageFileCaption = new QLabel( I18n.PAGE_LAYOUT.getString("ContainerUploadPage.DockerFile.label")); @@ -68,13 +86,12 @@ public class ContainerUploadPageLayout extends WizardPage { tpInput = new JTabbedPane(); tpInput.addTab("Dockerfile", p1); tpInput.addTab("Git Repository", p2); - tpInput.setSelectedIndex(ContainerBuildContextMethod.FILE.ordinal()); + tpInput.addTab("Image Repository", imageRepoPanel); + // set "Image Repository" as selected + tpInput.setSelectedIndex(2); grid.add(tpInput, 3).fill(true, false); - // Start as with Dockerfile as input! - tpInput.setSelectedIndex(0); - lblImageName = new QLabel(I18n.PANEL.getString("ContainerPanel.Label.ImageName.text")); txtImageName = new JTextField(); grid.add(lblImageName); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java index b16a9785..7ff19882 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java @@ -232,6 +232,12 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { ContainerBuildContextMethod method = getBuildContextMethod(); switch (method) { + case IMAGE_REPO: + if (txtImageRepo.getText() == null || txtImageRepo.getText().isEmpty()) { + setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoImageRepo")); + return false; + } + break; case FILE: if (txtImageFile.getText() == null || txtImageFile.getText().isEmpty()) { setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoReceipt")); @@ -270,6 +276,9 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { case FILE: containerDefinition.setContainerRecipe(state.descriptionFile); break; + case IMAGE_REPO: + containerMeta.setImageRepo(txtImageRepo.getText()); + state.descriptionFile = getDummyFile(); case GIT_REPOSITORY: containerMeta.setBuildContextUrl(txtGitRepo.getText()); state.descriptionFile = getDummyFile(); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerBuildContextMethod.java b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerBuildContextMethod.java index 6ed42ba8..54b7bd39 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerBuildContextMethod.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerBuildContextMethod.java @@ -2,7 +2,7 @@ package org.openslx.dozmod.model; public enum ContainerBuildContextMethod { - FILE, GIT_REPOSITORY; + FILE, GIT_REPOSITORY,IMAGE_REPO; public static ContainerBuildContextMethod fromInt(int index) { return values()[index]; diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java index 32818acf..ccdb0762 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java @@ -7,10 +7,16 @@ import java.util.Objects; /** * ContainerMeta is used to store container specific information. * An object of this class will be serialized with gson to a json file. + * + * TODO remove build_context_method + * no need to distinguish beettween methods + * TODO rename build_context_url to build_context */ public class ContainerMeta { + private int build_context_method; + private String image_repo; private String build_context_url; private String image_name; private String run_options; @@ -18,6 +24,7 @@ public class ContainerMeta { public ContainerMeta() { + image_repo = ""; build_context_method = ContainerBuildContextMethod.FILE.ordinal(); build_context_url = ""; image_name = ""; @@ -30,6 +37,7 @@ public class ContainerMeta { build_context_url = containerMeta.build_context_url; image_name = containerMeta.image_name; run_options = containerMeta.run_options; + image_repo = containerMeta.image_repo; for (ContainerBindMount bm : containerMeta.bind_mount_config) bind_mount_config.add(new ContainerBindMount(bm.getSource(), bm.getTarget(), bm.getOptions())); @@ -75,6 +83,10 @@ public class ContainerMeta { this.bind_mount_config = bindMountConfig; } + public String getImageRepo() { return image_repo; } + + public void setImageRepo(String from_image) { this.image_repo = from_image; } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -83,7 +95,7 @@ public class ContainerMeta { ContainerMeta that = (ContainerMeta) o; return Objects.equals(build_context_url, that.build_context_url) && Objects.equals(image_name, that.image_name) && Objects.equals(run_options, that.run_options) && Objects.equals( - bind_mount_config, that.bind_mount_config); + bind_mount_config, that.bind_mount_config) && Objects.equals(image_repo,that.image_repo) ; } @Override public int hashCode() { diff --git a/dozentenmodul/src/main/properties/i18n/page.properties b/dozentenmodul/src/main/properties/i18n/page.properties index f9c094a2..fb951700 100644 --- a/dozentenmodul/src/main/properties/i18n/page.properties +++ b/dozentenmodul/src/main/properties/i18n/page.properties @@ -69,6 +69,7 @@ ImageOvfConversion.Dialog.RemoveTmpDirectory.title=Delete temporary directory? # ContainerUploadPage ContainerUploadPage.Description.ContainerDefFinished=Container definition finished +ContainerUploadPage.Warning.NoImageRepo=No Image Repository provided ContainerUploadPage.Warning.NoReceipt=No Container Recipe provided! ContainerUploadPage.Warning.NoGitRepository=No Git Repository provided! ContainerUploadPage.Warning.NoProperName=Set proper Image Name diff --git a/dozentenmodul/src/main/properties/i18n/page_de_DE.properties b/dozentenmodul/src/main/properties/i18n/page_de_DE.properties index 43ab8f41..599bb26d 100644 --- a/dozentenmodul/src/main/properties/i18n/page_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/page_de_DE.properties @@ -70,6 +70,7 @@ ContainerUploadPage.Warning.NoReceipt=Keine Containeranweisungen angegeben! ContainerUploadPage.Warning.NoGitRepository=Kein Git Repository angegeben! ContainerUploadPage.Warning.NoProperName=Bitte Imagenamen setzen ContainerUploadPage.Warning.NoRunOptions=Bitte Container Start Optionen setzen +ContainerUploadPage.Warning.NoImageRepo=Kein Image Repository angegeben # ImageUploadSummaryPage ImageUploadSummary.UploadInitState.requesting=Der Upload-Vorgang wird mit dem Server ausgehandelt... @@ -112,3 +113,4 @@ LectureLocationSelection.WizardPage.errorMessage.tooManyLocations=Zu viele Räum # LectureOptionsPage LectureOptions.WizardPage.description=Klicken Sie auf ''Weiter'', um Berechtigungen festzulegen \ oder ''Fertigstellen''. + diff --git a/dozentenmodul/src/main/properties/i18n/page_layout.properties b/dozentenmodul/src/main/properties/i18n/page_layout.properties index 34e7d58e..55de57ef 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout.properties @@ -61,8 +61,10 @@ ImageOvfConversion.Button.StartConversion.text=Start conversion ContainerUploadPage.title=Create new Container Image ContainerUploadPage.description=Please provide an Input for a Docker Image ContainerUploadPage.DockerFile.label=Docker File +ContainerUploadPage.ImageRepo.label=Image Repository ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Set clone address of Git Repository [git@ | http://] [.git]. Currently no Validation Checks! +ContainerUploadPage.ImageRepository.ToolTipText=Specify the Container Image by his Repository Name (e.g python:3.7 or tensorflow/tensorflow) ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Contains license restricted software ContainerUploadPage.ContainerImageFile.label=Pre-build Container Image ContainerUploadPage.ContainerImageFile.ToolTipText=Optionally attach a tar archive of a container image to the upload.
\ diff --git a/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties b/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties index 10491635..a939bfb2 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties @@ -60,8 +60,10 @@ ImageOvfConversion.Button.StartConversion.text=Konvertierung starten ContainerUploadPage.title=Neues Container-Image anlegen ContainerUploadPage.description=Bitte geben Sie Daten für das Docker-Image an ContainerUploadPage.DockerFile.label=Docker File +ContainerUploadPage.ImageRepo.label=Image Repository ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Clone Addresse des Git Repositories setzen. [git@ | http://] [.git]. Derzeit keine Validierungsprüfungen! +ContainerUploadPage.ImageRepository.ToolTipText=Geben Sie das Container-Image durch seinen Repository-Namen an (z.B. python:3.7 oder tensorflow/tensorflow) ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Enthält lizenzpflichtige Software ContainerUploadPage.ContainerImageFile.label=Vorgebautes Container-Image\ -- cgit v1.2.3-55-g7522 From a742b83003743218efab443a34519bf0fde07438 Mon Sep 17 00:00:00 2001 From: ralph isenmann Date: Mon, 17 May 2021 10:57:33 +0200 Subject: [client] Allow user to set a container type for container images User can set for a container image the types: lecture, batch, data. The first two can be used in lectures, the second can also be used in by job system. The "data" type is used to mark a container which only transport data (for ml). --- .../openslx/dozmod/gui/panel/ContainerPanel.java | 37 +++++++++++++-- .../dozmod/gui/window/ImageDetailsWindow.java | 8 ++++ .../org/openslx/dozmod/model/ContainerMeta.java | 54 +++++++++++++++++++++- .../org/openslx/dozmod/util/ContainerUtils.java | 3 +- 4 files changed, 96 insertions(+), 6 deletions(-) (limited to 'dozentenmodul/src') diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java index 028b9878..8b79d064 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java @@ -6,11 +6,12 @@ import org.openslx.bwlp.thrift.iface.ImageDetailsRead; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; import org.openslx.dozmod.gui.configurator.ContainerBindMountConfigurator; +import org.openslx.dozmod.gui.control.ComboBox; import org.openslx.dozmod.gui.control.QLabel; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.I18n; -import org.openslx.dozmod.model.ContainerBuildContextMethod; import org.openslx.dozmod.model.ContainerDefinition; +import org.openslx.dozmod.model.ContainerMeta; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.ThriftUtil; @@ -32,7 +33,9 @@ public class ContainerPanel extends JPanel { private final Logger LOGGER = Logger.getLogger(ContainerBindMountConfigurator.class); private final QLabel lblContainerRunOpt; - private final QLabel lblContainerImageName; + + private final QLabel lblContainerImageType; + private final ComboBox cboContainerImageType; private final JTextArea txtContainerRecipe; private final JTextField txtContainerRun; @@ -63,7 +66,7 @@ public class ContainerPanel extends JPanel { GridManager grdContainer = new GridManager(this, 2, false, new Insets(8, 2, 8, 2)); - lblContainerImageName = new QLabel( + QLabel lblContainerImageName = new QLabel( I18n.PANEL.getString("ContainerPanel.Label.ImageName.text")); grdContainer.add(lblContainerImageName); txtContainerImageName = new JTextField(); @@ -75,6 +78,23 @@ public class ContainerPanel extends JPanel { scrollableTextArea.setMinimumSize(Gui.getScaledDimension(0, 200)); scrollableTextArea.setPreferredSize(Gui.getScaledDimension(0, 200)); grdContainer.add(scrollableTextArea, 2).fill(true, true).expand(true, true); + + + lblContainerImageType = new QLabel("Container Image Type"); + cboContainerImageType = new ComboBox<>(new ComboBox.ComboBoxRenderer() { + @Override public String renderItem(ContainerMeta.ContainerImageType item) { + if (item == null) + return "null"; + return item.name(); + } + }, ContainerMeta.ContainerImageType.class); + for (ContainerMeta.ContainerImageType type:ContainerMeta.ContainerImageType.values()) { + cboContainerImageType.addItem(type); + } + cboContainerImageType.setSelectedItem(ContainerMeta.ContainerImageType.LECTURE); + grdContainer.add(lblContainerImageType); + grdContainer.add(cboContainerImageType).fill(true,false).expand(true,false); + grdContainer.add(pnlContainerMeta, 2).fill(true, true).expand(true, true); grdContainer.finish(true); @@ -120,6 +140,8 @@ public class ContainerPanel extends JPanel { break; } + cboContainerImageType.setSelectedItem(containerDefinition.getContainerMeta().getImageType()); + if (context.equals(IMAGE_CONTEXT)) { initImageDetails(); } else if (context.equals(CONTAINER_CONTEXT)) { @@ -133,6 +155,8 @@ public class ContainerPanel extends JPanel { // currently do not allow user to change the Image Repository or Dockerfile in the suite. txtContainerRecipe.setEnabled(false); + + // do not show container specific input options lblContainerRunOpt.setVisible(false); txtContainerRun.setVisible(false); bindMountConfigurator.setVisible(false); @@ -141,6 +165,9 @@ public class ContainerPanel extends JPanel { private void initContainerDetails() { txtContainerRecipe.setEnabled(false); + lblContainerImageType.setVisible(false); + cboContainerImageType.setEditable(false); + cboContainerImageType.setVisible(false); txtContainerRun.setText(containerDefinition.getContainerMeta().getRunOptions()); bindMountConfigurator.setData(containerDefinition.getContainerMeta().getBindMountConfig()); } @@ -152,6 +179,7 @@ public class ContainerPanel extends JPanel { I18n.PANEL.getString("ContainerPanel.Constraint.NoEmptyDockerfile.text"))); changeMonitor.add(txtContainerRun); changeMonitor.add(bindMountConfigurator); + changeMonitor.addFixedCombo(cboContainerImageType,null); isFirstTime = false; } } @@ -167,11 +195,14 @@ public class ContainerPanel extends JPanel { ContainerDefinition newConDev = new ContainerDefinition(containerDefinition); + newConDev.getContainerMeta().setImageType( + (ContainerMeta.ContainerImageType) cboContainerImageType.getSelectedItem()); newConDev.getContainerMeta().setRunOptions(txtContainerRun.getText()); newConDev.getContainerMeta().setBindMountConfig(bindMountConfigurator.getData()); // TODO do I really need this check? Maybe just get every setting and upload it. if (!newConDev.equals(containerDefinition)) { + LOGGER.info("Update Container Definition"); try { ThriftManager.getSatClient() .setImageVersionVirtConfig(satelliteToken, image.getLatestVersionId(), diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java index bad9cea0..6aef01d5 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java @@ -576,6 +576,14 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout } } + // TODO maybe there could be a nicer way to distinguish between image and containerImage + if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER) ) { + if(!pnlTabContainer.saveChanges(Session.getSatelliteToken(),image)) + return false; + } else { + LOGGER.error("No Image: Could not save Container Settings!"); + } + changeMonitor.reset(); return true; } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java index ccdb0762..0306d0ee 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerMeta.java @@ -14,12 +14,47 @@ import java.util.Objects; */ public class ContainerMeta { + public enum ContainerImageType implements org.apache.thrift.TEnum { + LECTURE("lecture"), + BATCH("batch"), + DATA("data"); + + private final String name; + + ContainerImageType(String name){ + this.name = name; + } + + public boolean equalNames(String other){ + return name.equals(other); + } + public static ContainerImageType getByName(String name){ + for (ContainerImageType item : ContainerImageType.values()){ + if (item.name.equals(name)) + return item; + } + // name is not an enum, return lecture as default + return LECTURE; + } + + + + @Override public String toString() { + return this.name; + } + + @Override public int getValue() { + return this.ordinal(); + } + } + private int build_context_method; private String image_repo; private String build_context_url; private String image_name; private String run_options; + private String image_type; private List bind_mount_config = new ArrayList<>(); public ContainerMeta() { @@ -29,6 +64,7 @@ public class ContainerMeta { build_context_url = ""; image_name = ""; run_options = ""; + image_type = ContainerImageType.LECTURE.toString(); bind_mount_config = new ArrayList<>(); } @@ -38,6 +74,7 @@ public class ContainerMeta { image_name = containerMeta.image_name; run_options = containerMeta.run_options; image_repo = containerMeta.image_repo; + for (ContainerBindMount bm : containerMeta.bind_mount_config) bind_mount_config.add(new ContainerBindMount(bm.getSource(), bm.getTarget(), bm.getOptions())); @@ -87,6 +124,17 @@ public class ContainerMeta { public void setImageRepo(String from_image) { this.image_repo = from_image; } + public ContainerImageType getImageType() { + if (image_type == null || image_type.length() == 0) + return ContainerImageType.LECTURE; + + return ContainerImageType.getByName(image_type); + } + + public void setImageType(ContainerImageType image_type) { + this.image_type = image_type.toString(); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -95,10 +143,12 @@ public class ContainerMeta { ContainerMeta that = (ContainerMeta) o; return Objects.equals(build_context_url, that.build_context_url) && Objects.equals(image_name, that.image_name) && Objects.equals(run_options, that.run_options) && Objects.equals( - bind_mount_config, that.bind_mount_config) && Objects.equals(image_repo,that.image_repo) ; + bind_mount_config, that.bind_mount_config) && Objects.equals(image_repo,that.image_repo) + && Objects.equals(image_type,that.image_type); } @Override public int hashCode() { - return Objects.hash(build_context_url, image_name, run_options); + return Objects.hash(build_context_url, image_name, run_options, + bind_mount_config, image_repo, image_type); } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java index eeaae891..0e5a1d15 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java @@ -27,7 +27,8 @@ public class ContainerUtils { if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER)) { List lectureSummaries = LectureCache.get(true); for (LectureSummary lecture : lectureSummaries) { - if (lecture.imageBaseId.equals(image.imageBaseId)) { + // lecture.imageBaseId is null when no image linked to it -> NullPointer on equals + if (image.imageBaseId.equals(lecture.imageBaseId)) { return true; } } -- cgit v1.2.3-55-g7522