def create_ssl_context(self, *args, **kwargs): with SSL_LOCK: key = "%s%s" % (self.certfile, self.keyfile) if key not in SSL_CONTEXTS: # perform retries to circumvent "ssl.SSLError: [SSL] PEM lib (_ssl.c:4012)" def _do_create(): SSL_CONTEXTS[key] = create_ssl_context_orig(self, *args, **kwargs) retry(_do_create, retries=3, sleep=0.5) return SSL_CONTEXTS[key]
def checkpoint(self, checkpointer, sequence_number=None, sub_sequence_number=None): def do_checkpoint(): checkpointer.checkpoint(sequence_number, sub_sequence_number) try: retry(do_checkpoint, retries=CHECKPOINT_RETRIES, sleep=CHECKPOINT_SLEEP_SECS) except Exception as e: LOGGER.warning("Unable to checkpoint Kinesis after retries: %s", e)
def await_stack_status(stack_name, expected_statuses, retries=20, sleep=2, region_name=None): def check_stack(): stack = get_stack_details(stack_name, region_name=region_name) if stack["StackStatus"] not in expected_statuses: raise Exception( 'Status "%s" for stack "%s" not in expected list: %s' % (stack["StackStatus"], stack_name, expected_statuses)) return stack expected_statuses = (expected_statuses if isinstance( expected_statuses, list) else [expected_statuses]) return retry(check_stack, retries, sleep)
def _create_lambda_function(**kwargs): def _create_function(): resp = lambda_client.create_function(**kwargs) lambda_arns.append(resp["FunctionArn"]) def _is_not_pending(): try: result = (lambda_client.get_function( FunctionName=resp["FunctionName"])["Configuration"] ["State"] != "Pending") return result except Exception as e: LOG.error(e) raise wait_until(_is_not_pending) return resp # @AWS, takes about 10s until the role/policy is "active", until then it will fail # localstack should normally not require the retries and will just continue here return retry(_create_function, retries=3, sleep=4)
def install_elasticsearch(version=None): # locally import to avoid having a dependency on ASF when starting the CLI from localstack.aws.api.opensearch import EngineType from localstack.services.opensearch import versions if not version: version = ELASTICSEARCH_DEFAULT_VERSION version = get_elasticsearch_install_version(version) install_dir = get_elasticsearch_install_dir(version) installed_executable = os.path.join(install_dir, "bin", "elasticsearch") if not os.path.exists(installed_executable): log_install_msg(f"Elasticsearch ({version})") es_url = versions.get_download_url(version, EngineType.Elasticsearch) install_dir_parent = os.path.dirname(install_dir) mkdir(install_dir_parent) # download and extract archive tmp_archive = os.path.join(config.dirs.tmp, f"localstack.{os.path.basename(es_url)}") download_and_extract_with_retry(es_url, tmp_archive, install_dir_parent) elasticsearch_dir = glob.glob( os.path.join(install_dir_parent, "elasticsearch*")) if not elasticsearch_dir: raise Exception( f"Unable to find Elasticsearch folder in {install_dir_parent}") shutil.move(elasticsearch_dir[0], install_dir) for dir_name in ("data", "logs", "modules", "plugins", "config/scripts"): dir_path = os.path.join(install_dir, dir_name) mkdir(dir_path) chmod_r(dir_path, 0o777) # install default plugins for plugin in ELASTICSEARCH_PLUGIN_LIST: plugin_binary = os.path.join(install_dir, "bin", "elasticsearch-plugin") plugin_dir = os.path.join(install_dir, "plugins", plugin) if not os.path.exists(plugin_dir): LOG.info("Installing Elasticsearch plugin %s", plugin) def try_install(): output = run([plugin_binary, "install", "-b", plugin]) LOG.debug("Plugin installation output: %s", output) # We're occasionally seeing javax.net.ssl.SSLHandshakeException -> add download retries download_attempts = 3 try: retry(try_install, retries=download_attempts - 1, sleep=2) except Exception: LOG.warning( "Unable to download Elasticsearch plugin '%s' after %s attempts", plugin, download_attempts, ) if not os.environ.get("IGNORE_ES_DOWNLOAD_ERRORS"): raise # delete some plugins to free up space for plugin in ELASTICSEARCH_DELETE_MODULES: module_dir = os.path.join(install_dir, "modules", plugin) rm_rf(module_dir) # disable x-pack-ml plugin (not working on Alpine) xpack_dir = os.path.join(install_dir, "modules", "x-pack-ml", "platform") rm_rf(xpack_dir) # patch JVM options file - replace hardcoded heap size settings jvm_options_file = os.path.join(install_dir, "config", "jvm.options") if os.path.exists(jvm_options_file): jvm_options = load_file(jvm_options_file) jvm_options_replaced = re.sub(r"(^-Xm[sx][a-zA-Z0-9.]+$)", r"# \1", jvm_options, flags=re.MULTILINE) if jvm_options != jvm_options_replaced: save_file(jvm_options_file, jvm_options_replaced)
def wait_for_stepfunctions(): retry(check_stepfunctions, sleep=0.5, retries=15)
def wait_for_dynamodb(): retry(check_dynamodb, sleep=0.4, retries=10)