예제 #1
0
    def test_update_perf_events_xml_remove_all_events(self):
        data = objects.LibvirtLiveMigrateData(supported_perf_events=[])
        xml = """<domain>
  <perf>
    <event enabled="yes" name="cmt"/>
  </perf>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_perf_events_xml(doc, data),
                             encoding='unicode')

        self.assertThat(
            res,
            matchers.XMLMatches("""<domain>
  <perf>
    </perf>
</domain>"""))
예제 #2
0
    def test_update_memory_backing_xml_add(self):
        data = objects.LibvirtLiveMigrateData(
            dst_wants_file_backed_memory=True)
        xml = """<domain/>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_memory_backing_xml(doc, data),
                             encoding='unicode')

        self.assertThat(
            res,
            matchers.XMLMatches("""<domain>
  <memoryBacking>
    <source type="file"/>
    <access mode="shared"/>
    <allocation mode="immediate"/>
  </memoryBacking>
</domain>"""))
    def test_update_perf_events_xml_add_new_events1(self):
        data = objects.LibvirtLiveMigrateData(
            supported_perf_events=['cmt', 'mbml'])
        xml = """<domain>
  <perf>
    <event enabled="yes" name="cmt"/>
  </perf>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_perf_events_xml(doc, data))

        self.assertThat(
            res,
            matchers.XMLMatches("""<domain>
  <perf>
    <event enabled="yes" name="cmt"/><event enabled="yes" name="mbml"/></perf>
</domain>"""))
예제 #4
0
    def test_update_serial_xml_serial(self):
        data = objects.LibvirtLiveMigrateData(serial_listen_addr='127.0.0.100',
                                              serial_listen_ports=[2001])
        xml = """<domain>
  <devices>
    <serial type="tcp">
      <source host="127.0.0.1" service="2000"/>
      <target type="serial" port="0"/>
    </serial>
  </devices>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_serial_xml(doc, data),
                             encoding='unicode')
        new_xml = xml.replace("127.0.0.1",
                              "127.0.0.100").replace("2000", "2001")
        self.assertThat(res, matchers.XMLMatches(new_xml))
예제 #5
0
    def test_update_memory_backing_xml_remove(self):
        data = objects.LibvirtLiveMigrateData(
            dst_wants_file_backed_memory=False)
        xml = """<domain>
  <memoryBacking>
    <source type="file"/>
    <access mode="shared"/>
    <allocation mode="immediate"/>
  </memoryBacking>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_memory_backing_xml(doc, data),
                             encoding='unicode')

        self.assertXmlEqual(res, """<domain>
  <memoryBacking/>
</domain>""")
예제 #6
0
    def test_update_perf_events_xml_add_new_events1(self):
        data = objects.LibvirtLiveMigrateData(
            supported_perf_events=['cmt', 'mbml'])
        xml = """<domain>
  <perf>
    <event enabled="yes" name="cmt"/>
  </perf>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_perf_events_xml(doc, data),
                             encoding='unicode')

        self.assertXmlEqual(
            res, """<domain>
  <perf>
    <event enabled="yes" name="cmt"/><event enabled="yes" name="mbml"/></perf>
</domain>""")
예제 #7
0
 def test_live_migration(self):
     instance_ref, network_info = self._get_running_instance()
     instance_ref.info_cache = objects.InstanceInfoCache(
         network_info=network_info)
     fake_context = context.RequestContext('fake', 'fake')
     migration = objects.Migration(context=fake_context, id=1)
     migrate_data = objects.LibvirtLiveMigrateData(
         migration=migration,
         bdms=[],
         block_migration=False,
         serial_listen_addr='127.0.0.1')
     self.connection.live_migration(self.ctxt,
                                    instance_ref,
                                    'otherhost',
                                    lambda *a: None,
                                    lambda *a: None,
                                    migrate_data=migrate_data)
예제 #8
0
    def test_bind_ports_on_destination_provider_mapping(self, mock_bind_ports):
        """Assert that if only the provider mapping contains binding
        profile related information then that is sent to neutron.
        """

        self.task.migrate_data = objects.LibvirtLiveMigrateData(
            vifs=[
                objects.VIFMigrateData(
                    port_id=uuids.port1)
            ])
        provider_mappings = {uuids.port1: [uuids.dest_bw_rp]}

        self.task._bind_ports_on_destination('dest-host', provider_mappings)

        mock_bind_ports.assert_called_once_with(
            context=self.context, instance=self.instance, host='dest-host',
            vnic_types=None,
            port_profiles={uuids.port1: {'allocation': uuids.dest_bw_rp}})
예제 #9
0
    def test_update_graphics(self):
        data = objects.LibvirtLiveMigrateData(
            graphics_listen_addr_vnc='127.0.0.100',
            graphics_listen_addr_spice='127.0.0.200')
        xml = """<domain>
  <devices>
    <graphics type="vnc">
      <listen type="address" address="127.0.0.1"/>
    </graphics>
    <graphics type="spice">
      <listen type="address" address="127.0.0.2"/>
    </graphics>
  </devices>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_graphics_xml(doc, data))
        self.assertIn('127.0.0.100', six.text_type(res))
        self.assertIn('127.0.0.200', six.text_type(res))
예제 #10
0
    def test_update_graphics(self):
        data = objects.LibvirtLiveMigrateData(
            graphics_listen_addr_vnc='127.0.0.100',
            graphics_listen_addr_spice='127.0.0.200')
        xml = """<domain>
  <devices>
    <graphics type="vnc">
      <listen type="address" address="127.0.0.1"/>
    </graphics>
    <graphics type="spice">
      <listen type="address" address="127.0.0.2"/>
    </graphics>
  </devices>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_graphics_xml(doc, data))
        new_xml = xml.replace("127.0.0.1", "127.0.0.100")
        new_xml = new_xml.replace("127.0.0.2", "127.0.0.200")
        self.assertThat(res, matchers.XMLMatches(new_xml))
예제 #11
0
    def test_live_migration(self):
        instance_ref, network_info = self._get_running_instance()
        fake_context = context.RequestContext('fake', 'fake')
        migration = objects.Migration(context=fake_context, id=1)
        migrate_data = objects.LibvirtLiveMigrateData(
            migration=migration, bdms=[], block_migration=False,
            serial_listen_addr='127.0.0.1')

        # WRS: Need to fake as _update_numa_xml now accesses migration_context
        def fake_update_numa_xml(xml_doc, driver_interface, instance):
            return xml_doc

        self.stubs.Set(libvirt.migration, '_update_numa_xml',
                       fake_update_numa_xml)

        self.connection.live_migration(self.ctxt, instance_ref, 'otherhost',
                                       lambda *a: None,
                                       lambda *a, **kwargs: None,
                                       migrate_data=migrate_data)
예제 #12
0
    def test_bind_ports_on_destination_merges_profiles_extended_res_req(
            self, mock_bind_ports, mock_get_binding_profile_alloc):
        """Assert that if both the migration_data and the provider mapping
        contains binding profile related information and the port has extended
        resource request then such information is merged in the resulting
        profile.
        """

        self.task.migrate_data = objects.LibvirtLiveMigrateData(vifs=[
            objects.VIFMigrateData(port_id=uuids.port1,
                                   profile_json=jsonutils.dumps(
                                       {'some-key': 'value'}))
        ])
        provider_mappings = {
            uuids.bw_group: [uuids.dest_bw_rp],
            uuids.pps_group: [uuids.dest_pps_rp],
            uuids.accel_group: [uuids.cyborg_rp],
        }
        mock_get_binding_profile_alloc.return_value = {
            uuids.bw_group: uuids.dest_bw_rp,
            uuids.pps_group: uuids.dest_pps_rp,
        }

        self.task._bind_ports_on_destination('dest-host', provider_mappings)

        mock_bind_ports.assert_called_once_with(context=self.context,
                                                instance=self.instance,
                                                host='dest-host',
                                                vnic_types=None,
                                                port_profiles={
                                                    uuids.port1: {
                                                        'allocation': {
                                                            uuids.bw_group:
                                                            uuids.dest_bw_rp,
                                                            uuids.pps_group:
                                                            uuids.dest_pps_rp,
                                                        },
                                                        'some-key': 'value'
                                                    }
                                                })
        mock_get_binding_profile_alloc.assert_called_once_with(
            self.context, uuids.port1, provider_mappings)
예제 #13
0
    def test_bind_ports_on_destination_migration_data(self, mock_bind_ports):
        """Assert that if only the migration_data contains binding profile
        related information then that is sent to neutron.
        """

        self.task.migrate_data = objects.LibvirtLiveMigrateData(
            vifs=[
                objects.VIFMigrateData(
                    port_id=uuids.port1,
                    profile_json=jsonutils.dumps(
                        {'some-key': 'value'}))
            ])
        provider_mappings = {}

        self.task._bind_ports_on_destination('dest-host', provider_mappings)

        mock_bind_ports.assert_called_once_with(
            context=self.context, instance=self.instance, host='dest-host',
            vnic_types=None,
            port_profiles={uuids.port1: {'some-key': 'value'}})
예제 #14
0
    def test_call_livem_checks_on_host_bind_ports(self):
        data = objects.LibvirtLiveMigrateData()
        bindings = {
            uuids.port1: {
                'host': 'dest-host'
            },
            uuids.port2: {
                'host': 'dest-host'
            }
        }

        @mock.patch.object(self.task, '_check_can_migrate_pci')
        @mock.patch.object(self.task.compute_rpcapi,
                           'check_can_live_migrate_destination',
                           return_value=data)
        @mock.patch.object(self.task.network_api,
                           'supports_port_binding_extension',
                           return_value=True)
        @mock.patch.object(self.task.network_api,
                           'bind_ports_to_host',
                           return_value=bindings)
        def _test(mock_bind_ports_to_host, mock_supports_port_binding,
                  mock_check_can_live_migrate_dest,
                  mock_check_can_migrate_pci):
            nwinfo = network_model.NetworkInfo([
                network_model.VIF(uuids.port1),
                network_model.VIF(uuids.port2)
            ])
            self.instance.info_cache = objects.InstanceInfoCache(
                network_info=nwinfo)
            self.task._call_livem_checks_on_host('dest-host', {})
            # Assert the migrate_data set on the task based on the port
            # bindings created.
            self.assertIn('vifs', data)
            self.assertEqual(2, len(data.vifs))
            for vif in data.vifs:
                self.assertIn('source_vif', vif)
                self.assertEqual('dest-host', vif.host)
                self.assertEqual(vif.port_id, vif.source_vif['id'])

        _test()
    def test_update_serial_xml_console(self):
        data = objects.LibvirtLiveMigrateData(serial_listen_addr='127.0.0.100',
                                              serial_listen_ports=[299, 300])
        xml = """<domain>
  <devices>
    <console type="tcp">
      <source host="127.0.0.1" service="2001"/>
      <target type="serial" port="0"/>
    </console>
    <console type="tcp">
      <source host="127.0.0.1" service="2002"/>
      <target type="serial" port="1"/>
    </console>
  </devices>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_serial_xml(doc, data))
        new_xml = xml.replace("127.0.0.1", "127.0.0.100").replace(
            "2001", "299").replace("2002", "300")

        self.assertThat(res, matchers.XMLMatches(new_xml))
    def test_update_serial_xml_without_ports(self):
        # This test is for backwards compatibility when we don't
        # get the serial ports from the target node.
        data = objects.LibvirtLiveMigrateData(serial_listen_addr='127.0.0.100',
                                              serial_listen_ports=[])
        xml = """<domain>
  <devices>
    <console type="tcp">
      <source host="127.0.0.1" service="2001"/>
      <target type="serial" port="0"/>
    </console>
    <console type="tcp">
      <source host="127.0.0.1" service="2002"/>
      <target type="serial" port="1"/>
    </console>
  </devices>
</domain>"""
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_serial_xml(doc, data))
        new_xml = xml.replace("127.0.0.1", "127.0.0.100")
        self.assertThat(res, matchers.XMLMatches(new_xml))
예제 #17
0
    def test_get_instance_path_at_destination(self):
        instance = fake_instance.fake_instance_obj(None, name='fake_inst',
                                                   uuid=uuids.instance)

        migrate_data = None
        inst_path_at_dest = libvirt_utils.get_instance_path_at_destination(
            instance, migrate_data)
        expected_path = os.path.join(CONF.instances_path, instance['uuid'])
        self.assertEqual(expected_path, inst_path_at_dest)

        migrate_data = {}
        inst_path_at_dest = libvirt_utils.get_instance_path_at_destination(
            instance, migrate_data)
        expected_path = os.path.join(CONF.instances_path, instance['uuid'])
        self.assertEqual(expected_path, inst_path_at_dest)

        migrate_data = objects.LibvirtLiveMigrateData(
            instance_relative_path='fake_relative_path')
        inst_path_at_dest = libvirt_utils.get_instance_path_at_destination(
            instance, migrate_data)
        expected_path = os.path.join(CONF.instances_path, 'fake_relative_path')
        self.assertEqual(expected_path, inst_path_at_dest)
예제 #18
0
    def test_bind_ports_on_destination_merges_profiles(self, mock_bind_ports):
        """Assert that if both the migration_data and the provider mapping
        contains binding profile related information then such information is
        merged in the resulting profile.
        """

        self.task.migrate_data = objects.LibvirtLiveMigrateData(
            vifs=[
                objects.VIFMigrateData(
                    port_id=uuids.port1,
                    profile_json=jsonutils.dumps(
                        {'some-key': 'value'}))
            ])
        provider_mappings = {uuids.port1: [uuids.dest_bw_rp]}

        self.task._bind_ports_on_destination('dest-host', provider_mappings)

        mock_bind_ports.assert_called_once_with(
            context=self.context, instance=self.instance, host='dest-host',
            vnic_types=None,
            port_profiles={uuids.port1: {'allocation': uuids.dest_bw_rp,
                                         'some-key': 'value'}})
예제 #19
0
 def test_update_vif_xml_no_matching_vif(self):
     """Tests that the vif in the migrate data is not found in the existing
     guest interfaces.
     """
     data = objects.LibvirtLiveMigrateData(vifs=[
         objects.VIFMigrateData(source_vif=network_model.VIF(
             address="DE:AD:BE:EF:CA:FE"))])
     original_xml = """<domain>
      <uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
      <devices>
         <interface type="bridge">
             <mac address="CA:FE:DE:AD:BE:EF"/>
             <model type="virtio"/>
             <source bridge="qbra188171c-ea"/>
             <target dev="tapa188171c-ea"/>
         </interface>
      </devices>
     </domain>"""
     get_vif_config = mock.MagicMock(new_callable=mock.NonCallableMock)
     doc = etree.fromstring(original_xml)
     ex = self.assertRaises(KeyError, migration._update_vif_xml,
                            doc, data, get_vif_config)
     self.assertIn("CA:FE:DE:AD:BE:EF", six.text_type(ex))
예제 #20
0
 def test_serial_listen_addr_None(self):
     data = objects.LibvirtLiveMigrateData()
     data.serial_listen_addr = None
     addr = migration.serial_listen_addr(data)
     self.assertIsNone(addr)
예제 #21
0
 def test_serial_listen_addr(self):
     data = objects.LibvirtLiveMigrateData(serial_listen_addr='127.0.0.1')
     addr = migration.serial_listen_addr(data)
     self.assertEqual('127.0.0.1', addr)
예제 #22
0
 def test_graphics_listen_addrs_vnc(self):
     data = objects.LibvirtLiveMigrateData(
         graphics_listen_addr_vnc='127.0.0.1')
     addrs = migration.graphics_listen_addrs(data)
     self.assertEqual({'vnc': '127.0.0.1', 'spice': None}, addrs)
예제 #23
0
 def test_graphics_listen_addrs_empty(self):
     data = objects.LibvirtLiveMigrateData()
     addrs = migration.graphics_listen_addrs(data)
     self.assertIsNone(None, addrs)
예제 #24
0
 def test_serial_listen_ports_emtpy(self):
     data = objects.LibvirtLiveMigrateData()
     ports = migration.serial_listen_ports(data)
     self.assertEqual([], ports)
예제 #25
0
 def test_serial_listen_ports(self):
     data = objects.LibvirtLiveMigrateData(serial_listen_ports=[1, 2, 3])
     ports = migration.serial_listen_ports(data)
     self.assertEqual([1, 2, 3], ports)
예제 #26
0
    def test_update_vif_xml(self):
        """Simulates updating the guest xml for live migrating from a host
        using OVS to a host using vhostuser as the networking backend.
        """
        vif_ovs = network_model.VIF(id=uuids.vif,
                                    address='DE:AD:BE:EF:CA:FE',
                                    details={'port_filter': False},
                                    devname='tap-xxx-yyy-zzz',
                                    ovs_interfaceid=uuids.ovs)
        source_vif = vif_ovs
        migrate_vifs = [
            objects.VIFMigrateData(
                port_id=uuids.port_id,
                vnic_type=network_model.VNIC_TYPE_NORMAL,
                vif_type=network_model.VIF_TYPE_VHOSTUSER,
                vif_details={'vhostuser_socket': '/vhost-user/test.sock'},
                profile={},
                host='dest.host',
                source_vif=source_vif)
        ]
        data = objects.LibvirtLiveMigrateData(vifs=migrate_vifs)

        original_xml = """<domain>
 <uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
 <devices>
    <interface type="bridge">
        <mac address="DE:AD:BE:EF:CA:FE"/>
        <model type="virtio"/>
        <source bridge="qbra188171c-ea"/>
        <target dev="tapa188171c-ea"/>
        <virtualport type="openvswitch">
            <parameters interfaceid="%s"/>
        </virtualport>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
                 function='0x0'/>
    </interface>
 </devices>
</domain>""" % uuids.ovs

        conf = vconfig.LibvirtConfigGuestInterface()
        conf.net_type = "vhostuser"
        conf.vhostuser_type = "unix"
        conf.vhostuser_mode = "server"
        conf.mac_addr = "DE:AD:BE:EF:CA:FE"
        conf.vhostuser_path = "/vhost-user/test.sock"
        conf.model = "virtio"

        get_vif_config = mock.MagicMock(return_value=conf)
        doc = etree.fromstring(original_xml)
        updated_xml = etree.tostring(migration._update_vif_xml(
            doc, data, get_vif_config),
                                     encoding='unicode')

        # Note that <target> and <virtualport> are dropped from the ovs source
        # interface xml since they aren't applicable to the vhostuser
        # destination interface xml. The type attribute value changes and the
        # hardware address element is retained.
        expected_xml = """<domain>
 <uuid>3de6550a-8596-4937-8046-9d862036bca5</uuid>
 <devices>
    <interface type="vhostuser">
        <mac address="DE:AD:BE:EF:CA:FE"/>
        <model type="virtio"/>
        <source mode="server" path="/vhost-user/test.sock" type="unix"/>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
                 function='0x0'/>
    </interface>
 </devices>
</domain>"""
        self.assertThat(updated_xml, matchers.XMLMatches(expected_xml))
예제 #27
0
    def test_update_volume_xml_update_encryption(self):
        connection_info = {
            'driver_volume_type': 'rbd',
            'serial': 'd299a078-f0db-4993-bf03-f10fe44fd192',
            'data': {
                'access_mode': 'rw',
                'secret_type': 'ceph',
                'name': 'cinder-volumes/volume-d299a078',
                'encrypted': False,
                'discard': True,
                'cluster_name': 'ceph',
                'secret_uuid': '1a790a26-dd49-4825-8d16-3dd627cf05a9',
                'qos_specs': None,
                'auth_enabled': True,
                'volume_id': 'd299a078-f0db-4993-bf03-f10fe44fd192',
                'hosts': ['172.16.128.101', '172.16.128.121'],
                'auth_username': '******',
                'ports': ['6789', '6789', '6789']
            }
        }
        bdm = objects.LibvirtLiveMigrateBDMInfo(
            serial='d299a078-f0db-4993-bf03-f10fe44fd192',
            bus='scsi',
            type='disk',
            dev='sdb',
            connection_info=connection_info,
            encryption_secret_uuid=uuids.encryption_secret_uuid_new)
        data = objects.LibvirtLiveMigrateData(target_connect_addr=None,
                                              bdms=[bdm],
                                              block_migration=False)
        xml = """<domain>
 <devices>
    <disk type='network' device='disk'>
      <driver name='qemu' type='raw' cache='writeback' discard='unmap'/>
      <auth username='******'>
        <secret type='ceph' uuid='1a790a26-dd49-4825-8d16-3dd627cf05a9'/>
      </auth>
      <source protocol='rbd' name='cinder-volumes/volume-d299a078'>
        <host name='172.16.128.101' port='6789'/>
        <host name='172.16.128.121' port='6789'/>
      </source>
      <backingStore/>
      <target dev='sdb' bus='scsi'/>
      <serial>d299a078-f0db-4993-bf03-f10fe44fd192</serial>
      <alias name='scsi0-0-0-1'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='%(encryption_secret_uuid)s'/>
      </encryption>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
 </devices>
</domain>""" % {
            'encryption_secret_uuid': uuids.encryption_secret_uuid_old
        }
        conf = vconfig.LibvirtConfigGuestDisk()
        conf.source_device = bdm.type
        conf.driver_name = "qemu"
        conf.driver_format = "raw"
        conf.driver_cache = "writeback"
        conf.target_dev = bdm.dev
        conf.target_bus = bdm.bus
        conf.serial = bdm.connection_info.get('serial')
        conf.source_type = "network"
        conf.driver_discard = 'unmap'
        conf.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
        conf.device_addr.controller = 0

        get_volume_config = mock.MagicMock(return_value=conf)
        doc = etree.fromstring(xml)
        res = etree.tostring(migration._update_volume_xml(
            doc, data, get_volume_config),
                             encoding='unicode')
        new_xml = xml.replace(uuids.encryption_secret_uuid_old,
                              uuids.encryption_secret_uuid_new)
        self.assertThat(res, matchers.XMLMatches(new_xml))