summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/QemuConfig.java
blob: 8348790aa91d94c8c4651ae905fbcf64ecc2b419 (plain) (tree)





















                                                                            
                                                                                                        


                                         

                                      
                                                                         
 

                                                              



                                                                             
                                    



                                                  
                                 
                         
         

                                   

                               












                                                     
     
 













                                                                                                          

                                                                


























































                                                                                           
                        
 





                                                     
                                         


























                                                                                                                            
                                

                                                  
                     
                                              

                                         

                                                                                                    
                        


                                                                                            




                 
                                                               
                                             



                                                 



                                    
                                                                       


                                

                                                                                         



                                    

                                                
 


                                                   




                                        



                                                         















                                                                                            
                    


                                       













                                                                                                            
                                                   














                                                                                                      

                     





                                                                      
             










                                                          

                 

                                                                                        
                      









                                                     
                                                                                                 

                                                


                                                                                                                                                                                      




                                                                      
                                                                                                                                                           
 
                                                                
 













                                                                      









                                                              

                             
     
 
package org.openslx.util.vm;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import java.util.Map;
import java.util.TreeMap;
import org.apache.log4j.Logger;
import static org.openslx.util.vm.QemuConfig.Header.*;
import org.openslx.util.vm.VmMetaData.DriveBusType;

public final class QemuConfig {

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

    private Map<LinkedHashMap<String, String>, TreeMap<String, String>> entries = new LinkedHashMap<>();

    private String osName = new String();

    private final String quote = "\"";

    private ArrayList<VmMetaData.HardDisk> hddsArray = new ArrayList<>();

    // BOOT("netdev", "net0") -> toString -> "[netdev "net0"]"
    public static enum Header {
        BOOT("boot-opts", null), DEVICE("device", ""), DRIVE("drive", ""),
        MACHINE("machine", null), MEMORY("memory", null), NAME("name", null),
        NETDEV("netdev", ""), SMP("smp-opts", null);

        private final String header;

        private String id;

        private Header(String header, String id) {
            this.header = header;
            this.id = id;
        }

        public String getHeader() {
            return this.header;
        }

        public String getID() {
            return id;
        }

        public void setID(String id) {
            this.id = id;
        }

        @Override
        public String toString() {
            return "[" + header + " \"" + id + "\"]";
        }
    }

    public QemuConfig(byte[] vmContent, int length) {
        //transform byte[] to arralist sorted
        ArrayList<String> result;
        BufferedReader stream = null;
        try {
            stream = new BufferedReader(
                    new InputStreamReader(
                            new ByteArrayInputStream(vmContent, 0, length), StandardCharsets.ISO_8859_1));
            result = new ArrayList<>();
            String line;

            while ((line = stream.readLine()) != null) {
                if (line.startsWith("#") == false) {
                    if (line.isEmpty() == false) {
                        if (line.contains(DEVICE.getHeader())) {
                            result.add(DEVICE.getHeader());
                        } else {
                            result.add(line.trim());
                        }
                    }
                }
            }
            stream.close();
            stream = null;
        } catch (IOException e) {
            result = null;
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                    stream = null;
                } catch (IOException ioe2) {
                }
            }
        }
        init(result);
    }

    public QemuConfig(File configFile) {
        //Transform file into byte[]/arraylist
        ArrayList<String> result;
        BufferedReader stream = null;
        try {
            stream = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream(configFile), StandardCharsets.ISO_8859_1));
            result = new ArrayList<>();
            String line;

            while ((line = stream.readLine()) != null) {
                if (line.startsWith("#") == false) {
                    if (line.isEmpty() == false) {
                        result.add(line.trim());
                    }
                }
            }
            stream.close();
            stream = null;
        } catch (IOException e) {
            result = null;
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                    stream = null;
                } catch (IOException ioe2) {
                }
            }
        }
        init(result);
    }

    public void init(ArrayList<String> lines) {
        int index = -1;
        int nbDev = 0;
        int nbDrive = 0;

        ArrayList<String> listID = new ArrayList<>();
        LinkedHashMap<String, String> headers = null;
        TreeMap<String, String> options = null;
        boolean exist = false;
        if (lines != null) {
            //Adding all the lines to a Map
            for (String option : lines) {
                if (option.startsWith("[") && option.endsWith("]")) {
                    option = option.replaceAll("\\[|\\]", "");
                    headers = new LinkedHashMap<>();
                    if (option.contains(DRIVE.getHeader()) && option.contains(quote)) { //Check drive with id
                        String[] drive = option.split(quote);
                        for (String id : listID) {
                            if (drive[1].equals(id)) {
                                DRIVE.setID("id-disk-" + nbDrive);
                                listID.add(DRIVE.getID());
                                exist = true;
                            }
                        }
                        if (!exist) {
                            DRIVE.setID(drive[1]);
                            listID.add(DRIVE.getID());
                        }
                        headers.put(DRIVE.getHeader(), DRIVE.getID());
                        nbDrive++;
                    } else if (option.equals(DRIVE.getHeader())) {//Check drive without id
                        DRIVE.setID("id-disk-" + nbDrive);
                        listID.add(DRIVE.getID());
                        headers.put(option, DRIVE.getID());
                        nbDrive++;
                        // } else if (option.equals(NETDEV.toString())){//Check drive without id TODO                       
                    } else if (option.equals(DEVICE.getHeader())) {//This will alwas come as [device]
                        DRIVE.setID("dev" + nbDev);
                        headers.put(option, DRIVE.getID());
                        nbDev++;
                    } else {
                        headers.put(option, null);
                    }
                    options = new TreeMap<>();
                    index++;
                } else if (index == -1) {
                    //In case file doesn't begin with a header
                    LOGGER.error("This config file is invalid. Chech syntax. Must begin with [..]");
                } else {
                    String[] parameter = option.split("=");
                    options.put(parameter[0].trim(), parameter[1].trim().replace("\"", ""));
                    entries.put(headers, options);
                }
            }
        }
    }

    public TreeMap<String, String> get(String key, String id) {
        TreeMap<String, String> value = null;
        LinkedHashMap keys = new LinkedHashMap();
        keys.put(key, id);
        if (entries.containsKey(keys)) {
            value = entries.get(keys);
        }
        return value; //value of key
    }

    public void set(LinkedHashMap<String, String> key, TreeMap value) {
        entries.put(key, value);
    }

    public TreeMap<LinkedHashMap<String, String>, TreeMap<String, String>> get() {
        return (TreeMap<LinkedHashMap<String, String>, TreeMap<String, String>>) entries;
    }

    public String getDisplayName() {
        String result = "";
        LinkedHashMap key = new LinkedHashMap();
        key.put(NAME.getHeader(), null);

        if (entries.containsKey(key)) {
            result = entries.get(key).get("guest");
        }
        return result;
    }

    public boolean isMachineSnapshot() {
        boolean isSnapshot = false;
        LinkedHashMap key = new LinkedHashMap();
        key.put(DRIVE.getHeader(), DRIVE.getID());
        String active = entries.get(key).get("snapshot");

        if (active != null && active.equals("on")) {
            isSnapshot = true;
        }
        return isSnapshot;
    }

    public void setOsName() {
        //It is not defined in config file. Using dummy name. Will be set in combo box later
        osName = "QemuOS";
    }

    public String getOsName() {
        return osName;
    }

    public void setHdds() {
        int dev = 0;
        String filename = null;
        DriveBusType bus = null;
        String controllerDevice = null;
        TreeMap<String, String> options = new TreeMap<>();
        for (Map.Entry<LinkedHashMap<String, String>, TreeMap<String, String>> entry : entries.entrySet()) {
            if (entry.getKey().containsKey(DRIVE.getHeader())) {
                if (entry.getValue().containsKey("index")) {
                    if (entry.getValue().get("index").equals("0")) {
                        DRIVE.setID(entry.getKey().get(DRIVE.getHeader()));
                        //Get Path
                        filename = entry.getValue().get("file");
                        if (filename == null) {
                            LOGGER.error("Please make sure your harddrive has a path");
                        }
                        //Get Bus Type
                        String busType = entry.getValue().get("if");
                        if (busType == null) {
                            bus = DriveBusType.IDE;
                        } else {
                            switch (busType) {
                                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;
                            }
                        }
                    }
                }
            } //TODO set default device if no device found
            if (entry.getKey().containsKey(DEVICE.getHeader())) {
                String drive = entry.getValue().get("drive");
                if (drive != null && drive.equals(DRIVE.getID())) {
                    controllerDevice = entry.getValue().get("driver");
                }
            }
            for (String key : entry.getKey().keySet()) {
                if (key.contains(DEVICE.getHeader())) {
                    dev++;
                }
            }
            //No device
            if (dev == 0) {
                if (bus.equals(DriveBusType.IDE)) {
                    controllerDevice = "ide-hd";
                }else if (bus.equals(DriveBusType.SCSI)) {
                    controllerDevice = "scsi-hd";
                }
            }
            if ((bus != null) && (filename != null) && (controllerDevice != null)) {
                hddsArray.add(new VmMetaData.HardDisk(controllerDevice, bus, filename));
                break;
            }
        }
    }

    public ArrayList<VmMetaData.HardDisk> getHdds() {
        return hddsArray;
    }

    public String toString(boolean filtered) {
        StringBuilder sb = new StringBuilder(300);
        LinkedHashMap<LinkedHashMap<String, String>, TreeMap<String, String>> sortedArray = null;
        if (filtered) {
            sortedArray = new LinkedHashMap<>();
            for (Map.Entry<LinkedHashMap<String, String>, TreeMap<String, String>> entry : entries.entrySet()) {

                if ((entry.getKey().keySet().equals(NAME.getHeader())) || (entry.getKey().keySet().equals(DRIVE.getHeader()) || entry.getKey().keySet().equals(DEVICE.getHeader()))) {
                    sortedArray.put(entry.getKey(), entry.getValue());
                }
            }
        }

        for (Map.Entry<LinkedHashMap<String, String>, TreeMap<String, String>> entry : sortedArray == null ? entries.entrySet() : sortedArray.entrySet()) {

            String header = entry.getKey().keySet().toString();;

            if (entry.getKey().containsKey(DRIVE.getHeader())) {
                if ((entry.getValue().get("index") != null)) {
                    if ((entry.getValue().get("index").equals("0"))) {
                        header = DRIVE.toString();
                    } else {
                        continue;
                    }
                } else {
                    continue;
                }
            }

            if (entry.getKey().containsKey(DEVICE.getHeader())) {
                header = "[" + DEVICE.getHeader() + "]";
            }

            sb.append(header + "\n");
            TreeMap<String, String> values = entry.getValue();

            for (String key : values.keySet()) {
                String value = values.get(key);
                sb.append("  " + key + " = " + value + "\n");
            }
        }
        LOGGER.debug(sb);
        return sb.toString();
    }
}