summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/VboxMetaData.java
blob: fcb89d942afbffc8b9a8958513bdc599f2dac8e5 (plain) (tree)
1
2
3
4
5
6
7
8
9


                            
                           
                                
                                         
                      
                      
 

                                       




                                                                
 
                               

                                                     
                           
 










































                                                                                                                            
 
                                                                                    
 
                                                                                                     
 
                                        
 
                                                                                                                                
         

                                                     


                       
                                                                                                                                                   
         

                                                                  
                       

         

                           

                                  
                                   
                                                      
                                                          
 

                                                              

                 
 
                                                    

                                                                                                    
                                                                                            


                                                                                   
         
                                                        
 
                 

                                           
                                   


                 

                                                
                                                  


                 

                                               
                                                  
         
 
                 


                                                                            
         

                 


                                                                                         

                            
 
                 

                                                                                       
                                                           
                                                                                
 
                                                    
                                           
 
                                                                     
                                                                    

                                                                       
 
                                                         
                                                     


                                                                                                   
                               
                                               
                                             
                                       
                                                                               
                                
                                                                                
                         
 
                                                       
                                                       
                                                                                                 


                                   
                                                                                         
 



                                                                                
                 

                                             
                                                        

                                                                                                                                     


                                                                           
                                                                         
                            


                 


                                                             

                            
 

                             

                                      
                                                                                           


                                                          
         
 
                 

                                              
                                                  
 


                 


                                                                  
                            


                 


                                                                                       
                            


                 

                                                                          
 
                                      

                        
 


                 

                                               



                                                  
                 


                                                              

                            








                                                                                     
                                                      
         





                                                                                   


                 
                                                                       
         

                                                                                               
         
        
                 
                                                            
         











                                                                                  


                 



                                                                                                

                                                  




                                       

                                                                                            
                                                         

                                 











                                                                             



                                                                          




                                          




                                                                            
                                                                  
                                                                                                      

                                                                                                                

                                                                                                              
                                                                                 
                                                                                         








                                                                                                                
                                                                                                             










                                                                                  
         
 
package org.openslx.util.vm;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.w3c.dom.Element;

class VBoxSoundCardMeta
{
	public final boolean isPresent;
	public final String value;

	public VBoxSoundCardMeta( boolean present, String val )
	{
		isPresent = present;
		value = val;
	}
}

class VBoxDDAccelMeta
{
	public final boolean isPresent;

	public VBoxDDAccelMeta( boolean present )
	{
		isPresent = present;
	}
}

class VBoxHWVersionMeta
{
	public final int version;

	public VBoxHWVersionMeta( int vers )
	{
		version = vers;
	}
}

class VBoxEthernetDevTypeMeta
{
	public final String value;

	public VBoxEthernetDevTypeMeta( String val )
	{
		value = val;
	}
}

public class VboxMetaData extends VmMetaData<VBoxSoundCardMeta, VBoxDDAccelMeta, VBoxHWVersionMeta, VBoxEthernetDevTypeMeta>
{
	private static final Logger LOGGER = Logger.getLogger( VboxMetaData.class );

	private static final Virtualizer virtualizer = new Virtualizer( "virtualbox", "VirtualBox" );

	private final VboxConfig config;

	public VboxMetaData( List<OperatingSystem> osList, File file ) throws IOException, UnsupportedVirtualizerFormatException
	{
		super( osList );
		this.config = new VboxConfig( file );
		init();
	}

	public VboxMetaData( List<OperatingSystem> osList, byte[] vmContent, int length ) throws IOException, UnsupportedVirtualizerFormatException
	{
		super( osList );
		this.config = new VboxConfig( vmContent, length );
		init();
	}

	private void init()
	{
		populateTheMaps();

		this.config.init();
		displayName = config.getDisplayName();
		setOs( "virtualbox", config.getOsName() );

		for ( HardDisk hardDisk : config.getHdds() ) {
			hdds.add( hardDisk );
		}
	}

	// TODO DELETE LATER WHEN NOT NEEDED ANYMORE
	private void WriteToFile() throws TransformerFactoryConfigurationError, TransformerException
	{
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		StreamResult output = new StreamResult( new File( "output.xml" ) );
		Source input = new DOMSource( config.getConfigDoc() );
		transformer.transform( input, output );
	}
	// TODO END DELETE LATER WHEN NOT NEEDED ANYMORE

	@Override
	public Virtualizer getVirtualizer()
	{
		return virtualizer;
	}

	@Override
	public void enableUsb( boolean enabled )
	{
		// TODO Auto-generated method stub
	}

	@Override
	public void applySettingsForLocalEdit()
	{
		// TODO Auto-generated method stub
	}

	@Override
	public byte[] getFilteredDefinitionArray()
	{
		return config.toString().getBytes( StandardCharsets.UTF_8 );
	}

	@Override
	public boolean addHddTemplate( String diskImage, String hddMode, String redoDir )
	{
		config.changeAttribute( "HardDisk", "location", diskImage );
		return true;
	}

	@Override
	public boolean addHddTemplate( File diskImage, String hddMode, String redoDir )
	{
		String diskImagePath = diskImage.getName();
		config.changeAttribute( "HardDisk", "location", diskImagePath );

		UUID newhdduuid = UUID.randomUUID();
		LOGGER.debug( newhdduuid );

		// patching the new uuid in the vbox config file here
		String vboxUUid = "{" + newhdduuid.toString() + "}";
		config.changeAttribute( "HardDisk", "uuid", vboxUUid );
		config.changeAttribute( "Image", "uuid", vboxUUid );

		// write the new hdd uuid in the vdi file
		byte[] bytesToWrite = new byte[ 16 ];

		int[] bytesOffset = { 32, 40, 48, 56, 16, 24, 0, 8, 56, 48, 40, 32, 24, 16, 8, 0 };

		int offset = 0;
		for ( int i = 0; i < 2; i++ ) {
			Long uuidlong = null;
			if ( i == 0 ) {
				uuidlong = newhdduuid.getMostSignificantBits();
			} else {
				uuidlong = newhdduuid.getLeastSignificantBits();
			}

			for ( int j = 0; j < 8; j++ ) {
				int index = j + offset;
				bytesToWrite[index] = (byte) ( uuidlong >>> bytesOffset[index] );
			}
			offset = 8;
		}
		try ( RandomAccessFile file = new RandomAccessFile( diskImage, "rw" ) ) {

			file.seek( 392 );
			file.write( bytesToWrite, 0, 16 );
		} catch ( Exception e ) {
			LOGGER.warn( "could not patch new uuid in the vdi", e );
		}

		// we need a new machine uuid
		UUID newMachineUuid = UUID.randomUUID();
		if ( newMachineUuid.equals( newhdduuid ) ) {
			LOGGER.warn( "The new Machine UUID is the same as the new HDD UUID; tying again...this vm might not start" );
			newMachineUuid = UUID.randomUUID();
		}
		String machineUUid = "{" + newMachineUuid.toString() + "}";
		config.changeAttribute( "Machine", "uuid", machineUUid );
		return true;
	}

	@Override
	public boolean addDefaultNat()
	{
		config.addNewNode( "Adapter", "NAT", false );
		return true;
	}

	public void reWrite()
	{
		try {
			WriteToFile();
		} catch ( TransformerFactoryConfigurationError | TransformerException e ) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void setOs( String vendorOsId )
	{
		// TODO Auto-generated method stub

	}

	@Override
	public boolean addDisplayName( String name )
	{
		config.changeAttribute( "Machine", "name", name );
		return true;
	}

	@Override
	public boolean addRam( int mem )
	{
		config.changeAttribute( "Memory", "RAMSize", Integer.toString( mem ) );
		return true;
	}

	@Override
	public void addFloppy( int index, String image, boolean readOnly )
	{

		if ( image == null ) {
		} else {
		}

	}

	@Override
	public boolean addCdrom( String image )
	{
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addCpuCoreCount( int nrOfCores )
	{
		config.changeAttribute( "CPU", "count", "1" );
		return true;
	}

	@Override
	public void setSoundCard( org.openslx.util.vm.VmMetaData.SoundCardType type )
	{
		// TODO Auto-generated method stub

	}

	@Override
	public VmMetaData.SoundCardType getSoundCard()
	{
		VmMetaData.SoundCardType returnsct = null;
		// TODO ask about controller and driver
		Element x = (Element) config.findANode( "AudioAdapter" ).item( 0 );
		returnsct = VmMetaData.SoundCardType.DEFAULT;
		// TODO End
		return returnsct;
	}

	@Override
	public void setDDAcceleration( VmMetaData.DDAcceleration type )
	{
		VBoxDDAccelMeta accel = ddacc.get( type );
		config.changeAttribute( "Display", "accelerate3D", vmBoolean(accel.isPresent));
	}
	
	@Override
	public VmMetaData.DDAcceleration getDDAcceleration()
	{
		VmMetaData.DDAcceleration returndda = null;
		Element x = (Element)config.findANode( "Display" ).item( 0 );
		if ( x.hasAttribute( "accelerate3D" ) ) {
			if ( x.getAttribute( "accelerate3D" ).equals( "true" ) ) {
				returndda = VmMetaData.DDAcceleration.ON;
			} else {
				returndda = VmMetaData.DDAcceleration.OFF;
			}
		} else {
			returndda = VmMetaData.DDAcceleration.OFF;
		}
		return returndda;
	}

	@Override
	/**
	 * Function does nothing for Virtual Box;
	 * Virtual Box accepts per default only one hardware version and is hidden from the user
	 */
	public void setHWVersion( HWVersion type )
	{
	}

	@Override
	public HWVersion getHWVersion()
	{
		VmMetaData.HWVersion returnhwv = null;
		// TODO what do here? there is only one supported hwversion as far as I know
		returnhwv = VmMetaData.HWVersion.DEFAULT;
		// TODO End
		return returnhwv;
	}

	@Override
	public void setEthernetDevType( int cardIndex, EthernetDevType type )
	{
		// TODO Auto-generated method stub

	}

	@Override
	public EthernetDevType getEthernetDevType( int cardIndex )
	{
		VmMetaData.EthernetDevType returnedt = null;
		// TODO what do here?
		// TODO need to search for the 1.st adapter of network tag
		return VmMetaData.EthernetDevType.AUTO;
	}

	@Override
	public byte[] getDefinitionArray()
	{
		return config.toString().getBytes( StandardCharsets.UTF_8 );
	}

	public void populateTheMaps()
	{
		// add all from vmware supported sound cards here 
		soundCards.put( VmMetaData.SoundCardType.NONE, new VBoxSoundCardMeta( false, null ) );
		soundCards.put( VmMetaData.SoundCardType.SOUND_BLASTER, new VBoxSoundCardMeta( true, "sb16" ) );
		soundCards.put( VmMetaData.SoundCardType.ES, new VBoxSoundCardMeta( true, "es1371" ) );
		soundCards.put( VmMetaData.SoundCardType.HD_AUDIO, new VBoxSoundCardMeta( true, "hdaudio" ) );
		// end of supported sound cards
		// add all from vmware supported settings for the 3D acceleration
		ddacc.put( VmMetaData.DDAcceleration.OFF, new VBoxDDAccelMeta( false ) );
		ddacc.put( VmMetaData.DDAcceleration.ON, new VBoxDDAccelMeta( true ) );
		// end of all from vmware supported settings for the 3D acceleration
		// add all from vmware supported Hardware versions here 
		hwversion.put( VmMetaData.HWVersion.DEFAULT, new VBoxHWVersionMeta( 0 ) );

		// end of all from vmware supported Hardware versions here 
		// add all from vmware supported Ethernet devices versions here
		networkCards.put( VmMetaData.EthernetDevType.AUTO, new VBoxEthernetDevTypeMeta( null ) );
		networkCards.put( VmMetaData.EthernetDevType.PCNET32, new VBoxEthernetDevTypeMeta( "vlance" ) );
		networkCards.put( VmMetaData.EthernetDevType.E1000, new VBoxEthernetDevTypeMeta( "e1000" ) );
		// end of all from vmware supported Ethernet devices versions here
	}
	
	/**
	 * given a boolean value returns a string in lowercase of given boolean
	 * @param var
	 * @return
	 */
	private static String vmBoolean( boolean var )
	{
		return Boolean.toString( var ).toLowerCase();
	}
}