package org.openslx.util.vm;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.Virtualizer;
class VBoxSoundCardMeta
{
public final boolean isPresent;
public final String value;
public VBoxSoundCardMeta( boolean present, String val )
{
isPresent = present;
value = val;
}
}
class VBoxDDAccelMeta
{
public final boolean isPresent;
public VBoxDDAccelMeta( boolean present )
{
isPresent = present;
}
}
class VBoxHWVersionMeta
{
public final int version;
public VBoxHWVersionMeta( int vers )
{
version = vers;
}
}
class VBoxEthernetDevTypeMeta
{
public final String value;
public VBoxEthernetDevTypeMeta( String val )
{
value = val;
}
}
public class VboxMetaData extends VmMetaData<VBoxSoundCardMeta, VBoxDDAccelMeta, VBoxHWVersionMeta, VBoxEthernetDevTypeMeta>
{
private static final Logger LOGGER = Logger.getLogger( VboxMetaData.class );
private static final Virtualizer virtualizer = new Virtualizer( "virtualbox", "VirtualBox" );
private final VboxConfig config;
public VboxMetaData( List<OperatingSystem> osList, File file ) throws IOException, UnsupportedVirtualizerFormatException
{
super( osList );
this.config = new VboxConfig( file );
init();
}
public VboxMetaData( List<OperatingSystem> osList, byte[] vmContent, int length ) throws IOException, UnsupportedVirtualizerFormatException
{
super( osList );
this.config = new VboxConfig( vmContent, length );
init();
}
private void init()
{
this.config.init();
displayName = config.getDisplayName();
setOs( "virtualbox", config.getOsName() );
for ( HardDisk hardDisk : config.getHdds() ) {
hdds.add( hardDisk );
}
// hey debug code here
try {
addFloppy( 0, null, true );
WriteToFile();
} catch ( TransformerFactoryConfigurationError | TransformerException e ) {
// WriteToFile exceptions here...not important for the the LOGGER
e.printStackTrace();
}
// end here
}
// --TODO will be needed later again
private void WriteToFile() throws TransformerFactoryConfigurationError, TransformerException
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult output = new StreamResult( new File( "output.xml" ) );
Source input = new DOMSource( config.getConfigDoc() );
transformer.transform( input, output );
}
@Override
public Virtualizer getVirtualizer()
{
return virtualizer;
}
@Override
public void enableUsb( boolean enabled )
{
// TODO Auto-generated method stub
}
@Override
public void applySettingsForLocalEdit()
{
// TODO Auto-generated method stub
}
@Override
public byte[] getFilteredDefinitionArray()
{
return config.toString().getBytes( StandardCharsets.UTF_8 );
}
@Override
public boolean addHddTemplate( String diskImage, String hddMode, String redoDir )
{
config.changeAttribute( "HardDisk", "location", diskImage );
return true;
}
@Override
public boolean addHddTemplate( File diskImage, String hddMode, String redoDir )
{
String diskImagePath = diskImage.getName();
config.changeAttribute( "HardDisk", "location", diskImagePath );
UUID newhdduuid = UUID.randomUUID();
LOGGER.debug( newhdduuid );
// patching the new uuid in the vbox config file here
String vboxUUid = "{" + newhdduuid.toString() + "}";
config.changeAttribute( "HardDisk", "uuid", vboxUUid );
config.changeAttribute( "Image", "uuid", vboxUUid );
// write the new hdd uuid in the vdi file
byte[] bytesToWrite = new byte[ 16 ];
int[] bytesOffset = { 32, 40, 48, 56, 16, 24, 0, 8, 56, 48, 40, 32, 24, 16, 8, 0 };
int offset = 0;
for ( int i = 0; i < 2; i++ ) {
Long uuidlong = null;
if ( i == 0 ) {
uuidlong = newhdduuid.getMostSignificantBits();
} else {
uuidlong = newhdduuid.getLeastSignificantBits();
}
for ( int j = 0; j < 8; j++ ) {
int index = j + offset;
bytesToWrite[index] = (byte) ( uuidlong >>> bytesOffset[index] );
}
offset = 8;
}
try ( RandomAccessFile file = new RandomAccessFile( diskImage, "rw" ) ) {
file.seek( 392 );
file.write( bytesToWrite, 0, 16 );
} catch ( Exception e ) {
LOGGER.warn( "could not patch new uuid in the vdi", e );
}
// we need a new machine uuid
UUID newMachineUuid = UUID.randomUUID();
if ( newMachineUuid.equals( newhdduuid ) ) {
LOGGER.warn( "The new Machine UUID is the same as the new HDD UUID; tying again...this vm might not start" );
newMachineUuid = UUID.randomUUID();
}
String machineUUid = "{" + newMachineUuid.toString() + "}";
config.changeAttribute( "Machine", "uuid", machineUUid );
return true;
}
@Override
public boolean addDefaultNat()
{
config.addNewNode( "Adapter", "NAT", false );
return true;
}
public void reWrite()
{
try {
WriteToFile();
} catch ( TransformerFactoryConfigurationError | TransformerException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void setOs( String vendorOsId )
{
// TODO Auto-generated method stub
}
@Override
public boolean addDisplayName( String name )
{
config.changeAttribute( "Machine", "name", name );
return true;
}
@Override
public boolean addRam( int mem )
{
config.changeAttribute( "Memory", "RAMSize", Integer.toString( mem ) );
return true;
}
@Override
public void addFloppy( int index, String image, boolean readOnly )
{
if ( image == null ) {
} else {
}
}
@Override
public boolean addCdrom( String image )
{
// TODO Auto-generated method stub
return false;
}
@Override
public boolean addCpuCoreCount( int nrOfCores )
{
config.changeAttribute( "CPU", "count", "1" );
return true;
}
@Override
public void setSoundCard( org.openslx.util.vm.VmMetaData.SoundCardType type )
{
// TODO Auto-generated method stub
}
@Override
public org.openslx.util.vm.VmMetaData.SoundCardType getSoundCard()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void setDDAcceleration( org.openslx.util.vm.VmMetaData.DDAcceleration type )
{
// TODO Auto-generated method stub
}
@Override
public org.openslx.util.vm.VmMetaData.DDAcceleration getDDAcceleration()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void setHWVersion( HWVersion type )
{
// TODO Auto-generated method stub
}
@Override
public HWVersion getHWVersion()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void setEthernetDevType( int cardIndex, EthernetDevType type )
{
// TODO Auto-generated method stub
}
@Override
public EthernetDevType getEthernetDevType( int cardIndex )
{
// TODO Auto-generated method stub
return null;
}
@Override
public byte[] getDefinitionArray()
{
// TODO Auto-generated method stub
return null;
}
}