summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/QemuConfig.java
blob: 358fa1f8261f944d91698df05ec07318334d70b1 (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<String, TreeMap<String, String>> entries = new LinkedHashMap<>();

    private String osName = new String();

    private ArrayList<VmMetaData.HardDisk> hddsArray = new ArrayList<>();
    
    // BOOT("netdev", "net0") -> toString -> "[netdev "net0"]"
    public static enum Header {
        BOOT("[boot-opts]", "asd"), DEV("[dev"), DEVICE("[device]"), DRIVE("[drive"), 
            MACHINE("[machine]"), MEMORY("[memory]"), NAME("[name]"),
                NETDEV("[netdev "), SMP("[smp-opts]"); 
        
        private final String header;
        
        private Header(String header. String id){
            this.header = header;
        }
        
        public String value(){
            return this.header;
        }
    }
    
    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(DEV.value())) {
                            result.add(DEVICE.value());
                        } 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;
        Device dev;
        TreeMap<String, String> options = new TreeMap<>();
        if (lines != null) {

            for (String option : lines) {

                if (option.startsWith("[")) { //key only
                    if (option.equals(Header.DEVICE.value())) {
                        dev = new Device();
                        dev.setName(DEV.value()+ nbDev + "]");
                        option = dev.getName();
                        nbDev++;
                    }
                    entries.put(option, null);
                    options = new TreeMap();
                    index++;
                } else if (index == -1) {
                    // In case file doesnt begin with header
                    LOGGER.error("This config file is invalid.  Check syntax. Must begin with [...]");
                } else {
                    // adding value to key
                    String[] opt = option.split("=");
                    options.put(opt[0].trim(), opt[1].trim());
                    entries.keySet();
                    String key = (String) entries.keySet().toArray()[index];
                    entries.put(key, options);
                }
            }
        }
    }

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

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

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

    public String getDisplayName() {
        String result = "";
        if (entries.containsKey(NAME.value())) {
            result = (String) entries.get(NAME.value()).get("guest");
            result = result.replace("\"", "");
        }

        return result;
    }

    public boolean isMachineSnapshot() {
        boolean isSnapshot = false;
        String[] idDrive = null;
        for (String key : entries.keySet()) {
            if (key.contains(DRIVE.value())) {
                idDrive = key.split("\"");
            }
        }
        String active = entries.get(DRIVE.value()+" \"" + idDrive[1] + "\"]").get("snapshot");
        active = active.replace("\"", "");
        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() {
        String[] idDrive = null;
        String filename = null;
        DriveBusType bus = null;
        String controllerDevice = null;
        for (String entry : entries.keySet()) {

            if (entry.contains(DRIVE.value())) {
                idDrive = entry.split("\"");

                //Get Path
                filename = entries.get(entry).get("file");
                filename = filename.replace("\"", "");
                if (filename == null) {
                    LOGGER.error("Please make sure your harddrive has a path");
                }

                //Bus Type
                String busType = entries.get(entry).get("if");
                busType = busType.replace("\"", "");
                if (busType == null) {
                    LOGGER.error("Please make sure your harddrive has a bus");
                } 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;
                    }
                }
            }

            if (entry.contains(DEV.value())) {
                String drive = entries.get(entry).get("drive");
                drive = drive.replace("\"", "");

                if (drive != null && drive.equals(idDrive[1])) {
                    controllerDevice = entries.get(entry).get("driver");
                }
            }

            if ((bus != null) && (filename != null) && (controllerDevice != null)) {
                hddsArray.add(new VmMetaData.HardDisk(controllerDevice, bus, filename));
                idDrive = null;
                filename = null;
                bus = null;
                controllerDevice = null;
            }
        }
    }

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

    public String toString(boolean filtered) {
        StringBuilder sb = new StringBuilder(300);
        LinkedHashMap<String, TreeMap<String, String>> sortedArray = null;
        if (filtered) {
            sortedArray = new LinkedHashMap<>();
            for (Map.Entry<String, TreeMap<String, String>> entry : entries.entrySet()) {
            
                if ((entry.getKey().equals(NAME.value())) || (entry.getKey().contains(DRIVE.value())) || entry.getKey().contains(DEV.value())) {
                    sortedArray.put(entry.getKey(), entry.getValue());
                }
            }
        }

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

            String header = entry.getKey();

            if (header.contains(DEV.value())) {
                header = DEVICE.value();
            }

            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();

    }

    public static class Device {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

}