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


                            
                           
                                         
                               
                      
                         



                                                     
                                       
                                                      






































                                                           
                   
 

                              
 
                                                 
 



                           
 
                                                                                                                                                 
 
                                                                              
 
                                                                                                 
 
                                    
 

                                           

                                                 

                                 

                                  

                                  























                                                                                                                                               
                         

                                              
                                                       




                                                    

                                                
                                              









                                                                       
                              



                                                                                   
                                                                     



                                                                                         
                                
                                 
                                                              
 
                             

                                              
                                           
 

















                                                                                          


                                                     
 





                                                                
                                                 
 
                                               





                                                           
                    



                                                          
















                                                                 





                                           





                                    
                                     




                                             






                                                                      
                                         
                
                                          
         
                                   
                                  

                                       
                                                                
                                   





                                           
                                     
                                  
                                       
                                                              
                                   






                                                   
                                           



                                          




                                                             
                                                                 



                                                    

                                                 



                                                                   
                                         


















                                                                                    
                                  
              
                                                             

                                                              
                                 



                                                  
                                  



                                                                         
               





                                                           
                      
                                                                  
                          
                                            

                                                                                         
                                                           
                      
             
            
         
 
                       
                     











                                                                 

                   


                                                              



                                                       
                                




                                         
                                                                  



                                             
                        

                    





                                         





















                                                           



                                                                           
                                               
                        
                                                




                                                   
         
                                                 

                                                                  
         







                                                                                                    

                                                                             
 
                                                                              
 



                                                                                                          
 



                                                                                                             
 
     
 
package org.openslx.util.vm;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.thrifthelper.TConst;
import static org.openslx.util.vm.QemuConfig.Header.*;

class QemuDDAccelMeta {

    public final boolean isPresent;

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

class QemuHWVersionMeta {

    public final int version;

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

class QemuEthernetDevTypeMeta {

    public final String value;

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

class QemuSoundCardMeta {

    public final boolean isPresent;
    public final String value;

    public QemuSoundCardMeta(boolean present, String val) {

        isPresent = present;
        value = val;
    }
}
class QemuUSBMeta {

    public final String value;
    public final int speed;

    public QemuUSBMeta(String value, int speed) {

        this.value = value;
        this.speed = speed;
    }
}

public final class QemuMetaData extends VmMetaData<QemuSoundCardMeta, QemuDDAccelMeta, QemuHWVersionMeta, QemuEthernetDevTypeMeta, QemuUSBMeta> {

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

    private static final Virtualizer virtualizer = new Virtualizer(TConst.VIRT_QEMU, "QEMU-KVM");

    private final QemuConfig config;

    private TreeMap<String, String> option;

    private LinkedHashMap<String, String> header;

    private int cdromCounter = 0;

    private int floppyCounter = 0;

    private int netdevCounter = 0;

    public static enum EthernetType {
        NAT("qnet1"), BRIDGED("qnet0"), HOST_ONLY("qnet2");

        public final String vmnet;

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

    public QemuMetaData(List<OperatingSystem> osList, File config) {
        super(osList);
        this.config = new QemuConfig(config);
        init();
    }

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

    public void init() {
        registerVirtualHW();
        config.setHdds();
        displayName = config.getDisplayName();
        setOs(config.getOsName());
        isMachineSnapshot = config.isMachineSnapshot();
        for (HardDisk hardDisk : config.getHdds()) {
            hdds.add(hardDisk);
        }
    }

    @Override
    public byte[] getFilteredDefinitionArray() {
        //TODO: Filter is done fix server side
        return config.toString(false).getBytes(StandardCharsets.UTF_8);
    }

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

    @Override
    public void applySettingsForLocalEdit() {
        //nothing ! for VMware
    }

    @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) {
        DriveBusType bus = null;
        option = new TreeMap<>();
        option = config.get(DRIVE.getHeader(), DRIVE.getID());

        if (option != null) {
            option.remove("file");
            option.put("file", diskImagePath);
            if (option.get("if") == null) {

            } else {
                switch (option.get("if")) {
                    case "ide":
                        bus = DriveBusType.IDE;
                        break;
                    case "scsi":
                        bus = DriveBusType.SCSI;
                        break;
                    case "sata":
                        //not available for Qemu. Others : sd, mtd, floppy, pflash, virtio
                        break;
                    default:
                        break;
                }
            }
        } else {
            LOGGER.error("Missing disk");
        }
        header = new LinkedHashMap<>();
        header.put(DRIVE.getHeader(), DRIVE.getID());
        config.set(header, option);

        option = new TreeMap<>();
        option = config.get(DEVICE.getHeader(), DEVICE.getID());

        if (option == null) {
            option = new TreeMap<>();
            header = new LinkedHashMap<>();
            header.put(DEVICE.getHeader(), null);

            option.put("drive", DRIVE.getID());
            if (bus != null) {
                if (bus.equals(DriveBusType.IDE)) {
                    option.put("driver", "ide-hd");
                } else if (bus.equals(DriveBusType.SCSI)) {
                    option.put("driver", "scsi-hd");
                }
            } else {
                //Shouldn't come to this but to check TODO
            }
            config.set(header, option);
        }
        return true;
    }

    @Override
    public boolean addDefaultNat() {
        //No arguments needed, default on nat. But cannot receive
        return true;
    }

    @Override
    public void setOs(String vendorOsId) {
        setOs(TConst.VIRT_QEMU, vendorOsId);
    }

    @Override
    public boolean addDisplayName(String name) {
        option = new TreeMap<>();
        option.put("guest", name);

        header = new LinkedHashMap<>();
        header.put(NAME.getHeader(), null);

        config.set(header, option);
        return true;
    }

    @Override
    public boolean addRam(int mem) {
        option = new TreeMap<>();
        option.put("size", "" + mem);

        header = new LinkedHashMap<>();
        header.put(MEMORY.getHeader(), null);

        config.set(header, option);
        return true;
    }

    @Override
    public void addFloppy(int index, String image, boolean readOnly) {
        option = new TreeMap<>();
        if (readOnly) {
            option.put("readonly", "on");
        } else {
            option.put("readonly", "off");
        }
        option.put("if", "floppy");
        option.put("file", image);

        header = new LinkedHashMap<>();
        header.put(DRIVE.getHeader(), "floppy" + floppyCounter);
        config.set(header, option);
        floppyCounter++;
    }

    @Override
    public boolean addCdrom(String image) {
        option = new TreeMap<>();
        option.put("media", "cdrom");
        option.put("file", image);
        header = new LinkedHashMap<>();
        header.put(DRIVE.getHeader(), "cdrom" + cdromCounter);
        config.set(header, option);
        cdromCounter++;
        return true;
    }

    @Override
    public boolean addCpuCoreCount(int nrOfCores) {
        option = new TreeMap<>();
        option.put("cpus", nrOfCores + "");

        header = new LinkedHashMap<>();
        header.put(SMP.getHeader(), null);
        config.set(header, option);
        return true;
    }

    @Override
    public void setSoundCard(VmMetaData.SoundCardType type) {
        //TODO Not possible will be set as comment in config file
    }

    @Override
    public VmMetaData.SoundCardType getSoundCard() {
        //TODO set to default, just write comment
        return VmMetaData.SoundCardType.DEFAULT;
    }

    @Override
    public void setDDAcceleration(VmMetaData.DDAcceleration type) {
        //TODO: Not really used by qemu. 
    }

    @Override
    public VmMetaData.DDAcceleration getDDAcceleration() {
        return DDAcceleration.OFF;
    }

    @Override
    public void setHWVersion(VmMetaData.HWVersion type) {
        //nothing...
    }

    @Override
    public VmMetaData.HWVersion getHWVersion() {
        return VmMetaData.HWVersion.DEFAULT;
    }

    @Override
    public void setEthernetDevType(int cardIndex, VmMetaData.EthernetDevType type) {
				/*
        //TODO
        QemuEthernetDevTypeMeta dev = networkCards.get(type);
        header = new LinkedHashMap<>();
        header.put(DEVICE.getHeader(), "net" + netdevCounter);
        option = new TreeMap<>();
        option.put("driver",  dev.value);
        //option.put("netdev", "net" + cardIndex);
        config.set(header, option);
        netdevCounter++;
				*/
    }

    @Override
    public VmMetaData.EthernetDevType getEthernetDevType(int cardIndex) {
        //TO DO
        return EthernetDevType.AUTO;
    }

    @Override
    public boolean addEthernet(VmMetaData.EtherType type) {
        boolean ret = false;
        int index = 0;
        //TODO use existing interface if given or create a new one
        for (;; ++index) {
            DEVICE.setID("netType" + index);
            TreeMap<String, String> dev = config.get(DEVICE.getHeader(), DEVICE.getID());

            if (dev == null || dev.get("netdev") == 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) {
        NETDEV.setID("net" + index);
        header = new LinkedHashMap<>();
        header.put(NETDEV.getHeader(), NETDEV.getID());
        //netdev
        option = new TreeMap<>();
        //device tap,ifname=nat1
        option.put("ifname", type.vmnet);
        option.put("type", "tap");
        config.set(header, option);
        //device
        header = new LinkedHashMap<>();
        header.put(DEVICE.getHeader(), "netType" + netdevCounter);
        option = new TreeMap<>();
        option.put("driver", "e1000");
        option.put("netdev", NETDEV.getID());
        config.set(header, option);
        netdevCounter++;
        return true;
    }

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

//    @Override
//    public void enableUsb(boolean enabled) {
//        option = new TreeMap<>();
//        if (enabled) {
//            option.put("usb", "on");
//        } else {
//            option.put("usb", "off");
//        }
//
//        header = new LinkedHashMap<>();
//        header.put(MACHINE.getHeader(), MACHINE.getID());
//        config.set(header, option);
//    }

//    @Override
//   public boolean disableSuspend() {
//        return false;
//    }
		@Override
		public boolean tweakForNonPersistent() {
			return false;
		}
	public void setMaxUsbSpeed( VmMetaData.UsbSpeed speed )
	{
		// TODO: Actual speed setting?
		if ( speed == null || speed == VmMetaData.UsbSpeed.NONE ) {
			option.remove( "usb" );
		} else {
			option.put( "usb", "" );
		}
	}

	@Override
	public VmMetaData.UsbSpeed getMaxUsbSpeed()
	{
		if (option.containsKey( "usb" ) )
			return VmMetaData.UsbSpeed.USB2_0; // TODO
		return VmMetaData.UsbSpeed.NONE;
	}
    @Override
    public void registerVirtualHW() {
        soundCards.put(VmMetaData.SoundCardType.NONE, new QemuSoundCardMeta(false, null));
        soundCards.put(VmMetaData.SoundCardType.DEFAULT, new QemuSoundCardMeta(true, "ich6"));
        soundCards.put(VmMetaData.SoundCardType.AC, new QemuSoundCardMeta(true, "ac97"));
        soundCards.put(VmMetaData.SoundCardType.ES, new QemuSoundCardMeta(true, "es1370"));
        soundCards.put(VmMetaData.SoundCardType.SOUND_BLASTER, new QemuSoundCardMeta(true, "sb16"));

        ddacc.put(VmMetaData.DDAcceleration.OFF, new QemuDDAccelMeta(false));
        ddacc.put(VmMetaData.DDAcceleration.ON, new QemuDDAccelMeta(true));

        hwversion.put(VmMetaData.HWVersion.DEFAULT, new QemuHWVersionMeta(0));

				usbSpeeds.put(VmMetaData.UsbSpeed.NONE, new QemuUSBMeta(null, 0));
				usbSpeeds.put(VmMetaData.UsbSpeed.USB1_1, new QemuUSBMeta("usb", 1));
				usbSpeeds.put(VmMetaData.UsbSpeed.USB2_0, new QemuUSBMeta("ehci", 2));
				usbSpeeds.put(VmMetaData.UsbSpeed.USB3_0, new QemuUSBMeta("usb_xhci", 3));

        //networkCards.put(VmMetaData.EthernetDevType.VIRTIO, new QemuEthernetDevTypeMeta("virtio-net-pci"));
        networkCards.put(VmMetaData.EthernetDevType.E1000, new QemuEthernetDevTypeMeta("e1000"));
        networkCards.put(VmMetaData.EthernetDevType.PCNET32, new QemuEthernetDevTypeMeta("pcnet"));
        //networkCards.put(VmMetaData.EthernetDevType.RTL8139, new QemuEthernetDevTypeMeta("rtl8139"));

    }
}