diff options
35 files changed, 656 insertions, 630 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/ContainerBindMountConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/ContainerBindMountConfigurator.java index d7e73e3d..630ef571 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/ContainerBindMountConfigurator.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/ContainerBindMountConfigurator.java @@ -38,12 +38,13 @@ public class ContainerBindMountConfigurator extends JPanel grid.nextRow(); JPanel buttonPanel = new JPanel(); - GridManager gridButtonPanel = new GridManager(buttonPanel, 3); buttonPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); - JButton btnAddBindMount = new JButton(I18n.CONFIGURATOR.getString("ContainerBindMount.Button.AddBindMount.text")); - JButton btnDelBindMount = new JButton(I18n.CONFIGURATOR.getString("ContainerBindMount.Button.DeleteBindMount.text")); + JButton btnAddBindMount = new JButton( + I18n.CONFIGURATOR.getString("ContainerBindMount.Button.AddBindMount.text")); + JButton btnDelBindMount = new JButton( + I18n.CONFIGURATOR.getString("ContainerBindMount.Button.DeleteBindMount.text")); // add glue box to move Buttons to the right border. buttonPanel.add(Box.createGlue()); @@ -81,6 +82,10 @@ public class ContainerBindMountConfigurator extends JPanel fireUserChangeEvent(); } + public void setData(List<ContainerBindMount> bindMountConfig) { + setData(bindMountConfig, true); + } + public void setData(List<ContainerBindMount> bindMountConfig, boolean sort) { bindMountTable.setData(bindMountConfig, sort); } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/I18n.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/I18n.java index 7c76d870..61fdb049 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/I18n.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/I18n.java @@ -17,6 +17,7 @@ public enum I18n { GUI("gui"), PAGE("page"), PAGE_LAYOUT("page_layout"), + PANEL("panel"), THRIFT("thrift"), WINDOW("window"), WINDOW_LAYOUT("window_layout"), diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/StatusHeader.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/StatusHeader.java new file mode 100644 index 00000000..ae2e8adb --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/StatusHeader.java @@ -0,0 +1,64 @@ +package org.openslx.dozmod.gui.helper; + +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.control.QLabel; +import org.openslx.dozmod.util.ResourceLoader; + +import javax.swing.*; +import java.awt.*; + +/** + * StatusHeader can be used in GUI-Dialogs to inform a user about a current + * state of an Input. See {@link org.openslx.dozmod.gui.window.layout.ContainerBindMountWindowLayout} how to + * use it. + */ +public class StatusHeader extends JPanel { + + private final QLabel titleLabel; + private final QLabel messageLabel; + + + public StatusHeader(Container contentPane, String message) { + this(contentPane, "", message); + } + + public StatusHeader(Container contentPane, String title, String message) { + + this.setMinimumSize(Gui.getScaledDimension(0, 100)); + this.setOpaque(true); + this.setBackground(Color.WHITE); + this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + titleLabel = new QLabel(title); + messageLabel = new QLabel(message); + titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD)); + titleLabel.setForeground(Color.BLACK); + messageLabel.setForeground(Color.BLACK); + messageLabel.setHorizontalTextPosition(SwingConstants.RIGHT); + + this.add(titleLabel); + this.add(messageLabel); + + JPanel headerWrapper = new JPanel(); + GridManager grid = new GridManager(headerWrapper, 1, false); + grid.add(this).expand(true, false).fill(true, false); + grid.add(new JSeparator()).expand(true, false).fill(true, false); + grid.finish(false); + contentPane.add(headerWrapper, BorderLayout.PAGE_START); + } + + + + public void updateHeader(String pageTitle, String pageDesc, Icon icon, Color color) { + titleLabel.setText(pageTitle); + messageLabel.setText(pageDesc); + messageLabel.setIcon(ResourceLoader.getScaledIcon(icon, messageLabel.getHeight(), messageLabel)); + messageLabel.setForeground(color); + messageLabel.validate(); + } + + public void updateStatus(String statusMessage) { + messageLabel.setText(statusMessage); + } +} 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 new file mode 100644 index 00000000..7c116867 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java @@ -0,0 +1,175 @@ +package org.openslx.dozmod.gui.panel; + +import org.apache.log4j.Logger; +import org.apache.thrift.TException; +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.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.thrifthelper.ThriftManager; +import org.openslx.util.ThriftUtil; + +import javax.swing.*; +import java.awt.*; +import java.nio.ByteBuffer; + +public class ContainerPanel extends JPanel { + + // TODO Set the height of txtContainerRecipe dependent of the Context. Full height for IMAGE_CONTEXT. + + public static final String IMAGE_CONTEXT = "IMAGE"; + public static final String CONTAINER_CONTEXT = "CONTAINER"; + + private final Logger LOGGER = Logger.getLogger(ContainerBindMountConfigurator.class); + + private final QLabel lblContainerRunOpt; + private final QLabel lblContainerImageName; + + private final JTextArea txtContainerRecipe; + private final JTextField txtContainerRun; + private final JTextField txtContainerImageName; + private final ContainerBindMountConfigurator bindMountConfigurator; + + private ContainerDefinition containerDefinition = null; + + private boolean isFirstTime = true; + + public ContainerPanel() { + + JPanel pnlContainerMeta = new JPanel(); + GridManager grdContainerMeta = new GridManager(pnlContainerMeta, 3); + + lblContainerRunOpt = new QLabel( + I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.label")); + lblContainerRunOpt.setToolTipText( + I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.tooltip")); + grdContainerMeta.add(lblContainerRunOpt); + txtContainerRun = new JTextField(); + grdContainerMeta.add(txtContainerRun, 2).fill(true, false).expand(true, false); + grdContainerMeta.nextRow(); + + bindMountConfigurator = new ContainerBindMountConfigurator(); + grdContainerMeta.add(bindMountConfigurator, 3).fill(true, true).expand(true, true); + grdContainerMeta.finish(true); + + GridManager grdContainer = new GridManager(this, 2, false, new Insets(8, 2, 8, 2)); + + lblContainerImageName = new QLabel( + I18n.PANEL.getString("ContainerPanel.Label.ImageName.text")); + grdContainer.add(lblContainerImageName); + txtContainerImageName = new JTextField(); + grdContainer.add(txtContainerImageName, 1).fill(true, false).expand(true, false); + grdContainer.nextRow(); + + txtContainerRecipe = new JTextArea(); + JScrollPane scrollableTextArea = new JScrollPane(txtContainerRecipe); + scrollableTextArea.setMinimumSize(Gui.getScaledDimension(0, 200)); + scrollableTextArea.setPreferredSize(Gui.getScaledDimension(0, 200)); + grdContainer.add(scrollableTextArea, 2).fill(true, true).expand(true, true); + grdContainer.add(pnlContainerMeta, 2).fill(true, true).expand(true, true); + grdContainer.finish(true); + + } + + /** + * Retrieves Container specific details for the currently displayed lecture and disables gui elements for + * the specific context. + * + * @param satelliteToken The satelliteToken from which the information are retrieved. + * @param image The ImageDetailsRead which has general information about Image (name, type, version, etc.) + * @param context In which context this Panel ist used (Image or Lecture) + */ + public void init(String satelliteToken, ImageDetailsRead image, String context) { + + try { + byte[] rawVirtConfig; + ByteBuffer byteBuffer = ThriftManager.getSatClient() + .getImageVersionVirtConfig(satelliteToken, image.getLatestVersionId()); + rawVirtConfig = ThriftUtil.unwrapByteBuffer(byteBuffer); + containerDefinition = ContainerDefinition.fromByteArray(rawVirtConfig); + } catch (TException e) { + LOGGER.error("Failed to retrieve virtualizer config for image version " + "'" + + image.getLatestVersionId() + ", see trace: ", e); + } + + txtContainerImageName.setText(image.imageName); + txtContainerImageName.setEnabled(false); + // TODO simplify this mess. ContainerBuildContextMethod is to complex + if (containerDefinition.getBuildContextMethod() == ContainerBuildContextMethod.FILE) { + txtContainerRecipe.setText(containerDefinition.getContainerRecipe()); + } else if (containerDefinition.getBuildContextMethod() + == ContainerBuildContextMethod.GIT_REPOSITORY) { + txtContainerRecipe.setText(containerDefinition.getContainerMeta().getBuildContextUrl()); + } + + if (context.equals(IMAGE_CONTEXT)) { + initImageDetails(); + } else if (context.equals(CONTAINER_CONTEXT)) { + initContainerDetails(); + } 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. + txtContainerRecipe.setEnabled(false); + lblContainerRunOpt.setVisible(false); + txtContainerRun.setVisible(false); + bindMountConfigurator.setVisible(false); + } + + private void initContainerDetails() { + + txtContainerRecipe.setEnabled(false); + txtContainerRun.setText(containerDefinition.getContainerMeta().getRunOptions()); + bindMountConfigurator.setData(containerDefinition.getContainerMeta().getBindMountConfig()); + } + + public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { + if (isFirstTime) { + changeMonitor.add(txtContainerRecipe) + .addConstraint(new DialogChangeMonitor.TextNotEmptyConstraint( + I18n.PANEL.getString("ContainerPanel.Constraint.NoEmptyDockerfile.text"))); + changeMonitor.add(txtContainerRun); + changeMonitor.add(bindMountConfigurator); + isFirstTime = false; + } + } + + /** + * Stores changes in ContainerDefinition and Uploads changes to Sat. + * + * @param satelliteToken for current session to communicate with Sat. + * @param image of the image version, which will be updated. + * @return Returns true uf upload successfully finished, false if error occurred. + */ + public boolean saveChanges(String satelliteToken, ImageDetailsRead image) { + + ContainerDefinition newConDev = new ContainerDefinition(containerDefinition); + + 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)) { + try { + ThriftManager.getSatClient() + .setImageVersionVirtConfig(satelliteToken, image.getLatestVersionId(), + newConDev.toByteBuffer()); + } catch (TException e) { + LOGGER.error("Upload new ContainerDefinition failed", e); + return false; + } + } + return true; + } +} + diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ContainerBindMountWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ContainerBindMountWindow.java index a7c141fb..e261d99a 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ContainerBindMountWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ContainerBindMountWindow.java @@ -8,12 +8,14 @@ import org.openslx.dozmod.model.ContainerBindMount; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; public class ContainerBindMountWindow extends ContainerBindMountWindowLayout { - private ContainerBindMountTable bindMountTable; + private final ContainerBindMountTable bindMountTable; public ContainerBindMountWindow(Window modalParent, ContainerBindMountTable bindMountTable) { super(modalParent); @@ -31,8 +33,8 @@ public class ContainerBindMountWindow extends ContainerBindMountWindowLayout { dispose(); } }); - this.txtBmSource.getDocument().addDocumentListener(new TextChangeListener() { - @Override public void changed() { + this.cboSourceMountPoint.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { isInputComplete(); } }); @@ -44,21 +46,26 @@ public class ContainerBindMountWindow extends ContainerBindMountWindowLayout { } - // TODO add text if input not finished private boolean isInputComplete() { btnSave.setEnabled(false); - if (txtBmSource == null || txtBmSource.getText().isEmpty()) + + if (cboSourceMountPoint == null || cboSourceMountPoint.getSelectedIndex() == 0) { + header.updateStatus("Source Path is Missing"); return false; + } if (txtBmTarget == null || txtBmTarget.getText().isEmpty()) { + header.updateStatus("Target Path is Missing"); return false; } + header.updateStatus("Input Completed"); btnSave.setEnabled(true); return true; } private void saveEntry() { ContainerBindMount bindMount = new ContainerBindMount(); - bindMount.setSource(this.txtBmSource.getText()); + bindMount.setSource( + ContainerBindMountWindowLayout.SOURCE_MOUNT_POINTS[cboSourceMountPoint.getSelectedIndex()]); bindMount.setTarget(this.txtBmTarget.getText()); bindMount.setOptions(this.txtBmOptions.getText()); 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 efc75236..d4cacc0c 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 @@ -37,6 +37,7 @@ import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor.TextNotEmptyConstraint; import org.openslx.dozmod.gui.helper.PopupMenu; import org.openslx.dozmod.gui.helper.*; +import org.openslx.dozmod.gui.panel.ContainerPanel; import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; import org.openslx.dozmod.gui.window.layout.ImageDetailsWindowLayout; import org.openslx.dozmod.gui.wizard.ImageUpdateWizard; @@ -131,8 +132,6 @@ import java.util.*; private AbstractControlWrapper<?> changeListenerPermissions; - private ContainerDefinition containerDefinition = new ContainerDefinition(); - /** * Constructor * @@ -423,45 +422,6 @@ import java.util.*; }); } - /** - * Uploads ByteBuffer data to satellite server and stores it in ImageVersion.VirtConfig - * for the given imageVersionId. - * - * @param imageVersionId Id of the image version, which will be updated. - * @param data New virtConfig to store in database. - */ - private void uploadContainerDef(final String imageVersionId, ByteBuffer data) { - - try { - ThriftManager.getSatClient() - .setImageVersionVirtConfig(Session.getSatelliteToken(), imageVersionId, data); - } catch (TException e) { - e.printStackTrace(); - } - } - - /** - * Loads binary file ImageVersion.VirtConfig from the Satellites Database. - * - * @param selected the selected Image Version. TODO: For now only just the latest Version. - */ - private byte[] loadContainerDef(final ImageVersionDetails selected) { - - byte[] rawVirtConfig = null; - - try { - ByteBuffer byteBuffer = ThriftManager.getSatClient() - .getImageVersionVirtConfig(Session.getSatelliteToken(), selected.versionId); - rawVirtConfig = ThriftUtil.unwrapByteBuffer(byteBuffer); - - } catch (TException e) { - LOGGER.error( - "Failed to retrieve virtualizer config for image version " + "'" + image.latestVersionId - + ", see trace: ", e); - } - return rawVirtConfig; - } - /******************************************************************************** * * Helper triggering the actual thrift calls @@ -624,43 +584,11 @@ import java.util.*; } } - // if image is container - // prepare to upload container definition to local satellite server. - // TODO - if (image.getVirtId().equals(TConst.VIRT_DOCKER)) - saveContainerDefinition(); - changeMonitor.reset(); return true; } /** - * If the user make changes and saves it this method will be executed. - * It makes a deep copy of the current containerDefinition to get all settings. - * After that, every user setting is set in that copy-object. - * If the copy-object and containerDefinition differ, the new settings will be uploaded. - */ - private void saveContainerDefinition() { - // TODO do I really need this check? Maybe just get every setting and upload it. - - ContainerDefinition newConDev = new ContainerDefinition(containerDefinition); - - if (newConDev.getBuildContextMethod() == ContainerBuildContextMethod.FILE) { - newConDev.setContainerRecipe(txtContainerRecipe.getText()); - } - // currently no update of the git url allowed - - newConDev.getContainerMeta().setImageName(txtContainerImageName.getText()); - newConDev.getContainerMeta().setRunOptions(txtContainerRun.getText()); - newConDev.getContainerMeta().setBindMountConfig(bindMountConfigurator.getData()); - - if (!newConDev.equals(containerDefinition)) { - uploadContainerDef(image.versions.get(0).versionId, newConDev.toByteBuffer()); - LOGGER.info("Upload new DockerDefinition"); - } - } - - /** * Helper to save the custom user permissions (those not included in * ImageBaseWrite). * @@ -822,45 +750,6 @@ import java.util.*; if (virt != null) lblVirtualizer.setText(virt.getVirtName()); - if (TConst.VIRT_DOCKER.equals(image.getVirtId())) { - lblVirtualizer.setText(TConst.VIRT_DOCKER); - showContainerTab(); - - if (image.versions.isEmpty()) { - LOGGER.info("Close Window because no ImageVersions available!"); - dispose(); - return; - } - // TODO if only a single version is created an the user deletes it, next line will out of bounce! - containerDefinition = ContainerDefinition.fromByteArray(loadContainerDef(image.versions.get(0))); - - ContainerMeta containerMeta = containerDefinition.getContainerMeta(); - ContainerBuildContextMethod method = ContainerBuildContextMethod.fromInt( - containerMeta.getBuildContextMethod()); - - switch (method) { - case FILE: - txtContainerRecipe.setText(containerDefinition.getContainerRecipe()); - break; - case GIT_REPOSITORY: - txtContainerRecipe.setText(containerMeta.getBuildContextUrl()); - txtContainerRecipe.setEnabled(false); - break; - } - - txtContainerImageName.setText(containerMeta.getImageName()); - txtContainerRun.setText(containerMeta.getRunOptions()); - bindMountConfigurator.setData(containerMeta.getBindMountConfig(), true); - - changeMonitor.add(txtContainerRecipe). - addConstraint(new TextNotEmptyConstraint(I18n.WINDOW.getString("ImageDetails.Constraint.NoEmptyDockerfile.text"))); - changeMonitor.add(txtContainerImageName) - .addConstraint(new TextNotEmptyConstraint(I18n.WINDOW.getString("ImageDetails.Constraint.NoEmptyName.text"))); - changeMonitor.add(txtContainerRun) - .addConstraint(new TextNotEmptyConstraint(I18n.WINDOW.getString("ImageDetails.Constraint.NoEmptyRunOptions.text"))); - changeMonitor.add(bindMountConfigurator); - } - // fill share mode combo, if not already done if (cboShareMode.getItemCount() == 0) { for (ShareMode mode : ShareMode.values()) { @@ -929,12 +818,18 @@ import java.util.*; if (actionHandler.isImagePublishSupported()) btnUploadToMaster.setEnabled(editable); - if (image != null && TConst.VIRT_DOCKER.equals(image.getVirtId())) { + + // If this Image is from type Docker (Container) show the new Container Tab + if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER)) { + lblVirtualizer.setText(TConst.VIRT_DOCKER); + pnlTabContainer.init(Session.getSatelliteToken(), image, ContainerPanel.IMAGE_CONTEXT); + pnlTabContainer.addToChangeMonitor(changeMonitor); + showContainerTab(); + // TODO Currently, do not allow user to upload a new version or share an Container Image. btnUpdateImage.setEnabled(false); btnUploadToMaster.setEnabled(false); } - } /** diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java index b98023b0..cb242092 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java @@ -1,6 +1,5 @@ package org.openslx.dozmod.gui.window; -import java.awt.Color; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -45,6 +44,7 @@ import org.openslx.dozmod.gui.helper.DateTimeHelper; import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.UiFeedback; +import org.openslx.dozmod.gui.panel.ContainerPanel; import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; import org.openslx.dozmod.gui.window.layout.LectureDetailsWindowLayout; import org.openslx.dozmod.permissions.ImagePerms; @@ -59,6 +59,7 @@ import org.openslx.dozmod.thrift.ThriftError; import org.openslx.dozmod.thrift.cache.UserCache; import org.openslx.dozmod.util.FormatHelper; import org.openslx.thrifthelper.Comparators; +import org.openslx.thrifthelper.TConst; import org.openslx.thrifthelper.ThriftManager; /** @@ -117,7 +118,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /** * Constructor - * + * * @param modalParent parent of this popup window * @param callback function to be called when a lecture update occured */ @@ -193,6 +194,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements ctlRunscriptConfigurator.addToChangeMonitor(changeMonitor); ctlNetshareConfigurator.addToChangeMonitor(changeMonitor); ctlLdapFilterConfigurator.addToChangeMonitor(changeMonitor); + // TODO: LDAP/NetShare: Having uncommitted changes in the input fields should be // handled too // End change monitor @@ -299,7 +301,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /** * Sets the lecture to show the details of by setting the 'lecture' and 'image' * members to its metadata. This method will fetch the information from the sat - * + * * @param lectureId the id of the lecture to be displayed */ public void setLecture(final String lectureId) { @@ -340,6 +342,16 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements txtImageName.setText(image.getImageName()); lblImageNameInfo.setText(image.getImageName()); } + + // init container info panel + if (image != null && image.getVirtId().equals(TConst.VIRT_DOCKER) ) + { + showContainerTab(); + pnlTabContainer.init(Session.getSatelliteToken(), image, ContainerPanel.CONTAINER_CONTEXT); + + pnlTabContainer.addToChangeMonitor(changeMonitor); + } + // init permission info adminRightsFromDefaultPermissions = lecture.defaultPermissions.admin; ctlPermissionManager.initPanel(customPermissions, lecture.defaultPermissions, lecture.ownerId); @@ -431,7 +443,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /** * Sets the lecture's owner to the given user - * + * * @param user UserInfo representation of the new owner */ private void setLectureOwner(final UserInfo user) { @@ -549,6 +561,14 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements metadata.setLdapFilters(ctlLdapFilterConfigurator.getState()); metadata.setPresetScriptIds(startupSettings.selectedScripts); + // TODO maybe there could be a nicer way to distinguish between Lectures withs Containers + 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!"); + } + // now trigger the actual action try { ThriftManager.getSatClient().updateLecture(Session.getSatelliteToken(), lecture.getLectureId(), metadata); @@ -589,7 +609,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /** * Checks if the given start and end date represent a valid time period. This is * the case, if start < end and if current time < end - * + * * @param start date of the period to check * @param end date of the period to check * @param feedback true if the user should be shown feedback, false otherwise @@ -644,7 +664,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /** * Opens a new LectureDetailsWindow showing the details of the lecture with ID = * lectureId - * + * * @param modalParent parent of this window * @param lectureId id of the lecture to set the details of */ @@ -667,7 +687,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements /* * ***************************************************************************** * ** - * + * * UIFeedback implementation * ********************************************************************************/ diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ContainerBindMountWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ContainerBindMountWindowLayout.java index 2e5432b8..54befd60 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ContainerBindMountWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ContainerBindMountWindowLayout.java @@ -1,8 +1,10 @@ package org.openslx.dozmod.gui.window.layout; import org.openslx.dozmod.gui.Gui; +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.StatusHeader; import javax.swing.*; import java.awt.*; @@ -11,6 +13,7 @@ public class ContainerBindMountWindowLayout extends JDialog { private static final String title = "Add Bind Mount"; + protected final StatusHeader header; protected final QLabel lblBmSource; protected final JTextField txtBmSource; protected final QLabel lblBmTarget; @@ -20,17 +23,39 @@ public class ContainerBindMountWindowLayout extends JDialog { protected final JButton btnSave; protected final JButton btnCancel; + protected static final String EMPTY_MARKER = "-"; + protected static final String[] TAGS = { "USER_HOME", "USER_TMP" }; + protected static String[] SOURCE_MOUNT_POINTS = { EMPTY_MARKER, TAGS[0], TAGS[1], "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; + + protected final ComboBox<String> cboSourceMountPoint = new ComboBox<>( + new ComboBox.ComboBoxRenderer<String>() { + @Override public String renderItem(String letter) { + if (letter == null) + return null; + return letter; + } + }); + public ContainerBindMountWindowLayout(Window modalParent) { - super(modalParent, title, - modalParent != null ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS); + super(modalParent, title, ModalityType.APPLICATION_MODAL); + + setLayout(new BorderLayout()); - GridManager grid = new GridManager(this, 2, true, new Insets(2, 2, 2, 2)); + header = new StatusHeader(getContentPane(), "Source and Target Path Required"); + + JPanel contentPanel = new JPanel(); + add(contentPanel, BorderLayout.CENTER); + GridManager grid = new GridManager(contentPanel, 2, true, new Insets(2, 2, 2, 2)); lblBmSource = new QLabel("Source"); + txtBmSource = new JTextField(); + cboSourceMountPoint.setModel(new DefaultComboBoxModel<>(SOURCE_MOUNT_POINTS)); + cboSourceMountPoint.setSelectedItem(SOURCE_MOUNT_POINTS[0]); grid.add(lblBmSource); - grid.add(txtBmSource).fill(true, false).expand(true, false); + grid.add(cboSourceMountPoint).fill(true, false).expand(true, false); grid.nextRow(); lblBmTarget = new QLabel("Target"); @@ -57,11 +82,8 @@ public class ContainerBindMountWindowLayout extends JDialog { grid.add(buttonPane, 2).fill(true, false).expand(true, false); grid.finish(false); - //setPreferredSize(Gui.getScaledDimension(650, 350)); - - setSize(350, 150); + setSize(350, 200); setResizable(false); - //setMinimumSize(Gui.getScaledDimension(550, 650)); if (modalParent != null) { Gui.centerShellOverShell(modalParent, this); } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java index 4d141c18..64e2ddf5 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java @@ -30,6 +30,7 @@ import org.openslx.dozmod.gui.control.table.ImageVersionTable; import org.openslx.dozmod.gui.control.table.QScrollPane; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.I18n; +import org.openslx.dozmod.gui.panel.ContainerPanel; import org.openslx.thrifthelper.Comparators; import javax.swing.*; @@ -46,12 +47,6 @@ import java.awt.*; protected final JTextField txtTitle; protected final JEditorPane txtDescription; - private final JPanel pnlTabContainer; - protected final JTextArea txtContainerRecipe; - protected final JTextField txtContainerRun; - protected final JTextField txtContainerImageName; - protected ContainerBindMountConfigurator bindMountConfigurator; - protected QLabel lblError; protected final PersonLabel lblOwner; protected final JButton btnChangeOwner; @@ -88,6 +83,8 @@ import java.awt.*; protected ImagePermissionConfigurator ctlImagePermissionConfigurator; + protected final ContainerPanel pnlTabContainer; + public ImageDetailsWindowLayout(Frame modalParent) { super(modalParent, "<init>", ModalityType.APPLICATION_MODAL); setResizable(true); @@ -293,36 +290,7 @@ import java.awt.*; * Container panel * ********************************************************************************/ - pnlTabContainer = new JPanel(); - txtContainerRecipe = new JTextArea(); - JScrollPane scrollableTextArea = new JScrollPane(txtContainerRecipe); - scrollableTextArea.setMinimumSize(Gui.getScaledDimension(0, 200)); - scrollableTextArea.setPreferredSize(Gui.getScaledDimension(0, 200)); - - JPanel pnlContainerMeta = new JPanel(); - GridManager grdContainerMeta = new GridManager(pnlContainerMeta, 3); - - grdContainerMeta.add(new QLabel(I18n.WINDOW_LAYOUT.getString("ImageDetails.Label.ImageName.text"))); - txtContainerImageName = new JTextField(); - txtContainerImageName.setDocument(txtTitle.getDocument()); - grdContainerMeta.add(txtContainerImageName, 2).fill(true, false).expand(true, false); - grdContainerMeta.nextRow(); - - grdContainerMeta.add(new QLabel(I18n.WINDOW_LAYOUT.getString("ImageDetails.Label.ContainerRunOptions.text"))); - txtContainerRun = new JTextField(); - grdContainerMeta.add(txtContainerRun, 2).fill(true, false).expand(true, false); - grdContainerMeta.nextRow(); - - bindMountConfigurator = new ContainerBindMountConfigurator(); - grdContainerMeta.add(bindMountConfigurator, 3).fill(true, true).expand(true, true); - grdContainerMeta.finish(true); - - GridManager grdContainer = new GridManager(pnlTabContainer, 1, false, new Insets(8, 2, 8, 2)); - grdContainer.add(scrollableTextArea, 1).fill(true, true).expand(true, true); - grdContainer.add(pnlContainerMeta, 1).fill(true, true).expand(true, true); - //grdContainer.add(Box.createVerticalGlue()).fill(true, true).expand(true,true); - grdContainer.finish(true); - + pnlTabContainer = new ContainerPanel(); /* ******************************************************************************* @@ -362,6 +330,6 @@ import java.awt.*; protected void showContainerTab() { pnlTabs.addTab("Container", pnlTabContainer); // TODO currently, do not allow to alter the version of a container image. - pnlTabs.remove(pnlTabs.indexOfTab(TAB_VERSIONS_TITEL)); + //pnlTabs.remove(pnlTabs.indexOfTab(TAB_VERSIONS_TITEL)); } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java index 6abdfc47..ff8b4d54 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LectureDetailsWindowLayout.java @@ -36,11 +36,7 @@ import org.jdatepicker.JDatePicker; import org.openslx.bwlp.thrift.iface.ImageVersionDetails; import org.openslx.dozmod.Branding; import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.configurator.LdapFilterConfigurator; -import org.openslx.dozmod.gui.configurator.LecturePermissionConfigurator; -import org.openslx.dozmod.gui.configurator.NetrulesConfigurator; -import org.openslx.dozmod.gui.configurator.NetshareConfigurator; -import org.openslx.dozmod.gui.configurator.StartupConfigurator; +import org.openslx.dozmod.gui.configurator.*; import org.openslx.dozmod.gui.control.ComboBox; import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; import org.openslx.dozmod.gui.control.LocationSelector; @@ -50,6 +46,7 @@ import org.openslx.dozmod.gui.control.QLabel; import org.openslx.dozmod.gui.control.WordWrapLabel; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.I18n; +import org.openslx.dozmod.gui.panel.ContainerPanel; import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.dozmod.util.FormatHelper; @@ -115,6 +112,8 @@ public abstract class LectureDetailsWindowLayout extends JDialog { protected final JPanel pnlTabNetshare; protected final JPanel pnlTabLdapFilter; + protected final ContainerPanel pnlTabContainer; + public LectureDetailsWindowLayout(Frame modalParent) { super(modalParent, I18n.WINDOW_LAYOUT.getString("LectureDetails.Dialog.title"), ModalityType.APPLICATION_MODAL); @@ -183,7 +182,7 @@ public abstract class LectureDetailsWindowLayout extends JDialog { grdGeneral.add(new QLabel(I18n.WINDOW_LAYOUT.getString("LectureDetails.Label.title.text"))); grdGeneral.add(txtTitle, 4).expand(true, false).fill(true, false); grdGeneral.nextRow(); - + // description txtDescription = new JEditorPane(); grdGeneral.add(new QLabel(I18n.WINDOW_LAYOUT.getString("LectureDetails.Label.description.text"))).anchor(GridBagConstraints.FIRST_LINE_START); @@ -283,10 +282,10 @@ public abstract class LectureDetailsWindowLayout extends JDialog { grdGeneral.add(chkIsActive, 4); grdGeneral.nextRow(); grdGeneral.finish(true); - + Insets descriptionInset = new Insets(2, 4, 2, 4); Insets firstInset = new Insets(12, 4, 2, 4); - + // Network rules pnlTabNetrules = new JPanel(); GridManager grdNetrules = new GridManager(pnlTabNetrules, 1, true, new Insets(9, 4, 2, 4)); @@ -306,11 +305,11 @@ public abstract class LectureDetailsWindowLayout extends JDialog { grdNetrules.add(ctlNetrulesConfigurator).fill(true, true).expand(true, true); grdNetrules.nextRow(); grdNetrules.finish(false); - + // Tab restrictions pnlTabRestrictions = new JPanel(); GridManager grdRestrictions = new GridManager(pnlTabRestrictions, 2, true, new Insets(9, 4, 2, 4)); - + chkHasUsbAccess = new JCheckBox(I18n.WINDOW_LAYOUT.getString("LectureDetails.CheckBox.hasUSBAccess.text")); grdRestrictions.add(chkHasUsbAccess, 2); grdRestrictions.nextRow(); @@ -335,8 +334,8 @@ public abstract class LectureDetailsWindowLayout extends JDialog { .insets(descriptionInset); grdRestrictions.finish(true); - /* ******************************************************************************* - * + /* ******************************************************************************* + * * Tab "Permissions" * ********************************************************************************/ @@ -355,6 +354,13 @@ public abstract class LectureDetailsWindowLayout extends JDialog { grdPermissions.add(defaultPermissionPane).fill(true, false).expand(true, false); grdPermissions.finish(false); + /* ******************************************************************************* + * + * Tab "Container" + * + ********************************************************************************/ + pnlTabContainer = new ContainerPanel(); + /* ******************************************************************************* * * Tab "Locations" @@ -387,7 +393,7 @@ public abstract class LectureDetailsWindowLayout extends JDialog { GridManager grdNetshare = new GridManager(pnlTabNetshare, 1, false, new Insets(8, 2, 8, 2)); grdNetshare.add(ctlNetshareConfigurator).fill(true, true).expand(true, true); grdNetshare.finish(false); - + /* ******************************************************************************* * * Tab "LDAP-Filters" @@ -398,10 +404,10 @@ public abstract class LectureDetailsWindowLayout extends JDialog { GridManager grdLdap = new GridManager(pnlTabLdapFilter, 1, false, new Insets(8, 2, 8, 2)); grdLdap.add(ctlLdapFilterConfigurator).fill(true, true).expand(true, true); grdLdap.finish(false); - - /* ******************************************************************************* - * - * Main panel containing the tabs + + /* ******************************************************************************* + * + * Main panel containing the tabs * ********************************************************************************/ // finally build the tabbedPane and add it to the main view @@ -442,6 +448,10 @@ public abstract class LectureDetailsWindowLayout extends JDialog { add(buttonPanel, BorderLayout.SOUTH); } + protected void showContainerTab() { + pnlTabs.addTab("Container", pnlTabContainer); + } + private JSpinner makeTimeSpinner(int h, int m) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, h); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java index cccabe00..1a972b46 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java @@ -10,18 +10,17 @@ import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.QuitNotification; import org.openslx.dozmod.gui.helper.UiFeedback; import org.openslx.dozmod.gui.wizard.page.*; -import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.state.UploadWizardState; -import org.openslx.dozmod.thrift.*; +import org.openslx.dozmod.thrift.Session; +import org.openslx.dozmod.thrift.ThriftActions; +import org.openslx.dozmod.thrift.ThriftError; import org.openslx.dozmod.thrift.UploadInitiator.GotUploadTokenCallback; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; -import org.openslx.util.vm.DockerMetaDataDummy; import javax.swing.*; import java.awt.*; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -32,8 +31,6 @@ import java.util.List; private final UploadWizardState state = new UploadWizardState(); - private ContainerDefinition containerDefinition = new ContainerDefinition(); - private List<WizardPage> currentPages = new ArrayList<>(); private boolean baseWritten = false; @@ -59,7 +56,7 @@ import java.util.List; cleanCurrent(); state.imageUploadPage = new ImageUploadPage(this, state, null); currentPages.add(state.imageUploadPage); - currentPages.add(new ImageMetaDataPage(this, state, null)); + currentPages.add(new ImageMetaDataPage(this, state)); currentPages.add(new ImageCustomPermissionPage(this, state)); addPages(); @@ -73,8 +70,8 @@ import java.util.List; public void doDockerCreation() { cleanCurrent(); - currentPages.add(new ContainerUploadPage(this, state, containerDefinition)); - currentPages.add(new ImageMetaDataPage(this, state, containerDefinition)); + currentPages.add(new ContainerUploadPage(this, state)); + currentPages.add(new ImageMetaDataPage(this, state)); currentPages.add(new ImageCustomPermissionPage(this, state)); addPages(); } @@ -92,49 +89,11 @@ import java.util.List; } } - @Override - public String getWindowTitle() { + @Override public String getWindowTitle() { return I18n.WIZARD.getString("ImageCreation.Wizard.title"); } - /** - * initUpload will be called after a user finish the creation of a new ContainerDefinition. - * It creates the UploadInitiator with the collected information. - */ - private void initUpload() { - - if (state.uuid == null) { - state.uuid = ThriftActions.createImage(JOptionPane.getFrameForComponent(this), state.name); - if (state.uuid == null) { - // return false; - LOGGER.error("initUpload Failed: Count not get uuid!"); - return; - } - } - - // Create upload initiator that will manage requesting a token, hashing the - // file, connecting for upload... - if (state.upload == null) { - try { - state.upload = new UploadInitiator(state.uuid, state.diskFile, - state.meta.getFilteredDefinition()); - } catch (WrappedException e) { - ThriftError.showMessage(this, LOGGER, e.exception, e.displayMessage); - // return false; - } catch (IOException e) { - Gui.showMessageBox(this, I18n.WIZARD.getString("ImageCreation.Message.error.UploadInitializationFailure"), MessageType.ERROR, LOGGER, - e); - // return false; - } - } - // Start the hash check now - state.upload.startHashing(); - } - @Override public boolean wantFinish() { - - if (state.meta instanceof DockerMetaDataDummy) - initUpload(); // since we only started the upload and created a "blank" image entry // we can here do all the sanity checks on the fields of UploadWizardState // and react accordingly. @@ -162,7 +121,8 @@ import java.util.List; try { ThriftActions.writeImagePermissions(state.uuid, state.permissionMap); } catch (TException e) { - Gui.showMessageBox(this, I18n.WIZARD.getString("ImageCreation.Message.error.permissionsNotWritten"), + Gui.showMessageBox(this, + I18n.WIZARD.getString("ImageCreation.Message.error.permissionsNotWritten"), MessageType.ERROR, null, null); ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), state.uuid); return false; @@ -261,8 +221,7 @@ import java.util.List; state.shareMode); } - @Override - protected final void doPrevious() { + @Override protected final void doPrevious() { if (outOfOrderPage != null) { outOfOrderPage = null; returnAfterOutOfOrderPage(state.imageUploadPage, state.conversionPage); @@ -271,8 +230,7 @@ import java.util.List; } } - @Override - public final void doNext() { + @Override public final void doNext() { if (outOfOrderPage != null) { outOfOrderPage = null; returnAfterOutOfOrderPage(state.imageUploadPage, state.conversionPage); @@ -281,11 +239,11 @@ import java.util.List; } } - @Override - protected boolean onCancelRequest() { + @Override protected boolean onCancelRequest() { if (state.uuid == null) return true; - boolean confirmed = Gui.showMessageBox(this, I18n.WIZARD.getString("ImageCreation.Message.yesNo.cancelRequest"), + boolean confirmed = Gui.showMessageBox(this, + I18n.WIZARD.getString("ImageCreation.Message.yesNo.cancelRequest"), MessageType.QUESTION_YESNO, null, null); if (confirmed) { QuickTimer.scheduleOnce(new Task() { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java index 2907ebc4..35a4ddad 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java @@ -1,10 +1,11 @@ package org.openslx.dozmod.gui.wizard; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Window; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.helper.I18n; +import org.openslx.dozmod.gui.helper.StatusHeader; + +import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; @@ -12,27 +13,9 @@ import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JSeparator; -import javax.swing.SwingConstants; - -import org.openslx.dozmod.gui.Gui; -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.util.ResourceLoader; +@SuppressWarnings("serial") public abstract class Wizard extends JDialog { -@SuppressWarnings("serial") -public abstract class Wizard extends JDialog { - - private final QLabel titleLabel; - private final QLabel messageLabel; + private final StatusHeader header; private final List<WizardPage> pages = new ArrayList<>(); private WizardPage postFinishPage = null; private boolean isPostFinish = false; @@ -52,28 +35,8 @@ public abstract class Wizard extends JDialog { super(parent, ModalityType.APPLICATION_MODAL); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); setLayout(new BorderLayout()); - JPanel header = new JPanel(); - header.setMinimumSize(Gui.getScaledDimension(0, 100)); - header.setOpaque(true); - header.setBackground(Color.WHITE); - header.setLayout(new BoxLayout(header, BoxLayout.PAGE_AXIS)); - header.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - // Labels in header - titleLabel = new QLabel("<title>"); - messageLabel = new QLabel("<message>"); - titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD)); - titleLabel.setForeground(Color.BLACK); - messageLabel.setForeground(Color.BLACK); - messageLabel.setHorizontalTextPosition(SwingConstants.RIGHT); - header.add(titleLabel); - header.add(messageLabel); - // Add header - JPanel headerWrapper = new JPanel(); - GridManager grid = new GridManager(headerWrapper, 1, false); - grid.add(header).expand(true, false).fill(true, false); - grid.add(new JSeparator()).expand(true, false).fill(true, false); - grid.finish(false); - getContentPane().add(headerWrapper, BorderLayout.PAGE_START); + + this.header = new StatusHeader(getContentPane(), "<titel>", "<message>"); // Buttons in footer JPanel footer = new JPanel(); footer.setLayout(new BoxLayout(footer, BoxLayout.LINE_AXIS)); @@ -104,41 +67,34 @@ public abstract class Wizard extends JDialog { // Window events addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent we) { + @Override public void windowClosing(WindowEvent we) { doCancel(); } }); // Äkschns btnNext.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { doNext(); } }); btnPrev.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { doPrevious(); } }); btnCancel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { doCancel(); } }); btnFinish.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + @Override public void actionPerformed(ActionEvent e) { doFinish(); } }); } - @SuppressWarnings("deprecation") - @Override - public void show() { + @SuppressWarnings("deprecation") @Override public void show() { if (needsLayout) { needsLayout = false; pack(); @@ -180,9 +136,8 @@ public abstract class Wizard extends JDialog { // Show an out of order page e.g. for converting an image /** - * - * @param NewPage to return to. - * @param OldPage that should be hidden. + * @param newPage to return to. + * @param oldPage that should be hidden. */ public void returnAfterOutOfOrderPage(WizardPage newPage, WizardPage oldPage) { oldPage.onPageLeave(); @@ -204,12 +159,7 @@ public abstract class Wizard extends JDialog { pageTitle = "Step " + currentPage; if (pageDesc == null) pageDesc = ""; - titleLabel.setText(pageTitle); - messageLabel.setText(pageDesc); - messageLabel.setIcon( - ResourceLoader.getScaledIcon(page.getMessageIcon(), messageLabel.getHeight(), messageLabel)); - messageLabel.setForeground(page.getMessageColor()); - messageLabel.validate(); + header.updateHeader(pageTitle, pageDesc, page.getMessageIcon(), page.getMessageColor()); setTitle(getWindowTitle() + " - " + pageTitle); } @@ -265,7 +215,7 @@ public abstract class Wizard extends JDialog { /** * Returns whether the page currently shown is the summary page. - * + * * @return whether the page currently shown is the summary page. */ protected final boolean isSummaryPage() { @@ -275,7 +225,7 @@ public abstract class Wizard extends JDialog { /** * Returns true if the wizard was cancelled. Mostly useful in onPageLeave to * distinguish what's happening. - * + * * @return true if the wizard was cancelled. */ public final boolean isCancelled() { @@ -364,7 +314,7 @@ public abstract class Wizard extends JDialog { /** * User clicked cancel or (X) - when returning false, * wizard will stay open - * + * * @return */ protected boolean onCancelRequest() { @@ -374,9 +324,9 @@ public abstract class Wizard extends JDialog { /** * Called when user clicks finish. Override to do final checks and take * appropriate actions. - * + * * @return <code>true</code> if finish is allowed, <code>false</code> - * otherwise + * otherwise */ protected boolean wantFinish() { return true; @@ -389,9 +339,9 @@ public abstract class Wizard extends JDialog { * If a wizard page is returned, it will serve as a summary page shown to * the user within the wizard frame. The prev and next buttons will * disappear, and the finish button will change to a close button. - * + * * @return A wizard page that serves as a summary page, or null if the - * wizard should just close + * wizard should just close */ protected WizardPage performFinish() { return null; 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 7d873264..d4d253ab 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 @@ -16,20 +16,16 @@ public class ContainerUploadPageLayout extends WizardPage { protected final JTextField txtImageName; protected final JButton btnBrowseForImage; protected final JTextField txtImageFile; - protected final JCheckBox chkLicenseRestricted; protected final QLabel lblImageName; protected final JTextArea txtInfoText; - protected final JTextField txtContainerRun; - protected final QLabel lblContainerRun; - protected final JTabbedPane tpInput; protected final JTextField txtGitRepo; - // TODO set proper Text labels + protected final JTextField txtContainerImageFile; /** - * Page for uploading an imagefile + * Constructor to define the Layout */ public ContainerUploadPageLayout(Wizard wizard) { @@ -40,7 +36,8 @@ public class ContainerUploadPageLayout extends WizardPage { JPanel p1 = new JPanel(); p1.setVisible(true); GridManager g1 = new GridManager(p1, 3, true, new Insets(5, 0, 5, 0)); - QLabel imageFileCaption = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.DockerFile.label")); + QLabel imageFileCaption = new QLabel( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.DockerFile.label")); txtImageFile = new JTextField(); txtImageFile.setEditable(false); btnBrowseForImage = new JButton(I18n.PAGE_LAYOUT.getString("ImageUpload.Button.browseForImage.text")); @@ -54,11 +51,11 @@ public class ContainerUploadPageLayout extends WizardPage { p2.setVisible(false); GridManager g2 = new GridManager(p2, 2, true, new Insets(5, 0, 5, 0)); QLabel lblGitRepo = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.label")); - lblGitRepo.setToolTipText(I18n.PAGE_LAYOUT.getString( - "ContainerUploadPage.GitRepository.toolTipText")); + lblGitRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.toolTipText")); txtGitRepo = new JTextField(); - txtGitRepo.setToolTipText(I18n.PAGE_LAYOUT.getString( - "ContainerUploadPage.GitRepository.toolTipText")); + txtGitRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.toolTipText")); g2.add(lblGitRepo); g2.add(txtGitRepo).fill(true, false).expand(true, false); g2.finish(false); @@ -73,30 +70,25 @@ public class ContainerUploadPageLayout extends WizardPage { // Start as with Dockerfile as input! tpInput.setSelectedIndex(0); - lblImageName = new QLabel(I18n.PAGE_LAYOUT.getString( - "ContainerUploadPage.ImageName.text")); + lblImageName = new QLabel(I18n.PANEL.getString("ContainerPanel.Label.ImageName.text")); txtImageName = new JTextField(); grid.add(lblImageName); grid.add(txtImageName, 2, 1).fill(true, false).expand(true, false); grid.nextRow(); - // -- Software license changed - shown only in UploadWizard -- - chkLicenseRestricted = new JCheckBox(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text")); - chkLicenseRestricted.setVisible(false); - grid.skip(); - grid.add(chkLicenseRestricted, 2, 1).fill(false, false).expand(true, false); - grid.nextRow(); - - lblContainerRun = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerStartOptions.label")); - lblContainerRun.setToolTipText(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerStartOptions.tooltip")); - txtContainerRun = new JTextField(); - grid.add(lblContainerRun); - grid.add(txtContainerRun, 2, 1).fill(true, false).expand(true, false); + QLabel lblContainerImageFile = new QLabel("Prebuild Container Image"); + lblContainerImageFile.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.ToolTipText")); + txtContainerImageFile = new JTextField(); + txtContainerImageFile.setEnabled(false); + grid.add(lblContainerImageFile); + grid.add(txtContainerImageFile, 2).fill(true, false).expand(true, false); grid.nextRow(); - + grid.add(Box.createVerticalGlue(), 3).expand(true, true); txtInfoText = new JTextArea(); - txtInfoText.setBorder(BorderFactory.createTitledBorder(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.Infobox.label"))); + txtInfoText.setBorder(BorderFactory.createTitledBorder( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.Infobox.label"))); txtInfoText.setLineWrap(true); txtInfoText.setWrapStyleWord(true); txtInfoText.setEditable(false); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java index 8d53cba5..862712ea 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageMetaDataPageLayout.java @@ -1,15 +1,7 @@ package org.openslx.dozmod.gui.wizard.layout; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JEditorPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; - import org.openslx.bwlp.thrift.iface.OperatingSystem; import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.configurator.ContainerBindMountConfigurator; import org.openslx.dozmod.gui.control.ComboBox; import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; import org.openslx.dozmod.gui.control.QLabel; @@ -32,8 +24,6 @@ import javax.swing.*; protected final JCheckBox chkLicenseRestricted; protected final JCheckBox chkIsTemplate; - protected final ContainerBindMountConfigurator bindMountConfigurator; - /** * wizard page for entering image data at creating or editing an image * @@ -46,14 +36,14 @@ import javax.swing.*; GridManager grid = new GridManager(this, 2, false); lblOperatingSystem = new QLabel(I18n.PAGE_LAYOUT.getString("ImageMetaData.Label.OS.text")); - cboOperatingSystem = new ComboBox<>(Comparators.operatingSystem, new ComboBoxRenderer<OperatingSystem>() { - @Override - public String renderItem(OperatingSystem item) { - if (item == null) - return null; - return item.getOsName(); - } - }); + cboOperatingSystem = new ComboBox<>(Comparators.operatingSystem, + new ComboBoxRenderer<OperatingSystem>() { + @Override public String renderItem(OperatingSystem item) { + if (item == null) + return null; + return item.getOsName(); + } + }); cboOperatingSystem.setEditable(false); grid.add(lblOperatingSystem); grid.add(cboOperatingSystem); @@ -71,9 +61,9 @@ import javax.swing.*; grid.add(startCommandPane).fill(true, false).expand(true, false); grid.nextRow(); - // description - QLabel descriptionCaption = new QLabel(I18n.PAGE_LAYOUT.getString("ImageMetaData.Label.description.text")); + QLabel descriptionCaption = new QLabel( + I18n.PAGE_LAYOUT.getString("ImageMetaData.Label.description.text")); txtDescription = new JEditorPane(); txtDescription.setMinimumSize(Gui.getScaledDimension(0, 70)); JScrollPane descPane = new JScrollPane(txtDescription, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, @@ -88,12 +78,6 @@ import javax.swing.*; grid.add(chkLicenseRestricted, 2); grid.nextRow(); - bindMountConfigurator = new ContainerBindMountConfigurator(); - bindMountConfigurator.setVisible(false); // only visible in container context - - grid.add(bindMountConfigurator, 2).fill(true, true).expand(true, true); - grid.nextRow(); - // -- end permissions group -- chkIsTemplate = new JCheckBox(I18n.PAGE_LAYOUT.getString("ImageMetaData.CheckBox.isTemplate.text")); grid.add(chkIsTemplate, 2); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageTypePageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageTypePageLayout.java index 7dac1103..c9f3bf34 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageTypePageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageTypePageLayout.java @@ -1,6 +1,7 @@ package org.openslx.dozmod.gui.wizard.layout; import org.openslx.dozmod.gui.helper.GridManager; +import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.wizard.Wizard; import org.openslx.dozmod.gui.wizard.WizardPage; @@ -17,33 +18,28 @@ public abstract class ImageTypePageLayout extends WizardPage { */ public ImageTypePageLayout(Wizard wizard) { - super(wizard, "Wähle Image Type"); - setDescription("Möchten Sie eine VM oder ein Docker Image definieren?"); + super(wizard, I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.WizardPage.title")); + setDescription(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.WizardPage.description")); GridManager grid = new GridManager(this, 4, false); // Choose between new vm or new docker-image txtInfoText = new JTextArea(); - txtInfoText.setBorder(BorderFactory.createTitledBorder("Hinweis")); + txtInfoText.setBorder(BorderFactory.createTitledBorder(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.newVmInformation.border"))); txtInfoText.setLineWrap(true); txtInfoText.setWrapStyleWord(true); txtInfoText.setEditable(false); txtInfoText.setFocusable(false); txtInfoText.setOpaque(false); - txtInfoText.setText("Hier haben Sie die Möglichkeit ein neues Image als VM oder Container (Docker) " - + "zu definieren.\n\n" - + "Sie besitzen derzeit eine Entwicklungsstand der bwLehrpool Suite, in der sämtliche " - + "Funktionalitäten zur Erstellung und Verwaltung von Container Images in Entwicklung sind. " - + "Diese Funktionen können sich in späteren Versionen ändern und somit ihre erstellten Images " - + "inkompatibel machen."); + txtInfoText.setText(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.newVmInformation.text")); grid.add(txtInfoText, 4).fill(true, false).expand(true, false); grid.nextRow(); grid.nextRow(); // -- New VM Pick-- - btnNewVmImage = new JButton("New VM"); + btnNewVmImage = new JButton(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.button.newVM")); grid.add(btnNewVmImage, 2, 2).fill(true, true).expand(true, true); // -- New Docker-Image Pick-- - btnNewDockerImage = new JButton("new Docker-Image"); + btnNewDockerImage = new JButton(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.button.newDocker")); grid.add(btnNewDockerImage, 2, 2).fill(true, true).expand(true, true); grid.finish(false); 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 f784d844..e7e7adf5 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 @@ -4,7 +4,9 @@ import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.ImageDetailsRead; import org.openslx.dozmod.Config; +import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.helper.I18n; +import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.QFileChooser; import org.openslx.dozmod.gui.helper.TextChangeListener; import org.openslx.dozmod.gui.wizard.Wizard; @@ -13,6 +15,10 @@ import org.openslx.dozmod.model.ContainerBuildContextMethod; import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.model.ContainerMeta; import org.openslx.dozmod.state.UploadWizardState; +import org.openslx.dozmod.thrift.ThriftActions; +import org.openslx.dozmod.thrift.ThriftError; +import org.openslx.dozmod.thrift.UploadInitiator; +import org.openslx.dozmod.thrift.WrappedException; import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.util.vm.DockerMetaDataDummy; @@ -22,6 +28,8 @@ import javax.swing.event.ChangeListener; import javax.swing.filechooser.FileFilter; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; import java.util.regex.Matcher; @@ -34,19 +42,18 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { private final Logger LOGGER = Logger.getLogger(ContainerUploadPage.class); - /** - * Page for uploading an imagefile - * - * @param wizard - */ private final UploadWizardState state; private final ImageDetailsRead existingImage; private final ContainerDefinition containerDefinition; - public ContainerUploadPage(Wizard wizard, final UploadWizardState state, - ContainerDefinition containerDefinition) { + /** + * Page for uploading an Container Image + * + * @param wizard The wizard dialog in which this page is active. + */ + public ContainerUploadPage(Wizard wizard, final UploadWizardState state) { super(wizard); - this.containerDefinition = containerDefinition; + this.containerDefinition = new ContainerDefinition(); this.state = state; canComeBack = false; @@ -103,11 +110,6 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { reactOnUserInput(); } }); - txtContainerRun.getDocument().addDocumentListener(new TextChangeListener() { - @Override public void changed() { - reactOnUserInput(); - } - }); tpInput.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -121,9 +123,48 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { } }); + txtContainerImageFile.addMouseListener(new MouseListener() { + @Override public void mouseClicked(MouseEvent e) { + if (e.getClickCount() >= 2) + browseContainerImageFile(); + } + + @Override public void mousePressed(MouseEvent e) { + + } + + @Override public void mouseReleased(MouseEvent e) { + + } + + @Override public void mouseEntered(MouseEvent e) { + + } + + @Override public void mouseExited(MouseEvent e) { + + } + }); + btnBrowseForImage.requestFocus(); } + private void browseContainerImageFile() { + QFileChooser fc = new QFileChooser(Config.getUploadPath(), false); + fc.setAcceptAllFileFilterUsed(false); + fc.addChoosableFileFilter(new ContainerImageFileFiler()); + + int action = fc.showOpenDialog(getDialog()); + File file = fc.getSelectedFile(); + if (action != JFileChooser.APPROVE_OPTION || file == null) { + txtContainerImageFile.setText(""); + return; + } + + txtContainerImageFile.setText(file.getAbsolutePath()); + LOGGER.info("Tar File selected"); + } + private void browseFile() { QFileChooser fc = new QFileChooser(Config.getUploadPath(), false); @@ -148,10 +189,8 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { String imageName = file.getParentFile().getName(); File imageTarFile = new File(file.getParentFile(), imageName.concat(".tar")); if (imageTarFile.exists()) { - LOGGER.info("Upload also an created Image"); - state.diskFile = imageTarFile; - } else { - state.diskFile = getDummyFile(); + txtContainerImageFile.setText(imageTarFile.getAbsolutePath()); + LOGGER.info("Prebuild Container Image found"); } Config.setUploadPath(file.getParent()); @@ -206,11 +245,6 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoProperName")); return false; } - - if (txtContainerRun.getText() == null || txtContainerRun.getText().isEmpty()) { - setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoRunOptions")); - return false; - } return true; } @@ -219,31 +253,83 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { ContainerMeta containerMeta = containerDefinition.getContainerMeta(); containerMeta.setBuildContextMethod(getBuildContextMethod().ordinal()); containerMeta.setImageName(txtImageName.getText()); - containerMeta.setRunOptions(txtContainerRun.getText()); + + + File containerImageFile = new File(txtContainerImageFile.getText()); + if (containerImageFile.exists()) + state.diskFile = containerImageFile; + else + state.diskFile = getDummyFile(); + switch (containerDefinition.getBuildContextMethod()) { case FILE: containerDefinition.setContainerRecipe(state.descriptionFile); break; case GIT_REPOSITORY: containerMeta.setBuildContextUrl(txtGitRepo.getText()); - state.diskFile = getDummyFile(); state.descriptionFile = getDummyFile(); break; } return containerDefinition.createVmMeta(); } + /** + * This function starts the image creation process. It is triggered by the + * "Next" button. + * <p> + * Depending on the state, it will first try to get a UUID for the new image by + * calling createImage() of the thrift API. If a UUID is received, it will + * request an upload with requestImageVersionUpload(). If granted, it will + * finally start a thread for the UploadTask. + * <p> + * Then a callback to the Gui is executed where we can process the upload state + * and give the user feedback about it. + */ @Override protected boolean wantNextOrFinish() { + // are we creating a new image? then either: + // get the image name either auto filled by VmwareMetaData or by user + // get the image name from the image we are uploading a new version of state.name = existingImage != null ? existingImage.getImageName() : txtImageName.getText(); state.meta = createVmMeta(); + // -- create image to get uuid -- + if (existingImage == null) { + if (state.uuid == null) { + state.uuid = ThriftActions.createImage(JOptionPane.getFrameForComponent(this), state.name); + if (state.uuid == null) + return false; + txtImageName.setEnabled(false); + btnBrowseForImage.setEnabled(false); + txtImageFile.setEnabled(false); + } + } else { + state.uuid = existingImage.getImageBaseId(); + } + // Create upload initiator that will manage requesting a token, hashing the + // file, connecting for upload... + if (state.upload == null) { + try { + state.upload = new UploadInitiator(state.uuid, state.diskFile, + state.meta.getFilteredDefinition()); + } catch (WrappedException e) { + ThriftError.showMessage(this, LOGGER, e.exception, e.displayMessage); + return false; + } catch (IOException e) { + Gui.showMessageBox(this, + I18n.PAGE.getString("ImageUpload.Message.error.uploadInitiatorFailed"), + MessageType.ERROR, LOGGER, e); + return false; + } + } + // Start the hash check now + state.upload.startHashing(); return true; } private static class DockerfileFilter extends FileFilter { @Override public boolean accept(File f) { - + Pattern p = Pattern.compile("[Dd]ockerfile"); Matcher m = p.matcher(f.getName()); @@ -257,4 +343,19 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { return "Dockerfile"; } } + + private static class ContainerImageFileFiler extends FileFilter { + + @Override public boolean accept(File f) { + + boolean accept = false; + if ((f.isFile() && f.toString().endsWith(".tar")) || f.isDirectory()) + accept = true; + return accept; + } + + @Override public String getDescription() { + return "Container Image (.tar)"; + } + } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java index f2010da1..a20ef8b6 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageMetaDataPage.java @@ -1,10 +1,5 @@ package org.openslx.dozmod.gui.wizard.page; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.Collections; -import java.util.List; - import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.OperatingSystem; import org.openslx.bwlp.thrift.iface.ShareMode; @@ -13,7 +8,6 @@ import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.TextChangeListener; import org.openslx.dozmod.gui.wizard.Wizard; import org.openslx.dozmod.gui.wizard.layout.ImageMetaDataPageLayout; -import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.state.UploadWizardState; import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.cache.MetaDataCache; @@ -36,13 +30,10 @@ import java.util.List; private final static Logger LOGGER = Logger.getLogger(ImageMetaDataPage.class); private UploadWizardState state; - private final ContainerDefinition containerDefinition; - public ImageMetaDataPage(Wizard wizard, UploadWizardState uploadWizardState, - ContainerDefinition containerDefinition) { + public ImageMetaDataPage(Wizard wizard, UploadWizardState uploadWizardState) { super(wizard); this.state = uploadWizardState; - this.containerDefinition = containerDefinition; setPageComplete(false); // HACK set fixed uploadWizardState to test functions uploadWizardState.shareMode = ShareMode.LOCAL; @@ -78,9 +69,7 @@ import java.util.List; }); } - - @Override - protected void onPageEnter() { + @Override protected void onPageEnter() { // Preselect OS if possible if (state.detectedOs != null) { cboOperatingSystem.setSelectedItem(state.detectedOs); @@ -99,10 +88,6 @@ import java.util.List; state.isTemplate = chkIsTemplate.isSelected(); state.isRestricted = chkLicenseRestricted.isSelected(); - if (state.meta instanceof DockerMetaDataDummy) { - containerDefinition.getContainerMeta().setBindMountConfig(bindMountConfigurator.getData()); - state.meta = containerDefinition.createVmMeta(); - } return state.selectedOs != null && state.description != null; } @@ -134,8 +119,6 @@ import java.util.List; } if (state.meta instanceof DockerMetaDataDummy) { - bindMountConfigurator.setVisible(true); - // TODO we need Information about a OS in Container? Currently use "Other (32 Bit)" as default lblOperatingSystem.setVisible(false); cboOperatingSystem.setVisible(false); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java index ad1cd40d..c764bee3 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java @@ -36,6 +36,7 @@ import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.sat.thrift.version.Feature; import org.openslx.thrifthelper.TConst; import org.openslx.util.vm.DiskImage; +import org.openslx.util.vm.DiskImage.ImageFormat; import org.openslx.util.vm.DiskImage.UnknownImageFormatException; import org.openslx.util.vm.VmMetaData; import org.openslx.util.vm.VmMetaData.HardDisk; @@ -58,6 +59,8 @@ public class ImageUploadPage extends ImageUploadPageLayout { "vmx"); private final FileNameExtensionFilter vboxFilter = new FileNameExtensionFilter( "VirtualBox Virtual Machine", "vbox"); + private final FileNameExtensionFilter qemuFilter = new FileNameExtensionFilter( + "QEMU Virtual Machine", "xml"); private final FileNameExtensionFilter ovfFilter = new FileNameExtensionFilter( "OVF Virtual Machine Format", "ovf"); @@ -97,7 +100,7 @@ public class ImageUploadPage extends ImageUploadPageLayout { // initialize allSupportedFilter depending on whether multiple hypervisors // are supported or not if (Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) { - allSupportedFilter = new FileNameExtensionFilter("All Supported", "vmx", "ovf", "vbox", "ova"); + allSupportedFilter = new FileNameExtensionFilter("All Supported", "vmx", "ovf", "vbox", "xml", "ova"); } else { allSupportedFilter = new FileNameExtensionFilter("All Supported", "vmx", "ovf", "ova"); } @@ -112,6 +115,7 @@ public class ImageUploadPage extends ImageUploadPageLayout { fc.addChoosableFileFilter(ovaFilter); if (Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) { fc.addChoosableFileFilter(vboxFilter); + fc.addChoosableFileFilter(qemuFilter); } fc.addChoosableFileFilter(allSupportedFilter); fc.setFileFilter(allSupportedFilter); @@ -121,6 +125,8 @@ public class ImageUploadPage extends ImageUploadPageLayout { fc.setFileFilter(vmxFilter); } else if (existingImage.virtId.equals(TConst.VIRT_VIRTUALBOX)) { fc.setFileFilter(vboxFilter); + } else if (existingImage.virtId.equals(TConst.VIRT_QEMU)) { + fc.setFileFilter(qemuFilter); } } @@ -252,8 +258,9 @@ public class ImageUploadPage extends ImageUploadPageLayout { vmDiskFileInfo = new File(vmBaseDirectory, hdds.get(0).diskImage); } DiskImage diskImage; + List<DiskImage.ImageFormat> supportedImageFormats = state.meta.getSupportedImageFormats(); try { - diskImage = new DiskImage(vmDiskFileInfo); + diskImage = new DiskImage(vmDiskFileInfo, supportedImageFormats); } catch (FileNotFoundException e) { setErrorMessage(I18n.PAGE.getString("ImageUpload.WizardPage.errorMessage.diskImageNotFound", vmDiskFileInfo.getName())); 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 f41b4b47..4f9be05e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java @@ -10,6 +10,7 @@ import org.kamranzafar.jtar.TarOutputStream; import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.dozmod.util.TarArchiveUtil; import org.openslx.util.vm.DockerMetaDataDummy; +import org.openslx.util.vm.UnsupportedVirtualizerFormatException; import java.io.*; import java.nio.ByteBuffer; @@ -77,10 +78,15 @@ public class ContainerDefinition { } public DockerMetaDataDummy createVmMeta() { - byte[] rawContainerRecipe = toByteBuffer().array(); - return new DockerMetaDataDummy(MetaDataCache.getOperatingSystems(), rawContainerRecipe, - rawContainerRecipe.length); + try { + return new DockerMetaDataDummy(MetaDataCache.getOperatingSystems(), rawContainerRecipe, + rawContainerRecipe.length); + } catch (UnsupportedVirtualizerFormatException e) { + e.printStackTrace(); + LOGGER.error("Could not create ContainerMetaDataDummy"); + } + return null; } /** @@ -158,7 +164,7 @@ public class ContainerDefinition { int count; byte[] data = new byte[1024]; while ((count = bis.read(data)) != -1) { - rawFile.write(data,0,count); + rawFile.write(data, 0, count); } String rawRecipe = new String(rawFile.toByteArray(), StandardCharsets.UTF_8); 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 96c4d1f6..ab3db38b 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java @@ -450,37 +450,6 @@ public class ThriftActions { return; ImageWrapper.unpack(virtualizerId, tmpDiskFile, imageName, destDir, osId, fTransInf.getMachineDescription()); - DiskImage diskImage = null; - String ext = virtualizerId; - try { - diskImage = new DiskImage(tmpDiskFile); - } catch (IOException | UnknownImageFormatException e) { - LOGGER.warn("Could not open downloaded image for analyze step", e); - } - if (diskImage != null) { - if (diskImage.format != null) { - ext = diskImage.format.extension; - } - if (diskImage.isCompressed) { - Gui.asyncMessageBox( - I18n.THRIFT.getString("ThriftActions.Message.warning.diskImageCompressed", - imageName, Branding.getServiceFAQWebsite()), - MessageType.WARNING, null, null); - } - } - File destImage = new File(destDir.getAbsolutePath(), VmWrapper.generateFilename( - imageName, ext)); - destImage.delete(); - if (!tmpDiskFile.renameTo(destImage)) { - destImage = tmpDiskFile; // Must be Windows... - } - try { - VmWrapper.wrapVm(destImage, imageName, fTransInf.getMachineDescription(), - virtualizerId, osId, diskImage); - } catch (MetaDataMissingException | IOException e) { - Gui.asyncMessageBox(I18n.THRIFT.getString("ThriftActions.Message.warning.couldNotWrapVM"), - MessageType.WARNING, LOGGER, e); - } } }); 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 c86ddfa9..05ba40bd 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java @@ -1,9 +1,9 @@ package org.openslx.dozmod.util; import org.apache.log4j.Logger; - import org.openslx.dozmod.Branding; import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.thrifthelper.TConst; @@ -13,14 +13,22 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +/** + * This Class handle the unpacking of Images downloaded from + * the server individually (VM-Images, Docker-Images (Container Images)). + * + * In case of Container-Images the Image-Blob is not important because it can be recreated with the + * recipe (e.g. dockerfile). + * TODO Do not download the Image-Blob of a Container-Image. + */ public class ImageWrapper { private static final Logger LOGGER = Logger.getLogger(ImageWrapper.class); /** * @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 tmpDiskFile dont no! Maybe the part file + * @param imageName The name of the 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 @@ -31,7 +39,6 @@ public class ImageWrapper { // 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) DiskImage diskImage = null; String ext = virtualizerId; @@ -46,10 +53,9 @@ public class ImageWrapper { try { // delete image file, unused in container Context. Files.delete(tmpDiskFile.toPath()); - } catch (IOException e) { - Gui.asyncMessageBox("Konnte temporäre Download Datei nicht löschen", MessageType.WARNING, LOGGER, - e); + Gui.asyncMessageBox("Konnte temporäre Download Datei nicht löschen", MessageType.WARNING, + LOGGER, e); } } else { @@ -64,13 +70,11 @@ public class ImageWrapper { 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); + Gui.asyncMessageBox( + I18n.THRIFT.getString("ThriftActions.Message.warning.diskImageCompressed", + imageName, Branding.getServiceFAQWebsite()), MessageType.WARNING, null, + null); } } File destImage = new File(destDir.getAbsolutePath(), VmWrapper.generateFilename(imageName, ext)); @@ -84,8 +88,7 @@ public class ImageWrapper { VmWrapper.wrapVm(destImage, imageName, virtualizerConfig, 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.", + Gui.asyncMessageBox(I18n.THRIFT.getString("ThriftActions.Message.warning.couldNotWrapVM"), MessageType.WARNING, LOGGER, e); } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmMetaDataDummy.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmMetaDataDummy.java deleted file mode 100644 index bd5d4323..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmMetaDataDummy.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.openslx.dozmod.util; - -import org.openslx.bwlp.thrift.iface.Virtualizer; -import org.openslx.thrifthelper.TConst; -import org.openslx.util.vm.VmMetaData; - -import java.io.File; -import java.util.List; - -public class VmMetaDataDummy extends VmMetaData { - // TODO Define DOCKER CONSTANT - private final Virtualizer virtualizer = new Virtualizer( TConst.VIRT_VMWARE, "DOCKER" ); - - public VmMetaDataDummy(List osList) { - super(osList); - } - - @Override public byte[] getFilteredDefinitionArray() { - return new byte[0]; - } - - @Override public void applySettingsForLocalEdit() { - - } - - @Override public boolean addHddTemplate(File diskImage, String hddMode, String redoDir) { - return false; - } - - @Override public boolean addHddTemplate(String diskImagePath, String hddMode, String redoDir) { - return false; - } - - @Override public boolean addDefaultNat() { - return false; - } - - @Override public void setOs(String vendorOsId) { - - } - - @Override public boolean addDisplayName(String name) { - return false; - } - - @Override public boolean addRam(int mem) { - return false; - } - - @Override public void addFloppy(int index, String image, boolean readOnly) { - - } - - @Override public boolean addCdrom(String image) { - return false; - } - - @Override public boolean addCpuCoreCount(int nrOfCores) { - return false; - } - - @Override public void setSoundCard(SoundCardType type) { - - } - - @Override public SoundCardType getSoundCard() { - return SoundCardType.NONE; - } - - @Override public void setDDAcceleration(DDAcceleration type) { - - } - - @Override public DDAcceleration getDDAcceleration() { - return DDAcceleration.OFF; - } - - @Override public void setHWVersion(HWVersion type) { - - } - - @Override public HWVersion getHWVersion() { - return HWVersion.DEFAULT; - } - - @Override public void setEthernetDevType(int cardIndex, EthernetDevType type) { - - } - - @Override public EthernetDevType getEthernetDevType(int cardIndex) { - return EthernetDevType.NONE; - } - - @Override public void setMaxUsbSpeed(UsbSpeed speed) { - - } - - @Override public UsbSpeed getMaxUsbSpeed() { - return UsbSpeed.NONE; - } - - @Override public byte[] getDefinitionArray() { - return new byte[0]; - } - - @Override public boolean addEthernet(EtherType type) { - return false; - } - - @Override public Virtualizer getVirtualizer() { - return virtualizer; - } - - @Override public boolean tweakForNonPersistent() { - return false; - } - - @Override public void registerVirtualHW() { - - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java index 58093471..3f3b9fac 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java @@ -114,7 +114,7 @@ public class VmWrapper { } else if (vmMeta instanceof VboxMetaData) { fileType = ".vbox"; } else if (vmMeta instanceof QemuMetaData) { - fileType = "_startCommand.txt"; + fileType = ".xml"; } if (fileType == null) { LOGGER.warn("file type somehow unclear; application could stop working here!"); diff --git a/dozentenmodul/src/main/properties/i18n/page_layout.properties b/dozentenmodul/src/main/properties/i18n/page_layout.properties index ab5f74bd..19910681 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout.properties @@ -10,6 +10,17 @@ ImageCustomPermission.CheckBox.permissionRead.text=Download ImageCustomPermission.CheckBox.permissionEdit.text=Edit ImageCustomPermission.CheckBox.permissionAdmin.text=Admin +# ImageTypePageLayout +ImageTypePageLayout.WizardPage.title=Choose Image Type +ImageTypePageLayout.WizardPage.description=Do you want to create a Virtual Machine of Docker Image +ImageTypePageLayout.newVmInformation.border=Information +ImageTypePageLayout.newVmInformation.text=Here you can define and upload a new virtual machine or docker container.\n\n\ + The creation of docker images is still in a developing state. \ + The creation and management of docker containers may therefore change in the future and containers you upload now may \ + or may not work in the future. +ImageTypePageLayout.button.newVM=New Virtual Machine +ImageTypePageLayout.button.newDocker=New Docker Image + # ImageMetaDataPageLayout ImageMetaData.WizardPage.title=Metadata ImageMetaData.WizardPage.description=Please enter a meaningful name for the new VM. @@ -52,10 +63,8 @@ ContainerUploadPage.description=Please provide an Input for a Docker Image ContainerUploadPage.DockerFile.label=Docker File ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Set clone address of Git Repository [git@ | http://] [.git]. Currently no Checks! -ContainerUploadPage.ImageName.text=Name ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Contains license restricted software -ContainerUploadPage.ContainerStartOptions.label=Container Start Options -ContainerUploadPage.ContainerStartOptions.tooltip=Please provide the Container Run Options (Port, Name, Env,...) +ContainerUploadPage.ContainerImageFile.ToolTipText="Displays the path to a container image file archived as tar. Add manually with double click." ContainerUploadPage.Infobox.label=Information ContainerUploadPage.Infobox.text=Please provide all the information needed to define a container image. 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 170436b8..0695ed6c 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties @@ -10,6 +10,18 @@ ImageCustomPermission.CheckBox.permissionRead.text=Download ImageCustomPermission.CheckBox.permissionEdit.text=Bearbeiten ImageCustomPermission.CheckBox.permissionAdmin.text=Admin +# ImageTypePageLayout +ImageTypePageLayout.WizardPage.title=Wähle Image Type +ImageTypePageLayout.WizardPage.description=Möchten Sie eine VM oder ein Docker Image definieren? +ImageTypePageLayout.newVmInformation.border=Hinweis +ImageTypePageLayout.newVmInformation.text=Hier haben Sie die Möglichkeit ein neues Image als VM oder Container (Docker) zu definieren.\n\n\ + Sie besitzen derzeit eine Entwicklungsstand der bwLehrpool Suite, in der sämtliche\ + Funktionalitäten zur Erstellung und Verwaltung von Container Images in Entwicklung sind.\ + Diese Funktionen können sich in späteren Versionen ändern und somit ihre erstellten Images\ + inkompatibel machen. +ImageTypePageLayout.button.newVM=Neue Virtuele Maschine +ImageTypePageLayout.button.newDocker=Neues Docker Image + # ImageMetaDataPageLayout ImageMetaData.WizardPage.title=Metadaten ImageMetaData.WizardPage.description=Geben Sie bitte einen aussagekräftigen Namen für die neue VM ein. @@ -51,10 +63,8 @@ ContainerUploadPage.description=Bitte geben Sie Daten für das Docker Image an ContainerUploadPage.DockerFile.label=Docker File ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Clone Addresse des Git Repositories setzen. [git@ | http://] [.git]. Momentan noch keine Checks! -ContainerUploadPage.ImageName.text=Name ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Enthält lizenzpflichtige Software -ContainerUploadPage.ContainerStartOptions.label=Container Start Optionen -ContainerUploadPage.ContainerStartOptions.tooltip=Bitte die Container Start Optionen angeben (Port, Name, Env,...) +ContainerUploadPage.ContainerImageFile.ToolTipText="Zeigt den Pfad zu einer als tar archivierten Container-Image-Datei an. Manuell Hinzufügen mit Doppelklick" ContainerUploadPage.Infobox.label=Hinweis ContainerUploadPage.Infobox.text=In dieser Maske sind alle Infromationen zur Definition eines Container Images anzugeben. diff --git a/dozentenmodul/src/main/properties/i18n/page_layout_tr_TR.properties b/dozentenmodul/src/main/properties/i18n/page_layout_tr_TR.properties index 9c2daf0f..f85b555e 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout_tr_TR.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout_tr_TR.properties @@ -52,10 +52,7 @@ ContainerUploadPage.description=Lütfen Docker görüntüsü için gerekli bilgi ContainerUploadPage.DockerFile.label=Dockerfile ContainerUploadPage.GitRepository.label=Git deposu ContainerUploadPage.GitRepository.toolTipText=Git deposunun klon adresini belirtin. [git@ | http://] [.git]. Check iÅŸlemleri ÅŸimdilik desteklenmemektedir! -ContainerUploadPage.ImageName.text=Görüntü adı ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Lisans gerektiren yazılım içeriyor -ContainerUploadPage.ContainerStartOptions.label=Container baÅŸlatma seçenekleri -ContainerUploadPage.ContainerStartOptions.tooltip=Lütfen container baÅŸlatma seçeneklerini girin (Port, Name, Env,...) ContainerUploadPage.Infobox.label=Uyarı ContainerUploadPage.Infobox.text=Bir Docker görüntüsü tanımlamak için gereken tüm bilgilerin saÄŸlanması gerekmektedir. diff --git a/dozentenmodul/src/main/properties/i18n/panel.properties b/dozentenmodul/src/main/properties/i18n/panel.properties new file mode 100644 index 00000000..a8db9131 --- /dev/null +++ b/dozentenmodul/src/main/properties/i18n/panel.properties @@ -0,0 +1,10 @@ +# ContainerPanel +ContainerPanel.ContainerStartOptions.label=Container Start Options +ContainerPanel.ContainerStartOptions.tooltip=Please provide the Container Run Options (Port, Name, Env,...) +ContainerPanel.Label.ImageName.text=Image Name + +ContainerPanel.Constraint.NoEmptyDockerfile.text=Empty Dockerfile not allowed! + +# UNUSED +ImageDetails.Constraint.NoEmptyName.text=Empty Name not allowed! +ImageDetails.Constraint.NoEmptyRunOptions.text=No Container Run Options provided! diff --git a/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties b/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties new file mode 100644 index 00000000..832480bb --- /dev/null +++ b/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties @@ -0,0 +1,10 @@ +# ContainerPanel +ContainerPanel.ContainerStartOptions.label=Container Start Optionen +ContainerPanel.ContainerStartOptions.tooltip=Bitte die Container Start Optionen angeben (Port, Name, Env,...) +ContainerPanel.Label.ImageName.text=Image Name + +ContainerPanel.Constraint.NoEmptyDockerfile.text=Es muss ein Dockerfile angegeben werden! + +# UNUSED +ImageDetails.Constraint.NoEmptyName.text=Es muss ein Name angegeben werden! +ImageDetails.Constraint.NoEmptyRunOptions.text=Keine Container Start Optionen angegeben! diff --git a/dozentenmodul/src/main/properties/i18n/panel_tr_TR.properties b/dozentenmodul/src/main/properties/i18n/panel_tr_TR.properties new file mode 100644 index 00000000..09416eef --- /dev/null +++ b/dozentenmodul/src/main/properties/i18n/panel_tr_TR.properties @@ -0,0 +1,10 @@ +# ContainerPanel +ContainerPanel.ContainerStartOptions.label=Container ba?latma seçenekleri +ContainerPanel.ContainerStartOptions.tooltip=Lütfen container ba?latma seçeneklerini girin (Port, Name, Env,...) +ContainerPanel.Label.ImageName.text=Görüntü ad? + +ContainerPanel.Constraint.NoEmptyDockerfile.text=Dockerfile bo? b?rak?lamaz! + +# UNUSED +ImageDetails.Constraint.NoEmptyName.text=Görüntü ad? bo? b?rak?lamaz! +ImageDetails.Constraint.NoEmptyRunOptions.text=Container ba?latma seçenekleri girilmedi! diff --git a/dozentenmodul/src/main/properties/i18n/window.properties b/dozentenmodul/src/main/properties/i18n/window.properties index 924e37fd..ed908af3 100644 --- a/dozentenmodul/src/main/properties/i18n/window.properties +++ b/dozentenmodul/src/main/properties/i18n/window.properties @@ -53,9 +53,6 @@ ImageDetails.Message.error.performImageDownload=Selected version is invalid ImageDetails.Message.error.extendVersionExpiry=Could not extend expiry date of version {0}. ImageDetails.Message.info.extendVersionExpiry=Successfully extended images: {0} ImageDetails.Message.yesNo.safeClose=Changes will be discarded, do you really want to close? -ImageDetails.Constraint.NoEmptyDockerfile.text=Empty Dockerfile not allowed! -ImageDetails.Constraint.NoEmptyName.text=Empty Name not allowed! -ImageDetails.Constraint.NoEmptyRunOptions.text=No Container Run Options provided! # ImageListWindow ImageList.MenuItem.newLecture.text=New lecture diff --git a/dozentenmodul/src/main/properties/i18n/window_de_DE.properties b/dozentenmodul/src/main/properties/i18n/window_de_DE.properties index 181c140e..96c7efb1 100644 --- a/dozentenmodul/src/main/properties/i18n/window_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/window_de_DE.properties @@ -53,9 +53,6 @@ ImageDetails.Message.error.performImageDownload=Ausgewählte Version ist ungült ImageDetails.Message.error.extendVersionExpiry=Konnte Ablaufdatum der Version {0} nicht verlängern. ImageDetails.Message.info.extendVersionExpiry=Erfolgreich verlängerte Abbilder: {0} ImageDetails.Message.yesNo.safeClose=Änderungen werden verworfen, wollen Sie wirklich schließen? -ImageDetails.Constraint.NoEmptyDockerfile.text=Es muss ein Dockerfile angegeben werden! -ImageDetails.Constraint.NoEmptyName.text=Es muss ein Name angegeben werden! -ImageDetails.Constraint.NoEmptyRunOptions.text=Keine Container Start Optionen angegeben! # ImageListWindow ImageList.MenuItem.newLecture.text=Neue Veranstaltung diff --git a/dozentenmodul/src/main/properties/i18n/window_layout.properties b/dozentenmodul/src/main/properties/i18n/window_layout.properties index c2040724..2d9b78c4 100644 --- a/dozentenmodul/src/main/properties/i18n/window_layout.properties +++ b/dozentenmodul/src/main/properties/i18n/window_layout.properties @@ -69,8 +69,6 @@ ImageDetails.Button.close.text=Close ImageDetails.Tab.overview.title=Overview ImageDetails.Tab.versions.title=VM-Versions ImageDetails.Tab.permissions.title=Permissions -ImageDetails.Label.ImageName.text=Image Name -ImageDetails.Label.ContainerRunOptions.text=Container Run Options # ImageListWindowLayout ImageList.Label.title.text=Overview virtual machines diff --git a/dozentenmodul/src/main/properties/i18n/window_layout_de_DE.properties b/dozentenmodul/src/main/properties/i18n/window_layout_de_DE.properties index 734f5530..b4b4a9b7 100644 --- a/dozentenmodul/src/main/properties/i18n/window_layout_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/window_layout_de_DE.properties @@ -69,8 +69,6 @@ ImageDetails.Button.close.text=Schließen ImageDetails.Tab.overview.title=Ãœbersicht ImageDetails.Tab.versions.title=VM-Versionen ImageDetails.Tab.permissions.title=Berechtigungen -ImageDetails.Label.ImageName.text=Image Name -ImageDetails.Label.ContainerRunOptions.text=Container Start Optionen # ImageListWindowLayout ImageList.Label.title.text=Ãœbersicht Virtuelle Maschinen diff --git a/dozentenmodul/src/main/properties/i18n/window_layout_tr_TR.properties b/dozentenmodul/src/main/properties/i18n/window_layout_tr_TR.properties index 57fe904e..77709be6 100644 --- a/dozentenmodul/src/main/properties/i18n/window_layout_tr_TR.properties +++ b/dozentenmodul/src/main/properties/i18n/window_layout_tr_TR.properties @@ -69,8 +69,6 @@ ImageDetails.Button.close.text=Kapat ImageDetails.Tab.overview.title=Genel görünüm ImageDetails.Tab.versions.title=Sanal makine sürümleri ImageDetails.Tab.permissions.title=EriÅŸim izinleri -ImageDetails.Label.ImageName.text=Görüntü adı -ImageDetails.Label.ContainerRunOptions.text=Container baÅŸlatma seçenekleri # ImageListWindowLayout ImageList.Label.title.text=Sanal makineler genel görünümü diff --git a/dozentenmodul/src/main/properties/i18n/window_tr_TR.properties b/dozentenmodul/src/main/properties/i18n/window_tr_TR.properties index 1d5e2f93..8d22cf05 100644 --- a/dozentenmodul/src/main/properties/i18n/window_tr_TR.properties +++ b/dozentenmodul/src/main/properties/i18n/window_tr_TR.properties @@ -53,9 +53,6 @@ ImageDetails.Message.error.performImageDownload=Seçilen sürüm geçersiz ImageDetails.Message.error.extendVersionExpiry={0} sürümünün geçerlilik tarihi uzatılamadı. ImageDetails.Message.info.extendVersionExpiry=BaÅŸarılı bir ÅŸekilde uzatılmış olan imajlar: {0} ImageDetails.Message.yesNo.safeClose=DeÄŸiÅŸiklikler iptal edilecek, gerçekten kapatmak istiyor musunuz? -ImageDetails.Constraint.NoEmptyDockerfile.text=Dockerfile boÅŸ bırakılamaz! -ImageDetails.Constraint.NoEmptyName.text=Görüntü adı boÅŸ bırakılamaz! -ImageDetails.Constraint.NoEmptyRunOptions.text=Container baÅŸlatma seçenekleri girilmedi! # ImageListWindow ImageList.MenuItem.newLecture.text=Yeni etkinlik |