diff options
author | Manuel Bentele | 2021-04-15 15:10:38 +0200 |
---|---|---|
committer | Manuel Bentele | 2021-04-15 15:10:38 +0200 |
commit | f4c21ccda4f786fe388ffed1e4bd9a18aabea4bd (patch) | |
tree | f612fcec79b5fa3319e73c312e28cb77aa558f77 /core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java | |
parent | [qemu] Add API to register the functional interface based config filter method (diff) | |
download | mltk-f4c21ccda4f786fe388ffed1e4bd9a18aabea4bd.tar.gz mltk-f4c21ccda4f786fe388ffed1e4bd9a18aabea4bd.tar.xz mltk-f4c21ccda4f786fe388ffed1e4bd9a18aabea4bd.zip |
[qemu] Move generic filtering/transformation to master-sync-shared
Diffstat (limited to 'core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java')
-rw-r--r-- | core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java new file mode 100644 index 00000000..bdded447 --- /dev/null +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuArchitecture.java @@ -0,0 +1,199 @@ +package org.openslx.runvirt.plugin.qemu.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.openslx.libvirt.capabilities.Capabilities; +import org.openslx.libvirt.capabilities.guest.Guest; +import org.openslx.libvirt.capabilities.guest.Machine; +import org.openslx.libvirt.domain.Domain; +import org.openslx.libvirt.domain.Domain.OsType; +import org.openslx.libvirt.domain.Domain.Type; +import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; +import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; +import org.openslx.runvirt.virtualization.LibvirtHypervisorException; +import org.openslx.virtualization.configuration.transformation.TransformationException; +import org.openslx.virtualization.configuration.transformation.TransformationSpecific; + +public class TransformationSpecificQemuArchitecture extends TransformationSpecific<Domain, CommandLineArgs, LibvirtHypervisorQemu> +{ + private static final String FILTER_NAME = "QEMU Architecture [CPU architecture, machine type, ...]"; + + // used as instance of an singelton, always use getCapabilities to retrieve caps instance + private Capabilities capabilities = null; + + public TransformationSpecificQemuArchitecture( LibvirtHypervisorQemu hypervisor ) + { + super( TransformationSpecificQemuArchitecture.FILTER_NAME, hypervisor ); + } + + private Capabilities getCapabilities() throws TransformationException + { + // retrieve capabilities from QEMU hypervisor only once + if ( this.capabilities == null ) { + try { + this.capabilities = this.getVirtualizer().getCapabilites(); + } catch ( LibvirtHypervisorException e ) { + final String errorMsg = new String( + "Failed to get host capabilities from QEMU virtualizer: " + e.getLocalizedMessage() ); + throw new TransformationException( errorMsg ); + } + } + + return this.capabilities; + } + + private Guest getTargetGuestFromArchName( String architectureName ) throws TransformationException + { + final List<Guest> guests = this.getCapabilities().getGuests(); + Guest targetGuest = null; + + if ( architectureName == null ) { + return targetGuest; + } + + for ( Guest guest : guests ) { + final String guestArchitectureName = guest.getArchName(); + if ( architectureName.equals( guestArchitectureName ) ) { + targetGuest = guest; + break; + } + } + + return targetGuest; + } + + private Machine getTargetMachineFromGuest( Guest guest, String machineName ) throws TransformationException + { + final List<Machine> machines = guest.getArchMachines(); + Machine targetMachine = null; + + if ( machineName == null ) { + return targetMachine; + } + + for ( Machine machine : machines ) { + if ( machineName.equals( machine.getName() ) ) { + targetMachine = machine; + break; + } + } + + return targetMachine; + } + + private List<String> getCanonicalNamesFromTargetMachines( Guest guest ) throws TransformationException + { + final List<Machine> machines = guest.getArchMachines(); + final List<String> canonicalNames = new ArrayList<String>(); + + for ( Machine machine : machines ) { + final String canonicalName = machine.getCanonicalMachine(); + if ( canonicalName != null ) { + canonicalNames.add( canonicalName ); + } + } + + return canonicalNames; + } + + @Override + public void transform( Domain config, CommandLineArgs args ) throws TransformationException + { + // get source architecture, machine- and OS type + final String sourceArchitectureName = config.getOsArch(); + final String sourceMachine = config.getOsMachine(); + final OsType sourceOsType = config.getOsType(); + final Type sourceDomainType = config.getType(); + + // check if source architecture is supported by one of the hypervisor's guests + Guest targetGuest = null; + if ( sourceArchitectureName == null ) { + final String errorMsg = new String( "Source architecture is not specified!" ); + throw new TransformationException( errorMsg ); + } else { + targetGuest = this.getTargetGuestFromArchName( sourceArchitectureName ); + if ( targetGuest == null ) { + final String errorMsg = new String( "Source architecture is not supported by the virtualizer!" ); + throw new TransformationException( errorMsg ); + } + } + + // check if source machine is supported by the hypervisor + Machine targetMachine = null; + if ( sourceMachine == null ) { + final String errorMsg = new String( "Source machine type is not specified!" ); + throw new TransformationException( errorMsg ); + } else { + // get all possible machine type for supported source architecture + targetMachine = this.getTargetMachineFromGuest( targetGuest, sourceMachine ); + + if ( targetMachine == null ) { + // source machine is not directly supported by the hypervisor + // check if up- or downgraded version of the chipset is supported by the hypervisor + List<String> targetMachineCanonicalNames = this.getCanonicalNamesFromTargetMachines( targetGuest ); + + // retrieve overwrite chipset name from canonical machine names + String sourceMachineOverwrite = null; + for ( String targetMachineCanonicalName : targetMachineCanonicalNames ) { + if ( sourceMachine.contains( targetMachineCanonicalName ) ) { + sourceMachineOverwrite = targetMachineCanonicalName; + break; + } + } + + // if overwrite available, patch the machine type + if ( sourceMachineOverwrite != null ) { + config.setOsMachine( sourceMachineOverwrite ); + } else { + final String errorMsg = new String( "Source machine type is not supported by the virtualizer!" ); + throw new TransformationException( errorMsg ); + } + } + } + + // check if source OS type is supported by the hypervisor's architecture + if ( sourceOsType == null ) { + final String errorMsg = new String( "OS type is not specified!" ); + throw new TransformationException( errorMsg ); + } else { + if ( !sourceOsType.toString().equals( targetGuest.getOsType().toString() ) ) { + final String errorMsg = new String( "OS type is not supported by the virtualizer!" ); + throw new TransformationException( errorMsg ); + } + } + + // check if source domain type is supported by the hypervisor's architecture + Type targetDomainType = null; + if ( sourceDomainType == null ) { + final String errorMsg = new String( "Source domain type is not specified!" ); + throw new TransformationException( errorMsg ); + } else { + final List<org.openslx.libvirt.capabilities.guest.Domain> targetDomains = targetGuest.getArchDomains(); + + // retrieve supported domain type + for ( org.openslx.libvirt.capabilities.guest.Domain domain : targetDomains ) { + final Type domainType = domain.getType(); + if ( domainType == sourceDomainType ) { + targetDomainType = domainType; + break; + } + } + + // check supported domain type + if ( targetDomainType == null ) { + final String errorMsg = new String( "Source domain type is not supported by the virtualizer!" ); + throw new TransformationException( errorMsg ); + } + } + + // patch path of QEMU emulator binary + final String archEmulator = targetGuest.getArchEmulator(); + if ( archEmulator == null ) { + final String errorMsg = new String( "Emulation of source architecture is not supported by the virtualizer!" ); + throw new TransformationException( errorMsg ); + } else { + config.setDevicesEmulator( targetGuest.getArchEmulator() ); + } + } +} |