From 888f9e490cc3f03cc9399f779344c25d3082eafa Mon Sep 17 00:00:00 2001 From: Christopher Lucas Date: Wed, 5 Dec 2018 17:45:04 +0100 Subject: Upload and Download image with config file working --- .../java/org/openslx/util/vm/QemuMetaData.java | 577 +++++++++++++-------- 1 file changed, 367 insertions(+), 210 deletions(-) (limited to 'src/main/java/org/openslx/util/vm/QemuMetaData.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..cf3b550 100644 --- a/src/main/java/org/openslx/util/vm/QemuMetaData.java +++ b/src/main/java/org/openslx/util/vm/QemuMetaData.java @@ -1,225 +1,382 @@ 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.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; - -public class QemuMetaData extends VmMetaData -{ - - private final Map arguments = new HashMap(); - // the above map's elements will take the place of in the config string - private String config; - private static final Logger LOGGER = Logger.getLogger( QemuMetaData.class ); - - private static final Virtualizer virtualizer = new Virtualizer( TConst.VIRT_QEMU, "QEMU-KVM" ); - - public QemuMetaData( List 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 -enable-kvm \n\r qemu-system-x86_64 -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( "", 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( "", 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( "", 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; - } - - @Override - public boolean addCpuCoreCount( int nrOfCores ) - { - this.arguments.put( "smp", Integer.toString( nrOfCores ) ); - return true; - } - - @Override - public void setSoundCard( VmMetaData.SoundCardType type ) - { - } - - @Override - public VmMetaData.SoundCardType getSoundCard() - { - return null; - } - - @Override - public void setDDAcceleration( VmMetaData.DDAcceleration type ) - { - } - - @Override - public VmMetaData.DDAcceleration getDDAcceleration() - { - return null; - } - - @Override - public void setHWVersion( VmMetaData.HWVersion type ) - { - } - - @Override - public VmMetaData.HWVersion getHWVersion() - { - return null; - } - - @Override - public void setEthernetDevType( int cardIndex, VmMetaData.EthernetDevType type ) - { - } - - @Override - public VmMetaData.EthernetDevType getEthernetDevType( int cardIndex ) - { - return null; - } - - @Override - public byte[] getDefinitionArray() - { - return configWithArgs().getBytes( StandardCharsets.UTF_8 ); - } - - @Override - public boolean addEthernet( VmMetaData.EtherType type ) - { - return false; - } - - @Override - public Virtualizer getVirtualizer() - { - return virtualizer; - } - - @Override - public void enableUsb( boolean enabled ) - { - // TODO test this properly - if ( enabled ) { - arguments.put( "usb", "" ); - } else { - arguments.remove( "usb" ); - } - } - - @Override - public boolean disableSuspend() - { - return false; - } - - @Override - public void registerVirtualHW() - { - } +import org.openslx.util.vm.QemuConfig.Header; +import static org.openslx.util.vm.QemuConfig.Header.MACHINE; + +class QemuDDAccelMeta { + + public final boolean isPresent; + + public QemuDDAccelMeta(boolean present) { + isPresent = present; + } +} + +class QemuHWVersionMeta { + + public final int version; + + public QemuHWVersionMeta(int vers) { + version = vers; + } +} + +class QemuEthernetDevTypeMeta { + + public final String value; + + public QemuEthernetDevTypeMeta(String val) { + value = val; + } +} + +class QemuSoundCardMeta { + + public final boolean isPresent; + public final String value; + + public QemuSoundCardMeta(boolean present, String val) { + + isPresent = present; + value = val; + } +} + +public final class QemuMetaData extends VmMetaData { + + private final Map arguments = new HashMap<>(); //to remove at the end. easier + // the above map's elements will take the place of in the config string + private QemuConfig config; + + private String setup; + + private TreeMap option; + + private static final Logger LOGGER = Logger.getLogger(QemuMetaData.class); + + private static final Virtualizer virtualizer = new Virtualizer(TConst.VIRT_QEMU, "QEMU-KVM"); + + private int cdromCounter = 0; + + private int driveCounter = 0; + + private int floppyCounter = 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 osList, File config) { + super(osList); + this.config = new QemuConfig(config); + init(); + } + + public QemuMetaData(List osList, byte[] vmContent, int length) throws IOException, UnsupportedVirtualizerFormatException { + super(osList); + this.config = new QemuConfig(vmContent, length); + init(); + } + + public void init() { + registerVirtualHW(); + displayName = config.getDisplayName(); + setOs(config.getOsName()); + isMachineSnapshot = config.isMachineSnapshot(); + config.setHdds(); + for (HardDisk hardDisk : config.getHdds()) { + hdds.add(hardDisk); + } + } + + + @Override + public byte[] getFilteredDefinitionArray() { + 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) { + option = new TreeMap<>(); + String bus = "anychipset"; + DriveBusType busType = DriveBusType.IDE; + //drive + option = config.get("[drive \"disk0\"]"); + if (option != null) { + option.replace("file", "\"" + diskImage.getAbsolutePath() + "\""); + bus = option.get("if"); + } + switch (bus) { + case "ide": + busType = DriveBusType.IDE; + break; + case "scsi": + busType = DriveBusType.SCSI; + break; + case "sata": + //not available for Qemu. Others : sd, mtd, floppy, pflash, virtio + break; + default: + break; + } + //device + option = config.get("[dev0]"); + hdds.add(new HardDisk(option.get("driver"), busType, diskImage.getAbsolutePath())); + return true; + } + + @Override + public boolean addHddTemplate(String diskImagePath, String hddMode, String redoDir) { + option = new TreeMap<>(); + + //drive + option.put("file", "\"" + diskImagePath + "\""); + option.put("if", "\"scsi\""); + String status = (isMachineSnapshot == true ? "on" : "off"); + option.put("snapshot", "\"" + status + "\""); + config.set("[drive \"drive" + driveCounter + "\"]", option); + + //device + option.put("drive", "\"drive" + driveCounter + "\""); + option.put("driver", "scsi-hd"); + config.set("[device]", option); + + hdds.add(new HardDisk("anychipset", DriveBusType.IDE, diskImagePath)); + driveCounter++; + 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 + "\""); + config.set("[name]", option); + return true; + } + + @Override + public boolean addRam(int mem) { + option = new TreeMap<>(); + option.put("size", "\"" + mem + "\""); + config.set("[memory]", 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); + config.set("[drive \"floppy" + floppyCounter + "\"]", option); + floppyCounter++; + } + + @Override + public boolean addCdrom(String image) { + option = new TreeMap<>(); + option.put("media", "\"cdrom\""); + option.put("file", image); + config.set("[drive \"cdrom" + cdromCounter + "\"]", option); + cdromCounter++; + return true; + } + + @Override + public boolean addCpuCoreCount(int nrOfCores) { + option = new TreeMap<>(); + option.put("cpus", "\"" + nrOfCores + "\""); + config.set("[smp-opts]", option); + return true; + } + + @Override + public void setSoundCard(VmMetaData.SoundCardType type) { + //Not possible will be set as comment in config file + } + + @Override + public VmMetaData.SoundCardType getSoundCard() { + //not possible to set just write comment + VmMetaData.SoundCardType soundcard = null; + return soundcard; + } + + @Override + public void setDDAcceleration(VmMetaData.DDAcceleration type) { + //Not really used by qemu. TODO: + } + + @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) { + QemuEthernetDevTypeMeta dev = networkCards.get(type); + option = new TreeMap<>(); + option.put("driver", "\"" + dev.value + "\""); + option.put("netdev", "\"net" + cardIndex + "\""); + config.set("[device]", option); + } + + @Override + public VmMetaData.EthernetDevType getEthernetDevType(int cardIndex) { + QemuEthernetDevTypeMeta ethernetDevTypeMeta = null; + for (String key : config.get().keySet()) { + if (key.equals("[dev" + cardIndex + "]")) {//wont work dev0 + if (config.get(key).get("netdev").equals("\"net" + cardIndex + "\"")) { + String devs = config.get(key).get("driver"); + + for (EthernetDevType type : VmMetaData.EthernetDevType.values()) { + ethernetDevTypeMeta = networkCards.get(type); + if (ethernetDevTypeMeta == null) { + continue; + } + if (devs.equals(ethernetDevTypeMeta.value)) { + return type; + } + } + } + } + } + return EthernetDevType.AUTO; + } + + @Override + public boolean addEthernet(VmMetaData.EtherType type) { + boolean ret = false; + int index = 0; + for (;; ++index) { + TreeMap dev = config.get("[dev" + index + "]"); + + if (dev == null) { + break; + } else { + if (dev.get("netdev") == null) { + break; + } + } + } + switch (type) { + case NAT: + //netdev + option = new TreeMap<>(); + option.put("br", "nat1"); + option.put("type", "bridge"); + config.set("[netdev \"net" + index + "\"]", option); + //device + option = new TreeMap<>(); + break; + case BRIDGED: + option = new TreeMap<>(); + option.put("br", "'br0'"); + option.put("type", "'bridge'"); + config.set("[netdev \"net" + index + "\"]", option); + break; + case HOST_ONLY: + //Dont know how to do it... + break; + default: + // Should not come to this... + break; + } + return ret; + } + + @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\""); + } + config.set(MACHINE.value(), option); + } + + @Override + public boolean disableSuspend() { + return false; + } + + @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(DDAcceleration.OFF, new QemuDDAccelMeta(false)); + ddacc.put(DDAcceleration.ON, new QemuDDAccelMeta(true)); + + hwversion.put(HWVersion.DEFAULT, new QemuHWVersionMeta(0)); + + networkCards.put(EthernetDevType.VIRTIO, new QemuEthernetDevTypeMeta("virtio-net-pci")); + networkCards.put(EthernetDevType.E1000, new QemuEthernetDevTypeMeta("e1000")); + networkCards.put(EthernetDevType.PCNET32, new QemuEthernetDevTypeMeta("pcnet")); + networkCards.put(EthernetDevType.RTL8139, new QemuEthernetDevTypeMeta("rtl8139")); + + } } -- cgit v1.2.3-55-g7522