You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sw...@apache.org on 2016/04/28 21:55:55 UTC

[1/2] git commit: updated refs/heads/4.7 to c03e359

Repository: cloudstack
Updated Branches:
  refs/heads/4.7 d13ff88cb -> c03e35982


CLOUDSTACK-9142 Migrate VM changes xmlDesc in a safe way


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8a6afa6d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8a6afa6d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8a6afa6d

Branch: refs/heads/4.7
Commit: 8a6afa6d9ff6b69e45209c4a871d0624d016af74
Parents: 57a2a0b
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Jan 18 17:43:43 2016 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Thu Jan 21 21:32:35 2016 +0100

----------------------------------------------------------------------
 .../wrapper/LibvirtMigrateCommandWrapper.java   |  34 ++-
 .../resource/LibvirtComputingResourceTest.java  |  22 +-
 .../LibvirtMigrateCommandWrapperTest.java       | 306 +++++++++++++++++++
 3 files changed, 349 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8a6afa6d/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
index c1328aa..6736c51 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
@@ -48,6 +48,9 @@ import com.cloud.resource.ResourceWrapper;
 @ResourceWrapper(handles =  MigrateCommand.class)
 public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, LibvirtComputingResource> {
 
+    private static final String GRAPHICS_ELEM_END = "/graphics>";
+    private static final String GRAPHICS_ELEM_START = "<graphics";
+    private static final String CONTENTS_WILDCARD = "(?s).*";
     private static final Logger s_logger = Logger.getLogger(LibvirtMigrateCommandWrapper.class);
 
     @Override
@@ -90,9 +93,11 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
 
                                Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0.
              */
-            int xmlFlag = conn.getLibVirVersion() >= 1000000 ? 8 : 1; // 1000000 equals v1.0.0
+            final int xmlFlag = conn.getLibVirVersion() >= 1000000 ? 8 : 1; // 1000000 equals v1.0.0
 
-            xmlDesc = dm.getXMLDesc(xmlFlag).replace(libvirtComputingResource.getPrivateIp(), command.getDestinationIp());
+            final String target = command.getDestinationIp();
+            xmlDesc = dm.getXMLDesc(xmlFlag);
+            xmlDesc = replaceIpForVNCInDescFile(xmlDesc, target);
 
             dconn = libvirtUtilitiesHelper.retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system");
 
@@ -190,4 +195,27 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
 
         return new MigrateAnswer(command, result == null, result, null);
     }
-}
\ No newline at end of file
+
+    /**
+     * This function assumes an qemu machine description containing a single graphics element like
+     *     <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>
+     *       <listen type='address' address='10.10.10.1'/>
+     *     </graphics>
+     * @param xmlDesc the qemu xml description
+     * @param target the ip address to migrate to
+     * @return the new xmlDesc
+     */
+    String replaceIpForVNCInDescFile(String xmlDesc, final String target) {
+        final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START);
+        if (begin >= 0) {
+            final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length();
+            if (end > begin) {
+                String graphElem = xmlDesc.substring(begin, end);
+                graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'");
+                graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'");
+                xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem);
+            }
+        }
+        return xmlDesc;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8a6afa6d/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
index 04a27f3..a10b477 100644
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@ -391,9 +391,9 @@ public class LibvirtComputingResourceTest {
 
     @Test
     public void diskUuidToSerialTest() {
-        String uuid = "38400000-8cf0-11bd-b24e-10b96e4ef00d";
-        String expected = "384000008cf011bdb24e";
-        LibvirtComputingResource lcr = new LibvirtComputingResource();
+        final String uuid = "38400000-8cf0-11bd-b24e-10b96e4ef00d";
+        final String expected = "384000008cf011bdb24e";
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
         Assert.assertEquals(expected, lcr.diskUuidToSerial(uuid));
     }
 
@@ -711,7 +711,7 @@ public class LibvirtComputingResourceTest {
     @SuppressWarnings("unchecked")
     @Test
     public void testGetVmDiskStatsCommandException() {
-        final Connect conn = Mockito.mock(Connect.class);
+        Mockito.mock(Connect.class);
         final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
 
         final String vmName = "Test";
@@ -931,7 +931,7 @@ public class LibvirtComputingResourceTest {
     public void testGetHostStatsCommand() {
         // A bit difficult to test due to the logger being passed and the parser itself relying on the connection.
         // Have to spend some more time afterwards in order to refactor the wrapper itself.
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        Mockito.mock(LibvirtUtilitiesHelper.class);
         final CPUStat cpuStat = Mockito.mock(CPUStat.class);
         final MemStat memStat = Mockito.mock(MemStat.class);
 
@@ -1253,8 +1253,10 @@ public class LibvirtComputingResourceTest {
             when(conn.domainLookupByName(vmName)).thenReturn(dm);
 
             when(libvirtComputingResource.getPrivateIp()).thenReturn("127.0.0.1");
-            when(dm.getXMLDesc(8)).thenReturn("host_domain");
-            when(dm.getXMLDesc(1)).thenReturn("host_domain");
+            when(dm.getXMLDesc(8)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
+                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
+            when(dm.getXMLDesc(1)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
+                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
             when(dm.isPersistent()).thenReturn(1);
             doNothing().when(dm).undefine();
 
@@ -5010,13 +5012,13 @@ public class LibvirtComputingResourceTest {
 
     @Test
     public void testIsInterface () {
-        LibvirtComputingResource lvcr = new LibvirtComputingResource();
+        final LibvirtComputingResource lvcr = new LibvirtComputingResource();
         assertFalse(lvcr.isInterface("bla"));
         assertTrue(lvcr.isInterface("p99p00"));
-        for  (String ifNamePattern : lvcr._ifNamePatterns) {
+        for  (final String ifNamePattern : lvcr._ifNamePatterns) {
             // excluding regexps as "\\\\d+" won't replace with String.replaceAll(String,String);
             if (!ifNamePattern.contains("\\")) {
-                String ifName = ifNamePattern.replaceFirst("\\^", "") + "0";
+                final String ifName = ifNamePattern.replaceFirst("\\^", "") + "0";
                 assertTrue("The pattern '" + ifNamePattern + "' is expected to be valid for interface " + ifName,lvcr.isInterface(ifName));
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8a6afa6d/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
new file mode 100644
index 0000000..ed13cb2
--- /dev/null
+++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
@@ -0,0 +1,306 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package com.cloud.hypervisor.kvm.resource.wrapper;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class LibvirtMigrateCommandWrapperTest {
+    String fullfile =
+"<domain type='kvm' id='4'>\n" +
+"  <name>i-6-6-VM</name>\n" +
+"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
+"  <description>Other PV (64-bit)</description>\n" +
+"  <memory unit='KiB'>262144</memory>\n" +
+"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
+"  <vcpu placement='static'>1</vcpu>\n" +
+"  <cputune>\n" +
+"    <shares>100</shares>\n" +
+"  </cputune>\n" +
+"  <resource>\n" +
+"    <partition>/machine</partition>\n" +
+"  </resource>\n" +
+"  <sysinfo type='smbios'>\n" +
+"    <system>\n" +
+"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
+"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
+"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
+"    </system>\n" +
+"  </sysinfo>\n" +
+"  <os>\n" +
+"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
+"    <boot dev='cdrom'/>\n" +
+"    <boot dev='hd'/>\n" +
+"    <smbios mode='sysinfo'/>\n" +
+"  </os>\n" +
+"  <features>\n" +
+"    <acpi/>\n" +
+"    <apic/>\n" +
+"    <pae/>\n" +
+"  </features>\n" +
+"  <clock offset='utc'>\n" +
+"    <timer name='kvmclock'/>\n" +
+"  </clock>\n" +
+"  <on_poweroff>destroy</on_poweroff>\n" +
+"  <on_reboot>restart</on_reboot>\n" +
+"  <on_crash>destroy</on_crash>\n" +
+"  <devices>\n" +
+"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
+"    <disk type='file' device='disk'>\n" +
+"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
+"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
+"      <backingStore type='file' index='1'>\n" +
+"        <format type='raw'/>\n" +
+"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
+"        <backingStore/>\n" +
+"      </backingStore>\n" +
+"      <target dev='vda' bus='virtio'/>\n" +
+"      <serial>4650a2f7fce548e2beaa</serial>\n" +
+"      <alias name='virtio-disk0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
+"    </disk>\n" +
+"    <disk type='file' device='cdrom'>\n" +
+"      <driver name='qemu' type='raw' cache='none'/>\n" +
+"      <backingStore/>\n" +
+"      <target dev='hdc' bus='ide'/>\n" +
+"      <readonly/>\n" +
+"      <alias name='ide0-1-0'/>\n" +
+"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
+"    </disk>\n" +
+"    <controller type='usb' index='0'>\n" +
+"      <alias name='usb'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
+"    </controller>\n" +
+"    <controller type='pci' index='0' model='pci-root'>\n" +
+"      <alias name='pci.0'/>\n" +
+"    </controller>\n" +
+"    <controller type='ide' index='0'>\n" +
+"      <alias name='ide'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
+"    </controller>\n" +
+"    <interface type='bridge'>\n" +
+"      <mac address='06:fe:b4:00:00:06'/>\n" +
+"      <source bridge='breth0-50'/>\n" +
+"      <bandwidth>\n" +
+"        <inbound average='25600' peak='25600'/>\n" +
+"        <outbound average='25600' peak='25600'/>\n" +
+"      </bandwidth>\n" +
+"      <target dev='vnet4'/>\n" +
+"      <model type='virtio'/>\n" +
+"      <alias name='net0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
+"    </interface>\n" +
+"    <serial type='pty'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </serial>\n" +
+"    <console type='pty' tty='/dev/pts/2'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target type='serial' port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </console>\n" +
+"    <input type='tablet' bus='usb'>\n" +
+"      <alias name='input0'/>\n" +
+"    </input>\n" +
+"    <input type='mouse' bus='ps2'/>\n" +
+"    <input type='keyboard' bus='ps2'/>\n" +
+"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.22'>\n" +
+"      <listen type='address' address='192.168.22.22'/>\n" +
+"    </graphics>\n" +
+"    <video>\n" +
+"      <model type='cirrus' vram='16384' heads='1'/>\n" +
+"      <alias name='video0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
+"    </video>\n" +
+"    <memballoon model='none'>\n" +
+"      <alias name='balloon0'/>\n" +
+"    </memballoon>\n" +
+"  </devices>\n" +
+"</domain>";
+    String targetfile =
+"<domain type='kvm' id='4'>\n" +
+"  <name>i-6-6-VM</name>\n" +
+"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
+"  <description>Other PV (64-bit)</description>\n" +
+"  <memory unit='KiB'>262144</memory>\n" +
+"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
+"  <vcpu placement='static'>1</vcpu>\n" +
+"  <cputune>\n" +
+"    <shares>100</shares>\n" +
+"  </cputune>\n" +
+"  <resource>\n" +
+"    <partition>/machine</partition>\n" +
+"  </resource>\n" +
+"  <sysinfo type='smbios'>\n" +
+"    <system>\n" +
+"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
+"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
+"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
+"    </system>\n" +
+"  </sysinfo>\n" +
+"  <os>\n" +
+"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
+"    <boot dev='cdrom'/>\n" +
+"    <boot dev='hd'/>\n" +
+"    <smbios mode='sysinfo'/>\n" +
+"  </os>\n" +
+"  <features>\n" +
+"    <acpi/>\n" +
+"    <apic/>\n" +
+"    <pae/>\n" +
+"  </features>\n" +
+"  <clock offset='utc'>\n" +
+"    <timer name='kvmclock'/>\n" +
+"  </clock>\n" +
+"  <on_poweroff>destroy</on_poweroff>\n" +
+"  <on_reboot>restart</on_reboot>\n" +
+"  <on_crash>destroy</on_crash>\n" +
+"  <devices>\n" +
+"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
+"    <disk type='file' device='disk'>\n" +
+"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
+"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
+"      <backingStore type='file' index='1'>\n" +
+"        <format type='raw'/>\n" +
+"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
+"        <backingStore/>\n" +
+"      </backingStore>\n" +
+"      <target dev='vda' bus='virtio'/>\n" +
+"      <serial>4650a2f7fce548e2beaa</serial>\n" +
+"      <alias name='virtio-disk0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
+"    </disk>\n" +
+"    <disk type='file' device='cdrom'>\n" +
+"      <driver name='qemu' type='raw' cache='none'/>\n" +
+"      <backingStore/>\n" +
+"      <target dev='hdc' bus='ide'/>\n" +
+"      <readonly/>\n" +
+"      <alias name='ide0-1-0'/>\n" +
+"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
+"    </disk>\n" +
+"    <controller type='usb' index='0'>\n" +
+"      <alias name='usb'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
+"    </controller>\n" +
+"    <controller type='pci' index='0' model='pci-root'>\n" +
+"      <alias name='pci.0'/>\n" +
+"    </controller>\n" +
+"    <controller type='ide' index='0'>\n" +
+"      <alias name='ide'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
+"    </controller>\n" +
+"    <interface type='bridge'>\n" +
+"      <mac address='06:fe:b4:00:00:06'/>\n" +
+"      <source bridge='breth0-50'/>\n" +
+"      <bandwidth>\n" +
+"        <inbound average='25600' peak='25600'/>\n" +
+"        <outbound average='25600' peak='25600'/>\n" +
+"      </bandwidth>\n" +
+"      <target dev='vnet4'/>\n" +
+"      <model type='virtio'/>\n" +
+"      <alias name='net0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
+"    </interface>\n" +
+"    <serial type='pty'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </serial>\n" +
+"    <console type='pty' tty='/dev/pts/2'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target type='serial' port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </console>\n" +
+"    <input type='tablet' bus='usb'>\n" +
+"      <alias name='input0'/>\n" +
+"    </input>\n" +
+"    <input type='mouse' bus='ps2'/>\n" +
+"    <input type='keyboard' bus='ps2'/>\n" +
+"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.21'>\n" +
+"      <listen type='address' address='192.168.22.21'/>\n" +
+"    </graphics>\n" +
+"    <video>\n" +
+"      <model type='cirrus' vram='16384' heads='1'/>\n" +
+"      <alias name='video0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
+"    </video>\n" +
+"    <memballoon model='none'>\n" +
+"      <alias name='balloon0'/>\n" +
+"    </memballoon>\n" +
+"  </devices>\n" +
+"</domain>";
+
+    @Test
+    public void testReplaceIpForVNCInDescFile() {
+        final String targetIp = "192.168.22.21";
+        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
+        final String result = lw.replaceIpForVNCInDescFile(fullfile, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result));
+    }
+
+    @Test
+    public void testReplaceIpForVNCInDesc() {
+        final String xmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>" +
+                "      <listen type='address' address='10.10.10.1'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String expectedXmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10'>" +
+                "      <listen type='address' address='10.10.10.10'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String targetIp = "10.10.10.10";
+        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
+        final String result = lw.replaceIpForVNCInDescFile(xmlDesc, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
+    }
+
+    @Test
+    public void testReplaceFqdnForVNCInDesc() {
+        final String xmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local'>" +
+                "      <listen type='address' address='localhost.local'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String expectedXmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain'>" +
+                "      <listen type='address' address='localhost.localdomain'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String targetIp = "localhost.localdomain";
+        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
+        final String result = lw.replaceIpForVNCInDescFile(xmlDesc, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
+    }
+}


[2/2] git commit: updated refs/heads/4.7 to c03e359

Posted by sw...@apache.org.
Merge pull request #1348 from DaanHoogland/CLOUDSTACK-9142

CLOUDSTACK-9142 Migrate VM changes xmlDesc in a safe wayThe problem arises when the origin hypervisor has an ip addres that ends with 1, like '10.10.10.1' and the qemu VM description is containing an address that has that as part of its address, '10.10.10.100' for instance.
now migrating to '10.10.10.10' will change both addresses in the xml description file for qemu. It is fixed and unit tests are added. I am not sure yet how to integration test this. Regression will probably work so creating a PR now.

* pr/1348:
  CLOUDSTACK-9142 Migrate VM changes xmlDesc in a safe way

Signed-off-by: Will Stevens <wi...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c03e3598
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c03e3598
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c03e3598

Branch: refs/heads/4.7
Commit: c03e359824327b56af6b1921155d8796d2958f9c
Parents: d13ff88 8a6afa6
Author: Will Stevens <wi...@gmail.com>
Authored: Thu Apr 28 15:55:09 2016 -0400
Committer: Will Stevens <wi...@gmail.com>
Committed: Thu Apr 28 15:55:09 2016 -0400

----------------------------------------------------------------------
 .../wrapper/LibvirtMigrateCommandWrapper.java   |  34 ++-
 .../resource/LibvirtComputingResourceTest.java  |  22 +-
 .../LibvirtMigrateCommandWrapperTest.java       | 306 +++++++++++++++++++
 3 files changed, 349 insertions(+), 13 deletions(-)
----------------------------------------------------------------------