From 8bdbf6aa8b3d1672dbe00bbe7202b9ac95c85ec6 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 1 Oct 2024 15:37:16 -0500 Subject: [PATCH 1/8] k8s: add `get_pod` --- src/warnet/k8s.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/warnet/k8s.py b/src/warnet/k8s.py index 9c18d095d..589169e24 100644 --- a/src/warnet/k8s.py +++ b/src/warnet/k8s.py @@ -4,10 +4,11 @@ import tempfile from pathlib import Path from time import sleep +from typing import Optional import yaml from kubernetes import client, config, watch -from kubernetes.client.models import CoreV1Event, V1PodList +from kubernetes.client.models import CoreV1Event, V1Pod, V1PodList from kubernetes.client.rest import ApiException from kubernetes.dynamic import DynamicClient from kubernetes.stream import stream @@ -41,6 +42,13 @@ def get_pods() -> V1PodList: return pod_list +def get_pod(name: str, namespace: Optional[str] = None) -> V1Pod: + sclient = get_static_client() + if not namespace: + namespace = get_default_namespace() + return sclient.read_namespaced_pod(name=name, namespace=namespace) + + def get_mission(mission: str) -> list[V1PodList]: pods = get_pods() crew = [] From 23a8e2179faf5cf47acca46ab58fa4ee37acb704 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 1 Oct 2024 15:37:35 -0500 Subject: [PATCH 2/8] control: fix `_logs` to look for primary container Use the logic that the first container listed will be the primary container. --- src/warnet/control.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/warnet/control.py b/src/warnet/control.py index cea7bc9a0..1238ac7f2 100644 --- a/src/warnet/control.py +++ b/src/warnet/control.py @@ -21,6 +21,7 @@ delete_pod, get_default_namespace, get_mission, + get_pod, get_pods, pod_log, snapshot_bitcoin_datadir, @@ -329,7 +330,15 @@ def _logs(pod_name: str, follow: bool): return # cancelled by user try: - stream = pod_log(pod_name, container_name=None, follow=follow) + pod = get_pod(pod_name) + container_names = [container.name for container in pod.spec.containers] + container_name = container_names[0] + except Exception as e: + print(f"Could not determine primary container: {e}") + return + + try: + stream = pod_log(pod_name, container_name=container_name, follow=follow) for line in stream.stream(): print(line.decode("utf-8"), end=None) except Exception as e: From 3298bc7d1016f0f8a74ea8207c0662341bb49e64 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 1 Oct 2024 16:09:55 -0500 Subject: [PATCH 3/8] control: fix stream handling --- src/warnet/control.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/warnet/control.py b/src/warnet/control.py index 1238ac7f2..6a3419312 100644 --- a/src/warnet/control.py +++ b/src/warnet/control.py @@ -339,8 +339,8 @@ def _logs(pod_name: str, follow: bool): try: stream = pod_log(pod_name, container_name=container_name, follow=follow) - for line in stream.stream(): - print(line.decode("utf-8"), end=None) + for line in stream: + click.echo(line.decode("utf-8").rstrip()) except Exception as e: print(e) except KeyboardInterrupt: From 04352d4741311c7b26af38b430d67b5a70873d85 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 1 Oct 2024 16:57:49 -0500 Subject: [PATCH 4/8] bitcoin: add primary container logic to `rpc` --- src/warnet/bitcoin.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/warnet/bitcoin.py b/src/warnet/bitcoin.py index a27da3bc7..f22b2d4ff 100644 --- a/src/warnet/bitcoin.py +++ b/src/warnet/bitcoin.py @@ -10,7 +10,7 @@ from test_framework.messages import ser_uint256 from test_framework.p2p import MESSAGEMAP -from .k8s import get_default_namespace, get_mission +from .k8s import get_default_namespace, get_mission, get_pod from .process import run_command @@ -39,10 +39,19 @@ def _rpc(tank: str, method: str, params: str): # bitcoin-cli should be able to read bitcoin.conf inside the container # so no extra args like port, chain, username or password are needed namespace = get_default_namespace() + + try: + pod = get_pod(tank) + container_names = [container.name for container in pod.spec.containers] + container_name = container_names[0] + except Exception as e: + print(f"Could not determine primary container: {e}") + return + if params: - cmd = f"kubectl -n {namespace} exec {tank} -- bitcoin-cli {method} {' '.join(map(str, params))}" + cmd = f"kubectl -n {namespace} exec {tank} --container {container_name} -- bitcoin-cli {method} {' '.join(map(str, params))}" else: - cmd = f"kubectl -n {namespace} exec {tank} -- bitcoin-cli {method}" + cmd = f"kubectl -n {namespace} exec {tank} --container {container_name} -- bitcoin-cli {method}" return run_command(cmd) From 0ab373f815ae22738a25d2f47e6b82ebcff034a2 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 1 Oct 2024 15:49:23 -0500 Subject: [PATCH 5/8] make ruff happy --- src/warnet/bitcoin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/warnet/bitcoin.py b/src/warnet/bitcoin.py index f22b2d4ff..bb968ed8f 100644 --- a/src/warnet/bitcoin.py +++ b/src/warnet/bitcoin.py @@ -5,10 +5,9 @@ from io import BytesIO import click -from urllib3.exceptions import MaxRetryError - from test_framework.messages import ser_uint256 from test_framework.p2p import MESSAGEMAP +from urllib3.exceptions import MaxRetryError from .k8s import get_default_namespace, get_mission, get_pod from .process import run_command From 43e32405a7a882eb7bfbcff7acab479954a7880f Mon Sep 17 00:00:00 2001 From: Grant Date: Wed, 2 Oct 2024 11:00:24 -0500 Subject: [PATCH 6/8] add constants as they appear in the helm charts --- src/warnet/constants.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/warnet/constants.py b/src/warnet/constants.py index 99bdf2c5c..3bf666007 100644 --- a/src/warnet/constants.py +++ b/src/warnet/constants.py @@ -16,6 +16,9 @@ INGRESS_NAMESPACE = "ingress" HELM_COMMAND = "helm upgrade --install --create-namespace" +BITCOINCORE_CONTAINER = "bitcoincore" +COMMANDER_CONTAINER = "commander" + # Directories and files for non-python assets, e.g., helm charts, example scenarios, default configs SRC_DIR = files("warnet") RESOURCES_DIR = files("resources") From 8301302c1e7e3ca2d1ee653198d10711b270919e Mon Sep 17 00:00:00 2001 From: Grant Date: Wed, 2 Oct 2024 11:01:05 -0500 Subject: [PATCH 7/8] use constants in the `log` function --- src/warnet/control.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/warnet/control.py b/src/warnet/control.py index 6a3419312..6db4aec1a 100644 --- a/src/warnet/control.py +++ b/src/warnet/control.py @@ -16,7 +16,12 @@ from rich.prompt import Confirm, Prompt from rich.table import Table -from .constants import COMMANDER_CHART, LOGGING_NAMESPACE +from .constants import ( + BITCOINCORE_CONTAINER, + COMMANDER_CHART, + COMMANDER_CONTAINER, + LOGGING_NAMESPACE, +) from .k8s import ( delete_pod, get_default_namespace, @@ -331,10 +336,21 @@ def _logs(pod_name: str, follow: bool): try: pod = get_pod(pod_name) - container_names = [container.name for container in pod.spec.containers] - container_name = container_names[0] + eligible_container_names = [BITCOINCORE_CONTAINER, COMMANDER_CONTAINER] + available_container_names = [container.name for container in pod.spec.containers] + container_name = next( + ( + container_name + for container_name in available_container_names + if container_name in eligible_container_names + ), + None, + ) + if not container_name: + print("Could not determine primary container.") + return except Exception as e: - print(f"Could not determine primary container: {e}") + print(f"Error getting pods. Could not determine primary container: {e}") return try: From 9a7a97383df4237726eb779a007150eafe5a2aca Mon Sep 17 00:00:00 2001 From: Grant Date: Wed, 2 Oct 2024 11:01:29 -0500 Subject: [PATCH 8/8] use constant in the bitcoin `rpc` function --- src/warnet/bitcoin.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/warnet/bitcoin.py b/src/warnet/bitcoin.py index bb968ed8f..8ac3863f6 100644 --- a/src/warnet/bitcoin.py +++ b/src/warnet/bitcoin.py @@ -9,7 +9,8 @@ from test_framework.p2p import MESSAGEMAP from urllib3.exceptions import MaxRetryError -from .k8s import get_default_namespace, get_mission, get_pod +from .constants import BITCOINCORE_CONTAINER +from .k8s import get_default_namespace, get_mission from .process import run_command @@ -39,18 +40,10 @@ def _rpc(tank: str, method: str, params: str): # so no extra args like port, chain, username or password are needed namespace = get_default_namespace() - try: - pod = get_pod(tank) - container_names = [container.name for container in pod.spec.containers] - container_name = container_names[0] - except Exception as e: - print(f"Could not determine primary container: {e}") - return - if params: - cmd = f"kubectl -n {namespace} exec {tank} --container {container_name} -- bitcoin-cli {method} {' '.join(map(str, params))}" + cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method} {' '.join(map(str, params))}" else: - cmd = f"kubectl -n {namespace} exec {tank} --container {container_name} -- bitcoin-cli {method}" + cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method}" return run_command(cmd)