summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/QemuConfig.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/util/vm/QemuConfig.java')
-rw-r--r--src/main/java/org/openslx/util/vm/QemuConfig.java441
1 files changed, 441 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/util/vm/QemuConfig.java b/src/main/java/org/openslx/util/vm/QemuConfig.java
new file mode 100644
index 0000000..89df62c
--- /dev/null
+++ b/src/main/java/org/openslx/util/vm/QemuConfig.java
@@ -0,0 +1,441 @@
+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 static String QUOTE = "\"";
+
+ private ArrayList<VmMetaData.HardDisk> hddsArray = new ArrayList<>();
+
+ public static enum Header {
+ BOOT("boot-opts", null), DEVICE("device", null), 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() {
+ String result;
+ if (id == null) {
+ result = "[" + header + "]";
+ } else {
+ result = "[" + header + " " + QUOTE + id + QUOTE + "]";
+ }
+ return result;
+ }
+ }
+
+ public QemuConfig(byte[] vmContent, int length) {
+ 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) {
+ 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) {
+ 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;
+ int nbNetDev = 0;
+
+ ArrayList<String> listID = new ArrayList<>();
+ LinkedHashMap<String, String> headers = null;
+ TreeMap<String, String> options = null;
+ boolean exist = false;
+ boolean save = true;
+ if (lines != null) {
+ 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++;
+ exist = false;
+ } 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.contains(NETDEV.getHeader()) && option.contains(QUOTE)) {//Check netdev with id
+ String[] netdev = option.split(QUOTE);
+ for (String id : listID) {
+ if (netdev[1].equals(id)) {
+ NETDEV.setID("id-netdev-" + nbNetDev);
+ listID.add(NETDEV.getID());
+ exist = true;
+ }
+ }
+ if (!exist) {
+ NETDEV.setID(netdev[1]);
+ listID.add(NETDEV.getID());
+ }
+ headers.put(NETDEV.getHeader(), NETDEV.getID());
+ nbNetDev++;
+ exist = false;
+ } else if (option.equals(NETDEV.toString())) {//Check netdev without id
+ NETDEV.setID("id-netdev-" + nbNetDev);
+ listID.add(NETDEV.getID());
+ headers.put(option, NETDEV.getID());
+ } else if (option.equals(DEVICE.getHeader())) {//This will always come as [device]
+ DEVICE.setID("dev" + nbDev);
+ headers.put(option, DEVICE.getID());
+ nbDev++;
+ } else {
+ if (option.equals(MEMORY.getHeader()) || option.equals(SMP.getHeader()) || option.equals(MACHINE.getHeader())) {
+ save = false;
+ continue;
+ } 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 {
+ if (save) {
+ String[] parameter = option.split("=");
+ options.put(parameter[0].trim(), parameter[1].trim().replace(QUOTE, ""));
+ entries.put(headers, options);
+ }else{
+ save = true;
+ }
+ }
+ }
+ }
+ }
+
+ 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;
+ }
+
+ 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;
+ LinkedHashMap<String, String> keys;
+ TreeMap<String, String> options;
+ for (Map.Entry<LinkedHashMap<String, String>, TreeMap<String, String>> entry : entries.entrySet()) {
+ String busType;
+ 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()));
+
+ filename = entry.getValue().get("file");
+ if (filename == null) {
+ LOGGER.error("Please make sure your harddrive has a path");
+ }
+
+ busType = entry.getValue().get("if");
+ if (busType != null) {
+ switch (busType) {
+ case "ide":
+ bus = DriveBusType.IDE;
+ break;
+ case "scsi":
+ bus = DriveBusType.SCSI;
+ break;
+// case "virtio":
+ // bus = DriveBusType.VIRTIO;
+ case "sata":
+ //not available for Qemu. Others : sd, mtd, floppy, pflash
+ break;
+ default:
+ bus = DriveBusType.SCSI;
+ break;
+ }
+ } else {
+ bus = DriveBusType.SCSI;
+ busType = "scsi";
+ keys = new LinkedHashMap<>();
+ keys.put(DRIVE.getHeader(), DRIVE.getID());
+ options = entries.get(entry.getKey());
+ options.put("if", busType);
+ entries.put(keys, options);
+ }
+ }
+ }
+ }
+ if (entry.getKey().containsKey(DEVICE.getHeader())) {
+ String drive = entry.getValue().get("drive");
+ if (drive != null && drive.equals(DRIVE.getID())) {
+ controllerDevice = entry.getValue().get("driver");
+ dev++;
+ }
+ } else {
+ for (LinkedHashMap<String, String> key : entries.keySet()) {
+ if (key.containsKey(DEVICE.getHeader())) {
+ dev++;
+ }
+ }
+ }
+ if (dev == 0) {
+ if (bus != null) {
+ switch (bus) {
+ case IDE:
+ controllerDevice = "ide-hd";
+ break;
+ case SCSI:
+ controllerDevice = "scsi-generic";
+ break;
+ default:
+ controllerDevice = "scsi-generic";
+ break;
+ }
+ }
+ }
+ if ((bus != null) && (filename != null) && (controllerDevice != null)) {
+ hddsArray.add(new VmMetaData.HardDisk(controllerDevice, bus, filename));;
+
+ if (dev == 0) {
+ keys = new LinkedHashMap<>();
+ options = new TreeMap<>();
+ DEVICE.setID(DRIVE.getID());
+ keys.put(DEVICE.getHeader(), DEVICE.getID());
+ options.put("drive", DRIVE.getID());
+ options.put("driver", controllerDevice);
+ entries.put(keys, options);
+ }
+ 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().containsKey(DEVICE.getHeader())) {
+ DEVICE.setID(null);
+ entry.getKey().replace(DEVICE.getHeader(), null);
+ sortedArray.put(entry.getKey(), entry.getValue());
+ }
+ if (entry.getKey().containsKey(NAME.getHeader()) || entry.getKey().containsKey(DRIVE.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 if (entry.getValue().get("media") != null) {
+ DRIVE.setID(entry.getKey().get(DRIVE.getHeader()));
+ header = DRIVE.toString();
+ } else if (entry.getValue().get("if") != null) {
+ if (entry.getValue().get("if").equals("floppy")) {
+ DRIVE.setID(entry.getKey().get(DRIVE.getHeader()));
+ header = DRIVE.toString();
+ }
+ } else {
+ continue;
+ }
+ }
+
+ if (entry.getKey().containsKey(DEVICE.getHeader())) {
+ DEVICE.setID(null);
+ entry.getKey().remove(DEVICE.getHeader());
+ entry.getKey().put(DEVICE.getHeader(), null);
+ header = DEVICE.toString();
+ }
+
+ if (entry.getKey().containsKey(NETDEV.getHeader())) {
+ header = NETDEV.toString();
+ }
+
+ sb.append(header + "\n");
+ TreeMap<String, String> values = entry.getValue();
+
+ for (String key : values.keySet()) {
+ String value = values.get(key);
+ if (value == null) {
+ sb.append(" " + key + " = " + value + "\n");
+ } else {
+ if (key.equals("driver")) {
+ if (value.isEmpty()) {
+ continue;
+ }
+ }
+ sb.append(" " + key + " = " + QUOTE + value + QUOTE + "\n");
+ }
+ }
+ }
+ return sb.toString();
+ }
+}