summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ContainerUploadPage.java
blob: 874a2435ee978a8f2c96771e2f1e18b10f2a97fa (plain) (tree)
1
2
3
4
5
6
7
8
9

                                           
                                       
                               
                                                      
                                 

                                                        
                                            
                                                                      
                                                            
                                                    
                                              
                                                  
                                                     
                                               

                     

                                        
                                          



                                     

                               
 
                                                                    
 


                                                                                                       
                                                                                  






                                              
                                                     
                                                              
 

                                                                                
                              

                                                               
 
                                    

                                     

                                                               
 


                       

                                                                                                 
                                                                                      
                                                            

                              

                                                 
 


                                           


                                                               
 






                                                                                       
 
                                                               



                             










                                                                               

                                                                                         





                                                                                            

                         
 











                                                                                       
                                                 







                                                                                  






                                                                          




                                                                             

                                             

                                                                         

                                                                                             


                                                                    
                                                        

                 
                                                       
                                   

         

















                                                                                            
 




                                                                        

         
                                          
                                                                             














                                                                                                 
 
                                                                                         
                                                                   
                                     

                 
                                                                                               
                                                                       
                                     
                 

                            
 

                                                    
                                                                                     


                                                                                       
                                                                      
                          
                                                                                      


                                                                               



                                                               
                                                          

         
                                                        
                                                                                                           
                                            
 
                            
         
 



                                                                  






                                                                     






                                                          
 
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";
		}
	}
}