def runner(resource_mngr, options, exit): try: if not (options.dry_run or options.resource or options.disable_only): resource_mngr.wait_for_check_prerequisite(exit) for resource in resource_mngr.list(): # No need to continue if requested to exit. if exit.is_set(): return resource_func_to_call = None if options.disable_only: resource_func_to_call = resource_mngr.disable logging.info("Going to disable resource %s", resource_mngr.to_str(resource)) elif resource_mngr.should_delete(resource): resource_func_to_call = resource_mngr.delete logging.info("Going to delete %s", resource_mngr.to_str(resource)) if resource_func_to_call: # If we are in dry run mode, don't actually delete/disable # the resource if options.dry_run: continue # If we want to delete/disable only specific resources, many # things can go wrong, so we basically ignore all exceptions. exc = os_exceptions.OpenStackCloudException utils.call_and_ignore_exc(exc, resource_func_to_call, resource) except Exception as exc: log = logging.error recoverable = False def is_exception_recoverable(exc): if exc.__class__.__name__.lower().endswith('endpointnotfound'): return True elif hasattr(exc, 'inner_exception'): # inner_exception is a tuple (type, value, traceback) # mypy complains: "Exception" has no attribute # "inner_exception" exc_info = exc.inner_exception # type: ignore if exc_info[0].__name__.lower().endswith('endpointnotfound'): return True return False if is_exception_recoverable(exc): log = logging.info recoverable = True log("Can't deal with %s: %r", resource_mngr.__class__.__name__, exc) if not recoverable: exit.set()
def test_call_and_ignore_notfound(self): def raiser(): raise os_exceptions.OpenStackCloudException("") self.assertIsNone( utils.call_and_ignore_exc(os_exceptions.OpenStackCloudException, raiser)) m = mock.Mock() utils.call_and_ignore_exc(os_exceptions.OpenStackCloudException, m, 42) self.assertEqual([mock.call(42)], m.call_args_list)
def test_call_and_ignore_notfound(self): def raiser(): raise shade.exc.OpenStackCloudResourceNotFound("") self.assertIsNone( utils.call_and_ignore_exc(shade.exc.OpenStackCloudResourceNotFound, raiser)) m = mock.Mock() utils.call_and_ignore_exc(shade.exc.OpenStackCloudResourceNotFound, m, 42) self.assertEqual([mock.call(42)], m.call_args_list)
def runner( resource_mngr: ServiceResource, options: argparse.Namespace, exit: threading.Event ) -> None: try: if not (options.dry_run or options.resource): resource_mngr.wait_for_check_prerequisite(exit) for resource in resource_mngr.list(): # No need to continue if requested to exit. if exit.is_set(): return if resource_mngr.should_delete(resource): logging.info("Going to delete %s", resource_mngr.to_str(resource)) # If we are in dry run mode, don't actually delete the resource if options.dry_run: continue # If we want to delete only specific resources, many things # can go wrong, so we basically ignore all exceptions. if options.resource: exc = shade.OpenStackCloudException else: exc = shade.OpenStackCloudResourceNotFound utils.call_and_ignore_exc(exc, resource_mngr.delete, resource) except Exception as exc: log = logging.error recoverable = False def is_exception_recoverable(exc): if exc.__class__.__name__.lower().endswith('endpointnotfound'): return True elif hasattr(exc, 'inner_exception'): # inner_exception is a tuple (type, value, traceback) # mypy complains: "Exception" has no attribute # "inner_exception" exc_info = exc.inner_exception # type: ignore if exc_info[0].__name__.lower().endswith('endpointnotfound'): return True return False if is_exception_recoverable(exc): log = logging.info recoverable = True log("Can't deal with %s: %r", resource_mngr.__class__.__name__, exc) if not recoverable: exit.set()
def test_call_and_ignore_notfound(self): def raiser(): raise shade.exc.OpenStackCloudResourceNotFound("") self.assertIsNone( utils.call_and_ignore_exc( shade.exc.OpenStackCloudResourceNotFound, raiser ) ) m = mock.Mock() utils.call_and_ignore_exc( shade.exc.OpenStackCloudResourceNotFound, m, 42) self.assertEqual([mock.call(42)], m.call_args_list)