Example #1
0
def get_instances_without_type(
    context: 'nova_context.RequestContext',
    cell_uuid: ty.Optional[str] = None,
) -> ty.List[objects.instance.Instance]:
    """Find instances without hw_machine_type set, optionally within a cell.

    :param context: Request context
    :param cell_uuid: Optional cell UUID to look within
    :returns: A list of Instance objects or an empty list
    """
    if cell_uuid:
        cell_mapping = objects.CellMapping.get_by_uuid(context, cell_uuid)
        results = nova_context.scatter_gather_single_cell(
            context,
            cell_mapping,
            _get_instances_without_mtype
        )

    results = nova_context.scatter_gather_skip_cell0(
        context,
        _get_instances_without_mtype
    )

    # Flatten the returned list of results into a single list of instances
    return list(itertools.chain(*[r for c, r in results.items()]))
    def test_scatter_gather_cells(self):
        self._create_cell_mappings()

        # Create an instance in cell0
        with context.target_cell(self.context, self.mapping0) as cctxt:
            instance = objects.Instance(context=cctxt, uuid=uuids.instance0,
                                        project_id='fake-project')
            instance.create()

        # Create an instance in first cell
        with context.target_cell(self.context, self.mapping1) as cctxt:
            instance = objects.Instance(context=cctxt, uuid=uuids.instance1,
                                        project_id='fake-project')
            instance.create()

        # Create an instance in second cell
        with context.target_cell(self.context, self.mapping2) as cctxt:
            instance = objects.Instance(context=cctxt, uuid=uuids.instance2,
                                        project_id='fake-project')
            instance.create()

        filters = {'deleted': False, 'project_id': 'fake-project'}
        results = context.scatter_gather_all_cells(
            self.context, objects.InstanceList.get_by_filters, filters,
            sort_dir='asc')
        instances = objects.InstanceList()
        for result in results.values():
            instances = instances + result

        # Should have 3 instances across cells
        self.assertEqual(3, len(instances))

        # Verify we skip cell0 when specified
        results = context.scatter_gather_skip_cell0(
            self.context, objects.InstanceList.get_by_filters, filters)
        instances = objects.InstanceList()
        for result in results.values():
            instances = instances + result

        # Should have gotten only the instances from the last two cells
        self.assertEqual(2, len(instances))
        self.assertIn(self.mapping1.uuid, results)
        self.assertIn(self.mapping2.uuid, results)
        instance_uuids = [inst.uuid for inst in instances]
        self.assertIn(uuids.instance1, instance_uuids)
        self.assertIn(uuids.instance2, instance_uuids)

        # Try passing one cell
        results = context.scatter_gather_cells(
            self.context, [self.mapping1], 60,
            objects.InstanceList.get_by_filters, filters)
        instances = objects.InstanceList()
        for result in results.values():
            instances = instances + result

        # Should have gotten only one instance from cell1
        self.assertEqual(1, len(instances))
        self.assertIn(self.mapping1.uuid, results)
        self.assertEqual(uuids.instance1, instances[0].uuid)
    def test_scatter_gather_skip_cell0(self, mock_get_all, mock_scatter):
        ctxt = context.get_context()
        mapping0 = objects.CellMapping(database_connection='fake://db0',
                                       transport_url='none:///',
                                       uuid=objects.CellMapping.CELL0_UUID)
        mapping1 = objects.CellMapping(database_connection='fake://db1',
                                       transport_url='fake://mq1',
                                       uuid=uuids.cell1)
        mock_get_all.return_value = objects.CellMappingList(
            objects=[mapping0, mapping1])

        filters = {'deleted': False}
        context.scatter_gather_skip_cell0(
            ctxt, objects.InstanceList.get_by_filters, filters, sort_dir='foo')

        mock_scatter.assert_called_once_with(
            ctxt, [mapping1], 60, objects.InstanceList.get_by_filters, filters,
            sort_dir='foo')
Example #4
0
    def test_scatter_gather_skip_cell0(self, mock_get_all, mock_scatter):
        ctxt = context.get_context()
        mapping0 = objects.CellMapping(database_connection='fake://db0',
                                       transport_url='none:///',
                                       uuid=objects.CellMapping.CELL0_UUID)
        mapping1 = objects.CellMapping(database_connection='fake://db1',
                                       transport_url='fake://mq1',
                                       uuid=uuids.cell1)
        mock_get_all.return_value = objects.CellMappingList(
            objects=[mapping0, mapping1])

        filters = {'deleted': False}
        context.scatter_gather_skip_cell0(
            ctxt, objects.InstanceList.get_by_filters, filters, sort_dir='foo')

        mock_scatter.assert_called_once_with(
            ctxt, [mapping1], 60, objects.InstanceList.get_by_filters, filters,
            sort_dir='foo')
Example #5
0
    def get_marker_record(self, ctx, marker):
        """Get the marker migration from its cell.

        This returns the marker migration from the cell in which it lives
        """
        results = context.scatter_gather_skip_cell0(
            ctx, db.migration_get_by_uuid, marker)
        db_migration = None
        for result_cell_uuid, result in results.items():
            if not context.is_cell_failure_sentinel(result):
                db_migration = result
                cell_uuid = result_cell_uuid
                break
        if not db_migration:
            raise exception.MarkerNotFound(marker=marker)
        return cell_uuid, db_migration
Example #6
0
    def get_marker_record(self, ctx, marker):
        """Get the marker migration from its cell.

        This returns the marker migration from the cell in which it lives
        """
        results = context.scatter_gather_skip_cell0(
            ctx, db.migration_get_by_uuid, marker)
        db_migration = None
        for result in results.values():
            if result not in (context.did_not_respond_sentinel,
                              context.raised_exception_sentinel):
                db_migration = result
                break
        if not db_migration:
            raise exception.MarkerNotFound(marker=marker)
        return db_migration
Example #7
0
    def get_marker_record(self, ctx, marker):
        """Get the marker migration from its cell.

        This returns the marker migration from the cell in which it lives
        """
        results = context.scatter_gather_skip_cell0(ctx,
                                                    db.migration_get_by_uuid,
                                                    marker)
        db_migration = None
        for result in results.values():
            if result not in (context.did_not_respond_sentinel,
                              context.raised_exception_sentinel):
                db_migration = result
                break
        if not db_migration:
            raise exception.MarkerNotFound(marker=marker)
        return db_migration
Example #8
0
    def get_marker_record(self, ctx, marker):
        """Get the marker migration from its cell.

        This returns the marker migration from the cell in which it lives
        """
        results = context.scatter_gather_skip_cell0(ctx,
                                                    db.migration_get_by_uuid,
                                                    marker)
        db_migration = None
        for result_cell_uuid, result in results.items():
            if not context.is_cell_failure_sentinel(result):
                db_migration = result
                cell_uuid = result_cell_uuid
                break
        if not db_migration:
            raise exception.MarkerNotFound(marker=marker)
        return cell_uuid, db_migration
    def _show(self, req, id, rdp_only):
        """Checks a console auth token and returns the related connect info."""
        context = req.environ['nova.context']
        context.can(cat_policies.BASE_POLICY_NAME)

        token = id
        if not token:
            msg = _("token not provided")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        connect_info = None
        if CONF.workarounds.enable_consoleauth:
            connect_info = self._consoleauth_rpcapi.check_token(context, token)
        else:
            results = nova_context.scatter_gather_skip_cell0(
                context, objects.ConsoleAuthToken.validate, token)
            # NOTE(melwitt): Console token auths are stored in cell databases,
            # but with only the token as a request param, we can't know which
            # cell database contains the token's corresponding connection info.
            # So, we must query all cells for the info and we can break the
            # loop as soon as we find a result because the token is associated
            # with one instance, which can only be in one cell.
            for result in results.values():
                if result not in (nova_context.did_not_respond_sentinel,
                                  nova_context.raised_exception_sentinel):
                    connect_info = result.to_dict()
                    break

        if not connect_info:
            raise webob.exc.HTTPNotFound(explanation=_("Token not found"))

        console_type = connect_info.get('console_type')

        if rdp_only and console_type != "rdp-html5":
            raise webob.exc.HTTPUnauthorized(
                explanation=_("The requested console type details are not "
                              "accessible"))

        return {
            'console': {
                i: connect_info[i]
                for i in
                ['instance_uuid', 'host', 'port', 'internal_access_path']
                if i in connect_info
            }
        }
    def _show(self, req, id, rdp_only):
        """Checks a console auth token and returns the related connect info."""
        context = req.environ['nova.context']
        context.can(cat_policies.BASE_POLICY_NAME)

        token = id
        if not token:
            msg = _("token not provided")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        connect_info = None

        results = nova_context.scatter_gather_skip_cell0(
            context, objects.ConsoleAuthToken.validate, token)
        # NOTE(melwitt): Console token auths are stored in cell databases,
        # but with only the token as a request param, we can't know which
        # cell database contains the token's corresponding connection info.
        # So, we must query all cells for the info and we can break the
        # loop as soon as we find a result because the token is associated
        # with one instance, which can only be in one cell.
        for result in results.values():
            if not nova_context.is_cell_failure_sentinel(result):
                connect_info = result
                break

        if not connect_info:
            raise webob.exc.HTTPNotFound(explanation=_("Token not found"))

        console_type = connect_info.console_type

        if rdp_only and console_type != "rdp-html5":
            raise webob.exc.HTTPUnauthorized(
                explanation=_("The requested console type details are not "
                              "accessible"))

        return {
            'console': {
                'instance_uuid': connect_info.instance_uuid,
                'host': connect_info.host,
                'port': connect_info.port,
                'internal_access_path': connect_info.internal_access_path,
            }
        }
Example #11
0
    def _show(self, req, id, rdp_only):
        """Checks a console auth token and returns the related connect info."""
        context = req.environ['nova.context']
        context.can(cat_policies.BASE_POLICY_NAME)

        token = id
        if not token:
            msg = _("token not provided")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        connect_info = None
        if CONF.workarounds.enable_consoleauth:
            connect_info = self._consoleauth_rpcapi.check_token(context, token)
        else:
            results = nova_context.scatter_gather_skip_cell0(
                context, objects.ConsoleAuthToken.validate, token)
            # NOTE(melwitt): Console token auths are stored in cell databases,
            # but with only the token as a request param, we can't know which
            # cell database contains the token's corresponding connection info.
            # So, we must query all cells for the info and we can break the
            # loop as soon as we find a result because the token is associated
            # with one instance, which can only be in one cell.
            for result in results.values():
                if not nova_context.is_cell_failure_sentinel(result):
                    connect_info = result.to_dict()
                    break

        if not connect_info:
            raise webob.exc.HTTPNotFound(explanation=_("Token not found"))

        console_type = connect_info.get('console_type')

        if rdp_only and console_type != "rdp-html5":
            raise webob.exc.HTTPUnauthorized(
                explanation=_("The requested console type details are not "
                              "accessible"))

        return {'console':
                {i: connect_info[i]
                 for i in ['instance_uuid', 'host', 'port',
                           'internal_access_path']
                 if i in connect_info}}
Example #12
0
def _get_instance_group_hosts_all_cells(context, instance_group):
    def get_hosts_in_cell(cell_context):
        # NOTE(melwitt): The obj_alternate_context is going to mutate the
        # cell_instance_group._context and to do this in a scatter-gather
        # with multiple parallel greenthreads, we need the instance groups
        # to be separate object copies.
        cell_instance_group = instance_group.obj_clone()
        with cell_instance_group.obj_alternate_context(cell_context):
            return cell_instance_group.get_hosts()

    results = nova_context.scatter_gather_skip_cell0(context,
                                                     get_hosts_in_cell)
    hosts = []
    for result in results.values():
        # TODO(melwitt): We will need to handle scenarios where an exception
        # is raised while targeting a cell and when a cell does not respond
        # as part of the "handling of a down cell" spec:
        # https://blueprints.launchpad.net/nova/+spec/handling-down-cell
        if not nova_context.is_cell_failure_sentinel(result):
            hosts.extend(result)
    return hosts
Example #13
0
def _get_instance_group_hosts_all_cells(context, instance_group):
    def get_hosts_in_cell(cell_context):
        # NOTE(melwitt): The obj_alternate_context is going to mutate the
        # cell_instance_group._context and to do this in a scatter-gather
        # with multiple parallel greenthreads, we need the instance groups
        # to be separate object copies.
        cell_instance_group = instance_group.obj_clone()
        with cell_instance_group.obj_alternate_context(cell_context):
            return cell_instance_group.get_hosts()

    results = nova_context.scatter_gather_skip_cell0(context,
                                                     get_hosts_in_cell)
    hosts = []
    for result in results.values():
        # TODO(melwitt): We will need to handle scenarios where an exception
        # is raised while targeting a cell and when a cell does not respond
        # as part of the "handling of a down cell" spec:
        # https://blueprints.launchpad.net/nova/+spec/handling-down-cell
        if not nova_context.is_cell_failure_sentinel(result):
            hosts.extend(result)
    return hosts