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

                                           
                                    
                                                    
                                                       
                                  
                                          
                                                 
                                                      
                                                
                                            
                                                    
                                                  
                                   
                                                                        
                                              
                                              

                                        
                                                                                  
 

                     

                           

                           
 
                                                                                         
 




                                                                          
                                                                                             
 
                                                                        
 

                                                                                          

                                                                  

                                                   


                                                  

                                                                     
           
                                                   
                              
                                                                                                
 

                                                                   
                        

                                       





                                                                 
 
                               

                                                                               
                                                                     

                                                                             


                                                                               







                                                              

                                                                                            




                                                                             
                                                   




                                     
                                              


                                                                   

         
                                                  
                                                                           

         
                                               
 
                                                                              























                                                                                                                                   
                                                                                     

                                                                                          
                              

                                                     
                                                                                                                   
                                                                       
                                     
                 





                                                                                                     
                                                                                                                     
                                             
                         
                                           
                 





                                                                                                             

                                                                                                                                   
                                                                                       
                                                                                                                          



                                                     
                 
 
                                                                       
                                                      

                                                    

                                                                                                   

                                                                 

                                                                                                                                              







                                                                                                
                                                     
                                                                     
         
 

                                           
          
                                                                                 
                    
           

                                        
                                                                 


                                                              
                                                                               


                                                                     
                                                    

                                                                          
                        

                                                                                                           


                                             
                                             

                                                                   
                        

                                                                                                    


                                             
                                               

                                                            
                 

                                                                                     
                                     
                 
                                                         
                                                                      
                                     
                 
                                                       

                                                                     
                 
                                              


                                                                    
                                         


                                                              
                            
         
 

                                                          
                                                                                                    

                                                                                                      
         
 
                                                     

                                              





                                                                                               
                                              

                                              





                                                                                               
                                                       
                                       
                                                                           

                                                                                                   
                                                                        
                                
                                                            
                                                              
                                                                   
                                                                                                              

                                                                                               
                                             
                                                                                                                                      


                                                                                                   
                                 
                           

                                 

         
                                                    
                                          

         
                                               

                           
 
                                                   
                                                            
                                                                                             

                 
 
package org.openslx.dozmod.gui.wizard;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.ImageBaseWrite;
import org.openslx.bwlp.thrift.iface.ImageVersionWrite;
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.QuitNotification;
import org.openslx.dozmod.gui.helper.UiFeedback;
import org.openslx.dozmod.gui.wizard.page.*;
import org.openslx.dozmod.model.ContainerDefinition;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.*;
import org.openslx.dozmod.thrift.UploadInitiator.GotUploadTokenCallback;
import org.openslx.sat.thrift.version.Feature;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
import org.openslx.virtualization.configuration.VirtualizationConfigurationDocker;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class ImageCreationWizard extends Wizard implements UiFeedback, QuitNotification {

	/**
	 * Version for serialization.
	 */
	private static final long serialVersionUID = -353405234601306343L;

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

	private final UploadWizardState state = new UploadWizardState();

	private final ContainerDefinition containerDefinition = new ContainerDefinition();

	private List<WizardPage> currentPages = new ArrayList<>();

	private boolean baseWritten = false;
	private boolean permissionsWritten = false;

	/**
	 * Wizard for creating or editing an image
	 *
	 * @param parent whether to create new or edit existing image
	 */
	public ImageCreationWizard(Window parent) {
		super(parent);
		state.defaultPermissions = Session.getSatelliteConfig().defaultImagePermissions;

		if (Session.hasFeature(Feature.DOCKER_CONTAINER)) {
			addPage(new ImageTypePage(this));
		} else {
			doVmCreation();
		}
	}

	/**
	 * Adding Pages to the Wizard to create a virtual machine
	 */
	public void doVmCreation() {

		cleanCurrent();
		state.imageUploadPage = new ImageUploadPage(this, state, null);
		currentPages.add(state.imageUploadPage);
		currentPages.add(new ImageMetaDataPage(this, state));
		currentPages.add(new ImageCustomPermissionPage(this, state));
		addPages();

		state.conversionPage = new ImageOvfConversionPage(this, state);
		addOutOfOrderPage(state.conversionPage);
	}

	/**
	 * Adding Pages to the Wizard to define a docker image
	 */
	public void doDockerCreation() {
		cleanCurrent();

		currentPages.add(new ContainerUploadPage(this, state, containerDefinition));
		currentPages.add(new ImageMetaDataPage(this, state, containerDefinition));
		currentPages.add(new ImageCustomPermissionPage(this, state));
		addPages();
	}

	private void addPages() {
		for (WizardPage i : currentPages) {
			addPage(i);
		}
	}

	private void cleanCurrent() {
		if (!currentPages.isEmpty()) {
			removePages(currentPages);
			currentPages = new ArrayList<WizardPage>();
		}
	}

	@Override public String getWindowTitle() {
		return I18n.WIZARD.getString("ImageCreation.Wizard.title");
	}

	@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
		if (state.virtualizationConfig instanceof VirtualizationConfigurationDocker) {
			// 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();
		}

		// since we only started the upload and created a "blank" image entry
		// we can here do all the sanity checks on the fields of UploadWizardState
		// and react accordingly.
		// check state
		if (!isStateValid()) {
			// TODO: Show what went wrong
			Gui.showMessageBox(this, I18n.WIZARD.getString("ImageCreation.Message.error.stateInvalid"),
					MessageType.ERROR, null, null);
			return false;
		}
		// push image base to satellite
		if (!baseWritten) {
			try {
				ThriftActions.updateImageBase(state.uuid, imageBaseWriteFromState());
			} catch (TException e) {
				ThriftError.showMessage(null, LOGGER, e,
						I18n.WIZARD.getString("ImageCreation.Message.error.baseNotWritten"));
				return false;
			}
			baseWritten = true;
		}
		// push permissions to satellite if we have custom permissions
		if (!permissionsWritten) {
			if (state.permissionMap != null && !state.permissionMap.isEmpty()) {
				try {
					ThriftActions.writeImagePermissions(state.uuid, state.permissionMap);
				} catch (TException e) {
					Gui.showMessageBox(this,
							I18n.WIZARD.getString("ImageCreation.Message.error.permissionsNotWritten"),
							MessageType.ERROR, null, null);
					ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), state.uuid);
					return false;
				}
			}
			permissionsWritten = true;
		}

		state.upload.startUpload(new GotUploadTokenCallback() {
			@Override public void fire() {
				// push version data
				try {
					ThriftActions.updateImageVersion(state.upload.getToken(),
							new ImageVersionWrite(state.isRestricted));
				} catch (TException e) {
					if (state.isRestricted) {
						Gui.showMessageBox(null,
								I18n.WIZARD.getString("ImageCreation.Message.error.updateImageVersionFailed"),
								MessageType.WARNING, LOGGER, e);
					}
				}
			}
		});
		return true;
	}

	@Override public WizardPage performFinish() {
		return new ImageUploadSummaryPage(this, state, true);
	}

	/**
	 * Checks the validity of the state
	 *
	 * @return true if we have all the needed information in the state, false
	 * otherwise
	 */
	private boolean isStateValid() {
		// debug purposes
		if (state.name == null || state.name.isEmpty()) {
			LOGGER.error("No name set in state!");
			return false;
		}
		if (state.description == null || state.description.isEmpty()) {
			LOGGER.error("No description set in state!");
			return false;
		}
		if (state.descriptionFile == null) {
			LOGGER.error("No description file set in state!");
			return false;
		} else {
			if (!state.descriptionFile.canRead()) {
				LOGGER.error(state.descriptionFile.getAbsolutePath() + " cannot be read!");
				return false;
			}
		}
		if (state.diskFile == null) {
			LOGGER.error("No disk file set in state!");
			return false;
		} else {
			if (!state.diskFile.canRead()) {
				LOGGER.error(state.diskFile.getAbsolutePath() + " cannot be read!");
				return false;
			}
		}
		if (state.selectedOs == null) {
			LOGGER.error("No OS set in state!");
			return false;
		}
		if (!state.selectedOs.isSetOsId()) {
			LOGGER.error("OS has no id: " + state.selectedOs.toString());
			return false;
		}
		if (state.virtualizationConfig == null) {
			LOGGER.error("No vm meta data set in state!");
			return false;
		}
		if (state.defaultPermissions == null) {
			LOGGER.error("No permissions set in state!");
			return false;
		}
		if (state.shareMode == null) {
			LOGGER.error("No share mode set in state!");
			return false;
		}
		if (state.uuid == null) {
			LOGGER.error("No uuid set in state!");
			return false;
		}
		return true;
	}

	private ImageBaseWrite imageBaseWriteFromState() {
		// build imageBaseWrite
		return new ImageBaseWrite(state.name, state.description, state.selectedOs.getOsId(),
				state.virtualizationConfig.getVirtualizer().getId(), state.isTemplate,
				state.defaultPermissions, state.shareMode);
	}

	@Override protected final void doPrevious() {
		if (outOfOrderPage != null) {
			outOfOrderPage = null;
			returnAfterOutOfOrderPage(state.imageUploadPage, state.conversionPage);
		} else {
			super.doPrevious();
		}
	}

	@Override public final void doNext() {
		if (outOfOrderPage != null) {
			outOfOrderPage = null;
			returnAfterOutOfOrderPage(state.imageUploadPage, state.conversionPage);
		} else {
			super.doNext();
		}
	}

	@Override protected boolean onCancelRequest() {
		if (state.uuid == null)
			return true; // Allow closing - nothing in progress
		boolean confirmed = Gui.showMessageBox(this,
				I18n.WIZARD.getString("ImageCreation.Message.yesNo.cancelRequest"),
				MessageType.QUESTION_YESNO, null, null);
		if (confirmed) {
			QuickTimer.scheduleOnce(new Task() {
				@Override public void fire() {
					if (state.upload != null) {
						state.upload.cancelError("Cancelled through aborting wizard");
					}
					// As we're creating a new VM, delete base image aswell
					try {
						ThriftManager.getSatClient().deleteImageBase(Session.getSatelliteToken(), state.uuid);
					} catch (TException e) {
						LOGGER.debug("Error canceling upload on sat: ", e);
					}
				}
			});
		}
		return confirmed;
	}

	@Override public boolean wantConfirmQuit() {
		return state.uuid != null;
	}

	@Override public void escapePressed() {
		doCancel();
	}

	@Override public void onApplicationQuit() {
		if (state != null && state.upload != null) {
			state.upload.cancelError("Application quit (redirected via wizard)");
		}
	}
}