Exemple #1
0
    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))
Exemple #2
0
    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()