summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java
blob: 50fee151274b9eb3c7beada8d7802580ce92b2a0 (plain) (tree)
1
2
3
4
5
6
7
8


                                
                                
                           
                           
                                              
                                         







                                                     
 
                                       
                                           
                                     

                                           
                                                     

                                                 
                                                     
                                       

                                                                                     
                                                                                
                                                                                  
                                                                                                 

                                                                                                   


                                                          


                        
                                                                                   
 
                                                                                             
                                                                                                                             
                                     
 




                                                                                                                 



                                                                                                              
                                                                                                                                  

                                 

                                                                                                                           
                         
                 
 



                                                                
                 
 
                                                                            
                                                                                                    
                                                                                                                                 
 
                                                                           
                                            
                     
                                                                                                                                              

                                                                                                                              
                                                                                           

                                                                                                  
                 
 
                                                     
                                                                                        


                                                                                                                                              
                                                            

                                               


                                                                                                                                
                                                                                                                     






                                                                                                                                      

                 


                                                                                                        
                                                                                     

                                                                    
                                
 
                                                                      
                                                                      

         
                                                                                                                  
                                                                                   
                                                                                
                                                                                                                  

         

                                                                                
                                                                     
           


                                                          
           
                                                                                   



                                                                                    
                                                               
                                           
                        
                                                    
                 
                                

         
















                                                                                                                    
 
package org.openslx.dozmod.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.nio.charset.StandardCharsets;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.thrifthelper.TConst;
import org.openslx.virtualization.configuration.VirtualizationConfiguration;
import org.openslx.virtualization.configuration.VirtualizationConfigurationException;
import org.openslx.virtualization.configuration.VirtualizationConfigurationQemu;
import org.openslx.virtualization.configuration.VirtualizationConfigurationVmware;
import org.openslx.virtualization.configuration.data.ConfigurationDataDozModServerToDozModClient;
import org.openslx.virtualization.configuration.logic.ConfigurationLogicDozModServerToDozModClient;
import org.openslx.virtualization.configuration.transformation.TransformationException;
import org.openslx.virtualization.disk.DiskImage;
import org.openslx.virtualization.disk.DiskImageException;
import org.openslx.virtualization.disk.DiskImageVmdk;

public class VmWrapper {

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

	public static void wrapVm(File diskFile, String imageName, byte[] machineDescription,
			String virtualizerId, int osId, DiskImage diskImageInfo) throws VirtualizationConfigurationException,
			IOException {

		// check if virtualization configuration is missing
		if (machineDescription == null) {
			// configuration is not available
			if (TConst.VIRT_VMWARE.equals(virtualizerId) && diskImageInfo instanceof DiskImageVmdk) {
				// get fallback VMX if virtualizer is VMware with VMDK disk image
				final DiskImageVmdk vmdkImageInfo = DiskImageVmdk.class.cast( diskImageInfo );
				try {
					machineDescription = VmWrapper.getFallbackVmx(vmdkImageInfo);
				} catch (DiskImageException e) {
					throw new VirtualizationConfigurationException("Can not get fallback VMX configuration!");
				}
			} else {
				// there is no way to reconstruct a configuration for other virtualizer
				throw new VirtualizationConfigurationException("Virtualization configuration is missing!");
			}
		}

		// get guest operating system if possible
		OperatingSystem guestOs = null;
		if (osId != 0) {
			guestOs = MetaDataCache.getOsById(osId);
		}

		// handle machine description to generate configuration file
		final VirtualizationConfiguration virtualizationConfig = VirtualizationConfiguration
				.getInstance(MetaDataCache.getOperatingSystems(), machineDescription, machineDescription.length);

		// transform virtualization configuration for local editing
		byte[] configuration = null;
		try {
			final ConfigurationLogicDozModServerToDozModClient downloadLogic = new ConfigurationLogicDozModServerToDozModClient();
			downloadLogic.apply( virtualizationConfig, new ConfigurationDataDozModServerToDozModClient( imageName,
					diskFile, guestOs, virtualizerId, getMainMemoryMb() ) );
			configuration = virtualizationConfig.getConfigurationAsByteArray();
		} catch ( TransformationException e ) {
			throw new VirtualizationConfigurationException( e.getLocalizedMessage() );
		}

		// save BIOS if virtualizer is VMware
		if (virtualizationConfig instanceof VirtualizationConfigurationVmware) {
			try {
				FileOutputStream output = new FileOutputStream(new File(diskFile.getAbsoluteFile().getParentFile(), "nvram"));
				InputStream input = ResourceLoader.getStream("/data/nvram");
				IOUtils.copy(input, output);
				input.close();
				output.close();
			} catch (Exception e) {
				Gui.asyncMessageBox("Konnte das BIOS für die VM nicht kopieren", MessageType.ERROR, LOGGER, e);
			}
		} else if ( virtualizationConfig instanceof VirtualizationConfigurationQemu && OsHelper.isLinux() ) {
			try {
				final VirtualizationConfigurationQemu virtualizationConfigQemu = VirtualizationConfigurationQemu.class
						.cast( virtualizationConfig );
				virtualizationConfigQemu.transformOsLoader();
			} catch ( VirtualizationConfigurationException | ClassCastException e ) {
				Gui.asyncMessageBox( "Konnte das BIOS für die VM nicht anpassen", MessageType.ERROR, LOGGER, e );
			}
		}

		// save virtualization configuration as file to disk
		final String baseFileName = FilenameUtils.removeExtension( diskFile.getAbsolutePath() );
		final String fileNameExtension = virtualizationConfig.getFileNameExtension();
		final File vmFile = new File(baseFileName + "." + fileNameExtension);

		// delete original virtualization configuration file
		vmFile.delete();

		// actually write virtualization configuration to disk
		FileUtils.writeByteArrayToFile(vmFile, configuration);
	}

	private static byte[] getFallbackVmx(DiskImageVmdk diskImageInfo) throws IOException, DiskImageException {
		final String vmx = ResourceLoader.getTextFile("/txt/vmx_template");
		final short hwVersion = diskImageInfo.getHwVersion().getMajor();
		return vmx.replace("%VM_HW_VERSION%", Short.toString(hwVersion)).getBytes(StandardCharsets.UTF_8);
	}

	/**
	 * Generates a filename based on the given imageName and with the proper
	 * extension. The given imageName is sanitized and shortened.
	 * 
	 * @param imageName desired basename of image file
	 * @param extension desired extension
	 * @return the generated name
	 */
	public static String generateFilename(String imageName, String extension) {
		String fileName = imageName.replaceAll("[^a-zA-Z0-9_\\.\\-]+", "_");
		if (fileName.length() > 50) {
			fileName = fileName.substring(0, 50);
		}
		if (extension == null || extension.isEmpty()) {
			fileName += ".img";
		} else {
			fileName += "." + extension;
		}
		return fileName;
	}

	private static int getMainMemoryMb() {
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
		Object attribute;
		try {
			attribute = mBeanServer.getAttribute(new ObjectName("java.lang", "type", "OperatingSystem"),
					"TotalPhysicalMemorySize");
		} catch (AttributeNotFoundException | InstanceNotFoundException | MalformedObjectNameException
				| MBeanException | ReflectionException e) {
			return -1;
		}
		try {
			return (int) (Long.parseLong(attribute.toString()) / (1024 * 1024));
		} catch (Exception e) {
			return -1;
		}
	}

}