package org.ovirt.engine.core.bll.exportimport;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.businessentities.DisplayType;
import org.ovirt.engine.core.common.businessentities.GraphicsDevice;
import org.ovirt.engine.core.common.businessentities.GraphicsType;
import org.ovirt.engine.core.common.businessentities.VmBase;
import org.ovirt.engine.core.common.businessentities.VmDevice;
import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
import org.ovirt.engine.core.common.businessentities.VmDeviceId;
import org.ovirt.engine.core.common.osinfo.OsRepository;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.common.utils.SimpleDependencyInjector;
import org.ovirt.engine.core.common.utils.VmDeviceCommonUtils;
import org.ovirt.engine.core.common.utils.VmDeviceType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
public class ImportUtils {
/**
* Checks whether imported VM/Template has Graphics devices.
* - If the VM/Template has Video devices and no Graphics devices, this method
* adds compatible graphics device to devices map (This could mean
* the exported VM/Template has been created when we didn't have Graphics
* devices).
* - If the VM/Template has no Video devices, no Graphics devices are added
* (we assume headless VM/Template).
*/
public static void updateGraphicsDevices(VmBase vmBase, Version clusterVersion) {
if (vmBase == null || vmBase.getManagedDeviceMap() == null || clusterVersion == null) {
return;
}
if (Version.v4_0.lessOrEquals(clusterVersion)) {
if (removeVideoDevice(VmDeviceType.VNC, VmDeviceType.CIRRUS, vmBase.getManagedDeviceMap())) {
vmBase.setDefaultDisplayType(DisplayType.vga);
VmDeviceCommonUtils.addVideoDevice(vmBase);
}
}
List<VmDevice> videoDevs = getDevicesOfType(VmDeviceGeneralType.VIDEO, vmBase.getManagedDeviceMap());
boolean hasNoGraphics = getDevicesOfType(VmDeviceGeneralType.GRAPHICS, vmBase.getManagedDeviceMap()).isEmpty();
if (!videoDevs.isEmpty() && hasNoGraphics) {
GraphicsDevice compatibleGraphics = getCompatibleGraphics(VmDeviceType.getByName(videoDevs.get(0).getDevice()), clusterVersion, vmBase);
if (compatibleGraphics != null) {
vmBase.getManagedDeviceMap().put(compatibleGraphics.getDeviceId(), compatibleGraphics);
}
}
}
private static boolean removeVideoDevice(VmDeviceType whenGraphicsExists, VmDeviceType videoToRemove,
Map<Guid, VmDevice> managedDevicesMap) {
if (VmDeviceCommonUtils.isVmDeviceExists(managedDevicesMap, whenGraphicsExists)) {
Guid key = null;
for (Map.Entry<Guid, VmDevice> graphicsDevice : managedDevicesMap.entrySet()) {
if (videoToRemove.getName().equals(graphicsDevice.getValue().getDevice())) {
key = graphicsDevice.getKey();
break;
}
}
if (key != null) {
managedDevicesMap.remove(key);
return true;
}
}
return false;
}
private static List<VmDevice> getDevicesOfType(VmDeviceGeneralType type, Map<Guid, VmDevice> managedDevicesMap) {
return managedDevicesMap.values().stream().filter(device -> device.getType() == type).collect(toList());
}
private static GraphicsDevice getCompatibleGraphics(VmDeviceType videoDeviceType, Version clusterVersion, VmBase vmBase) {
GraphicsDevice graphicsDevice = null;
GraphicsType compatibleType = null;
OsRepository osRepository = SimpleDependencyInjector.getInstance().get(OsRepository.class);
for (Pair<GraphicsType, DisplayType> graphicsDisplayPair : osRepository.getGraphicsAndDisplays(vmBase.getOsId(), clusterVersion)) {
if (graphicsDisplayPair.getSecond().getDefaultVmDeviceType() == videoDeviceType) {
compatibleType = graphicsDisplayPair.getFirst();
// previously to spice+vnc, QXL was only used by spice, so prefer spice if available
if (videoDeviceType == VmDeviceType.QXL && compatibleType == GraphicsType.SPICE) {
break;
}
}
}
if (compatibleType != null) {
graphicsDevice = new GraphicsDevice(compatibleType.getCorrespondingDeviceType());
graphicsDevice.setId(new VmDeviceId(Guid.newGuid(), vmBase.getId()));
}
return graphicsDevice;
}
}