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

                                           



                                     
                    
                                     

                           
 
                                
                               

                                                       
                               
                                                      
                                                 
                                   
                                 
                                  
                                                 
                                                  
                                            
                                                                  
                                                  
                                         
                                               


                                                  
                                                     
                                              
                                       
                                     
                                                                 
                                      
                                               
                                          
 


                                  
                           

                                                            
                                                                                     
 
                                        
                                               
                                                      
 
                                                                 



                                                                                                               
 

                                                                                  
                              
                                       
                                         
                                               
                                                   
 

                                                               
                                                              
                                                                                         

                                                                                                     
 
                                   
                                                                          
                                 
                                                                    
                                              
                         
                   
 
                                                                  
                                 

                                                                

                                                      
                   






                                                                                                         
                                                 
         
 
                                    
                                                                                  

                                                     


                                                                       
                                                              
                                                     

                                                             
                                                                              
                                                            
                                                                                         

                                                             
                 
 

                                                            
 
                                                                          
                               
                                                   
         
 
                                            
                                                       

                                         
                     

                                                                                                       
                                         
                                                                                                                        



                                               
 






                                                                                       






                                                                                                                   
                                                                       
                                                                                                                



                                                                                                                      
                                                                                                                     


                                               
 
                                                           
                                                                        
                                                                                                                       



                                               

                                                                                                                               

                                               
                                              
                 
 


                                                                      
                                                                             

                                                                                          
                 







                                                                                                          
                                                                                                         

                                               

                                                                                                           
                                                                                  

                                               
                 
 
                                           
                                                                             
                                                                                                                           
                                                                                                                                                                
                                                                                                                        
                                                                                               



                                               

                                                                                                            
                                                                                                                                                            
                                                                                                                
                                                                                              



                                               

                                                
                                             
 
                                            
                                                                                  
                                                                  
                                                                                        
                                                                                  
                         
                 
                                                               
                                                      
                                                             
                                                        
                                      
                                                                        
                                      

         















                                                                                                                                        
           
                                                                                  
                         

                                                                                    


                                                                                  

                                                                                 
                                                     
           
           

                                              






                                                                                                


                                                                                      
                                                                                                           

                                                 
                                            



                                                                                                                           


                                                                    


                                                                    
                 

                                                                                           









                                                                                                                            
                                             
                         
                 

                                            
                            
 
         
 
package org.openslx.dozmod.gui.wizard.page;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.dozmod.Branding;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.QFileChooser;
import org.openslx.dozmod.gui.wizard.Wizard;
import org.openslx.dozmod.gui.wizard.layout.ImageUploadPageLayout;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.Session;
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.sat.thrift.version.Feature;
import org.openslx.thrifthelper.TConst;
import org.openslx.util.vm.DiskImage;
import org.openslx.util.vm.DiskImage.UnknownImageFormatException;
import org.openslx.util.vm.VmMetaData;
import org.openslx.util.vm.VmMetaData.HardDisk;
import org.openslx.util.vm.VmwareMetaData;

/**
 * Page for uploading a new image.
 */
@SuppressWarnings("serial")
public class ImageUploadPage extends ImageUploadPageLayout {

	private final static Logger LOGGER = Logger.getLogger(ImageUploadPage.class);

	private UploadWizardState state;
	private String lastDetectedName = null;
	private ImageDetailsRead existingImage = null;

	private final FileNameExtensionFilter allSupportedFilter;
	private final FileNameExtensionFilter vmxFilter = new FileNameExtensionFilter("VMware Virtual Machine",
			"vmx");
	private final FileNameExtensionFilter vboxFilter = new FileNameExtensionFilter(
			"VirtualBox Virtual Machine", "vbox");

	public ImageUploadPage(Wizard wizard, UploadWizardState uploadWizardState,
			final ImageDetailsRead existingImage) {
		super(wizard);
		setPageComplete(false);
		this.canComeBack = false;
		this.state = uploadWizardState;
		this.existingImage = existingImage;

		lblImageName.setVisible(existingImage == null);
		txtImageName.setVisible(existingImage == null);
		txtInfoText.setVisible(existingImage == null);
		// show the licensed software checkbox since we are uploading new version
		chkLicenseRestricted.setVisible(existingImage != null);
		chkLicenseRestricted.setSelected(existingImage != null); // TODO selected by default?

		// Browse for *.vmx
		btnBrowseForImage.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				browseForVm();
			}
		});

		txtImageFile.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 1)
					browseForVm();
			}
		});
		// initialize allSupportedFilter depending on whether multiple hypervisors
		// are supported or not
		if (Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) {
			allSupportedFilter = new FileNameExtensionFilter("All Supported", "vmx", "vbox");
		} else {
			allSupportedFilter = new FileNameExtensionFilter("All Supported", "vmx");
		}
		btnBrowseForImage.requestFocus();
	}

	private void browseForVm() {
		QFileChooser fc = new QFileChooser(Config.getUploadPath(), false);
		fc.setAcceptAllFileFilterUsed(false);
		fc.addChoosableFileFilter(vmxFilter);
		if (Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) {
			fc.addChoosableFileFilter(vboxFilter);
		}
		fc.addChoosableFileFilter(allSupportedFilter);
		fc.setFileFilter(allSupportedFilter);
		// differentiate between existing and new VMs
		if (existingImage != null) {
			if (existingImage.virtId.equals(TConst.VIRT_VMWARE)) {
				fc.setFileFilter(vmxFilter);
			} else if (existingImage.virtId.equals(TConst.VIRT_VIRTUALBOX)) {
				fc.setFileFilter(vboxFilter);
			}
		}

		int action = fc.showOpenDialog(getDialog());
		File file = fc.getSelectedFile();

		if (action != JFileChooser.APPROVE_OPTION || file == null)
			return;
		vmSelected(file.getAbsoluteFile());
	}

	private void vmSelected(File file) {
		Config.setUploadPath(file.getParent());
		txtImageFile.setText("");
		txtImageName.setText("");
		try {
			// gets the metadata object of the selected VM depending on its type
			state.meta = VmMetaData.getInstance(MetaDataCache.getOperatingSystems(), file);
		} catch (IOException e) {
			Gui.showMessageBox(this, "Konnte " + file.getPath() + " nicht lesen", MessageType.ERROR, LOGGER,
					e);
			setPageComplete(false);
			return;
		}

		if (state.meta == null || state.meta.getDisplayName() == null) {
			setErrorMessage("Ungültige Konfigurationsdatei ausgewählt!");
			setPageComplete(false);
			return;
		}

		final String fileformat = state.meta.getVirtualizer().virtName;
		// bail if multiple hypervisors are not supported
		if (!(state.meta instanceof VmwareMetaData) && !Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) {
			setErrorMessage("Der Hypervisor der gewählten VM (" + fileformat
					+ ") wird vom aktuellen Satellitenserver nicht unterstützt.");
			setPageComplete(false);
			return;
		}
		// check if the user somehow changed the type of the VM
		if (existingImage != null && !existingImage.virtId.equals(state.meta.getVirtualizer().virtId)) {
			Virtualizer existingImageVirtualizer = MetaDataCache.getVirtualizerById(existingImage.virtId);
			String existingImageVirtualizerName = "<error>";
			if (existingImageVirtualizer != null)
				existingImageVirtualizerName = existingImageVirtualizer.virtName;
			setErrorMessage("Neue Versionen müssen vom Typ " + existingImageVirtualizerName + " sein.");
			setPageComplete(false);
			return;
		}

		List<HardDisk> hdds = state.meta.getHdds();
		if (hdds.size() == 0 || hdds.get(0).diskImage == null) {
			setErrorMessage("Die gewählte " + fileformat + "-Datei enthält keine virtuelle Festplatte!");
			setPageComplete(false);
			return;
		}
		if (hdds.size() > 1) {
			setErrorMessage(
					"Die gewählte " + fileformat + "-Datei enthält mehr als eine virtuelle Festplatte!");
			setPageComplete(false);
			return;
			// Allow to continue!?
		}

		// now check the disk files
		File vmDiskFileInfo = new File(hdds.get(0).diskImage);
		if (!vmDiskFileInfo.isAbsolute()) {
			// it's relative, compose path using the vmx location
			File vmBaseDirectory = file.getParentFile();
			vmDiskFileInfo = new File(vmBaseDirectory, hdds.get(0).diskImage);
		}
		DiskImage diskImage;
		try {
			diskImage = new DiskImage(vmDiskFileInfo);
		} catch (FileNotFoundException e) {
			setErrorMessage("'" + vmDiskFileInfo.getName() + "' kann nicht gefunden werden!");
			setPageComplete(false);
			return;
		} catch (IOException e) {
			setErrorMessage("'" + vmDiskFileInfo.getName() + "' kann nicht gelesen werden!");
			setPageComplete(false);
			return;
		} catch (UnknownImageFormatException e) {
			setErrorMessage("'" + vmDiskFileInfo.getName() + "' hat unbekanntes Dateiformat!");
			LOGGER.debug("Selected disk file has unknown format.", e);
			setPageComplete(false);
			return;
		}

		// Warn user about snapshot
		if (diskImage.isSnapshot || state.meta.isMachineSnapshot()) {
			Gui.showMessageBox("Von der ausgewählten VM wurde ein Snapshot erstellt. In diesem Zustand kann\n"
					+ "die VM leider nicht ins " + Branding.getServiceName() + "-System geladen werden. Bitte konsolidieren Sie zunächst\n"
					+ "den Snapshot und versuchen Sie es erneut.", MessageType.WARNING, null, null);
			setErrorMessage("Die gewählte VM befindet sich im Snapshot-Zustand.");
			setPageComplete(false);
			return;
		}
		if (!diskImage.isStandalone) {
			Gui.showMessageBox("Die zu dieser VM gehörige Virtuelle Festplatte ist im Format '"
					+ diskImage.subFormat + "'.\n"
					+ "Dieses Format wird von " + Branding.getApplicationName() + " nicht unterstützt. Bitte konvertieren Sie die VM\n"
					+ "in das Format 'monolithicSparse'.", MessageType.WARNING, null, null);
			setErrorMessage("Die VMDK Datei der VM hat ein inkompatibles Format");
			setPageComplete(false);
			return;
		}

		// everything seems fine so far
		state.diskFile = vmDiskFileInfo;
		state.descriptionFile = file;

		if (existingImage == null) {
			// User didn't enter a name yet or didn't change it -> set
			String imageName = txtImageName.getText();
			if (imageName.isEmpty() || imageName.equals(lastDetectedName)) {
				txtImageName.setText(state.meta.getDisplayName());
			}
		}
		lastDetectedName = state.meta.getDisplayName();
		state.detectedOs = state.meta.getOs();
		txtImageFile.setText(file.getAbsolutePath());
		// let the user know the upload is ready
		setErrorMessage(null);
		setDescription("Sie können jetzt den Upload starten.");
		setPageComplete(true);
	}

	private boolean askCancelLockFile(String... lockFiles) {
		for (String lockFile : lockFiles) {
			File file = new File(lockFile);
			if (!file.exists())
				continue;
			return !Gui.showMessageBox(this,
					"Die gewählte VM scheint noch in Verwendung zu sein. Bitte fahren Sie die VM\n"
							+ "vor dem Hochladen herunter und schließen Sie den VMware Player, ansonsten\n"
							+ "kann die VM nach dem Hochladen beschädigt sein.\n\n"
							+ "Möchten Sie diese Warnung ignorieren und trotzdem fortfahren?\n"
							+ "(Sie sollten sich sicher sein, was sie tun, wenn Sie hier 'Ja' wählen)",
					MessageType.QUESTION_YESNO, null, null);
		}
		return false;
	}

	/**
	 * This function starts the image creation process. It is triggered by the
	 * "Next" button.
	 * 
	 * 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.
	 * 
	 * 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() {
		// Check for vmware player lock files - warn user if found, might corrupt upload
		if (askCancelLockFile(state.descriptionFile.getAbsolutePath() + ".lck",
				state.diskFile.getAbsolutePath() + ".lck")) {
			setErrorMessage("Die gewählte VM wird noch verwendet");
			return false;
		}

		// 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();

		// -- 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, "Upload-Initialisierung fehlgeschlagen", MessageType.ERROR, LOGGER,
						e);
				return false;
			}
		}
		// Start the hash check now
		state.upload.startHashing();
		return true;

	}
}