'Use hotplug to add an network adapter to an instance.'

@wrap_exception()
@wrap_instance_fault
def attach_interface(self, context, instance, network_id, port_id, requested_ip, tag=None):

    if (not self.driver.capabilities['supports_attach_interface']):
        raise exception.AttachInterfaceNotSupported(instance_uuid=instance.uuid)
    if (tag and (not self.driver.capabilities.get('supports_tagged_attach_interface', False))):
        raise exception.NetworkInterfaceTaggedAttachNotSupported()
    bind_host_id = self.driver.network_binding_host_id(context, instance)
    network_info = self.network_api.allocate_port_for_instance(context, instance, port_id, network_id, requested_ip, bind_host_id=bind_host_id, tag=tag)
    if (len(network_info) != 1):
        LOG.error('allocate_port_for_instance    returned    %(ports)s    ports', {'ports': len(network_info)})
        raise exception.InterfaceAttachFailed(instance_uuid=instance.uuid)
    image_meta = objects.ImageMeta.from_instance(instance)
    try:
        self.driver.attach_interface(context, instance, image_meta, network_info[0])
    except exception.NovaException as ex:
        port_id = network_info[0].get('id')
        LOG.warning('attach    interface    failed    ,    try    to    deallocate    port    %(port_id)s,    reason:    %(msg)s', {'port_id': port_id, 'msg': ex}, instance=instance)
        try:
            self.network_api.deallocate_port_for_instance(context, instance, port_id)
        except Exception:
            LOG.warning('deallocate    port    %(port_id)s    failed', {'port_id': port_id}, instance=instance)
        raise exception.InterfaceAttachFailed(instance_uuid=instance.uuid)
    return network_info[0]
