From c9e2b627ed478f0f6a0405e77aec7fd7255b0778 Mon Sep 17 00:00:00 2001 From: Johannes Dillmann Date: Fri, 6 Mar 2026 13:54:31 +0100 Subject: [PATCH 1/4] Add helper for local dev workflow --- scripts/dev.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 scripts/dev.py diff --git a/scripts/dev.py b/scripts/dev.py new file mode 100644 index 00000000..a795ade5 --- /dev/null +++ b/scripts/dev.py @@ -0,0 +1,75 @@ +import subprocess +import json +import sys +import questionary + +from ruamel.yaml import YAML + +from pathlib import Path + + +def get_bake_config() -> dict: + result = subprocess.run(["docker", "buildx", "bake", "--print"], capture_output=True, text=True, check=True) + return json.loads(result.stdout) + + +def find_matches(values: dict, image_name: str) -> list: + image_key_paths = [] + for component, component_values in values.items(): + if isinstance(component_values, dict): + repo = component_values.get("image", {}).get("repository", "") + if repo.endswith(image_name): + image_key_paths.append(component) + return image_key_paths + + +def check_cluster(): + temp_path = Path("temp") + if not temp_path.exists(): + print("Before running this script, please run `make up` to create the cluster.") + sys.exit(1) + + +if __name__ == "__main__": + check_cluster() + + bake_config = get_bake_config() + targets = bake_config.get("group", {}).get("all", {}).get("targets", []) + + targets.remove("cflinuxfs4") + targets.remove("fileserver") + + release = questionary.select("Which release are you working on?", choices=targets).ask() + project = questionary.select("Which project are you working on?", choices=bake_config.get("group", {}).get(release, {}).get("targets", [])).ask() + + tags = bake_config.get("target", {}).get(project, {}).get("tags", []) + latest_tag = tags[0] if tags[0].endswith(":latest") else tags[1] + image_name = latest_tag.split(":")[0] + + yaml = YAML() + yaml.preserve_quotes = True + yaml.representer.add_representer(type(None), lambda dumper, _: dumper.represent_scalar("tag:yaml.org,2002:null", "~")) + + values_path = Path(f"releases/{release}/helm/values.yaml") + + with open(values_path, "r") as f: + values = yaml.load(f) + + for match in find_matches(values, image_name): + keys = match.split(".") + target = values + for key in keys: + target = target[key] + + target["image"]["repository"] = image_name + target["image"]["tag"] = "latest" + + with open(values_path, "w") as f: + yaml.dump(values, f) + + print("Here are some instructions to build a local image and load it into the cluster. Make sure to replace with the actual path to the release you are working on.") + print("Docker will ask for confirmation to access the local file system, please allow it to do so.") + print() + print(f"docker buildx bake {project} --set {project}.contexts.src=/src") + print(f"kind load docker-image {latest_tag} --name cfk8s") + print("make up") From d1df998d71828e360cfd644987ff0d5d35ea40cf Mon Sep 17 00:00:00 2001 From: Johannes Dillmann Date: Tue, 10 Mar 2026 09:36:27 +0100 Subject: [PATCH 2/4] wip --- scripts/dev.py | 54 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/scripts/dev.py b/scripts/dev.py index a795ade5..cf1af863 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -30,22 +30,24 @@ def check_cluster(): sys.exit(1) -if __name__ == "__main__": - check_cluster() - - bake_config = get_bake_config() - targets = bake_config.get("group", {}).get("all", {}).get("targets", []) - - targets.remove("cflinuxfs4") - targets.remove("fileserver") +def get_image_name(project): + tags = bake_config.get("target", {}).get(project, {}).get("tags", []) + latest_tag = tags[0] if tags[0].endswith(":latest") else tags[1] + return latest_tag.split(":")[0] - release = questionary.select("Which release are you working on?", choices=targets).ask() - project = questionary.select("Which project are you working on?", choices=bake_config.get("group", {}).get(release, {}).get("targets", [])).ask() +def build_instructions(project): tags = bake_config.get("target", {}).get(project, {}).get("tags", []) latest_tag = tags[0] if tags[0].endswith(":latest") else tags[1] - image_name = latest_tag.split(":")[0] + # image_name = latest_tag.split(":")[0] + update_values(project) + + print(f"docker buildx bake {project} --set {project}.contexts.src=/src") + print(f"kind load docker-image {latest_tag} --name cfk8s") + + +def update_values(project): yaml = YAML() yaml.preserve_quotes = True yaml.representer.add_representer(type(None), lambda dumper, _: dumper.represent_scalar("tag:yaml.org,2002:null", "~")) @@ -55,6 +57,7 @@ def check_cluster(): with open(values_path, "r") as f: values = yaml.load(f) + image_name = get_image_name(project) for match in find_matches(values, image_name): keys = match.split(".") target = values @@ -67,9 +70,34 @@ def check_cluster(): with open(values_path, "w") as f: yaml.dump(values, f) + +if __name__ == "__main__": + check_cluster() + + bake_config = get_bake_config() + all_releases = bake_config.get("group", {}).get("all", {}).get("targets", []) + + all_releases.remove("cflinuxfs4") + all_releases.remove("fileserver") + + + release = questionary.select("Which release are you working on?", choices=all_releases).ask() + + if release == "bosh-dns": + pass + + all_projects = bake_config.get("group", {}).get(release, {}).get("targets", []) + + # single project releases are not included in the release group + if not all_projects: + all_projects.append(release) + + default_choices = [questionary.Choice(title=project, checked=True) for project in all_projects] + projects = questionary.checkbox("Which project(s) are you working on?", choices=default_choices).ask() + print("Here are some instructions to build a local image and load it into the cluster. Make sure to replace with the actual path to the release you are working on.") print("Docker will ask for confirmation to access the local file system, please allow it to do so.") print() - print(f"docker buildx bake {project} --set {project}.contexts.src=/src") - print(f"kind load docker-image {latest_tag} --name cfk8s") + for project in projects: + build_instructions(project) print("make up") From ec9effb3397a4ccacc1e19110d7d02b1a4956386 Mon Sep 17 00:00:00 2001 From: Johannes Dillmann Date: Wed, 11 Mar 2026 09:52:58 +0100 Subject: [PATCH 3/4] exclude bosh-dns --- scripts/dev.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/dev.py b/scripts/dev.py index cf1af863..0e1eac4c 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -79,13 +79,11 @@ def update_values(project): all_releases.remove("cflinuxfs4") all_releases.remove("fileserver") + all_releases.remove("bosh-dns") release = questionary.select("Which release are you working on?", choices=all_releases).ask() - if release == "bosh-dns": - pass - all_projects = bake_config.get("group", {}).get(release, {}).get("targets", []) # single project releases are not included in the release group From 223c2a553663e60a513db7db38954b9103337985 Mon Sep 17 00:00:00 2001 From: Johannes Dillmann Date: Wed, 11 Mar 2026 10:12:35 +0100 Subject: [PATCH 4/4] wip --- scripts/dev.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/scripts/dev.py b/scripts/dev.py index 0e1eac4c..9b5b93e4 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -30,24 +30,20 @@ def check_cluster(): sys.exit(1) -def get_image_name(project): - tags = bake_config.get("target", {}).get(project, {}).get("tags", []) - latest_tag = tags[0] if tags[0].endswith(":latest") else tags[1] - return latest_tag.split(":")[0] - - def build_instructions(project): tags = bake_config.get("target", {}).get(project, {}).get("tags", []) - latest_tag = tags[0] if tags[0].endswith(":latest") else tags[1] - # image_name = latest_tag.split(":")[0] + latest_tag = next((tag for tag in tags if tag.endswith(":latest")), None) + if not latest_tag and len(tags) < 2: + raise ValueError(f"No tag ending with ':latest' found for project {project}") + image_name = latest_tag.split(":")[0] - update_values(project) + update_values(image_name) print(f"docker buildx bake {project} --set {project}.contexts.src=/src") print(f"kind load docker-image {latest_tag} --name cfk8s") -def update_values(project): +def update_values(image_name): yaml = YAML() yaml.preserve_quotes = True yaml.representer.add_representer(type(None), lambda dumper, _: dumper.represent_scalar("tag:yaml.org,2002:null", "~")) @@ -57,7 +53,6 @@ def update_values(project): with open(values_path, "r") as f: values = yaml.load(f) - image_name = get_image_name(project) for match in find_matches(values, image_name): keys = match.split(".") target = values @@ -81,12 +76,11 @@ def update_values(project): all_releases.remove("fileserver") all_releases.remove("bosh-dns") - release = questionary.select("Which release are you working on?", choices=all_releases).ask() all_projects = bake_config.get("group", {}).get(release, {}).get("targets", []) - # single project releases are not included in the release group + # single project releases are not included in the targets group if not all_projects: all_projects.append(release)