diff options
Diffstat (limited to 'dozentenmodul/src')
17 files changed, 471 insertions, 205 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java index 1cb861ee..42a50418 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/panel/ContainerPanel.java @@ -26,7 +26,7 @@ public class ContainerPanel extends JPanel { */ private static final long serialVersionUID = -3335320345960410582L; - // TODO Set the height of txtContainerRecipe to a proper Value + // TODO Set the height of txtContainerRecipe to a proper Value public static final String IMAGE_CONTEXT = "IMAGE"; public static final String CONTAINER_CONTEXT = "CONTAINER"; @@ -53,19 +53,15 @@ public class ContainerPanel extends JPanel { pnlContainerMeta = new JPanel(); GridManager grdContainerMeta = new GridManager(pnlContainerMeta, 3); - QLabel lblContainerRunOpt = new QLabel( - I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.label")); - lblContainerRunOpt.setToolTipText( - I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.tooltip")); + QLabel lblContainerRunOpt = new QLabel(I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.label")); + lblContainerRunOpt.setToolTipText(I18n.PANEL.getString("ContainerPanel.ContainerStartOptions.tooltip")); txtContainerRun = new JTextField(); grdContainerMeta.add(lblContainerRunOpt); grdContainerMeta.add(txtContainerRun, 2).fill(true, false).expand(true, false); grdContainerMeta.nextRow(); - QLabel lblContainerRunCommand = new QLabel( - I18n.PANEL.getString("ContainerPanel.ContainerRunCommand.label")); - lblContainerRunCommand.setToolTipText( - I18n.PANEL.getString("ContainerPanel.ContainerRunCommand.tooltip")); + QLabel lblContainerRunCommand = new QLabel(I18n.PANEL.getString("ContainerPanel.ContainerRunCommand.label")); + lblContainerRunCommand.setToolTipText(I18n.PANEL.getString("ContainerPanel.ContainerRunCommand.tooltip")); txtContainerRunCommand = new JTextField(); grdContainerMeta.add(lblContainerRunCommand); grdContainerMeta.add(txtContainerRunCommand, 2).fill(true, false).expand(true, false); @@ -77,8 +73,7 @@ public class ContainerPanel extends JPanel { GridManager grdContainer = new GridManager(this, 2, false, new Insets(8, 2, 8, 2)); - QLabel lblContainerImageName = new QLabel( - I18n.PANEL.getString("ContainerPanel.Label.ImageName.text")); + QLabel 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); @@ -90,8 +85,7 @@ public class ContainerPanel extends JPanel { scrollableTextArea.setPreferredSize(Gui.getScaledDimension(0, 200)); grdContainer.add(scrollableTextArea, 2).fill(true, true).expand(true, true); - lblContainerImageType = new QLabel( - I18n.PANEL.getString("ContainerPanel.Label.ContainerImageType.text")); + lblContainerImageType = new QLabel(I18n.PANEL.getString("ContainerPanel.Label.ContainerImageType.text")); cboContainerImageType = ContainerPanel.createContainerImageTypeCBO(); grdContainer.add(lblContainerImageType); grdContainer.add(cboContainerImageType).fill(true, false).expand(true, false); @@ -102,39 +96,44 @@ public class ContainerPanel extends JPanel { } /** - * Retrieves Container specific details for the currently displayed lecture and disables gui elements for - * the specific context. + * 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 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()); + 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); + 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 or useless - switch (containerDefinition.getBuildContextMethod()) { - case FILE: + switch (containerDefinition.getContainerImageContext()) { + case DOCKERFILE: txtContainerRecipe.setText(containerDefinition.getContainerRecipe()); break; - case IMAGE_REPO: + case IMAGE_REPOSITORY: txtContainerRecipe.setText(containerDefinition.getContainerMeta().getImageRepo()); break; case GIT_REPOSITORY: txtContainerRecipe.setText(containerDefinition.getContainerMeta().getBuildContextUrl()); break; + case DOCKER_ARCHIVE: + txtContainerRecipe.setText(containerDefinition.getContainerMeta().getImageName()); + break; default: LOGGER.error("Unknown Build Context"); break; @@ -153,17 +152,22 @@ public class ContainerPanel extends JPanel { private void initImageDetails() { + // TODO currently no support for different containerImageType + lblContainerImageType.setVisible(false); + cboContainerImageType.setEditable(false); + cboContainerImageType.setVisible(false); + cboContainerImageType.setSelectedItem(containerDefinition.getContainerMeta().getImageType()); if (containerDefinition.getContainerMeta().getImageType() == ContainerMeta.ContainerImageType.DATA) { - // do not allowed to change type if it is data + // do not allow changing type if it is data cboContainerImageType.setEnabled(false); - } - else { - // do not allow to switch type to data after creation + } else { + // do not allow switching type to data after creation cboContainerImageType.removeItem(ContainerMeta.ContainerImageType.DATA); } - // currently do not allow user to change the Image Repository or Dockerfile in the suite. + // currently, do not allow user to change the Image Repository or Dockerfile in + // the suite. txtContainerRecipe.setEnabled(false); // do not show container specific input options @@ -184,9 +188,8 @@ public class ContainerPanel extends JPanel { public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { if (isFirstTime) { - changeMonitor.add(txtContainerRecipe) - .addConstraint(new DialogChangeMonitor.TextNotEmptyConstraint( - I18n.PANEL.getString("ContainerPanel.Constraint.NoEmptyDockerfile.text"))); + changeMonitor.add(txtContainerRecipe).addConstraint(new DialogChangeMonitor.TextNotEmptyConstraint( + I18n.PANEL.getString("ContainerPanel.Constraint.NoEmptyDockerfile.text"))); changeMonitor.add(txtContainerRun); changeMonitor.add(txtContainerRunCommand); changeMonitor.add(bindMountConfigurator); @@ -200,7 +203,8 @@ public class ContainerPanel extends JPanel { * * @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. + * @return Returns true uf upload successfully finished, false if error + * occurred. */ public boolean saveChanges(String satelliteToken, ImageDetailsRead image) { @@ -216,9 +220,8 @@ public class ContainerPanel extends JPanel { if (!newConDev.equals(containerDefinition)) { LOGGER.info("Update Container Definition"); try { - ThriftManager.getSatClient() - .setImageVersionVirtConfig(satelliteToken, image.getLatestVersionId(), - newConDev.toByteBuffer()); + ThriftManager.getSatClient().setImageVersionVirtConfig(satelliteToken, image.getLatestVersionId(), + newConDev.toByteBuffer()); } catch (TException e) { LOGGER.error("Upload new ContainerDefinition failed", e); return false; @@ -227,17 +230,18 @@ public class ContainerPanel extends JPanel { return true; } - public static ComboBox<ContainerMeta.ContainerImageType> createContainerImageTypeCBO (){ + public static ComboBox<ContainerMeta.ContainerImageType> createContainerImageTypeCBO() { ComboBox<ContainerMeta.ContainerImageType> cbo = new ComboBox<>( new ComboBox.ComboBoxRenderer<ContainerMeta.ContainerImageType>() { - @Override public String renderItem(ContainerMeta.ContainerImageType item) { - switch (item){ + @Override + public String renderItem(ContainerMeta.ContainerImageType item) { + switch (item) { case LECTURE: return "Pool"; case BATCH: return "Pool/Cluster"; case DATA: - return "Daten"; + return I18n.PANEL.getString("ContainerPanel.ContainerImageType.Item.label"); default: return ""; } @@ -250,4 +254,3 @@ public class ContainerPanel extends JPanel { return cbo; } } - 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 3fc632b8..8d31798f 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 @@ -827,7 +827,6 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout 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/wizard/ImageCreationWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java index 33ed8800..885e40f7 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 @@ -108,6 +108,7 @@ public class ImageCreationWizard extends Wizard implements UiFeedback, QuitNotif @Override public boolean wantFinish() { + // TODO copy/paste from ContainerUploadPage.wantNextOrFinish() // In order for settings for a container to be recorded in the ImageMetaDataPage for the ContainerDefinition, // the UploadInitiator was only allowed to be created here. // TODO maybe also for VM-Images this is suitable 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 b0201e47..2bc4c768 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 @@ -5,7 +5,7 @@ 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; -import org.openslx.virtualization.configuration.container.ContainerBuildContextMethod; +import org.openslx.virtualization.configuration.container.ContainerImageContext; import javax.swing.*; import java.awt.*; @@ -29,7 +29,8 @@ public class ContainerUploadPageLayout extends WizardPage { protected final JTabbedPane tpInput; protected final JTextField txtGitRepo; - protected final JTextField txtContainerImageFile; + protected final JTextField txtImageTar; + protected final JButton btnBrowseImageTar; /** * Constructor to define the Layout @@ -39,75 +40,97 @@ public class ContainerUploadPageLayout extends WizardPage { super(wizard, I18n.PAGE_LAYOUT.getString("ContainerUploadPage.title")); setDescription(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.description")); GridManager grid = new GridManager(this, 3, false); + GridManager tmpGrid; - JPanel imageRepoPanel = new JPanel(); - imageRepoPanel.setVisible(true); - GridManager tmpGrid = new GridManager(imageRepoPanel, 2, true, new Insets(0, 5, 0, 5)); - QLabel lblImageRepo = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepo.label")); - lblImageRepo.setToolTipText( - I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); - txtImageRepo = new JTextField(); - txtImageRepo.setEditable(true); - txtImageRepo.setToolTipText( - I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); - tmpGrid.add(lblImageRepo); - tmpGrid.add(txtImageRepo).fill(true, false).expand(true, false); - tmpGrid.finish(false); - - JPanel p1 = new JPanel(); - p1.setVisible(false); - GridManager g1 = new GridManager(p1, 3, true, new Insets(0, 5, 0, 5)); + // #################################### + // Dockerfile Input Panel -- UNUSED -- + JPanel pnlDockerfileInput = new ContainerTabPanel(ContainerImageContext.DOCKERFILE); + pnlDockerfileInput.setVisible(false); + tmpGrid = new GridManager(pnlDockerfileInput, 3, true, new Insets(0, 5, 0, 5)); 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")); btnBrowseForImage.setMnemonic(KeyEvent.VK_B); - g1.add(imageFileCaption); - g1.add(txtImageFile).fill(true, false).expand(true, false); - g1.add(btnBrowseForImage); - g1.finish(false); - - JPanel p2 = new JPanel(); - p2.setVisible(false); - GridManager g2 = new GridManager(p2, 2, true, new Insets(0, 5, 0, 5)); + tmpGrid.add(imageFileCaption); + tmpGrid.add(txtImageFile).fill(true, false).expand(true, false); + tmpGrid.add(btnBrowseForImage); + tmpGrid.finish(false); + + // #################################### + // Git Repository Input Panel -- UNUSED -- + JPanel pnlGitRepositoryInput = new ContainerTabPanel(ContainerImageContext.GIT_REPOSITORY); + pnlGitRepositoryInput.setVisible(false); + tmpGrid = new GridManager(pnlGitRepositoryInput, 2, true, new Insets(0, 5, 0, 5)); QLabel lblGitRepo = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.label")); lblGitRepo.setToolTipText( I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.toolTipText")); txtGitRepo = new JTextField(); txtGitRepo.setToolTipText( I18n.PAGE_LAYOUT.getString("ContainerUploadPage.GitRepository.toolTipText")); - g2.add(lblGitRepo); - g2.add(txtGitRepo).fill(true, false).expand(true, false); - g2.finish(false); + tmpGrid.add(lblGitRepo); + tmpGrid.add(txtGitRepo).fill(true, false).expand(true, false); + tmpGrid.finish(false); + + // #################################### + // Container Archive Input Panel + JPanel pnlContainerImage = new ContainerTabPanel(ContainerImageContext.DOCKER_ARCHIVE); + pnlGitRepositoryInput.setVisible(false); + tmpGrid = new GridManager(pnlContainerImage, 3, true, new Insets(0, 5, 0, 5)); + + QLabel lblImageTarFile = new QLabel( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.label")); + lblImageTarFile.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.ToolTipText")); + + txtImageTar = new JTextField(); + txtImageTar.setEnabled(false); + btnBrowseImageTar = new JButton(I18n.PAGE_LAYOUT.getString("ImageUpload.Button.browseForImage.text")); + btnBrowseImageTar.setMnemonic(KeyEvent.VK_B); + tmpGrid.add(lblImageTarFile); + tmpGrid.add(txtImageTar).fill(true, false).expand(true, false); + tmpGrid.add(btnBrowseImageTar); + tmpGrid.finish(false); + // #################################### + // Image Repository Input Panel + JPanel pnlImageRepo = new ContainerTabPanel(ContainerImageContext.IMAGE_REPOSITORY); + pnlImageRepo.setVisible(true); + tmpGrid = new GridManager(pnlImageRepo, 2, true, new Insets(0, 5, 0, 5)); + QLabel lblImageRepo = new QLabel(I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepo.label")); + lblImageRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); + txtImageRepo = new JTextField(); + txtImageRepo.setEditable(true); + txtImageRepo.setToolTipText( + I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ImageRepository.ToolTipText")); + tmpGrid.add(lblImageRepo); + tmpGrid.add(txtImageRepo).fill(true, false).expand(true, false); + tmpGrid.finish(false); + + // #################################### + // Tabbed Input Pane tpInput = new JTabbedPane(); - tpInput.addTab("Dockerfile", p1); - tpInput.addTab("Git-Repository", p2); - tpInput.addTab("Image-Repository", imageRepoPanel); + // TODO we need first a proper backend in bwlp-sat to build container + //tpInput.addTab("Dockerfile", pnlDockerfileInput); + //tpInput.addTab("Git-Repository", pnlGitRepositoryInput); + tpInput.addTab("Docker-Archive", pnlContainerImage); + tpInput.addTab("Image-Repository", pnlImageRepo); tpInput.setSelectedIndex(0); - grid.add(tpInput, 3).fill(true, false); grid.nextRow(); + // #################################### + // Image Name 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(); - QLabel lblContainerImageFile = new QLabel( - I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.label")); - lblContainerImageFile.setToolTipText( - I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.ToolTipText")); - txtContainerImageFile = new JTextField(); - txtContainerImageFile.setEnabled(false); - txtContainerImageFile.setToolTipText( - I18n.PAGE_LAYOUT.getString("ContainerUploadPage.ContainerImageFile.ToolTipText")); - grid.add(lblContainerImageFile); - grid.add(txtContainerImageFile, 2).fill(true, false).expand(true, false); - grid.nextRow(); - + // #################################### + // Info Box grid.add(Box.createVerticalGlue(), 3).expand(true, true); txtInfoText = new JTextArea(); txtInfoText.setBorder(BorderFactory.createTitledBorder( @@ -125,7 +148,15 @@ public class ContainerUploadPageLayout extends WizardPage { grid.finish(true); } - protected ContainerBuildContextMethod getBuildContextMethod() { - return ContainerBuildContextMethod.fromInt(tpInput.getSelectedIndex()); + protected ContainerImageContext getCurrentContext() { + return ((ContainerTabPanel) tpInput.getSelectedComponent()).containerImageContext; + } + + static class ContainerTabPanel extends JPanel { + public final ContainerImageContext containerImageContext; + + ContainerTabPanel(ContainerImageContext imageContext) { + this.containerImageContext = imageContext; + } } } 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 8999e880..d858882a 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 @@ -15,8 +15,9 @@ public abstract class ImageTypePageLayout extends WizardPage { private static final long serialVersionUID = 2548125409461846482L; protected final JTextArea txtInfoText; - protected final JButton btnNewVmImage; - protected final JButton btnNewDockerImage; + protected final JRadioButton rbtnNewVmImage; + protected final JRadioButton rbtnNewDockerImage; + protected final ButtonGroup btgrpImageTyp; /** * Page to choose between new VM-Image or Docker Image @@ -40,12 +41,14 @@ public abstract class ImageTypePageLayout extends WizardPage { grid.nextRow(); grid.nextRow(); - // -- New VM Pick-- - 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(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.button.newDocker")); - grid.add(btnNewDockerImage, 2, 2).fill(true, true).expand(true, true); + rbtnNewVmImage = new JRadioButton(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.button.newVM")); + grid.add(rbtnNewVmImage, 2, 2).fill(true, true).expand(true, true); + rbtnNewDockerImage = new JRadioButton(I18n.PAGE_LAYOUT.getString("ImageTypePageLayout.button.newDocker")); + grid.add(rbtnNewDockerImage, 2, 2).fill(true, true).expand(true, true); + + btgrpImageTyp = new ButtonGroup(); + btgrpImageTyp.add(rbtnNewVmImage); + btgrpImageTyp.add(rbtnNewDockerImage); 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 b21564a6..283019b6 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,18 +4,19 @@ 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; import org.openslx.dozmod.gui.wizard.layout.ContainerUploadPageLayout; import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.state.UploadWizardState; -import org.openslx.dozmod.thrift.ThriftActions; +import org.openslx.dozmod.thrift.*; import org.openslx.dozmod.thrift.cache.MetaDataCache; +import org.openslx.dozmod.util.ContainerUtils; import org.openslx.virtualization.configuration.VirtualizationConfigurationDocker; -import org.openslx.virtualization.configuration.container.ContainerBuildContextMethod; -import org.openslx.virtualization.configuration.container.ContainerMeta; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -23,10 +24,9 @@ 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.nio.ByteBuffer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -65,8 +65,7 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { init(); } - // TODO this constructor is currently used in case if user wants do upload a new version. - // This makes no currently no sens in context of docker container and this is used. + // This constructor is used in case the user wants do upload a new version. public ContainerUploadPage(Wizard wizard, UploadWizardState uploadWizardState, ImageDetailsRead imageDetailsRead) { super(wizard); @@ -74,13 +73,16 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { state = uploadWizardState; existingImage = imageDetailsRead; - // TODO fix this! - containerDefinition = null; + containerDefinition = ContainerUtils.getContainerDefinition( + Session.getSatelliteToken(), + imageDetailsRead.getLatestVersionId()); lblImageName.setEnabled(existingImage == null); txtImageName.setEnabled(existingImage == null); + txtImageName.setText(existingImage.getImageName()); txtInfoText.setVisible(existingImage == null); + state.name = imageDetailsRead.imageName; state.defaultPermissions = imageDetailsRead.getDefaultPermissions(); state.description = imageDetailsRead.getDescription(); @@ -129,45 +131,37 @@ 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) { - + this.btnBrowseImageTar.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + browseImageTarFile(); } + }); - @Override public void mouseExited(MouseEvent e) { - + this.txtImageTar.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + browseImageTarFile(); } }); btnBrowseForImage.requestFocus(); } - private void browseContainerImageFile() { + private void browseImageTarFile() { 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(""); + + if (action != JFileChooser.APPROVE_OPTION || file == null || !ContainerUtils.isValidTar(file)) { + txtImageTar.setText(""); return; } - txtContainerImageFile.setText(file.getAbsolutePath()); + txtImageTar.setText(file.getAbsolutePath()); + Config.setUploadPath(file.getParent()); + reactOnUserInput(); LOGGER.info("Tar File selected"); } @@ -191,13 +185,6 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { txtImageName.setText(existingImage.getImageName()); state.descriptionFile = file; - // TESTING: Upload also a prematurely created image (tar) - String imageName = file.getParentFile().getName(); - File imageTarFile = new File(file.getParentFile(), imageName.concat(".tar")); - if (imageTarFile.exists()) { - txtContainerImageFile.setText(imageTarFile.getAbsolutePath()); - LOGGER.info("Prebuild Container Image found"); - } Config.setUploadPath(file.getParent()); reactOnUserInput(); @@ -230,21 +217,20 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { } private boolean checkUserInput() { - ContainerBuildContextMethod method = getBuildContextMethod(); - switch (method) { - case IMAGE_REPO: + switch (getCurrentContext()) { + case IMAGE_REPOSITORY: if (txtImageRepo.getText() == null || txtImageRepo.getText().isEmpty()) { setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoImageRepo")); return false; } break; - case FILE: + case DOCKERFILE: if (txtImageFile.getText() == null || txtImageFile.getText().isEmpty()) { setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoReceipt")); return false; } - if (! ContainerDefinition.isValidDockerfile(txtImageFile.getText())) { + if (!ContainerDefinition.isValidDockerfile(txtImageFile.getText())) { setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoValidDockerfiler")); return false; } @@ -255,6 +241,16 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { return false; } break; + case DOCKER_ARCHIVE: + if (txtImageTar.getText() == null || txtImageTar.getText().isEmpty()) { + setWarningMessage(I18n.PAGE.getString("ContainerUploadPage.Warning.NoDockerArchive")); + return false; + } + break; + + default: + // The case is not provided + return false; } if (txtImageName.getText() == null || txtImageName.getText().isEmpty()) { @@ -266,27 +262,26 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { private VirtualizationConfigurationDocker createVirtualizationConfig() { - ContainerMeta containerMeta = containerDefinition.getContainerMeta(); - containerMeta.setBuildContextMethod(getBuildContextMethod().ordinal()); - containerMeta.setImageName(txtImageName.getText()); + containerDefinition.getContainerMeta().setContainerImageContext(getCurrentContext().ordinal()); + containerDefinition.getContainerMeta().setImageName(txtImageName.getText()); - File containerImageFile = new File(txtContainerImageFile.getText()); - if (containerImageFile.exists()) - state.diskFile = containerImageFile; - else - state.diskFile = getDummyFile(); - - switch (containerDefinition.getBuildContextMethod()) { - case FILE: + switch (containerDefinition.getContainerImageContext()) { + case DOCKERFILE: containerDefinition.setContainerRecipe(state.descriptionFile); + state.diskFile = getDummyFile(); break; - case IMAGE_REPO: - containerMeta.setImageRepo(txtImageRepo.getText()); + case IMAGE_REPOSITORY: + containerDefinition.getContainerMeta().setImageRepo(txtImageRepo.getText()); + state.diskFile = getDummyFile(); state.descriptionFile = getDummyFile(); case GIT_REPOSITORY: - containerMeta.setBuildContextUrl(txtGitRepo.getText()); + containerDefinition.getContainerMeta().setBuildContextUrl(txtGitRepo.getText()); + state.diskFile = getDummyFile(); state.descriptionFile = getDummyFile(); break; + case DOCKER_ARCHIVE: + state.diskFile = new File(txtImageTar.getText()); + state.descriptionFile = getDummyFile(); } return containerDefinition.createVirtualizationConfig(); } @@ -321,6 +316,29 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { state.uuid = existingImage.getImageBaseId(); state.name = existingImage.getImageName(); } + + // TODO copy/paste from ImageCreationWizard.wantFinish() + // Do this only if the user wants to upload a new image version! + if (existingImage != null) { + // 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, + ByteBuffer.wrap(state.virtualizationConfig.getConfigurationAsByteArray())); + } 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; } @@ -331,10 +349,7 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { Pattern p = Pattern.compile("[Dd]ockerfile"); Matcher m = p.matcher(f.getName()); - boolean accept = false; - if ((f.isFile() && m.matches()) || f.isDirectory()) - accept = true; - return accept; + return (f.isFile() && m.matches()) || f.isDirectory(); } @Override public String getDescription() { @@ -346,10 +361,7 @@ public class ContainerUploadPage extends ContainerUploadPageLayout { @Override public boolean accept(File f) { - boolean accept = false; - if ((f.isFile() && f.toString().endsWith(".tar")) || f.isDirectory()) - accept = true; - return accept; + return (f.isFile() && f.toString().endsWith(".tar")) || f.isDirectory(); } @Override public String getDescription() { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageTypePage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageTypePage.java index cd80a41e..d839559e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageTypePage.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageTypePage.java @@ -16,25 +16,25 @@ public class ImageTypePage extends ImageTypePageLayout { public ImageTypePage(final ImageCreationWizard wizard) { super(wizard); - btnNewVmImage.addActionListener(new ActionListener() { + rbtnNewVmImage.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + setPageComplete(false); wizard.doVmCreation(); setPageComplete(true); - wizard.doNext(); } }); - btnNewDockerImage.addActionListener(new ActionListener() { + rbtnNewDockerImage.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + setPageComplete(false); wizard.doDockerCreation(); setPageComplete(true); - wizard.doNext(); } }); } @Override protected void onPageEnter() { - // set onPageEnter to disable Next and Finish button - setPageComplete(false); + if(btgrpImageTyp.getSelection() == null) + rbtnNewVmImage.doClick(); } } 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 99d73c23..9724ce61 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/model/ContainerDefinition.java @@ -3,9 +3,9 @@ package org.openslx.dozmod.model; import org.openslx.dozmod.thrift.cache.MetaDataCache; import org.openslx.virtualization.configuration.VirtualizationConfigurationDocker; import org.openslx.virtualization.configuration.VirtualizationConfigurationException; +import org.openslx.virtualization.configuration.container.ContainerMeta; -import java.io.File; -import java.io.FileNotFoundException; +import java.io.*; import java.util.Scanner; public class ContainerDefinition extends @@ -31,6 +31,28 @@ public class ContainerDefinition extends return null; } + private void setContainerMeta(ContainerMeta containerMeta){ + this.containerMeta = containerMeta; + } + + /** + * Masks the fromByteArray Method in org.openslx.virtualization.configuration.container.ContainerDefinition. + * Prevents ClassCastExceptions while casting from parent to child! + * @param rawTarData + * @return + */ + public static ContainerDefinition fromByteArray(byte[] rawTarData) { + + ContainerDefinition conDef = new ContainerDefinition(); + + org.openslx.virtualization.configuration.container.ContainerDefinition pConDef = org.openslx.virtualization.configuration.container.ContainerDefinition.fromByteArray(rawTarData); + + conDef.setContainerRecipe(pConDef.getContainerRecipe()); + conDef.setContainerMeta(pConDef.getContainerMeta()); + + return conDef; + } + public static boolean isValidDockerfile(String dockerfile) { try { File file = new File(dockerfile); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java index 0e5a1d15..3d65ea5d 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerUtils.java @@ -1,15 +1,30 @@ package org.openslx.dozmod.util; +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; import org.apache.log4j.Logger; +import org.apache.thrift.TException; +import org.kamranzafar.jtar.TarEntry; +import org.kamranzafar.jtar.TarHeader; +import org.kamranzafar.jtar.TarInputStream; import org.openslx.bwlp.thrift.iface.ImageSummaryRead; import org.openslx.bwlp.thrift.iface.LectureSummary; import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.dozmod.model.ContainerDefinition; import org.openslx.dozmod.thrift.cache.LectureCache; import org.openslx.thrifthelper.TConst; +import org.openslx.thrifthelper.ThriftManager; +import org.openslx.util.ThriftUtil; +import javax.swing.*; import java.awt.*; +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.List; /** @@ -17,6 +32,7 @@ import java.util.List; */ public class ContainerUtils { + private static final Logger LOGGER = Logger.getLogger(ContainerUtils.class); /** * Checks ImageBaseId of image if already linked with existing Lectures in LectureCache. * @@ -40,4 +56,117 @@ public class ContainerUtils { Gui.showMessageBox(c, I18n.WINDOW.getString("LectureDetails.Message.error.containerLinkedWithLecture"), MessageType.WARNING, logger, null); } + + public static ContainerDefinition getContainerDefinition(String satelliteToken, String latestVersionId) { + byte[] rawVirtConfig = null; + try { + ByteBuffer byteBuffer = ThriftManager.getSatClient() + .getImageVersionVirtConfig(satelliteToken, latestVersionId); + rawVirtConfig = ThriftUtil.unwrapByteBuffer(byteBuffer); + } catch (TException e) { + LOGGER.error("Failed to retrieve virtualizer config for image version " + "'" + + latestVersionId + ", see trace: ", e); + return null; + } + return ContainerDefinition.fromByteArray(rawVirtConfig); + } + + /** + * Check if a provided tar file contains information about a single docker image. + * To check the validity of the file, the existence of two JSON files is checked + * and one of the files must only contain information for one image. + * + * The tar file have to be created by the 'docker save ...' command. + * + * @param tarFile the user selected tar file. + * @return true if the images imageBaseId is already linked with a lecture. + */ + public static boolean isValidTar(File tarFile) { + + boolean isValid = false; + boolean containsManifest = false; + boolean containsRepositories = false; + JsonArray manifestJson = null; + + try { + TarInputStream tis = new TarInputStream(new FileInputStream(tarFile)); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + byte[] rawData = new byte[1024]; + TarEntry entry; + + // setDefaultSkip seems to fasten things up while processing the file, + // because we want only to check manifest.json and repositories file + tis.setDefaultSkip(true); + while ((entry = tis.getNextEntry()) != null) { + if(!TarHeader.USTAR_MAGIC.equals(entry.getHeader().magic.toString())) + break; + Arrays.fill(rawData, (byte) 0); + output.reset(); + int count = 0; + + if (entry.getName().equals("manifest.json")) { + containsManifest = true; + while ((count = tis.read(rawData)) != -1) { + output.write(rawData, 0, count); + } + manifestJson = new JsonParser().parse( + new String(output.toByteArray(), StandardCharsets.UTF_8)).getAsJsonArray(); + } + + if (entry.getName().equals("repositories")) { + containsRepositories = true; + // dont read the file, no checks for the Content + } + + if (containsManifest && containsRepositories) + break; + } + tis.close(); + // check the json files inside the tar file + if (containsManifest && containsRepositories && manifestJson.isJsonArray() + && manifestJson.size() == 1) { + isValid = true; + String repoTag = manifestJson.get(0).getAsJsonObject().get("RepoTags").getAsString(); + LOGGER.info(String.format("Tar File contains Docker Image with repoTag=%s", repoTag)); + } else if (containsManifest && containsRepositories && manifestJson.isJsonArray() + && manifestJson.size() > 1) { + Gui.showMessageBox("Tar File container more then one Images!", MessageType.ERROR, + LOGGER, + null); + } else { + Gui.showMessageBox("No valid Tar File with Images provided!", MessageType.ERROR, + LOGGER, + null); + } + + } catch (IOException e) { + LOGGER.error("IOError while processing tar file", e); + } + return isValid; + } + + public static JPanel createDownloadContainerInfo(String imageRepo, String infoText) { + JPanel pnlUserInfo = new JPanel(); + GridManager grid = new GridManager(pnlUserInfo, 1, true); + + JTextArea txtInfoText = new JTextArea(); + txtInfoText.setBorder(BorderFactory.createTitledBorder( + I18n.PAGE_LAYOUT.getString("Info"))); + txtInfoText.setLineWrap(true); + txtInfoText.setWrapStyleWord(true); + txtInfoText.setEditable(false); + txtInfoText.setFocusable(false); + txtInfoText.setOpaque(false); + txtInfoText.setText(infoText); + grid.add(txtInfoText).fill(true,true); + grid.nextRow(); + + JTextField txtUserInfo = new JTextField(); + txtUserInfo.setText(imageRepo); + grid.add(txtUserInfo).fill(true,true); + grid.finish(true); + + return pnlUserInfo; + } + } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerWrapper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerWrapper.java new file mode 100644 index 00000000..38ca2477 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ContainerWrapper.java @@ -0,0 +1,79 @@ +package org.openslx.dozmod.util; + +import org.apache.log4j.Logger; +import org.openslx.dozmod.gui.Gui; +import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.virtualization.configuration.container.ContainerDefinition; + +import javax.swing.*; +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public class ContainerWrapper { + + private static final Logger LOGGER = Logger.getLogger(ContainerWrapper.class); + + + public static void unwrapContainer(File tmpDiskFile, String imageName, File destDir, + byte[] virtualizerConfig) { + ContainerDefinition conDef = ContainerDefinition.fromByteArray(virtualizerConfig); + try { + switch (conDef.getContainerImageContext()) { + case DOCKERFILE: + conDef.saveLocal(destDir); + showImageMessageInfo(destDir.getPath(), + "Dieses Image wird durch ein Dockerfile gebaut. Wechseln Sie in das Verzeichnis und bauen Sie das Image lokal (docker build)."); + + break; + case GIT_REPOSITORY: + Files.delete(tmpDiskFile.toPath()); + Files.delete(destDir.toPath()); + + showImageMessageInfo(conDef.getContainerMeta().getBuildContextUrl(), + "Dieses Image wird durch ein öffentliches Git-Repository gebaut. Das Image kann mit dem angezeigten Link lokal gebaut werden (docker build), zudem können die Image-Quellen über diesen betrachtet werden."); + break; + case IMAGE_REPOSITORY: + Files.delete(tmpDiskFile.toPath()); + Files.delete(destDir.toPath()); + + showImageMessageInfo( + conDef.getContainerMeta().getImageRepo(), + "Dieses Image ist lediglich eine Referenz auf ein öffentliches Image. Das Image kann mittels des angezeigten Links gepullt werden." + ); + break; + case DOCKER_ARCHIVE: + File destImage = new File(destDir.getAbsolutePath(), + VmWrapper.generateFilename(imageName, "tar")); + if (destImage.exists()) + Files.delete(destImage.toPath()); + Files.move(tmpDiskFile.toPath(),destImage.toPath()); + break; + } + + if (tmpDiskFile.exists()) + Files.delete(tmpDiskFile.toPath()); + } catch (IOException e) { + Gui.asyncMessageBox("Konnte temporäre Download Datei nicht löschen", MessageType.WARNING, + LOGGER, e); + } + } + + private static void showImageMessageInfo(String imageSourceUrl, String infoText) { + Gui.asyncExec(new Runnable() { + @Override public void run() { + Object oldDimension = UIManager.get("OptionPane.minimumSize"); + UIManager.put("OptionPane.minimumSize",new Dimension(400,200)); + JOptionPane.showMessageDialog(null, + ContainerUtils.createDownloadContainerInfo( + imageSourceUrl, + infoText + ), + "Container-Image Info", + JOptionPane.INFORMATION_MESSAGE); + UIManager.put("OptionPane.minimumSize",oldDimension); + } + }); + } +} 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 fe884a15..3c3a5f1c 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/ImageWrapper.java @@ -7,22 +7,16 @@ import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.thrifthelper.TConst; import org.openslx.virtualization.configuration.VirtualizationConfigurationException; -import org.openslx.virtualization.configuration.container.ContainerDefinition; import org.openslx.virtualization.disk.DiskImage; import org.openslx.virtualization.disk.DiskImage.ImageFormat; import org.openslx.virtualization.disk.DiskImageException; 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 { @@ -47,20 +41,10 @@ public class ImageWrapper { boolean imageIsCompressed = false; ImageFormat imageFormat = null; - // unwrap each image individually - // TODO In future maybe this is a check to distinguish between VM-Image and Container Image + // unwrap container image individually if (virtualizerId.equals(TConst.VIRT_DOCKER)) { - ContainerDefinition conDef = ContainerDefinition.fromByteArray(virtualizerConfig); - conDef.saveLocal(destDir); - - 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); - } + ContainerWrapper.unwrapContainer(tmpDiskFile, imageName, destDir, virtualizerConfig); } else { @@ -73,8 +57,9 @@ public class ImageWrapper { } if (imageIsCompressed && imageFormat != ImageFormat.QCOW2) { - Gui.asyncMessageBox(I18n.THRIFT.getString("ThriftActions.Message.warning.diskImageCompressed", - imageName, Branding.getServiceFAQWebsite()), 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)); destImage.delete(); diff --git a/dozentenmodul/src/main/properties/i18n/page.properties b/dozentenmodul/src/main/properties/i18n/page.properties index eef4b242..1c096ad5 100644 --- a/dozentenmodul/src/main/properties/i18n/page.properties +++ b/dozentenmodul/src/main/properties/i18n/page.properties @@ -73,6 +73,7 @@ ContainerUploadPage.Warning.NoImageRepo=No Image Repository provided ContainerUploadPage.Warning.NoReceipt=No Container Recipe provided! ContainerUploadPage.Warning.NoValidDockerfiler=No valid Dockerfile provided! ContainerUploadPage.Warning.NoGitRepository=No Git Repository provided! +ContainerUploadPage.Warning.NoDockerArchive=No Docker Archive provided! ContainerUploadPage.Warning.NoProperName=Set proper Image Name ContainerUploadPage.Warning.NoRunOptions=Set container run options diff --git a/dozentenmodul/src/main/properties/i18n/page_de_DE.properties b/dozentenmodul/src/main/properties/i18n/page_de_DE.properties index ba151a9a..8a7efd04 100644 --- a/dozentenmodul/src/main/properties/i18n/page_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/page_de_DE.properties @@ -69,6 +69,7 @@ ContainerUploadPage.Description.ContainerDefFinished=Container Definition vollst ContainerUploadPage.Warning.NoReceipt=Keine Containeranweisungen angegeben! ContainerUploadPage.Warning.NoValidDockerfiler=Kein valides Dockerfile angegeben! ContainerUploadPage.Warning.NoGitRepository=Kein Git Repository angegeben! +ContainerUploadPage.Warning.NoDockerArchive=Kein Docker Archive angegeben! ContainerUploadPage.Warning.NoProperName=Bitte Imagenamen setzen ContainerUploadPage.Warning.NoRunOptions=Bitte Container Start Optionen setzen ContainerUploadPage.Warning.NoImageRepo=Kein Image Repository angegeben diff --git a/dozentenmodul/src/main/properties/i18n/page_layout.properties b/dozentenmodul/src/main/properties/i18n/page_layout.properties index b14eae34..7b2f3b13 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout.properties @@ -65,14 +65,13 @@ ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Set clone address of Git Repository [git@ | http://] [.git]. Currently no Validation Checks! ContainerUploadPage.ImageRepository.ToolTipText=Specify the Container Image by his Repository Name (e.g python:3.7 or tensorflow/tensorflow) ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Contains license restricted software -ContainerUploadPage.ContainerImageFile.label=Pre-build Container Image -ContainerUploadPage.ContainerImageFile.ToolTipText=<html>Optionally attach a tar archive of a container image to the upload.<br>\ -Open dialogue with double click<html> +ContainerUploadPage.ContainerImageFile.label=Container Image +ContainerUploadPage.ContainerImageFile.ToolTipText=<html>Attach a container image archived as tarball<br>\ +For example: docker save IMAGE --output image_name.tar<html> ContainerUploadPage.Infobox.label=Information ContainerUploadPage.Infobox.text=Enter the information necessary for creating a container image here.\n\n\ -Container images are currently built and run on clients. \ -If the build takes too much time, you can optionally add a pre-built \ -container image as a tar archive to the upload (docker save). +It is possible to reference an image directly from a public registry or to add a self-created \ +image to the upload. For more information on creating an image, see the bwLehrpool documentation. # ImageUploadSummaryPageLayout ImageUploadSummary.WizardPage.title=Done! 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 de385d68..4972b451 100644 --- a/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/page_layout_de_DE.properties @@ -64,16 +64,13 @@ ContainerUploadPage.GitRepository.label=Git Repository ContainerUploadPage.GitRepository.toolTipText=Clone Addresse des Git Repositories setzen. [git@ | http://] [.git]. Derzeit keine Validierungsprüfungen! ContainerUploadPage.ImageRepository.ToolTipText=Geben Sie das Container-Image durch seinen Repository-Namen an (z.B. python:3.7 oder tensorflow/tensorflow) ContainerUploadPage.CheckBox.ContainsLicenseRestricted.text=Enthält lizenzpflichtige Software -ContainerUploadPage.ContainerImageFile.label=Vorgebautes Container-Image\ - -ContainerUploadPage.ContainerImageFile.ToolTipText=<html>Fügen Sie dem Upload optional ein ein als tar archiviertes Container-Image an.<br>\ -Öffne Dialog mit Doppelklick<html> +ContainerUploadPage.ContainerImageFile.label=Container-Image +ContainerUploadPage.ContainerImageFile.ToolTipText=<html>Fügen Sie ein archiviertes Container-Image als tar-Datei an.<br>\ +Zum Beispiel: docker save IMAGE --output image_name.tar.<html> ContainerUploadPage.Infobox.label=Hinweis ContainerUploadPage.Infobox.text=Geben Sie hier die zur Erstellung eines Container-Images nötigen Informationen an.\n\n\ -Container-Images werden derzeit auf Clients gebaut und ausgeführt. \ -Sollte der Bau zu viel Zeit benötigen, können Sie optional dem \ -Upload ein vorgebautes Container-Image als tar-Archive hinzufügen\ -(docker save). +Es ist möglich ein Image direkt von einer öffentlichen Registry zu referenzieren oder ein selbsterstelltes \ +Image dem Upload hinzuzufügen. Weiter Informationen zur Erstellung entnehmen Sie der bwLehrpool-Dokumentation. # ImageUploadSummaryPageLayout ImageUploadSummary.WizardPage.title=Fertig! diff --git a/dozentenmodul/src/main/properties/i18n/panel.properties b/dozentenmodul/src/main/properties/i18n/panel.properties index 8770f86f..44fbee3b 100644 --- a/dozentenmodul/src/main/properties/i18n/panel.properties +++ b/dozentenmodul/src/main/properties/i18n/panel.properties @@ -8,3 +8,5 @@ ContainerPanel.ContainerRunCommand.label=Container Run Command ContainerPanel.ContainerRunCommand.tooltip=Specify the programme and arguments for the Docker Run command. ContainerPanel.Label.ContainerImageType.text=Container Image Type + +ContainerPanel.ContainerImageType.Item.label=Data diff --git a/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties b/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties index e3f47cba..9b5b06bb 100644 --- a/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties +++ b/dozentenmodul/src/main/properties/i18n/panel_de_DE.properties @@ -8,3 +8,5 @@ ContainerPanel.ContainerRunCommand.label=Container-Startbefehl ContainerPanel.ContainerRunCommand.tooltip=Geben Sie das Programm und Argumente für docker run an. ContainerPanel.Label.ContainerImageType.text=Container-Image-Typ + +ContainerPanel.ContainerImageType.Item.label=Daten |