def _fuzzy_find_pod(c, podname): pods = kubectl(c, "get pods", hide="out") podnames = [re.split(" +", l)[0] for l in pods.stdout.splitlines()[1:]] if podname not in podnames: aux = [p for p in podnames if podname in p] if aux and len(aux) == 1: podname = aux[0] elif len(aux) > 1: podnames = ", ".join(aux) raise Failure(f"More than one pod matching {podname}: {podnames}!") else: podnames = ", ".join(podnames) raise Failure(f"{podname} not found in pods: {podnames}!") return podname
def build(ctx, c, nocache=False, push=False): """ Build container images """ this_version = get_version() for container in c: tag_name = "faabric/{}:{}".format(container, this_version) if nocache: no_cache_str = "--no-cache" else: no_cache_str = "" dockerfile = join(PROJ_ROOT, "docker", "{}.dockerfile".format(container)) if not exists(dockerfile): raise Failure("Invalid container: {}".format(container)) cmd = "docker build {} -t {} --build-arg FAABRIC_VERSION={} -f {} .".format(no_cache_str, tag_name, this_version, dockerfile) print(cmd) run(cmd, shell=True, check=True, env={ "DOCKER_BUILDKIT": "1" }) if push: run("docker push faabric/{}:{}".format(container, this_version), shell=True, check=True)
def style(context, check=False): """ Format code """ for result in [ isort(context, check), black(context, check), ]: if result.failed: raise Failure(result)
def config_from_dir(c, name, directory=None, secret=False): config = "secret" if secret else "configmap" if "/" in name and os.path.isdir(name) and not directory: # name parameter is the directory, find the name of the configmap/secret name = _normalize(name) names = kubectl(c, f"get {config} -o=name", hide=True).stdout.splitlines() for n in names: n = n.split("/")[1] # removes resource prefix if name == get_annotation(c, config, n, "config-from-dir"): directory, name = name, n break if not directory: raise Failure(f"No existing {config} found with config-from-dir={name}") if directory is None: directory = get_annotation(c, config, name, "config-from-dir") if not directory: raise Failure(f"Missing directory parameter and annotation not found") directory = _normalize(directory) template_file = tempfile.NamedTemporaryFile(suffix=".yaml", mode="wt") template_file.write(YTT_CREATE_SECRET if secret else YTT_CREATE_CONFIGMAP) template_file.flush() values = {"name": name, "annotations": {"config-from-dir": directory}, "files": {}} for filename in os.listdir(directory): file_str = open(os.path.join(directory, filename), "rb" if secret else "rt").read() if secret: values["files"][filename] = base64.b64encode(file_str) else: values["files"][filename] = file_str return run_ytt(c, template_file.name, values, apply=True)
def build_docs(ctx): '''Build Documentation...''' docs = join(dirname(__file__), 'docs') print('Removing old docs...') if isdir(join(docs, 'html')): shutil.rmtree(join(docs, 'html')) if isdir(join(docs, 'doctrees')): shutil.rmtree(join(docs, 'doctrees')) print('Building new docs...') with ctx.cd(docs): result = ctx.run('make html') if 'Traceback' in result.stdout + result.stderr: raise Failure(result, 'Failed to build docs...')
def request_with_retries(method, url, data={}, step=10, attempts=10): timeout = 5 response = None current_attempts = 0 log_info("Sending request '{}' '{}'...".format(method, url)) log_debug("Payload data: {}".format(data)) while True: try: current_attempts += 1 if 'PUT' == method: response = requests.put(url, timeout=timeout, json=data) elif 'GET' == method: response = requests.get(url, timeout=timeout) elif 'POST' == method: response = requests.post(url, timeout=timeout, json=data) else: log_error( "Unsupported method \'{}\' specified!".format(method)) return False log_info("response code: HTTP {}".format(response.status_code)) log_debug("response: Headers:: {}".format(response.headers)) # we might get a 200, 201, etc if not str(response.status_code).startswith('2'): response.raise_for_status() else: return response except (ConnectionError, HTTPError) as e: if current_attempts >= attempts: msg = "Exceeded max attempts. Giving up!: {}".format(str(e)) log_debug(msg) raise Failure(msg) from e else: log_info( "Request did not succeeed. Sleeping and trying again... : {}" .format(str(e))) sleep(step) return response
def run_with_retries(cmd, echo=False, sleep=10, attempts=10): current_attempts = 0 result = None while current_attempts <= attempts: current_attempts += 1 try: result = run(cmd, echo=echo) break except Failure as e: if current_attempts < attempts: msg = "Attempt {}/{} of {} failed. Sleeping for {}...".format(current_attempts, attempts, cmd) log_info(msg) sleep(sleep) else: msg = "Exceeded max attempts {} for {}!".format(attempts, cmd) log_debug(msg) raise Failure(msg) from e return result
def _check_crossenv_on(): actual = os.environ.get("VIRTUAL_ENV") if actual != CROSSENV_DIR: print("Got VIRTUAL_ENV={} but expected {}".format( actual, CROSSENV_DIR)) raise Failure("Cross-env not activated")