def wait_backup_available(self, backup_region: str, backup_id: str, lambda_method: str, lambda_args: Dict) -> bool: """Wait for backup to become available. If running in lambda environment, pass lambda method and arguments to be executed if lambda functions times out, and return false. Always return true in non-lambda mode""" has_timed_out = {'value': False} engine = self def call_recursively(): # check if exceeded allowed number of wait iterations in lambda if self.lambda_wait_iteration > RuntimeConfig.get_max_lambda_wait_iterations(): raise Exception(f"Reached maximum of {RuntimeConfig.get_max_lambda_wait_iterations()} lambda wait" f"operations") lambda_args['lambda_wait_iteration'] = self.lambda_wait_iteration + 1 if lambda_method is not None and lambda_args is not None: ShelveryInvoker().invoke_shelvery_operation( engine, method_name=lambda_method, method_arguments=lambda_args) has_timed_out['value'] = True def panic(): self.logger.error(f"Failed to wait for backup to become available, exiting...") sys.exit(-5) # if running in lambda environment, call function recursively on timeout # otherwise in cli mode, just exit timeout_fn = call_recursively if RuntimeConfig.is_lambda_runtime(self) else panic self.do_wait_backup_available(backup_region=backup_region, backup_id=backup_id, timeout_fn=timeout_fn) return not (has_timed_out['value'] and RuntimeConfig.is_lambda_runtime(self))
def invoke_shelvery_operation(self, engine, method_name: str, method_arguments: Dict): """ Invokes shelvery engine asynchronously If shelvery is running within lambda environment, new lambda function invocation will be made. If running on server, it will start new thread and invoke the function Function invoke must accept arguments in form of map """ is_lambda_context = RuntimeConfig.is_lambda_runtime(engine) is_offload_queueing = RuntimeConfig.is_offload_queueing(engine) parameters = { 'backup_type': engine.get_engine_type(), 'action': method_name, 'arguments': method_arguments } if is_lambda_context: if 'config' in engine.lambda_payload: parameters['config'] = engine.lambda_payload['config'] if is_offload_queueing: sqs = ShelveryQueue(RuntimeConfig.get_sqs_queue_url(engine),RuntimeConfig.get_sqs_queue_wait_period(engine)) sqs.send(parameters) else: parameters['is_started_internally'] = True payload = json.dumps(parameters) bytes_payload = bytearray() bytes_payload.extend(map(ord, payload)) function_name = os.environ['AWS_LAMBDA_FUNCTION_NAME'] lambda_client = AwsHelper.boto3_client('lambda') lambda_client.invoke_async(FunctionName=function_name, InvokeArgs=bytes_payload) else: resource_type = engine.get_engine_type() def execute(): from shelvery.factory import ShelveryFactory backup_engine = ShelveryFactory.get_shelvery_instance(resource_type) method = backup_engine.__getattribute__(method_name) method(method_arguments) logging.info(f"Start new thread to execute :{method_name}") if 'SHELVERY_MONO_THREAD' in os.environ and os.environ['SHELVERY_MONO_THREAD'] == "1": execute() else: thread = Thread(target=execute) thread.start()