summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/openslx/util/vm/DiskImage.java40
-rw-r--r--src/main/java/org/openslx/util/vm/QemuConfig.java441
-rw-r--r--src/main/java/org/openslx/util/vm/QemuMetaData.java589
-rw-r--r--src/main/java/org/openslx/util/vm/VboxConfig.java4
-rw-r--r--src/main/java/org/openslx/util/vm/VmMetaData.java63
-rw-r--r--src/main/java/org/openslx/util/vm/VmwareMetaData.java57
6 files changed, 926 insertions, 268 deletions
diff --git a/src/main/java/org/openslx/util/vm/DiskImage.java b/src/main/java/org/openslx/util/vm/DiskImage.java
index 2b24a3f..30fea99 100644
--- a/src/main/java/org/openslx/util/vm/DiskImage.java
+++ b/src/main/java/org/openslx/util/vm/DiskImage.java
@@ -19,9 +19,6 @@ public class DiskImage
*/
private static final int VMDK_MAGIC = 0x4b444d56;
private static final int VDI_MAGIC = 0x7f10dabe;
- /**
- * Big endian representation of the 4 bytes 'QFI\xFB'
- */
private static final int QEMU_MAGIC = 0x514649fb;
public enum ImageFormat
@@ -163,19 +160,30 @@ public class DiskImage
return;
}
- // TODO: qcow
- file.seek( 0 );
- if ( file.readInt() == QEMU_MAGIC ) {
- // dummy values
- this.isStandalone = true;
- this.isCompressed = false;
- this.isSnapshot = false;
- this.format = ImageFormat.QCOW2;
- this.subFormat = null;
- this.diskDescription = null;
- this.hwVersion = 0;
- return;
- }
+ file.seek(0);
+ //TODO: Standalone & Snapshot
+ if (file.readInt() == QEMU_MAGIC) {
+ //skip the next 14 ints as they don't interest us
+ // - QFI version (4 bytes)
+ // - backing file offset (8 bytes)
+ // - backing (8 bytes)
+ // - crypt method (4 bytes)
+ // - l1 size (4 bytes)
+ // - l1 table offset (8 bytes)
+ // - refcount table offset (8 bytes)
+ // - refcount cluster (4 bytes)
+ file.skipBytes( 14 * 4 );
+ this.isSnapshot = file.readInt() > 0;
+ //skip the next 14 ints as they don't interest us
+ file.seek(374);
+ this.isCompressed = file.read() == 1;
+ this.diskDescription = null;
+ this.format = ImageFormat.QCOW2;
+ this.isStandalone = true;
+ this.subFormat = null;
+ this.hwVersion = 0;
+ return;
+ }
}
throw new UnknownImageFormatException();
}
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();
+ }
+}
diff --git a/src/main/java/org/openslx/util/vm/QemuMetaData.java b/src/main/java/org/openslx/util/vm/QemuMetaData.java
index 201ffd8..814bfa4 100644
--- a/src/main/java/org/openslx/util/vm/QemuMetaData.java
+++ b/src/main/java/org/openslx/util/vm/QemuMetaData.java
@@ -1,233 +1,442 @@
package org.openslx.util.vm;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
+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 org.openslx.util.vm.DiskImage.ImageFormat;
-import org.openslx.util.vm.DiskImage.UnknownImageFormatException;
+import static org.openslx.util.vm.QemuConfig.Header.*;
-public class QemuMetaData extends VmMetaData<VBoxSoundCardMeta, VBoxDDAccelMeta, VBoxHWVersionMeta, VBoxEthernetDevTypeMeta, VBoxUsbSpeedMeta>
-{
+class QemuDDAccelMeta {
- private final Map<String, String> arguments = new HashMap<String, String>();
- // the above map's elements will take the place of <args> in the config string
- private String config;
- private static final Logger LOGGER = Logger.getLogger( QemuMetaData.class );
+ public final boolean isPresent;
- private static final Virtualizer virtualizer = new Virtualizer( TConst.VIRT_QEMU, "QEMU-KVM" );
-
- public QemuMetaData( List<OperatingSystem> osList, File file ) throws FileNotFoundException, IOException, UnsupportedVirtualizerFormatException
- {
- super( osList );
- DiskImage di;
- try {
- di = new DiskImage( file );
- } catch ( UnknownImageFormatException e ) {
- di = null;
- }
- if ( di == null || di.format != ImageFormat.QCOW2 ) {
- throw new UnsupportedVirtualizerFormatException( "This is not a qcow2 disk image" );
- }
- config = "qemu-system-i386 <args> <image> -enable-kvm\nqemu-system-x86_64 <args> <image> -enable-kvm";
- displayName = file.getName().substring( 0, file.getName().indexOf( "." ) );
- setOs( "anyOs" );
- hdds.add( new HardDisk( "anychipset", DriveBusType.IDE, file.getAbsolutePath() ) );
- makeStartSequence();
- }
-
- // initiates the arguments map with a default working sequence that will later be used in the definition array
- public void makeStartSequence()
- {
- arguments.put( "cpu", "host" );
- arguments.put( "smp", "2" );
- arguments.put( "m", "1024" );
- arguments.put( "vga", "std" );
- }
-
- private String configWithArgs()
- {
- String tempString = "";
- for ( String key : arguments.keySet() ) {
- tempString += "-" + key + " " + arguments.get( key ) + " ";
- }
- return config.replaceAll( "<args>", tempString );
- }
-
- @Override
- public byte[] getFilteredDefinitionArray()
- {
- return configWithArgs().getBytes( StandardCharsets.UTF_8 );
- }
-
- @Override
- public void applySettingsForLocalEdit()
- {
- }
-
- @Override
- public boolean addHddTemplate( File diskImage, String hddMode, String redoDir )
- {
- String tempS = config.replaceAll( "<image>", diskImage.getAbsolutePath() );
- config = tempS;
- hdds.add( new HardDisk( "anychipset", DriveBusType.IDE, diskImage.getAbsolutePath() ) );
- return true;
- }
-
- @Override
- public boolean addHddTemplate( String diskImagePath, String hddMode, String redoDir )
- {
- String tempS = config.replaceAll( "<image>", diskImagePath );
- config = tempS;
- hdds.add( new HardDisk( "anychipset", DriveBusType.IDE, diskImagePath ) );
- return true;
- }
-
- @Override
- public boolean addDefaultNat()
- {
- return true;
- }
-
- @Override
- public void setOs( String vendorOsId )
- {
- setOs( TConst.VIRT_QEMU, vendorOsId );
- }
-
- @Override
- public boolean addDisplayName( String name )
- {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean addRam( int mem )
- {
- this.arguments.put( "m", Integer.toString( mem ) );
- return true;
- }
-
- @Override
- public void addFloppy( int index, String image, boolean readOnly )
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public boolean addCdrom( String image )
- {
- // TODO Auto-generated method stub
- return false;
- }
+ public QemuDDAccelMeta(boolean present) {
+ isPresent = present;
+ }
+}
- @Override
- public boolean addCpuCoreCount( int nrOfCores )
- {
- this.arguments.put( "smp", Integer.toString( nrOfCores ) );
- return true;
- }
+class QemuHWVersionMeta {
- @Override
- public void setSoundCard( VmMetaData.SoundCardType type )
- {
- }
-
- @Override
- public VmMetaData.SoundCardType getSoundCard()
- {
- return null;
- }
+ public final int version;
- @Override
- public void setDDAcceleration( VmMetaData.DDAcceleration type )
- {
- }
+ public QemuHWVersionMeta(int vers) {
+ version = vers;
+ }
+}
- @Override
- public VmMetaData.DDAcceleration getDDAcceleration()
- {
- return null;
- }
+class QemuEthernetDevTypeMeta {
- @Override
- public void setHWVersion( VmMetaData.HWVersion type )
- {
- }
+ public final String value;
- @Override
- public VmMetaData.HWVersion getHWVersion()
- {
- return null;
- }
+ public QemuEthernetDevTypeMeta(String val) {
+ value = val;
+ }
+}
- @Override
- public void setEthernetDevType( int cardIndex, VmMetaData.EthernetDevType type )
- {
- }
+class QemuSoundCardMeta {
- @Override
- public VmMetaData.EthernetDevType getEthernetDevType( int cardIndex )
- {
- return null;
- }
+ public final boolean isPresent;
+ public final String value;
- @Override
- public byte[] getDefinitionArray()
- {
- return configWithArgs().getBytes( StandardCharsets.UTF_8 );
- }
+ public QemuSoundCardMeta(boolean present, String val) {
- @Override
- public boolean addEthernet( VmMetaData.EtherType type )
- {
- return false;
- }
+ isPresent = present;
+ value = val;
+ }
+}
+class QemuUSBMeta {
- @Override
- public Virtualizer getVirtualizer()
- {
- return virtualizer;
- }
+ public final String value;
+ public final int speed;
- @Override
- public boolean tweakForNonPersistent()
- {
- return false;
- }
+ public QemuUSBMeta(String value, int speed) {
- @Override
- public void registerVirtualHW()
- {
- }
+ this.value = value;
+ this.speed = speed;
+ }
+}
- @Override
+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 ) {
- arguments.remove( "usb" );
+ option.remove( "usb" );
} else {
- arguments.put( "usb", "" );
+ option.put( "usb", "" );
}
}
@Override
public VmMetaData.UsbSpeed getMaxUsbSpeed()
{
- if ( arguments.containsKey( "usb" ) )
+ 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"));
+
+ }
}
diff --git a/src/main/java/org/openslx/util/vm/VboxConfig.java b/src/main/java/org/openslx/util/vm/VboxConfig.java
index e9870a5..6153abf 100644
--- a/src/main/java/org/openslx/util/vm/VboxConfig.java
+++ b/src/main/java/org/openslx/util/vm/VboxConfig.java
@@ -101,7 +101,9 @@ public class VboxConfig
}
} catch ( SAXException e ) {
LOGGER.error( "Selected vbox file was not validated against the XSD schema: " + e.getMessage() );
- }
+ } catch ( Exception e) {
+ LOGGER.error( "Some error occured while trying to parse select virtualbox machine files: " + e.getMessage() );
+ }
// valid xml, try to create the DOM
doc = XmlHelper.parseDocumentFromStream( new FileInputStream( file ) );
doc = XmlHelper.removeFormattingNodes( doc );
diff --git a/src/main/java/org/openslx/util/vm/VmMetaData.java b/src/main/java/org/openslx/util/vm/VmMetaData.java
index 29e2db9..714a7e4 100644
--- a/src/main/java/org/openslx/util/vm/VmMetaData.java
+++ b/src/main/java/org/openslx/util/vm/VmMetaData.java
@@ -20,9 +20,9 @@ import org.openslx.bwlp.thrift.iface.Virtualizer;
*/
public abstract class VmMetaData<T, U, V, W, X>
{
- private static final Logger LOGGER = Logger.getLogger( VmMetaData.class );
+ private static final Logger LOGGER = Logger.getLogger(VmMetaData.class);
- /*
+ /*
* Helper types
*/
protected Map<SoundCardType, T> soundCards = new HashMap<>();
@@ -146,19 +146,19 @@ public abstract class VmMetaData<T, U, V, W, X>
}
/*
* Members
- */
+ */
- protected final List<HardDisk> hdds = new ArrayList<>();
+ protected final List<HardDisk> hdds = new ArrayList<>();
- private final List<OperatingSystem> osList;
+ private final List<OperatingSystem> osList;
- private OperatingSystem os = null;
+ private OperatingSystem os = null;
- protected String displayName = null;
+ protected String displayName = null;
- protected boolean isMachineSnapshot;
+ protected boolean isMachineSnapshot;
- /*
+ /*
* Getters for virtual hardware
*/
public List<SoundCardType> getSupportedSoundCards()
@@ -222,27 +222,25 @@ public abstract class VmMetaData<T, U, V, W, X>
/*
* 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() );
- }
-
- /*
+ */
+ 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
*/
@@ -338,6 +336,11 @@ public abstract class VmMetaData<T, U, V, W, X>
} catch ( UnsupportedVirtualizerFormatException e ) {
exceptions.put( "Not a VirtualBox file", e );
}
+ try {
+ return new QemuMetaData( osList, vmContent, length );
+ } catch ( UnsupportedVirtualizerFormatException e ) {
+ exceptions.put( "Not a QEMU 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" );
for ( Entry<String, Exception> e : exceptions.entrySet() ) {
diff --git a/src/main/java/org/openslx/util/vm/VmwareMetaData.java b/src/main/java/org/openslx/util/vm/VmwareMetaData.java
index 29227a7..fab90de 100644
--- a/src/main/java/org/openslx/util/vm/VmwareMetaData.java
+++ b/src/main/java/org/openslx/util/vm/VmwareMetaData.java
@@ -17,46 +17,42 @@ import org.openslx.thrifthelper.TConst;
import org.openslx.util.Util;
import org.openslx.util.vm.VmwareConfig.ConfigEntry;
-class VmWareSoundCardMeta
-{
- public final boolean isPresent;
- public final String value;
+class VmWareSoundCardMeta {
- public VmWareSoundCardMeta( boolean present, String val )
- {
- isPresent = present;
- value = val;
- }
+ public final boolean isPresent;
+ public final String value;
+
+ public VmWareSoundCardMeta(boolean present, String val) {
+ isPresent = present;
+ value = val;
+ }
}
-class VmWareDDAccelMeta
-{
- public final boolean isPresent;
+class VmWareDDAccelMeta {
- public VmWareDDAccelMeta( boolean present )
- {
- isPresent = present;
- }
+ public final boolean isPresent;
+
+ public VmWareDDAccelMeta(boolean present) {
+ isPresent = present;
+ }
}
-class VmWareHWVersionMeta
-{
- public final int version;
+class VmWareHWVersionMeta {
- public VmWareHWVersionMeta( int vers )
- {
- version = vers;
- }
+ public final int version;
+
+ public VmWareHWVersionMeta(int vers) {
+ version = vers;
+ }
}
-class VmWareEthernetDevTypeMeta
-{
- public final String value;
+class VmWareEthernetDevTypeMeta {
- public VmWareEthernetDevTypeMeta( String val )
- {
- value = val;
- }
+ public final String value;
+
+ public VmWareEthernetDevTypeMeta(String val) {
+ value = val;
+ }
}
class VmwareUsbSpeed
@@ -660,5 +656,4 @@ public class VmwareMetaData extends VmMetaData<VmWareSoundCardMeta, VmWareDDAcce
usbSpeeds.put( VmMetaData.UsbSpeed.USB2_0, new VmwareUsbSpeed( 2, "ehci" ) );
usbSpeeds.put( VmMetaData.UsbSpeed.USB3_0, new VmwareUsbSpeed( 3, "usb_xhci" ) );
}
-
}