[KVM] Fix VM migration error due to VNC password on libvirt limiting versions (#6404)

* [KVM] Fix VM migration error due to VNC password on libvirt limiting versions

* Fix passwd value

* Simplify implementation
This commit is contained in:
Nicolas Vazquez 2022-05-23 08:12:49 -03:00 committed by GitHub
parent dc975dff95
commit b1c8b5ab37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 12 deletions

View File

@ -149,7 +149,11 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
final String target = command.getDestinationIp(); final String target = command.getDestinationIp();
xmlDesc = dm.getXMLDesc(xmlFlag); xmlDesc = dm.getXMLDesc(xmlFlag);
xmlDesc = replaceIpForVNCInDescFile(xmlDesc, target);
// Limit the VNC password in case the length is greater than 8 characters
// Since libvirt version 8 VNC passwords are limited to 8 characters
String vncPassword = org.apache.commons.lang3.StringUtils.truncate(to.getVncPassword(), 8);
xmlDesc = replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, target, vncPassword);
String oldIsoVolumePath = getOldVolumePath(disks, vmName); String oldIsoVolumePath = getOldVolumePath(disks, vmName);
String newIsoVolumePath = getNewVolumePathIfDatastoreHasChanged(libvirtComputingResource, conn, to); String newIsoVolumePath = getNewVolumePathIfDatastoreHasChanged(libvirtComputingResource, conn, to);
@ -450,9 +454,10 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
* </graphics> * </graphics>
* @param xmlDesc the qemu xml description * @param xmlDesc the qemu xml description
* @param target the ip address to migrate to * @param target the ip address to migrate to
* @param vncPassword if set, the VNC password truncated to 8 characters
* @return the new xmlDesc * @return the new xmlDesc
*/ */
String replaceIpForVNCInDescFile(String xmlDesc, final String target) { String replaceIpForVNCInDescFileAndNormalizePassword(String xmlDesc, final String target, String vncPassword) {
final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START); final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START);
if (begin >= 0) { if (begin >= 0) {
final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length(); final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length();
@ -460,6 +465,9 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
String graphElem = xmlDesc.substring(begin, end); String graphElem = xmlDesc.substring(begin, end);
graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'"); graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'");
graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'"); graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'");
if (org.apache.commons.lang3.StringUtils.isNotBlank(vncPassword)) {
graphElem = graphElem.replaceAll("passwd='([^\\s]+)'", "passwd='" + vncPassword + "'");
}
xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem); xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem);
} }
} }

View File

@ -571,16 +571,16 @@ public class LibvirtMigrateCommandWrapperTest {
@Test @Test
public void testReplaceIpForVNCInDescFile() { public void testReplaceIpForVNCInDescFile() {
final String targetIp = "192.168.22.21"; final String targetIp = "192.168.22.21";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(fullfile, targetIp); final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(fullfile, targetIp, null);
assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result)); assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result));
} }
@Test @Test
public void testReplaceIpForVNCInDesc() { public void testReplaceIpAndPasswordForVNCInDesc() {
final String xmlDesc = final String xmlDesc =
"<domain type='kvm' id='3'>" + "<domain type='kvm' id='3'>" +
" <devices>" + " <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>" + " <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1' passwd='123456789012345'>" +
" <listen type='address' address='10.10.10.1'/>" + " <listen type='address' address='10.10.10.1'/>" +
" </graphics>" + " </graphics>" +
" </devices>" + " </devices>" +
@ -588,22 +588,23 @@ public class LibvirtMigrateCommandWrapperTest {
final String expectedXmlDesc = final String expectedXmlDesc =
"<domain type='kvm' id='3'>" + "<domain type='kvm' id='3'>" +
" <devices>" + " <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10'>" + " <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10' passwd='12345678'>" +
" <listen type='address' address='10.10.10.10'/>" + " <listen type='address' address='10.10.10.10'/>" +
" </graphics>" + " </graphics>" +
" </devices>" + " </devices>" +
"</domain>"; "</domain>";
final String targetIp = "10.10.10.10"; final String targetIp = "10.10.10.10";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp); final String password = "12345678";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, targetIp, password);
assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result)); assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
} }
@Test @Test
public void testReplaceFqdnForVNCInDesc() { public void testReplaceFqdnAndPasswordForVNCInDesc() {
final String xmlDesc = final String xmlDesc =
"<domain type='kvm' id='3'>" + "<domain type='kvm' id='3'>" +
" <devices>" + " <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local'>" + " <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local' passwd='123456789012345'>" +
" <listen type='address' address='localhost.local'/>" + " <listen type='address' address='localhost.local'/>" +
" </graphics>" + " </graphics>" +
" </devices>" + " </devices>" +
@ -611,13 +612,14 @@ public class LibvirtMigrateCommandWrapperTest {
final String expectedXmlDesc = final String expectedXmlDesc =
"<domain type='kvm' id='3'>" + "<domain type='kvm' id='3'>" +
" <devices>" + " <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain'>" + " <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain' passwd='12345678'>" +
" <listen type='address' address='localhost.localdomain'/>" + " <listen type='address' address='localhost.localdomain'/>" +
" </graphics>" + " </graphics>" +
" </devices>" + " </devices>" +
"</domain>"; "</domain>";
final String targetIp = "localhost.localdomain"; final String targetIp = "localhost.localdomain";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp); final String password = "12345678";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, targetIp, password);
assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result)); assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
} }
@ -789,5 +791,4 @@ public class LibvirtMigrateCommandWrapperTest {
Assert.assertTrue(replaced.contains("csdpdk-7")); Assert.assertTrue(replaced.contains("csdpdk-7"));
Assert.assertFalse(replaced.contains("csdpdk-1")); Assert.assertFalse(replaced.contains("csdpdk-1"));
} }
} }