summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/VboxConfig.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/util/vm/VboxConfig.java')
-rw-r--r--src/main/java/org/openslx/util/vm/VboxConfig.java122
1 files changed, 90 insertions, 32 deletions
diff --git a/src/main/java/org/openslx/util/vm/VboxConfig.java b/src/main/java/org/openslx/util/vm/VboxConfig.java
index 1eee0ed..5f2a21d 100644
--- a/src/main/java/org/openslx/util/vm/VboxConfig.java
+++ b/src/main/java/org/openslx/util/vm/VboxConfig.java
@@ -6,6 +6,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
@@ -47,7 +48,6 @@ public class VboxConfig
"/VirtualBox/Machine/Hardware/GuestProperties",
"/VirtualBox/Machine/Hardware/VideoCapture",
"/VirtualBox/Machine/Hardware/HID",
- "/VirtualBox/Machine/Hardware/USB",
"/VirtualBox/Machine/Hardware/LPT",
"/VirtualBox/Machine/Hardware/SharedFolders",
"/VirtualBox/Machine/Hardware/Network/Adapter[@enabled='true']/*",
@@ -141,6 +141,7 @@ public class VboxConfig
try {
ensureHardwareUuid();
setOsType();
+ fixUsb(); // Since we now support selecting specific speed
if ( checkForPlaceholders() ) {
return;
}
@@ -152,6 +153,33 @@ public class VboxConfig
return;
}
}
+
+ private void fixUsb()
+ {
+ NodeList list = findNodes( "/VirtualBox/Machine/Hardware/USB/Controllers/Controller" );
+ if ( list != null && list.getLength() != 0 ) {
+ LOGGER.info( "USB present, not fixing anything" );
+ return;
+ }
+ // If there's no USB section, this can mean two things:
+ // 1) Old config that would always default to USB 2.0 for "USB enabled" or nothing for disabled
+ // 2) New config with USB disabled
+ list = findNodes( "/VirtualBox/OpenSLX/USB[@disabled]" );
+ if ( list != null && list.getLength() != 0 ) {
+ LOGGER.info( "USB explicitly disabled" );
+ return; // Explicitly marked as disabled, do nothing
+ }
+ // We assume case 1) and add USB 2.0
+ LOGGER.info( "Fixing USB: Adding USB 2.0" );
+ Element controller;
+ Element node = createNodeRecursive( "/VirtualBox/Machine/Hardware/USB/Controllers" );
+ controller = addNewNode( node, "Controller" );
+ controller.setAttribute( "name", "OHCI" );
+ controller.setAttribute( "type", "OHCI" );
+ controller = addNewNode( node, "Controller" );
+ controller.setAttribute( "name", "EHCI" );
+ controller.setAttribute( "type", "EHCI" );
+ }
/**
* Saves the machine's uuid as hardware uuid to prevent VMs from
@@ -379,35 +407,6 @@ public class VboxConfig
}
/**
- * Enable USB by adding the element /VirtualBox/Machine/Hardware/USB
- * and adding controllers for OHCI and EHCI (thus enabling USB 2.0).
- */
- public void enableUsb()
- {
- addNewNode( "/VirtualBox/Machine/Hardware", "USB" );
- addNewNode( "/VirtualBox/Machine/Hardware/USB", "Controllers" );
- // OHCI for USB 1.0
- Node ohci = addNewNode( "/VirtualBox/Machine/Hardware/USB/Controllers", "Controller" );
- addAttributeToNode( ohci, "name", "OHCI" );
- addAttributeToNode( ohci, "type", "OHCI" );
- // EHCI for USB 2.0
- Node ehci = addNewNode( "/VirtualBox/Machine/Hardware/USB/Controllers", "Controller" );
- addAttributeToNode( ehci, "name", "EHCI" );
- addAttributeToNode( ehci, "type", "EHCI" );
- }
-
- /**
- * Removes all USB elements
- */
- public void disableUsb()
- {
- NodeList usbList = findNodes( "/VirtualBox/Machine/Hardware/USB" );
- for ( int i = 0; i < usbList.getLength(); i++ ) {
- removeNode( usbList.item( 0 ) );
- }
- }
-
- /**
* Detect if the vbox file has any machine snapshot by looking at
* the existance of '/VirtualBox/Machine/Snapshot' elements.
*
@@ -502,6 +501,39 @@ public class VboxConfig
return addNewNode( possibleParents.item( 0 ), childName );
}
+ public Element createNodeRecursive( String xPath )
+ {
+ String[] nodeNames = xPath.split( "/" );
+ Node parent = this.doc;
+ Element latest = null;
+ for ( int nodeIndex = 0; nodeIndex < nodeNames.length; ++nodeIndex ) {
+ if ( nodeNames[nodeIndex].length() == 0 )
+ continue;
+ Node node = skipNonElementNodes( parent.getFirstChild() );
+ while ( node != null ) {
+ if ( node.getNodeType() == Node.ELEMENT_NODE && nodeNames[nodeIndex].equals( node.getNodeName() ) )
+ break; // Found existing
+ // Check next on same level
+ node = skipNonElementNodes( node.getNextSibling() );
+ }
+ if ( node == null ) {
+ node = doc.createElement( nodeNames[nodeIndex] );
+ parent.appendChild( node );
+ }
+ parent = node;
+ latest = (Element)node;
+ }
+ return latest;
+ }
+
+ private Element skipNonElementNodes( Node nn )
+ {
+ while ( nn != null && nn.getNodeType() != Node.ELEMENT_NODE ) {
+ nn = nn.getNextSibling();
+ }
+ return (Element)nn;
+ }
+
/**
* Creates a new element to the given parent node.
*
@@ -509,12 +541,12 @@ public class VboxConfig
* @param childName name of the new element to create
* @return the newly created node
*/
- public Node addNewNode( Node parent, String childName )
+ public Element addNewNode( Node parent, String childName )
{
if ( parent == null || parent.getNodeType() != Node.ELEMENT_NODE ) {
return null;
}
- Node newNode = null;
+ Element newNode = null;
try {
newNode = doc.createElement( childName );
parent.appendChild( newNode );
@@ -548,4 +580,30 @@ public class VboxConfig
{
return XmlHelper.getXmlFromDocument( doc, prettyPrint );
}
+
+ /**
+ * Remove all nodes with name childName from parentPath
+ * @param parentPath XPath to parent node of where child nodes are to be deleted
+ * @param childName Name of nodes to delete
+ */
+ public void removeNodes( String parentPath, String childName )
+ {
+ NodeList parentNodes = findNodes( parentPath );
+ // XPath might match multiple nodes
+ for ( int i = 0; i < parentNodes.getLength(); ++i ) {
+ Node parent = parentNodes.item( i );
+ List<Node> 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 );
+ }
+ }
+ }
}