mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
server,kvm: detect boot options for vm import (#11218)
* server,kvm: detect boot options for vm import Fixes #11184 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * tests and changes Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> --------- Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
6868f052de
commit
9349b69b7e
@ -48,6 +48,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef;
|
||||
|
||||
public class LibvirtDomainXMLParser {
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
@ -63,6 +64,8 @@ public class LibvirtDomainXMLParser {
|
||||
private LibvirtVMDef.CpuTuneDef cpuTuneDef;
|
||||
private LibvirtVMDef.CpuModeDef cpuModeDef;
|
||||
private String name;
|
||||
private GuestDef.BootType bootType;
|
||||
private GuestDef.BootMode bootMode;
|
||||
|
||||
public boolean parseDomainXML(String domXML) {
|
||||
DocumentBuilder builder;
|
||||
@ -388,6 +391,7 @@ public class LibvirtDomainXMLParser {
|
||||
}
|
||||
extractCpuTuneDef(rootElement);
|
||||
extractCpuModeDef(rootElement);
|
||||
extractBootDef(rootElement);
|
||||
return true;
|
||||
} catch (ParserConfigurationException e) {
|
||||
logger.debug(e.toString());
|
||||
@ -516,6 +520,14 @@ public class LibvirtDomainXMLParser {
|
||||
return cpuModeDef;
|
||||
}
|
||||
|
||||
public GuestDef.BootType getBootType() {
|
||||
return bootType;
|
||||
}
|
||||
|
||||
public GuestDef.BootMode getBootMode() {
|
||||
return bootMode;
|
||||
}
|
||||
|
||||
private void extractCpuTuneDef(final Element rootElement) {
|
||||
NodeList cpuTunesList = rootElement.getElementsByTagName("cputune");
|
||||
if (cpuTunesList.getLength() > 0) {
|
||||
@ -569,4 +581,26 @@ public class LibvirtDomainXMLParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void extractBootDef(final Element rootElement) {
|
||||
bootType = GuestDef.BootType.BIOS;
|
||||
bootMode = GuestDef.BootMode.LEGACY;
|
||||
Element osElement = (Element) rootElement.getElementsByTagName("os").item(0);
|
||||
if (osElement == null) {
|
||||
return;
|
||||
}
|
||||
NodeList loaderList = osElement.getElementsByTagName("loader");
|
||||
if (loaderList.getLength() == 0) {
|
||||
return;
|
||||
}
|
||||
Element loader = (Element) loaderList.item(0);
|
||||
String type = loader.getAttribute("type");
|
||||
String secure = loader.getAttribute("secure");
|
||||
if ("pflash".equalsIgnoreCase(type) || loader.getTextContent().toLowerCase().contains("uefi")) {
|
||||
bootType = GuestDef.BootType.UEFI;
|
||||
}
|
||||
if ("yes".equalsIgnoreCase(secure)) {
|
||||
bootMode = GuestDef.BootMode.SECURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ public class LibvirtVMDef {
|
||||
}
|
||||
}
|
||||
|
||||
enum BootType {
|
||||
public enum BootType {
|
||||
UEFI("UEFI"), BIOS("BIOS");
|
||||
|
||||
String _type;
|
||||
@ -80,7 +80,7 @@ public class LibvirtVMDef {
|
||||
}
|
||||
}
|
||||
|
||||
enum BootMode {
|
||||
public enum BootMode {
|
||||
LEGACY("LEGACY"), SECURE("SECURE");
|
||||
|
||||
String _mode;
|
||||
|
||||
@ -135,6 +135,12 @@ public final class LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
|
||||
instance.setNics(getUnmanagedInstanceNics(parser.getInterfaces()));
|
||||
instance.setDisks(getUnmanagedInstanceDisks(parser.getDisks(),libvirtComputingResource, conn, domain.getName()));
|
||||
instance.setVncPassword(getFormattedVncPassword(parser.getVncPasswd()));
|
||||
if (parser.getBootType() != null) {
|
||||
instance.setBootType(parser.getBootType().toString());
|
||||
}
|
||||
if (parser.getBootMode() != null) {
|
||||
instance.setBootMode(parser.getBootMode().toString());
|
||||
}
|
||||
|
||||
return instance;
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -20,8 +20,13 @@
|
||||
package com.cloud.hypervisor.kvm.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
|
||||
@ -31,10 +36,15 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.cloudstack.utils.qemu.QemuObject;
|
||||
import org.apache.cloudstack.utils.security.ParserUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LibvirtDomainXMLParserTest extends TestCase {
|
||||
@ -386,4 +396,84 @@ public class LibvirtDomainXMLParserTest extends TestCase {
|
||||
Assert.assertEquals("CPU cores count is parsed", 4, libvirtDomainXMLParser.getCpuModeDef().getCoresPerSocket());
|
||||
Assert.assertEquals("CPU threads count is parsed", 2, libvirtDomainXMLParser.getCpuModeDef().getThreadsPerCore());
|
||||
}
|
||||
|
||||
private LibvirtDomainXMLParser parseElementFromXML(String xml) {
|
||||
LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
|
||||
DocumentBuilder builder;
|
||||
try {
|
||||
builder = ParserUtils.getSaferDocumentBuilderFactory().newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
Document doc = builder.parse(is);
|
||||
Element element = doc.getDocumentElement();
|
||||
parser.extractBootDef(element);
|
||||
} catch (ParserConfigurationException | IOException | SAXException e) {
|
||||
Assert.fail("Failed to parse XML: " + e.getMessage());
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractBootDefParsesUEFISecureBootCorrectly() {
|
||||
String xml = "<domain type='kvm'>" +
|
||||
"<os>" +
|
||||
"<loader type='pflash' secure='yes'>/path/to/uefi/loader</loader>" +
|
||||
"</os>" +
|
||||
"</domain>";
|
||||
|
||||
LibvirtDomainXMLParser parser = parseElementFromXML(xml);
|
||||
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootType.UEFI, parser.getBootType());
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootMode.SECURE, parser.getBootMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractBootDefParsesUEFILegacyBootCorrectly() {
|
||||
String xml = "<domain type='kvm'>" +
|
||||
"<os>" +
|
||||
"<loader type='pflash' secure='no'>/path/to/uefi/loader</loader>" +
|
||||
"</os>" +
|
||||
"</domain>";
|
||||
|
||||
LibvirtDomainXMLParser parser = parseElementFromXML(xml);
|
||||
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootType.UEFI, parser.getBootType());
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootMode.LEGACY, parser.getBootMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractBootDefDefaultsToBIOSLegacyWhenNoLoaderPresent() {
|
||||
String xml = "<domain type='kvm'>" +
|
||||
"<os>" +
|
||||
"<type arch='x86_64'>hvm</type>" +
|
||||
"</os>" +
|
||||
"</domain>";
|
||||
|
||||
LibvirtDomainXMLParser parser = parseElementFromXML(xml);
|
||||
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootType.BIOS, parser.getBootType());
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootMode.LEGACY, parser.getBootMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractBootDefHandlesEmptyOSSection() {
|
||||
String xml = "<domain type='kvm'>" +
|
||||
"<os></os>" +
|
||||
"</domain>";
|
||||
|
||||
LibvirtDomainXMLParser parser = parseElementFromXML(xml);
|
||||
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootType.BIOS, parser.getBootType());
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootMode.LEGACY, parser.getBootMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractBootDefHandlesMissingOSSection() {
|
||||
String xml = "<domain type='kvm'></domain>";
|
||||
|
||||
LibvirtDomainXMLParser parser = parseElementFromXML(xml);
|
||||
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootType.BIOS, parser.getBootType());
|
||||
assertEquals(LibvirtVMDef.GuestDef.BootMode.LEGACY, parser.getBootMode());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user