Пример #1
0
    def test_supports_os_vif_delegation(self):
        # first try setting on a object without 'profile' defined
        migrate_vif = objects.VIFMigrateData(
            port_id=uuids.port_id,
            vnic_type=network_model.VNIC_TYPE_NORMAL,
            vif_type=network_model.VIF_TYPE_OVS,
            vif_details={},
            host='fake-dest-host')
        migrate_vif.supports_os_vif_delegation = True
        self.assertTrue(migrate_vif.supports_os_vif_delegation)
        self.assertEqual(migrate_vif.profile, {'os_vif_delegation': True})

        # now do the same but with profile defined
        migrate_vif = objects.VIFMigrateData(
            port_id=uuids.port_id,
            vnic_type=network_model.VNIC_TYPE_NORMAL,
            vif_type=network_model.VIF_TYPE_OVS,
            vif_details={},
            host='fake-dest-host',
            profile={'interface_name': 'eth0'})
        migrate_vif.supports_os_vif_delegation = True
        self.assertTrue(migrate_vif.supports_os_vif_delegation)
        self.assertEqual(migrate_vif.profile, {
            'os_vif_delegation': True,
            'interface_name': 'eth0'
        })
Пример #2
0
    def _bind_ports_on_destination(self, destination):
        LOG.debug('Start binding ports on destination host: %s', destination,
                  instance=self.instance)
        # Bind ports on the destination host; returns a dict, keyed by
        # port ID, of a new destination host port binding dict per port
        # that was bound. This information is then stuffed into the
        # migrate_data.
        try:
            bindings = self.network_api.bind_ports_to_host(
                self.context, self.instance, destination)
        except exception.PortBindingFailed as e:
            # Port binding failed for that host, try another one.
            raise exception.MigrationPreCheckError(
                reason=e.format_message())

        source_vif_map = {
            vif['id']: vif for vif in self.instance.get_network_info()
        }
        migrate_vifs = []
        for port_id, binding in bindings.items():
            migrate_vif = objects.VIFMigrateData(
                port_id=port_id, **binding)
            migrate_vif.source_vif = source_vif_map[port_id]
            migrate_vifs.append(migrate_vif)
        return migrate_vifs
Пример #3
0
 def test_update_vif_xml_no_mac_address_in_xml(self):
     """Tests that the <mac address> is not found in the <interface> XML
     which results in an error.
     """
     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='direct'>
             <source dev='eth0' mode='private'/>
             <virtualport type='802.1Qbh'>
               <parameters profileid='finance'/>
             </virtualport>
         </interface>
      </devices>
     </domain>"""
     get_vif_config = mock.MagicMock(new_callable=mock.NonCallableMock)
     doc = etree.fromstring(original_xml)
     ex = self.assertRaises(exception.NovaException,
                            migration._update_vif_xml, doc, data,
                            get_vif_config)
     self.assertIn('Unable to find MAC address in interface XML',
                   six.text_type(ex))
Пример #4
0
 def test_vif_migrate_data(self):
     source_vif = network_model.VIF(
         id=uuids.port_id,
         network=network_model.Network(id=uuids.network_id),
         type=network_model.VIF_TYPE_OVS,
         vnic_type=network_model.VNIC_TYPE_NORMAL,
         active=True,
         profile={'migrating_to': 'dest-host'})
     vif_details_dict = {'port_filter': True}
     profile_dict = {'trusted': False}
     vif_data = objects.VIFMigrateData(
         port_id=uuids.port_id,
         vnic_type=network_model.VNIC_TYPE_NORMAL,
         vif_type=network_model.VIF_TYPE_BRIDGE,
         vif_details=vif_details_dict,
         profile=profile_dict,
         host='dest-host',
         source_vif=source_vif)
     # Make sure the vif_details and profile fields are converted and
     # stored properly.
     self.assertEqual(jsonutils.dumps(vif_details_dict),
                      vif_data.vif_details_json)
     self.assertEqual(jsonutils.dumps(profile_dict), vif_data.profile_json)
     self.assertDictEqual(vif_details_dict, vif_data.vif_details)
     self.assertDictEqual(profile_dict, vif_data.profile)
     obj = migrate_data.LibvirtLiveMigrateData(
         file_backed_memory_discard=False)
     obj.vifs = [vif_data]
     manifest = ovo_base.obj_tree_get_versions(obj.obj_name())
     primitive = obj.obj_to_primitive(target_version='1.8',
                                      version_manifest=manifest)
     self.assertIn('file_backed_memory_discard',
                   primitive['nova_object.data'])
     self.assertNotIn('vifs', primitive['nova_object.data'])
 def test_get_dest_vif_source_vif_not_set(self):
     migrate_vif = objects.VIFMigrateData(
         port_id=uuids.port_id, vnic_type=network_model.VNIC_TYPE_NORMAL,
         vif_type=network_model.VIF_TYPE_OVS, vif_details={},
         profile={}, host='fake-dest-host')
     self.assertRaises(
         exception.ObjectActionError, migrate_vif.get_dest_vif)
Пример #6
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'
                                                    }
                                                })
Пример #7
0
    def _test_update_vif_xml(self, conf, original_xml, expected_xml):
        """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)

        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')
        self.assertThat(updated_xml, matchers.XMLMatches(expected_xml))
 def test_get_dest_vif(self):
     source_vif = network_model.VIF(
         id=uuids.port_id, type=network_model.VIF_TYPE_OVS, details={},
         vnic_type=network_model.VNIC_TYPE_DIRECT, profile={'foo': 'bar'},
         ovs_interfaceid=uuids.ovs_interfaceid)
     migrate_vif = objects.VIFMigrateData(
         port_id=uuids.port_id, vnic_type=network_model.VNIC_TYPE_NORMAL,
         vif_type=network_model.VIF_TYPE_BRIDGE, vif_details={'bar': 'baz'},
         profile={}, host='fake-dest-host', source_vif=source_vif)
     dest_vif = migrate_vif.get_dest_vif()
     self.assertEqual(migrate_vif.port_id, dest_vif['id'])
     self.assertEqual(migrate_vif.vnic_type, dest_vif['vnic_type'])
     self.assertEqual(migrate_vif.vif_type, dest_vif['type'])
     self.assertEqual(migrate_vif.vif_details, dest_vif['details'])
     self.assertEqual(migrate_vif.profile, dest_vif['profile'])
     self.assertEqual(uuids.ovs_interfaceid, dest_vif['ovs_interfaceid'])
Пример #9
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}})
Пример #10
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)
Пример #11
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'}})
Пример #12
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))
Пример #13
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))