summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/virtualization/configuration/VirtualizationConfigurationVmware.java
blob: a2376741f1773bf71b8ca3e87ce0062fcb7c354e (plain) (tree)
1
2
3
4
5
6
7
8
                                                 
 
                    
                           
                                         
                           
                         
                          





                               

                                           
                                                     
                                       
                             
                                          
                                                                                                        




                                                               
                                                                
 
                                                                                  
 
           

                                                                             
                                                               
 
                                                                                                             
 
                                                                                                                       
                                                   
 




                                                                                      
 
                                                                         
 

                              

                                                                                                                   




                                                                                                                                         


                                                                                                                     

                                                                                                                
                                                                                                                   

         











                                                                            

                                                                                           
         
                                                         
                                                                                      
                       

         

                                                                                                               
         
                                                         
                                                                                                                        
                                       

         
                           
         
                                                                
                                                                              
                                                        
                 



                                                                                         
                                                                                          
                                                             





                                                                                                                                     

                               






                                                                                              
                                                                  


                                                                  
                                                                                                                       







                                                                                   

                                                                                   

                                                                                                        

                                                                                                   

                         

                                                                            
 







                                                                                  

         









                                                                                                               

                                                            
                                         
         
 





                                                                         
                                                                                                       
         
                                                               
                                       
                                                           
                                                     
                                       

                               
                                                         
                                            

                               
                                                                    
                                   
                                                                                                                     


                 
                                                                                                                                           




























                                                                                   
 
                 





                                                                                                         





                                                                                       
                                                                                             
         



                                                                       
 

                                                                        

                                     



                                                   
                              
                                    
                          
                                                           



                                               
                          
                          
                                                                    
                              
                        
                                                                                     

                                     

                                                           





                                                                       
                                        


                                                                         
                 

                                                 
                            

         
                                      





                                                                 
                                                                                
         
                                    




                                                                                    














                                                                           















                                                                          
 





                                                                          

                                                                   

                                                                   



                                                                       
                                                                                



                                                             


















                                                                                                          
 



                                                             
 




                                                  
                 
                                                                                        
         






                                                                                                               
                                                          
         
 
                 


                                                                                   




















                                                                                     


















                                                                                                                           





                                                    
                 





                                                                  


                                                     



                                                                                                                    

         
                                                   
         
                                                                            

         























                                                                                                    

         



                                            

                                                       
         









                                                                           

                                                            






                                                                

         
                                                              
         



                                                                     
                 






                                                                              
                 






                                                                

         
                                                          
         




















                                                                                                    

         
                                                   
         



                                                                     
                 












                                                                                                 

         
                                                         
         
                                                                                 

         
                                              
         

                                                                                                                           
         

                                                    
         
 





                                                                                     
                 
 




                                                                                        
                                
                                                                                          

                         







                                                                                           
                 
 
         




                                                                                   
 
































                                                                                                                    
                         
                                            
                 
                
         



                                                      
                                                                 
                            



                                       




























                                                                                                                     
         
 


                                            
                                                                             

         



                                                                          





                                                          
 
package org.openslx.virtualization.configuration;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.thrifthelper.TConst;
import org.openslx.util.Util;
import org.openslx.virtualization.Version;
import org.openslx.virtualization.configuration.VirtualizationConfigurationVmwareFileFormat.ConfigEntry;
import org.openslx.virtualization.hardware.VirtOptionValue;
import org.openslx.virtualization.hardware.ConfigurationGroups;
import org.openslx.virtualization.hardware.Ethernet;
import org.openslx.virtualization.hardware.SoundCard;
import org.openslx.virtualization.hardware.Usb;
import org.openslx.virtualization.virtualizer.VirtualizerVmware;

public class VirtualizationConfigurationVmware extends VirtualizationConfiguration
{
	/**
	 * File name extension for VMware virtualization configuration files.
	 */
	public static final String FILE_NAME_EXTENSION = "vmx";

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

	private static final Pattern HDD_PATTERN = Pattern.compile( "^(ide\\d|scsi\\d|sata\\d|nvme\\d):?(\\d?)\\.(.*)",
			Pattern.CASE_INSENSITIVE );

	/** Lowercase regex of allowed settings for stateless execution */
	private static final Pattern STATELESS_WHITELIST_PATTERN;

	/** Lowercase regex of forbidden settings when uploading (privacy concerns) */
	private static final Pattern PRIVACY_BLACKLIST_PATTERN;

	private final VirtualizationConfigurationVmwareFileFormat config;

	// Init static members
	static {
		// LOWERCASE - Client execution whitelist
		String[] list1 = { "^guestos", "^uuid\\.bios", "^config\\.version", "^ehci[.:]", "^mks\\.enable3d",
				"^virtualhw\\.",
				"^sound[.:]", "\\.pcislotnumber$", "^pcibridge", "\\.virtualdev$", "^tools\\.syncTime$",
				"^time\\.synchronize",
				"^bios\\.bootDelay", "^rtc\\.", "^xhci[.:]", "^usb_xhci[.:]", "\\.deviceType$", "\\.port$", "\\.parent$",
				"^usb[.:]",
				"^firmware", "^hpet", "^vm\\.genid",
				"^svga\\.graphicsMemoryKB$" };
		STATELESS_WHITELIST_PATTERN = Pattern.compile( String.join( "|", list1 ), Pattern.CASE_INSENSITIVE );
		// LOWERCASE - Upload privacy filter
		String[] list2 = { "^displayname$", "^extendedconfigfile$", "^gui\\.", "^nvram$", "^memsize$" };
		PRIVACY_BLACKLIST_PATTERN = Pattern.compile( String.join( "|", list2 ), Pattern.CASE_INSENSITIVE );
	}

	public static enum EthernetType
	{
		NAT( "vmnet1" ), BRIDGED( "vmnet0" ), HOST_ONLY( "vmnet2" );

		public final String vmnet;

		private EthernetType( String vnet )
		{
			this.vmnet = vnet;
		}
	}

	public VirtualizationConfigurationVmware( List<OperatingSystem> osList, File file )
			throws IOException, VirtualizationConfigurationException
	{
		super( new VirtualizerVmware(), osList );
		this.config = new VirtualizationConfigurationVmwareFileFormat( file );
		init();
	}

	public VirtualizationConfigurationVmware( List<OperatingSystem> osList, byte[] vmxContent, int length )
			throws VirtualizationConfigurationException
	{
		super( new VirtualizerVmware(), osList );
		this.config = new VirtualizationConfigurationVmwareFileFormat( vmxContent, length ); // still unfiltered
		init(); // now filtered
	}

	private void init()
	{
		Map<String, Controller> disks = new HashMap<>();
		for ( Entry<String, ConfigEntry> entry : config.entrySet() ) {
			handleLoadEntry( entry, disks );
		}
		// Fix accidentally filtered USB config if we see EHCI is present
		if ( isSetAndTrue( "ehci.present" ) && !isSetAndTrue( "usb.present" ) ) {
			addFiltered( "usb.present", "TRUE" );
		}
		// if we find this tag, we already went through the hdd's - so we're done.
		if ( config.get( "#SLX_HDD_BUS" ) != null ) {
			try {
				hdds.add( new HardDisk( config.get( "#SLX_HDD_CHIP" ),
						DriveBusType.valueOf( config.get( "#SLX_HDD_BUS" ) ), "empty" ) );
			} catch ( Exception e ) {
				LOGGER.debug( "Error adding HDD object when parsing #SLX_HDD_BUS. Meta-data will be incorrect.", e );
			}
			return;
		}
		// Now find the HDDs and add to list
		for ( Entry<String, Controller> cEntry : disks.entrySet() ) {
			Controller controller = cEntry.getValue();
			String controllerType = cEntry.getKey();
			if ( !controller.present )
				continue;
			for ( Entry<String, Device> dEntry : controller.devices.entrySet() ) {
				String deviceId = dEntry.getKey();
				Device device = dEntry.getValue();
				if ( !device.present )
					continue; // Not present
				if ( device.deviceType != null && !device.deviceType.toLowerCase().endsWith( "disk" ) )
					continue; // Not a HDD
				DriveBusType bus = null;
				if ( controllerType.startsWith( "ide" ) ) {
					bus = DriveBusType.IDE;
				} else if ( controllerType.startsWith( "scsi" ) ) {
					bus = DriveBusType.SCSI;
				} else if ( controllerType.startsWith( "sata" ) ) {
					bus = DriveBusType.SATA;
				} else if ( controllerType.startsWith( "nvme" ) ) {
					bus = DriveBusType.NVME;
				}
				hdds.add( new HardDisk( controller.virtualDev, bus, device.filename ) );
				// Remove original entries from VMX
				removeEntriesStartingWith( controllerType + ":" + deviceId + "." );
			}
		}
		// TODO check if this machine is in a paused/suspended state
		this.isMachineSnapshot = false;

		// Add HDD to cleaned vmx
		if ( !hdds.isEmpty() ) {
			HardDisk hdd = hdds.get( 0 );
			addFiltered( "#SLX_HDD_BUS", hdd.bus.toString() );
			if ( hdd.chipsetDriver != null ) {
				addFiltered( "#SLX_HDD_CHIP", hdd.chipsetDriver );
			}
		}
	}

	private void removeEntriesStartingWith( String start )
	{
		for ( Iterator<Entry<String, ConfigEntry>> it = config.entrySet().iterator(); it.hasNext(); ) {
			Entry<String, ConfigEntry> entry = it.next();
			if ( entry.getKey().startsWith( start ) ) {
				it.remove();
			}
		}
	}

	private void addFiltered( String key, String value )
	{
		config.set( key, value );
	}

	private boolean isSetAndTrue( String key )
	{
		String value = config.get( key );
		return value != null && value.equalsIgnoreCase( "true" );
	}

	private void handleLoadEntry( Entry<String, ConfigEntry> entry, Map<String, Controller> disks )
	{
		String lowerKey = entry.getKey().toLowerCase();
		// Dig Usable meta data
		String value = entry.getValue().getValue();
		if ( lowerKey.equals( "guestos" ) ) {
			setOs( value );
			return;
		}
		if ( lowerKey.equals( "displayname" ) ) {
			displayName = value;
			return;
		}
		Matcher hdd = HDD_PATTERN.matcher( entry.getKey() );
		if ( hdd.find() ) {
			handleHddEntry( disks, hdd.group( 1 ).toLowerCase(), hdd.group( 2 ), hdd.group( 3 ), value );
		}
	}

	private void handleHddEntry( Map<String, Controller> disks, String controllerStr, String deviceStr, String property, String value )
	{
		Controller controller = disks.get( controllerStr );
		if ( controller == null ) {
			controller = new Controller();
			disks.put( controllerStr, controller );
		}
		if ( deviceStr == null || deviceStr.isEmpty() ) {
			// Controller property
			if ( property.equalsIgnoreCase( "present" ) ) {
				controller.present = Boolean.parseBoolean( value );
			} else if ( property.equalsIgnoreCase( "virtualDev" ) ) {
				controller.virtualDev = value;
			}
			return;
		}
		// Device property
		Device device = controller.devices.get( deviceStr );
		if ( device == null ) {
			device = new Device();
			controller.devices.put( deviceStr, device );
		}
		if ( property.equalsIgnoreCase( "deviceType" ) ) {
			device.deviceType = value;
		} else if ( property.equalsIgnoreCase( "filename" ) ) {
			device.filename = value;
		} else if ( property.equalsIgnoreCase( "present" ) ) {
			device.present = Boolean.parseBoolean( value );
		}
	}

	@Override
	public boolean addEmptyHddTemplate()
	{
		return this.addHddTemplate( "%VM_DISK_PATH%", "%VM_DISK_MODE%", "%VM_DISK_REDOLOGDIR%" );
	}

	@Override
	public boolean addHddTemplate( File diskImage, String hddMode, String redoDir )
	{
		return addHddTemplate( diskImage.getName(), hddMode, redoDir );
	}

	@Override
	public boolean addHddTemplate( String diskImagePath, String hddMode, String redoDir )
	{
		if ( diskImagePath.isEmpty() ) {
			LOGGER.error( "Empty disk image path given!" );
			return false;
		}

		if ( hdds.isEmpty() ) {
			LOGGER.warn( "No HDDs found in configuration" );
			return false;
		}

		HardDisk hdd = hdds.get( 0 );

		String chipset = hdd.chipsetDriver;
		String prefix;
		switch ( hdd.bus ) {
		case SATA:
			// Cannot happen?... use lsisas1068
			prefix = "scsi0";
			chipset = "lsisas1068";
			break;
		case IDE:
		case SCSI:
		case NVME:
			prefix = hdd.bus.name().toLowerCase() + "0";
			break;
		default:
			LOGGER.warn( "Unknown HDD bus type: " + hdd.bus.toString() );
			return false;
		}
		// Gen
		addFiltered( prefix + ".present", "TRUE" );
		if ( chipset != null ) {
			addFiltered( prefix + ".virtualDev", chipset );
		}
		addFiltered( prefix + ":0.present", "TRUE" );
		addFiltered( prefix + ":0.deviceType", "disk" );
		addFiltered( prefix + ":0.fileName", diskImagePath );
		if ( hddMode != null ) {
			addFiltered( prefix + ":0.mode", hddMode );
			addFiltered( prefix + ":0.redo", "" );
			addFiltered( prefix + ":0.redoLogDir", redoDir );
		}
		config.remove( "#SLX_HDD_BUS" );
		config.remove( "#SLX_HDD_CHIP" );
		return true;
	}

	public boolean addDefaultNat()
	{
		addFiltered( "ethernet0.present", "TRUE" );
		addFiltered( "ethernet0.connectionType", "nat" );
		return true;
	}

	public boolean addEthernet( VirtualizationConfiguration.EtherType type )
	{
		boolean ret = false;
		int index = 0;
		for ( ;; ++index ) {
			if ( config.get( "ethernet" + index + ".present" ) == null )
				break;
		}
		switch ( type ) {
		case NAT:
			ret = addEthernet( index, EthernetType.NAT );
			break;
		case BRIDGED:
			ret = addEthernet( index, EthernetType.BRIDGED );
			break;
		case HOST_ONLY:
			ret = addEthernet( index, EthernetType.HOST_ONLY );
			break;
		default:
			// Should not come to this...
			break;
		}
		return ret;
	}

	public boolean addEthernet( int index, EthernetType type )
	{
		String ether = "ethernet" + index;
		addFiltered( ether + ".present", "TRUE" );
		addFiltered( ether + ".connectionType", "custom" );
		addFiltered( ether + ".vnet", type.vmnet );
		if ( config.get( ether + ".virtualDev" ) == null ) {
			String dev = config.get( "ethernet0.virtualDev" );
			if ( dev != null ) {
				addFiltered( ether + ".virtualDev", dev );
			}
		}
		return true;
	}

	public void addFloppy( int index, String image, boolean readOnly )
	{
		String pre = "floppy" + index;
		addFiltered( pre + ".present", "TRUE" );
		if ( image == null ) {
			addFiltered( pre + ".startConnected", "FALSE" );
			addFiltered( pre + ".fileType", "device" );
			config.remove( pre + ".fileName" );
			config.remove( pre + ".readonly" );
			addFiltered( pre + ".autodetect", "TRUE" );
		} else {
			addFiltered( pre + ".startConnected", "TRUE" );
			addFiltered( pre + ".fileType", "file" );
			addFiltered( pre + ".fileName", image );
			addFiltered( pre + ".readonly", vmBoolean( readOnly ) );
			config.remove( pre + ".autodetect" );
		}
	}

	public boolean addCdrom( String image )
	{
		for ( String port : new String[] { "ide0:0", "ide0:1", "ide1:0", "ide1:1", "scsi0:1" } ) {
			if ( !isSetAndTrue( port + ".present" ) ) {
				addFiltered( port + ".present", "TRUE" );
				if ( image == null ) {
					addFiltered( port + ".autodetect", "TRUE" );
					addFiltered( port + ".deviceType", "cdrom-raw" );
					config.remove( port + ".fileName" );
				} else {
					config.remove( port + ".autodetect" );
					addFiltered( port + ".deviceType", "cdrom-image" );
					addFiltered( port + ".fileName", image );
				}
				return true;
			}
		}
		return false;
	}

	private static String vmBoolean( boolean var )
	{
		return Boolean.toString( var ).toUpperCase();
	}

	private static String vmInteger( int val )
	{
		return Integer.toString( val );
	}

	@Override
	public void transformNonPersistent() throws VirtualizationConfigurationException
	{
		// Cleaned vmx construction
		for ( Iterator<Entry<String, ConfigEntry>> it = config.entrySet().iterator(); it.hasNext(); ) {
			Entry<String, ConfigEntry> elem = it.next();
			if ( !STATELESS_WHITELIST_PATTERN.matcher( elem.getKey() ).find() ) {
				it.remove();
			}
		}
		addFiltered( "suspend.disabled", "TRUE" );
	}

	@Override
	public void transformEditable() throws VirtualizationConfigurationException
	{
		addFiltered( "gui.applyHostDisplayScalingToGuest", "FALSE" );
		// This is for a very old bug: Check we have at lerast USB 2.0, as
		// a buggy dmsd removed all USB controllers
		List<ConfigurableOptionGroup> groups = getConfigurableOptions();
		for ( ConfigurableOptionGroup group : groups ) {
			if ( group.groupIdentifier != ConfigurationGroups.USB_SPEED )
				continue;
			int currentSpeed = 0;
			VirtOptionValue twoPointOh = null;
			for ( VirtOptionValue option : group.availableOptions ) {
				int s = Util.parseInt( option.getId(), 0 );
				if ( option.isActive() && s > currentSpeed ) {
					currentSpeed = s;
				}
				if ( s == 2 ) {
					twoPointOh = option;
				}
			}
			if ( currentSpeed < 3 && twoPointOh != null ) {
				twoPointOh.apply();
			}
		}
	}

	@Override
	public void transformPrivacy() throws VirtualizationConfigurationException
	{
		for ( Iterator<Entry<String, ConfigEntry>> it = config.entrySet().iterator(); it.hasNext(); ) {
			Entry<String, ConfigEntry> elem = it.next();
			String key = elem.getKey();
			String value = elem.getValue().getValue();
			if ( key.endsWith( ".fileName" ) && !value.startsWith( "-" )
					&& ( value.contains( "." ) || value.contains( "/" ) || value.contains( "\\" ) ) ) {
				it.remove();
			} else if ( PRIVACY_BLACKLIST_PATTERN.matcher( key ).find() ) {
				it.remove();
			}
		}
	}

	@Override
	public boolean addDisplayName( String name )
	{
		addFiltered( "displayName", name );
		return true;
	}

	@Override
	public boolean addRam( int mem )
	{
		addFiltered( "memsize", Integer.toString( mem ) );
		return true;
	}

	public void setOs( String vendorOsId )
	{
		addFiltered( "guestOS", vendorOsId );

		final OperatingSystem os = VirtualizationConfigurationUtils.getOsOfVirtualizerFromList( this.osList,
				TConst.VIRT_VMWARE, vendorOsId );
		this.setOs( os );
	}

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

	private static class Device
	{
		public boolean present = false;
		public String deviceType = null;
		public String filename = null;

		@Override
		public String toString()
		{
			return filename + " is " + deviceType + " (present: " + present + ")";
		}
	}

	private static class Controller
	{
		public boolean present = true; // Seems to be implicit, seen at least for IDE...
		public String virtualDev = null;
		Map<String, Device> devices = new HashMap<>();

		@Override
		public String toString()
		{
			return virtualDev + " is (present: " + present + "): " + devices.toString();
		}
	}

	public String getValue( String key )
	{
		return config.get( key );
	}
	
	class VmwareNoSoundCard extends VirtOptionValue
	{

		public VmwareNoSoundCard( String displayName )
		{
			super( "", displayName );
		}

		@Override
		public void apply()
		{
			addFiltered( "sound.present", vmBoolean( false ) );
			config.remove( "sound.virtualDev" );
		}

		@Override
		public boolean isActive()
		{
			return !isSetAndTrue( "sound.present" );
		}

	}

	class VmWareSoundCardModelNone extends VirtOptionValue
	{

		public VmWareSoundCardModelNone( String displayName )
		{
			super( "none", displayName );
		}

		@Override
		public void apply()
		{
			addFiltered( "sound.present", vmBoolean( false ) );
			addFiltered( "sound.autodetect", vmBoolean( false ) );
			config.remove( "sound.virtualDev" );
		}

		@Override
		public boolean isActive()
		{
			return !isSetAndTrue( "sound.present" );
		}

	}

	class VmWareSoundCardModel extends VirtOptionValue
	{

		public VmWareSoundCardModel( String id, String displayName )
		{
			super( id, displayName );
		}

		@Override
		public void apply()
		{
			addFiltered( "sound.present", vmBoolean( true ) );
			addFiltered( "sound.autodetect", vmBoolean( true ) );
			addFiltered( "sound.virtualDev", this.id );
		}

		@Override
		public boolean isActive()
		{
			return isSetAndTrue( "sound.present" ) && isSetAndTrue( "sound.autodetect" )
					&& this.id.equals( config.get( "sound.virtualDev" ) );
		}

	}

	class VmWareAccel3D extends VirtOptionValue
	{

		public VmWareAccel3D( String id, String displayName )
		{
			super( id, displayName );
		}

		@Override
		public void apply()
		{
			addFiltered( "mks.enable3d", this.id );
		}

		@Override
		public boolean isActive()
		{
			return Boolean.parseBoolean( this.id ) == isSetAndTrue( "mks.enable3d" );
		}

	}

	public void setVirtualizerVersion( Version type )
	{
		addFiltered( "virtualHW.version", vmInteger( type.getMajor() ) );
	}

	public Version getVirtualizerVersion()
	{
		final short major = Integer.valueOf( Util.parseInt( config.get( "virtualHW.version" ), -1 ) ).shortValue();
		return Version.getInstanceByMajorFromVersions( major, this.getVirtualizer().getSupportedVersions() );
	}
	
	class VmwareNicModel extends VirtOptionValue
	{

		private final int cardIndex;
		
		public VmwareNicModel( int cardIndex, String id, String displayName )
		{
			super( id, displayName );
			this.cardIndex = cardIndex;
		}

		@Override
		public void apply()
		{
			if ( Util.isEmptyString( id ) ) {
				config.remove( "ethernet" + cardIndex + ".virtualDev" );
			} else {
				addFiltered( "ethernet" + cardIndex + ".virtualDev", id );
			}
		}

		@Override
		public boolean isActive()
		{
			String temp = config.get( "ethernet" + cardIndex + ".virtualDev" );
			if ( temp == null )
				return Util.isEmptyString( this.id );
			return temp.equals( this.id );
		}

	}
	
	class VmWareUsbSpeed extends VirtOptionValue
	{
		private final String[] SPEED = { null, "usb", "ehci", "usb_xhci" };
		private final int speed;

		public VmWareUsbSpeed( int speed, String displayName )
		{
			super( Integer.toString( speed ), displayName );
			this.speed = speed;
		}

		@Override
		public void apply()
		{
			// XXX TODO This sucks, qnd
			for ( int i = 1; i < SPEED.length; ++i ) {
				String key = SPEED[i] + ".present";
				if ( i <= speed ) {
					// Enable desired speed class, plus all lower ones
					addFiltered( key, "TRUE" );
				} else {
					config.remove( key );
				}
			}
			// VMware 14+ needs this to use USB 3.0 devices at USB 3.0 ports in VMs configured for < 3.0
			if ( speed > 0 && speed < 3 ) {
				addFiltered( "usb.mangleUsb3Speed", "TRUE" );
			}
		}

		@Override
		public boolean isActive()
		{
			int max = 0;
			for ( int i = 1; i < SPEED.length; ++i ) {
				if ( isSetAndTrue( SPEED[i] + ".present" ) ) {
					max = i;
				}
			}
			return speed == max;
		}
		
	}

	@Override
	public boolean addCpuCoreCount( int numCores )
	{
		addFiltered( "numvcpus", vmInteger( numCores ) );
		return true;
	}

	public void registerVirtualHW()
	{
		List<VirtOptionValue> list;
		list = new ArrayList<>();
		list.add( new VmWareSoundCardModelNone( SoundCard.NONE ) );
		list.add( new VmWareSoundCardModel( "", SoundCard.DEFAULT ) );
		list.add( new VmWareSoundCardModel( "sb16", SoundCard.SOUND_BLASTER ) );
		list.add( new VmWareSoundCardModel( "es1371", SoundCard.ES ) );
		list.add( new VmWareSoundCardModel( "hdaudio", SoundCard.HD_AUDIO ) );
		configurableOptions.add( new ConfigurableOptionGroup( ConfigurationGroups.SOUND_CARD_MODEL, list ) );

		list = new ArrayList<>();
		list.add( new VmWareAccel3D( "FALSE", "2D" ) );
		list.add( new VmWareAccel3D( "TRUE", "3D" ) );
		configurableOptions.add( new ConfigurableOptionGroup( ConfigurationGroups.GFX_TYPE, list ) );
		
		list = new ArrayList<>();
		list.add( new VmwareNicModel( 0, "", Ethernet.AUTO ) );
		list.add( new VmwareNicModel( 0, "vlance", Ethernet.PCNET32 ) );
		list.add( new VmwareNicModel( 0, "e1000", Ethernet.E1000 ) );
		list.add( new VmwareNicModel( 0, "e1000e", Ethernet.E1000E ) );
		list.add( new VmwareNicModel( 0, "vmxnet", Ethernet.VMXNET ) );
		list.add( new VmwareNicModel( 0, "vmxnet3", Ethernet.VMXNET3 ) );
		configurableOptions.add( new ConfigurableOptionGroup( ConfigurationGroups.NIC_MODEL, list ) );

		list = new ArrayList<>();
		list.add( new VmWareUsbSpeed( 0, Usb.NONE ) );
		list.add( new VmWareUsbSpeed( 1, Usb.USB1_1 ) );
		list.add( new VmWareUsbSpeed( 2, Usb.USB2_0 ) );
		list.add( new VmWareUsbSpeed( 3, Usb.USB3_0 ) );
		configurableOptions.add( new ConfigurableOptionGroup( ConfigurationGroups.USB_SPEED, list ) );
	}

	@Override
	public String getFileNameExtension()
	{
		return VirtualizationConfigurationVmware.FILE_NAME_EXTENSION;
	}

	@Override
	public void validate() throws VirtualizationConfigurationException
	{
	}

	@Override
	public void disableUsb()
	{
		new VmWareUsbSpeed( 0, Usb.NONE ).apply();
	}
}