diff options
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java')
-rw-r--r-- | dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java | 260 |
1 files changed, 260 insertions, 0 deletions
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 new file mode 100644 index 00000000..874a2435 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java @@ -0,0 +1,260 @@ +package org.openslx.dozmod.gui.wizard.page; + +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.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.ContainerBuildContextMethod; +import org.openslx.dozmod.model.ContainerDefinition; +import org.openslx.dozmod.model.ContainerMeta; +import org.openslx.dozmod.state.UploadWizardState; +import org.openslx.dozmod.thrift.cache.MetaDataCache; +import org.openslx.util.vm.DockerMetaDataDummy; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.filechooser.FileFilter; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ContainerUploadPage extends ContainerUploadPageLayout { + + // TODO: Add a Instruction for the new Container-Feature in bwLehrpool. + // TODO: Add link to instructions for Docker-Intetragtion at https://www.bwlehrpool.de/doku.php + + 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) { + super(wizard); + this.containerDefinition = containerDefinition; + this.state = state; + + canComeBack = false; + existingImage = null; + + // HACK set dummy os + state.selectedOs = MetaDataCache.getOsById(18); + + 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. + public ContainerUploadPage(Wizard wizard, UploadWizardState uploadWizardState, + ImageDetailsRead imageDetailsRead) { + super(wizard); + + state = uploadWizardState; + existingImage = imageDetailsRead; + + // TODO fix this! + containerDefinition = null; + + lblImageName.setEnabled(existingImage == null); + txtImageName.setEnabled(existingImage == null); + txtInfoText.setVisible(existingImage == null); + + state.name = imageDetailsRead.imageName; + state.defaultPermissions = imageDetailsRead.getDefaultPermissions(); + state.description = imageDetailsRead.getDescription(); + state.detectedOs = MetaDataCache.getOsById(imageDetailsRead.getOsId()); + state.selectedOs = MetaDataCache.getOsById(imageDetailsRead.getOsId()); + state.tags = imageDetailsRead.getTags(); + state.defaultPermissions = imageDetailsRead.getUserPermissions(); + + state.uuid = imageDetailsRead.getImageBaseId(); + init(); + } + + private void init() { + this.txtImageFile.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + browseFile(); + } + }); + this.btnBrowseForImage.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + browseFile(); + } + }); + + txtImageName.getDocument().addDocumentListener(new TextChangeListener() { + @Override public void changed() { + reactOnUserInput(); + } + }); + txtContainerRun.getDocument().addDocumentListener(new TextChangeListener() { + @Override public void changed() { + reactOnUserInput(); + } + }); + + tpInput.addChangeListener(new ChangeListener() { + @Override public void stateChanged(ChangeEvent e) { + reactOnUserInput(); + } + }); + + txtGitRepo.getDocument().addDocumentListener(new TextChangeListener() { + @Override public void changed() { + reactOnUserInput(); + } + }); + + btnBrowseForImage.requestFocus(); + } + + private void browseFile() { + + QFileChooser fc = new QFileChooser(Config.getUploadPath(), false); + fc.setAcceptAllFileFilterUsed(false); + fc.addChoosableFileFilter(new DockerfileFilter()); + + int action = fc.showOpenDialog(getDialog()); + File file = fc.getSelectedFile(); + + if (action != JFileChooser.APPROVE_OPTION || file == null) + return; + + txtImageFile.setText(file.getAbsolutePath()); + + if (existingImage == null) + txtImageName.setText(file.getParentFile().getName()); + else + 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()) { + LOGGER.info("Upload also an created Image"); + state.diskFile = imageTarFile; + } else { + state.diskFile = getDummyFile(); + } + + Config.setUploadPath(file.getParent()); + reactOnUserInput(); + } + + private File getDummyFile() { + String configDir = Config.getPath(); + File zeroFile = new File(configDir, "ZERO-FILE"); + // create a temp file with dummy content, + // because vmchooser relies on an existing image after choosing a lecture. + // TODO change behavior in vmchooser to allow start lectures without images. + try { + if (!zeroFile.exists()) { + zeroFile.createNewFile(); + FileUtils.writeStringToFile(zeroFile, "ZERO\n", "UTF-8"); + } + } catch (IOException e) { + e.printStackTrace(); + LOGGER.error("Could not create a dummy file.", e); + } + LOGGER.info("Use dummy file"); + return zeroFile; + } + + private void reactOnUserInput() { + boolean completed = checkUserInput(); + if (completed) + setDescription("Container definition finished"); + setPageComplete(completed); + } + + private boolean checkUserInput() { + ContainerBuildContextMethod method = getBuildContextMethod(); + + switch (method) { + case FILE: + if (txtImageFile.getText() == null || txtImageFile.getText().isEmpty()) { + setWarningMessage("No Container Recipe provided!"); + return false; + } + break; + case GIT_REPOSITORY: + if (txtGitRepo.getText() == null || txtGitRepo.getText().isEmpty()) { + setWarningMessage("No Git Repository provided!"); + return false; + } + break; + } + + if (txtImageName.getText() == null || txtImageName.getText().isEmpty()) { + setWarningMessage("Set proper Image Name"); + return false; + } + + if (txtContainerRun.getText() == null || txtContainerRun.getText().isEmpty()) { + setWarningMessage("set container run options"); + return false; + } + return true; + } + + private DockerMetaDataDummy createVmMeta() { + + ContainerMeta containerMeta = containerDefinition.getContainerMeta(); + containerMeta.setBuildContextMethod(getBuildContextMethod().ordinal()); + containerMeta.setImageName(txtImageName.getText()); + containerMeta.setRunOptions(txtContainerRun.getText()); + 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(); + } + + @Override protected boolean wantNextOrFinish() { + state.name = existingImage != null ? existingImage.getImageName() : txtImageName.getText(); + state.meta = createVmMeta(); + + 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()); + + boolean accept = false; + if (f.isFile() && m.matches()) + accept = true; + return accept; + } + + @Override public String getDescription() { + return "Dockerfile"; + } + } +} |