package org.openslx.util.vm; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.OperatingSystem; import org.openslx.bwlp.thrift.iface.Virtualizer; /** * Describes a configured virtual machine. This class is parsed from a machine * description, like a *.vmx for VMware machines. */ public abstract class VmMetaData { private static final Logger LOGGER = Logger.getLogger(VmMetaData.class); /* * Helper types */ protected Map soundCards = new HashMap<>(); protected Map ddacc = new HashMap<>(); protected Map hwversion = new HashMap<>(); protected Map networkCards = new HashMap<>(); /** * Virtual sound cards types */ public static enum SoundCardType { NONE("None"), DEFAULT("(default)"), SOUND_BLASTER("Sound Blaster 16"), ES("ES 1371"), HD_AUDIO("Intel Integrated HD Audio"), AC("Intel ICH Audio Codec 97"); public final String displayName; private SoundCardType(String dName) { this.displayName = dName; } } /** * 3D acceleration types */ public static enum DDAcceleration { OFF("Off"), ON("On"); public final String displayName; private DDAcceleration(String dName) { this.displayName = dName; } } /** * Virtual hardware version - currently only in use for VMPlayer */ public static enum HWVersion { NONE("(invalid)"), THREE(" 3 (Workstation 4/5, Player 1)"), FOUR(" 4 (Workstation 4/5, Player 1/2, Fusion 1)"), SIX(" 6 (Workstation 6)"), SEVEN( " 7 (Workstation 6.5/7, Player 3, Fusion 2/3)"), EIGHT(" 8 (Workstation 8, Player/Fusion 4)"), NINE(" 9 (Workstation 9, Player/Fusion 5)"), TEN( "10 (Workstation 10, Player/Fusion 6)"), ELEVEN( "11 (Workstation 11, Player/Fusion 7)"), TWELVE("12 (Workstation/Player 12, Fusion 8)"), DEFAULT("default"); public final String displayName; private HWVersion(String dName) { this.displayName = dName; } } /** * Virtual network cards */ public static enum EthernetDevType { AUTO("(default)"), PCNET32("AMD PCnet32"), E1000("Intel E1000 (PCI)"), E1000E("Intel E1000e (PCI-Express)"), VMXNET("VMXnet"), VMXNET3("VMXnet 3"), PCNETPCI2( "PCnet-PCI II"), PCNETFAST3("PCnet-FAST III"), PRO1000MTD("Intel PRO/1000 MT Desktop"), PRO1000TS( "Intel PRO/1000 T Server"), PRO1000MTS("Intel PRO/1000 MT Server"), PARAVIRT("Paravirtualized Network"), VIRTIO("Virtual High Performance Ethernet card"), RTL8139("Realtek Fast Ethernet "), NONE("No Network Card"); public final String displayName; private EthernetDevType(String dName) { this.displayName = dName; } } public static enum DriveBusType { SCSI, IDE, SATA, VIRTIO; } public static class HardDisk { public final String chipsetDriver; public final DriveBusType bus; public final String diskImage; public HardDisk(String chipsetDriver, DriveBusType bus, String diskImage) { this.chipsetDriver = chipsetDriver; this.bus = bus; this.diskImage = diskImage; } } public static enum EtherType { NAT, BRIDGED, HOST_ONLY; } /* * Members */ protected final List hdds = new ArrayList<>(); private final List osList; private OperatingSystem os = null; protected String displayName = null; protected boolean isMachineSnapshot; /* * Getters for virtual hardware */ public List getSupportedSoundCards() { ArrayList availables = new ArrayList(soundCards.keySet()); Collections.sort(availables); return availables; } public List getSupportedDDAccs() { ArrayList availables = new ArrayList(ddacc.keySet()); Collections.sort(availables); return availables; } public List getSupportedHWVersions() { ArrayList availables = new ArrayList(hwversion.keySet()); Collections.sort(availables); return availables; } public List getSupportedEthernetDevices() { ArrayList availables = new ArrayList(networkCards.keySet()); Collections.sort(availables); return availables; } /** * Get operating system of this VM. */ public OperatingSystem getOs() { return os; } /** * Get all hard disks of this VM. */ public List getHdds() { return Collections.unmodifiableList(hdds); } /** * Get display name of VM. */ public String getDisplayName() { return displayName; } /* * Getter for isMachineSnapshot */ public boolean isMachineSnapshot() { return isMachineSnapshot; } /** * This method should return a minimal representation of the input meta * data. The representation is platform dependent, and should be stripped of * all non-essential configuration, such as CD/DVD/FLoppy drives, serial or * parallel ports, shared folders, or anything else that could be considered * sensible information (absolute paths containing the local user's name). */ public abstract byte[] getFilteredDefinitionArray(); public final ByteBuffer getFilteredDefinition() { return ByteBuffer.wrap(getFilteredDefinitionArray()); } /* * Methods */ public VmMetaData(List osList) { this.osList = osList; } /** * Called from subclass to set the OS. If the OS cannot be determined from * the given parameters, it will not be set. * * @param virtId virtualizer, eg "vmware" for VMware * @param virtOsId the os identifier used by the virtualizer, eg. * windows7-64 for 64bit Windows 7 on VMware */ protected final void setOs(String virtId, String virtOsId) { OperatingSystem lazyMatch = null; for (OperatingSystem os : osList) { if (os.getVirtualizerOsId() == null) { continue; } for (Entry entry : os.getVirtualizerOsId().entrySet()) { if (!entry.getValue().equals(virtOsId)) { continue; } if (entry.getKey().equals(virtId)) { this.os = os; return; } else { lazyMatch = os; } } } this.os = lazyMatch; } /** * Apply config options that are desired when locally editing a VM. for * vmware, this disables automatic DPI scaling of the guest. */ public abstract void applySettingsForLocalEdit(); /** * Returns a VmMetaData instance of the given machine description given as * file * * @param osList List of supported operating systems * @param file VM's machine description file to get the metadata instance * from * @return VmMetaData object representing the relevant parts of the given * machine description */ public static VmMetaData getInstance(List osList, File file) throws IOException { try { return new VmwareMetaData(osList, file); } catch (UnsupportedVirtualizerFormatException e) { LOGGER.info("Not a VMware file", e); } try { return new VboxMetaData(osList, file); } catch (UnsupportedVirtualizerFormatException e) { LOGGER.info("Not a VirtualBox file", e); } try { return new QemuMetaData(osList, file); } catch (Exception e) { LOGGER.info("Not a QEmu file", e); } LOGGER.error("Could not detect any known virtualizer format"); return null; } /** * Returns a VmMetaData instance of the given machine description given as a * byte array * * @param osList List of supported operating systems * @param vmContent VM's machine description as byte array (e.g. stored in * DB) * @param length length of the byte array given as vmContent * @return VmMetaData object representing the relevant parts of the given * machine description * @throws IOException */ public static VmMetaData getInstance(List osList, byte[] vmContent, int length) throws IOException { try { return new VmwareMetaData(osList, vmContent, length); } catch (UnsupportedVirtualizerFormatException e) { LOGGER.info("Not a VMware file", e); } try { return new VboxMetaData(osList, vmContent, length); } catch (UnsupportedVirtualizerFormatException e) { LOGGER.info("Not a VirtualBox file", e); } try { return new QemuMetaData(osList, vmContent, length); } catch (UnsupportedVirtualizerFormatException e) { LOGGER.info("Not a VirtualBox file", e); } // TODO QEmu -- hack above expects qcow2 file, so we can't do anything here yet LOGGER.error("Could not detect any known virtualizer format"); return null; } public abstract boolean addHddTemplate(File diskImage, String hddMode, String redoDir); public abstract boolean addHddTemplate(String diskImagePath, String hddMode, String redoDir); public abstract boolean addDefaultNat(); public abstract void setOs(String vendorOsId); public abstract boolean addDisplayName(String name); public abstract boolean addRam(int mem); public abstract void addFloppy(int index, String image, boolean readOnly); public abstract boolean addCdrom(String image); public abstract boolean addCpuCoreCount(int nrOfCores); public abstract void setSoundCard(SoundCardType type); public abstract SoundCardType getSoundCard(); public abstract void setDDAcceleration(DDAcceleration type); public abstract DDAcceleration getDDAcceleration(); public abstract void setHWVersion(HWVersion type); public abstract HWVersion getHWVersion(); public abstract void setEthernetDevType(int cardIndex, EthernetDevType type); public abstract EthernetDevType getEthernetDevType(int cardIndex); public abstract byte[] getDefinitionArray(); public abstract boolean addEthernet(EtherType type); public abstract Virtualizer getVirtualizer(); public abstract void enableUsb(boolean enabled); public abstract boolean disableSuspend(); /** * Function used to register virtual devices */ public abstract void registerVirtualHW(); }