def unset_worker(self):
     if self.worker:
         db.worker_destroy(self._context,
                           id=self.worker.id,
                           status=self.worker.status,
                           service_id=self.worker.service_id)
         self.worker = None
Exemple #2
0
 def _remove_worker(self, context, id):
     # Remove the cleanup worker from the DB when we change a resource
     # status since it renders useless the entry.
     res = db.worker_destroy(context, resource_type=self.collection.title(),
                             resource_id=id)
     if res:
         LOG.debug('Worker entry for %s with id %s has been deleted.',
                   self.collection, id)
Exemple #3
0
    def test_worker_destroy(self):
        """Test that worker destroy really deletes the DB entry."""
        worker = self._create_workers(1)[0]
        res = db.worker_destroy(self.ctxt, id=worker.id)
        self.assertEqual(1, res)

        db_workers = db.worker_get_all(self.ctxt, read_deleted='yes')
        self.assertListEqual([], db_workers)
    def test_worker_destroy(self):
        """Test that worker destroy really deletes the DB entry."""
        worker = self._create_workers(1)[0]
        res = db.worker_destroy(self.ctxt, id=worker.id)
        self.assertEqual(1, res)

        db_workers = db.worker_get_all(self.ctxt, read_deleted='yes')
        self.assertListEqual([], db_workers)
Exemple #5
0
 def _remove_worker(self, context, id):
     # Remove the cleanup worker from the DB when we change a resource
     # status since it renders useless the entry.
     res = db.worker_destroy(context, resource_type=self.collection.title(),
                             resource_id=id)
     if res:
         LOG.debug('Worker entry for %s with id %s has been deleted.',
                   self.collection, id)
    def do_cleanup(self, context, cleanup_request):
        LOG.info('Initiating service %s cleanup', cleanup_request.service_id)

        # If the 'until' field in the cleanup request is not set, we default to
        # this very moment.
        until = cleanup_request.until or timeutils.utcnow()
        keep_entry = False

        to_clean = db.worker_get_all(
            context,
            resource_type=cleanup_request.resource_type,
            resource_id=cleanup_request.resource_id,
            service_id=cleanup_request.service_id,
            until=until)

        for clean in to_clean:
            original_service_id = clean.service_id
            original_time = clean.updated_at
            # Try to do a soft delete to mark the entry as being cleaned up
            # by us (setting service id to our service id).
            res = db.worker_claim_for_cleanup(context,
                                              claimer_id=self.service_id,
                                              orm_worker=clean)

            # Claim may fail if entry is being cleaned by another service, has
            # been removed (finished cleaning) by another service or the user
            # started a new cleanable operation.
            # In any of these cases we don't have to do cleanup or remove the
            # worker entry.
            if not res:
                continue

            # Try to get versioned object for resource we have to cleanup
            try:
                vo_cls = getattr(objects, clean.resource_type)
                vo = vo_cls.get_by_id(context, clean.resource_id)
                # Set the worker DB entry in the VO and mark it as being a
                # clean operation
                clean.cleaning = True
                vo.worker = clean
            except exception.NotFound:
                LOG.debug('Skipping cleanup for non existent %(type)s %(id)s.',
                          {
                              'type': clean.resource_type,
                              'id': clean.resource_id
                          })
            else:
                # Resource status should match
                if vo.status != clean.status:
                    LOG.debug(
                        'Skipping cleanup for mismatching work on '
                        '%(type)s %(id)s: %(exp_sts)s <> %(found_sts)s.', {
                            'type': clean.resource_type,
                            'id': clean.resource_id,
                            'exp_sts': clean.status,
                            'found_sts': vo.status
                        })
                else:
                    LOG.info(
                        'Cleaning %(type)s with id %(id)s and status '
                        '%(status)s', {
                            'type': clean.resource_type,
                            'id': clean.resource_id,
                            'status': clean.status
                        },
                        resource=vo)
                    try:
                        # Some cleanup jobs are performed asynchronously, so
                        # we don't delete the worker entry, they'll take care
                        # of it
                        keep_entry = self._do_cleanup(context, vo)
                    except Exception:
                        LOG.exception('Could not perform cleanup.')
                        # Return the worker DB entry to the original service
                        db.worker_update(context,
                                         clean.id,
                                         service_id=original_service_id,
                                         updated_at=original_time)
                        continue

            # The resource either didn't exist or was properly cleaned, either
            # way we can remove the entry from the worker table if the cleanup
            # method doesn't want to keep the entry (for example for delayed
            # deletion).
            if not keep_entry and not db.worker_destroy(context, id=clean.id):
                LOG.warning('Could not remove worker entry %s.', clean.id)

        LOG.info('Service %s cleanup completed.', cleanup_request.service_id)
Exemple #7
0
 def test_worker_destroy_non_existent(self):
     """Test that worker destroy returns 0 when entry doesn't exist."""
     res = db.worker_destroy(self.ctxt, id=100)
     self.assertEqual(0, res)
 def test_worker_destroy_non_existent(self):
     """Test that worker destroy returns 0 when entry doesn't exist."""
     res = db.worker_destroy(self.ctxt, id=100)
     self.assertEqual(0, res)
Exemple #9
0
    def do_cleanup(self, context, cleanup_request):
        LOG.info('Initiating service %s cleanup',
                 cleanup_request.service_id)

        # If the 'until' field in the cleanup request is not set, we default to
        # this very moment.
        until = cleanup_request.until or timeutils.utcnow()
        keep_entry = False

        to_clean = db.worker_get_all(
            context,
            resource_type=cleanup_request.resource_type,
            resource_id=cleanup_request.resource_id,
            service_id=cleanup_request.service_id,
            until=until)

        for clean in to_clean:
            original_service_id = clean.service_id
            original_time = clean.updated_at
            # Try to do a soft delete to mark the entry as being cleaned up
            # by us (setting service id to our service id).
            res = db.worker_claim_for_cleanup(context,
                                              claimer_id=self.service_id,
                                              orm_worker=clean)

            # Claim may fail if entry is being cleaned by another service, has
            # been removed (finished cleaning) by another service or the user
            # started a new cleanable operation.
            # In any of these cases we don't have to do cleanup or remove the
            # worker entry.
            if not res:
                continue

            # Try to get versioned object for resource we have to cleanup
            try:
                vo_cls = getattr(objects, clean.resource_type)
                vo = vo_cls.get_by_id(context, clean.resource_id)
                # Set the worker DB entry in the VO and mark it as being a
                # clean operation
                clean.cleaning = True
                vo.worker = clean
            except exception.NotFound:
                LOG.debug('Skipping cleanup for non existent %(type)s %(id)s.',
                          {'type': clean.resource_type,
                           'id': clean.resource_id})
            else:
                # Resource status should match
                if vo.status != clean.status:
                    LOG.debug('Skipping cleanup for mismatching work on '
                              '%(type)s %(id)s: %(exp_sts)s <> %(found_sts)s.',
                              {'type': clean.resource_type,
                               'id': clean.resource_id,
                               'exp_sts': clean.status,
                               'found_sts': vo.status})
                else:
                    LOG.info('Cleaning %(type)s with id %(id)s and status '
                             '%(status)s',
                             {'type': clean.resource_type,
                              'id': clean.resource_id,
                              'status': clean.status},
                             resource=vo)
                    try:
                        # Some cleanup jobs are performed asynchronously, so
                        # we don't delete the worker entry, they'll take care
                        # of it
                        keep_entry = self._do_cleanup(context, vo)
                    except Exception:
                        LOG.exception('Could not perform cleanup.')
                        # Return the worker DB entry to the original service
                        db.worker_update(context, clean.id,
                                         service_id=original_service_id,
                                         updated_at=original_time)
                        continue

            # The resource either didn't exist or was properly cleaned, either
            # way we can remove the entry from the worker table if the cleanup
            # method doesn't want to keep the entry (for example for delayed
            # deletion).
            if not keep_entry and not db.worker_destroy(context, id=clean.id):
                LOG.warning('Could not remove worker entry %s.', clean.id)

        LOG.info('Service %s cleanup completed.', cleanup_request.service_id)
Exemple #10
0
 def unset_worker(self):
     if self.worker:
         db.worker_destroy(self._context, id=self.worker.id,
                           status=self.worker.status,
                           service_id=self.worker.service_id)
         self.worker = None