From 50325c96681b1b23d457aed49bac594dcd51f37f Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Thu, 28 Feb 2019 11:09:00 +0100 Subject: [vbox] fix bad detection of multiple hard drives --- src/main/java/org/openslx/util/vm/VboxConfig.java | 43 ++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'src/main/java/org/openslx/util/vm/VboxConfig.java') diff --git a/src/main/java/org/openslx/util/vm/VboxConfig.java b/src/main/java/org/openslx/util/vm/VboxConfig.java index fe85638..1eee0ed 100644 --- a/src/main/java/org/openslx/util/vm/VboxConfig.java +++ b/src/main/java/org/openslx/util/vm/VboxConfig.java @@ -306,24 +306,42 @@ public class VboxConfig } /** - * Search disk drives within the DOM using this class + * Search for attached hard drives and determine their controller and their path. * * @throws XPathExpressionException */ public void setHdds() throws XPathExpressionException { - XPathExpression hddsExpr = XmlHelper.XPath.compile( "/VirtualBox/Machine/MediaRegistry/HardDisks/*" ); + XPathExpression hddsExpr = XmlHelper.XPath.compile( "/VirtualBox/Machine/StorageControllers/StorageController/AttachedDevice[@type='HardDisk']/Image" ); NodeList nodes = (NodeList)hddsExpr.evaluate( this.doc, XPathConstants.NODESET ); + if ( nodes == null ) { + LOGGER.error( "Failed to find attached hard drives." ); + return; + } for ( int i = 0; i < nodes.getLength(); i++ ) { Element hddElement = (Element)nodes.item( i ); if ( hddElement == null ) continue; - String fileName = hddElement.getAttribute( "location" ); - String type = hddElement.getAttribute( "type" ); + String uuid = hddElement.getAttribute( "uuid" ); + if ( uuid.isEmpty() ) + continue; + // got uuid, check if it was registered + XPathExpression hddsRegistered = XmlHelper.XPath.compile( "/VirtualBox/Machine/MediaRegistry/HardDisks/HardDisk[@uuid='" + uuid + "']" ); + NodeList hddsRegisteredNodes = (NodeList)hddsRegistered.evaluate( this.doc, XPathConstants.NODESET ); + if ( hddsRegisteredNodes == null || hddsRegisteredNodes.getLength() != 1 ) { + LOGGER.error( "Found hard disk with uuid '" + uuid + "' which does not appear (unique) in the Media Registry. Skipping." ); + continue; + } + Element hddElementReg = (Element)hddsRegisteredNodes.item( 0 ); + if ( hddElementReg == null ) + continue; + String fileName = hddElementReg.getAttribute( "location" ); + String type = hddElementReg.getAttribute( "type" ); if ( !type.equals( "Normal" ) && !type.equals( "Writethrough" ) ) { LOGGER.warn( "Type of the disk file is neither 'Normal' nor 'Writethrough' but: " + type ); LOGGER.warn( "This makes the image not directly modificable, which might lead to problems when editing it locally." ); } + // search if it is also attached to a controller Node hddDevice = hddElement.getParentNode(); if ( hddDevice == null ) { LOGGER.error( "HDD node had a null parent, shouldn't happen" ); @@ -334,18 +352,19 @@ public class VboxConfig LOGGER.error( "HDD node had a null parent, shouldn't happen" ); continue; } - String controllerDevice = hddController.getAttribute( "type" ); - String bus = hddController.getAttribute( "name" ); + String controllerMode = hddController.getAttribute( "type" ); + String controllerType = hddController.getAttribute( "name" ); DriveBusType busType = null; - if ( bus.equals( "IDE" ) ) { + if ( controllerType.equals( "IDE" ) ) { busType = DriveBusType.IDE; - } else if ( bus.equals( "SCSI" ) ) { + } else if ( controllerType.equals( "SCSI" ) ) { busType = DriveBusType.SCSI; - } else if ( bus.equals( "SATA" ) ) { + } else if ( controllerType.equals( "SATA" ) ) { busType = DriveBusType.SATA; - } - // add them together - hddsArray.add( new HardDisk( controllerDevice, busType, fileName ) ); + } else + continue; + LOGGER.info( "Adding hard disk with controller: " + busType + " (" + controllerMode + ") from file '" + fileName + "'." ); + hddsArray.add( new HardDisk( controllerMode, busType, fileName ) ); } } -- cgit v1.2.3-55-g7522 From cb6aee22c694781bfc4c63332ec8ba471e6f4e18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 18 Jun 2019 17:34:41 +0200 Subject: Add support for configuring USB speed --- .../java/org/openslx/util/vm/QemuMetaData.java | 32 ++++-- src/main/java/org/openslx/util/vm/VboxConfig.java | 122 +++++++++++++++------ .../java/org/openslx/util/vm/VboxMetaData.java | 77 +++++++++++-- src/main/java/org/openslx/util/vm/VmMetaData.java | 43 ++++++-- .../java/org/openslx/util/vm/VmwareMetaData.java | 78 +++++++++++-- 5 files changed, 279 insertions(+), 73 deletions(-) (limited to 'src/main/java/org/openslx/util/vm/VboxConfig.java') diff --git a/src/main/java/org/openslx/util/vm/QemuMetaData.java b/src/main/java/org/openslx/util/vm/QemuMetaData.java index dcb3b68..cd18abd 100644 --- a/src/main/java/org/openslx/util/vm/QemuMetaData.java +++ b/src/main/java/org/openslx/util/vm/QemuMetaData.java @@ -15,7 +15,7 @@ import org.openslx.thrifthelper.TConst; import org.openslx.util.vm.DiskImage.ImageFormat; import org.openslx.util.vm.DiskImage.UnknownImageFormatException; -public class QemuMetaData extends VmMetaData +public class QemuMetaData extends VmMetaData { private final Map arguments = new HashMap(); @@ -37,7 +37,7 @@ public class QemuMetaData extends VmMetaData delList = new ArrayList<>( 0 ); + // Iterate over child nodes + for ( Node child = parent.getFirstChild(); child != null; child = child.getNextSibling() ) { + if ( childName.equals( child.getNodeName() ) ) { + // Remember all to be deleted (don't delete while iterating) + delList.add( child ); + } + } + // Now delete them all + for ( Node child : delList ) { + parent.removeChild( child ); + } + } + } } diff --git a/src/main/java/org/openslx/util/vm/VboxMetaData.java b/src/main/java/org/openslx/util/vm/VboxMetaData.java index 00ca8ad..8fa530b 100644 --- a/src/main/java/org/openslx/util/vm/VboxMetaData.java +++ b/src/main/java/org/openslx/util/vm/VboxMetaData.java @@ -7,6 +7,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; +import java.util.Map.Entry; import java.util.UUID; import org.apache.log4j.Logger; @@ -14,6 +15,7 @@ import org.openslx.bwlp.thrift.iface.OperatingSystem; import org.openslx.bwlp.thrift.iface.Virtualizer; import org.openslx.thrifthelper.TConst; import org.openslx.util.vm.VboxConfig.PlaceHolder; +import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -62,7 +64,18 @@ class VBoxEthernetDevTypeMeta } } -public class VboxMetaData extends VmMetaData +class VBoxUsbSpeedMeta +{ + public final String value; + public final int speed; + public VBoxUsbSpeedMeta( String value, int speed ) + { + this.value = value; + this.speed = speed; + } +} + +public class VboxMetaData extends VmMetaData { private static final Logger LOGGER = Logger.getLogger( VboxMetaData.class ); @@ -113,16 +126,6 @@ public class VboxMetaData extends VmMetaData s : usbSpeeds.entrySet() ) { + if ( s.getValue().speed > maxSpeed && type.equals( s.getValue().value ) ) { + maxSpeed = s.getValue().speed; + maxItem = s.getKey(); + } + } + } + return maxItem; + } } diff --git a/src/main/java/org/openslx/util/vm/VmMetaData.java b/src/main/java/org/openslx/util/vm/VmMetaData.java index c750ecc..9cff9f5 100644 --- a/src/main/java/org/openslx/util/vm/VmMetaData.java +++ b/src/main/java/org/openslx/util/vm/VmMetaData.java @@ -18,7 +18,7 @@ import org.openslx.bwlp.thrift.iface.Virtualizer; * Describes a configured virtual machine. This class is parsed from a machine * description, like a *.vmx for VMware machines. */ -public abstract class VmMetaData +public abstract class VmMetaData { private static final Logger LOGGER = Logger.getLogger( VmMetaData.class ); @@ -29,6 +29,7 @@ public abstract class VmMetaData protected Map ddacc = new HashMap<>(); protected Map hwversion = new HashMap<>(); protected Map networkCards = new HashMap<>(); + protected Map usbSpeeds = new HashMap<>(); /** * Virtual sound cards types @@ -103,6 +104,21 @@ public abstract class VmMetaData this.displayName = dName; } } + + public static enum UsbSpeed + { + NONE( "None" ), + USB1_1( "USB 1.1" ), + USB2_0( "USB 2.0" ), + USB3_0( "USB 3.0" ); + + public final String displayName; + + private UsbSpeed( String dName ) + { + this.displayName = dName; + } + } public static enum DriveBusType { @@ -172,6 +188,13 @@ public abstract class VmMetaData return availables; } + public List getSupportedUsbSpeeds() + { + ArrayList availables = new ArrayList<>( usbSpeeds.keySet() ); + Collections.sort( availables ); + return availables; + } + /** * Get operating system of this VM. */ @@ -270,7 +293,7 @@ public abstract class VmMetaData * @param file VM's machine description file to get the metadata instance from * @return VmMetaData object representing the relevant parts of the given machine description */ - public static VmMetaData getInstance( List osList, File file ) + public static VmMetaData getInstance( List osList, File file ) throws IOException { try { @@ -301,20 +324,24 @@ public abstract class VmMetaData * @return VmMetaData object representing the relevant parts of the given machine description * @throws IOException */ - public static VmMetaData getInstance( List osList, byte[] vmContent, int length ) throws IOException + public static VmMetaData getInstance( List osList, byte[] vmContent, int length ) throws IOException { + Map exceptions = new HashMap<>(); try { return new VmwareMetaData( osList, vmContent, length ); } catch ( UnsupportedVirtualizerFormatException e ) { - LOGGER.info( "Not a VMware file", e ); + exceptions.put( "Not a VMware file", e ); } try { return new VboxMetaData( osList, vmContent, length ); } catch ( UnsupportedVirtualizerFormatException e ) { - LOGGER.info( "Not a VirtualBox file", e ); + exceptions.put( "Not a VirtualBox 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 e : exceptions.entrySet() ) { + LOGGER.error( e.getKey(), e.getValue() ); + } return null; } @@ -352,14 +379,16 @@ public abstract class VmMetaData public abstract EthernetDevType getEthernetDevType( int cardIndex ); + public abstract void setMaxUsbSpeed( UsbSpeed speed ); + + public abstract UsbSpeed getMaxUsbSpeed(); + public abstract byte[] getDefinitionArray(); public abstract boolean addEthernet( EtherType type ); public abstract Virtualizer getVirtualizer(); - public abstract void enableUsb( boolean enabled ); - public abstract boolean disableSuspend(); /** diff --git a/src/main/java/org/openslx/util/vm/VmwareMetaData.java b/src/main/java/org/openslx/util/vm/VmwareMetaData.java index 4e154c3..1e87d72 100644 --- a/src/main/java/org/openslx/util/vm/VmwareMetaData.java +++ b/src/main/java/org/openslx/util/vm/VmwareMetaData.java @@ -59,7 +59,19 @@ class VmWareEthernetDevTypeMeta } } -public class VmwareMetaData extends VmMetaData +class VmwareUsbSpeed +{ + public final String keyName; + public final int speedNumeric; + + public VmwareUsbSpeed( int speed, String key ) + { + this.keyName = key + ".present"; + this.speedNumeric = speed; + } +} + +public class VmwareMetaData extends VmMetaData { private static final Logger LOGGER = Logger.getLogger( VmwareMetaData.class ); @@ -157,6 +169,11 @@ public class VmwareMetaData extends VmMetaData entry : usbSpeeds.entrySet() ) { + VmwareUsbSpeed v = entry.getValue(); + if ( v.speedNumeric > max && isSetAndTrue( v.keyName ) ) { + max = v.speedNumeric; + maxEnum = entry.getKey(); + } + } + return maxEnum; } @Override @@ -599,5 +649,11 @@ public class VmwareMetaData extends VmMetaData public abstract Virtualizer getVirtualizer(); - public abstract boolean disableSuspend(); + public abstract boolean tweakForNonPersistent(); /** * Function used to register virtual devices diff --git a/src/main/java/org/openslx/util/vm/VmwareMetaData.java b/src/main/java/org/openslx/util/vm/VmwareMetaData.java index 1e87d72..fb5b22a 100644 --- a/src/main/java/org/openslx/util/vm/VmwareMetaData.java +++ b/src/main/java/org/openslx/util/vm/VmwareMetaData.java @@ -396,7 +396,7 @@ public class VmwareMetaData extends VmMetaData