Skip to content

Commit 258fb0a

Browse files
committed
auto port-forward and teardown
1 parent 1429a31 commit 258fb0a

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

src/warnet/control.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from rich.table import Table
1616

1717
from .constants import COMMANDER_CHART
18+
from .deploy import _port_stop_internal
1819
from .k8s import (
1920
get_default_namespace,
2021
get_mission,
@@ -162,6 +163,8 @@ def delete_pod(pod_name, namespace):
162163
for future in as_completed(futures):
163164
console.print(f"[yellow]{future.result()}[/yellow]")
164165

166+
# Shutdown any port forwarding
167+
_port_stop_internal()
165168
console.print("[bold yellow]Teardown process initiated for all components.[/bold yellow]")
166169
console.print("[bold yellow]Note: Some processes may continue in the background.[/bold yellow]")
167170
console.print("[bold green]Warnet teardown process completed.[/bold green]")

src/warnet/deploy.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import os
2+
import subprocess
3+
import sys
14
import tempfile
25
from pathlib import Path
36

@@ -16,7 +19,7 @@
1619
NAMESPACES_FILE,
1720
NETWORK_FILE,
1821
)
19-
from .k8s import get_default_namespace
22+
from .k8s import get_default_namespace, wait_for_caddy_ready
2023
from .process import stream_command
2124

2225

@@ -102,14 +105,18 @@ def deploy_caddy(directory: Path, debug: bool):
102105
return
103106

104107
namespace = get_default_namespace()
105-
cmd = f"{HELM_COMMAND} 'caddy' {CADDY_CHART} --namespace {namespace}"
108+
name = "caddy"
109+
cmd = f"{HELM_COMMAND} {name} {CADDY_CHART} --namespace {namespace}"
106110
if debug:
107111
cmd += " --debug"
108112

109113
if not stream_command(cmd):
110114
click.echo(f"Failed to run Helm command: {cmd}")
111115
return
112116

117+
wait_for_caddy_ready(name, namespace)
118+
_port_start_internal()
119+
113120

114121
def deploy_fork_observer(directory: Path, debug: bool):
115122
network_file_path = directory / NETWORK_FILE
@@ -242,3 +249,43 @@ def deploy_namespaces(directory: Path):
242249
finally:
243250
if temp_override_file_path.exists():
244251
temp_override_file_path.unlink()
252+
253+
254+
def is_windows():
255+
return sys.platform.startswith("win")
256+
257+
258+
def run_detached_process(command):
259+
if is_windows():
260+
# For Windows, use CREATE_NEW_PROCESS_GROUP and DETACHED_PROCESS
261+
subprocess.Popen(
262+
command,
263+
shell=True,
264+
stdin=None,
265+
stdout=None,
266+
stderr=None,
267+
close_fds=True,
268+
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS,
269+
)
270+
else:
271+
# For Unix-like systems, use nohup and redirect output
272+
command = f"nohup {command} > /dev/null 2>&1 &"
273+
subprocess.Popen(command, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)
274+
275+
print(f"Started detached process: {command}")
276+
277+
278+
def _port_start_internal():
279+
command = "kubectl port-forward service/caddy 2019:80"
280+
run_detached_process(command)
281+
click.echo(
282+
"Port forwarding on port 2019 started in the background. To access landing page visit localhost:2019."
283+
)
284+
285+
286+
def _port_stop_internal():
287+
if is_windows():
288+
os.system("taskkill /F /IM kubectl.exe")
289+
else:
290+
os.system("pkill -f 'kubectl port-forward service/caddy-service 2019:80'")
291+
click.echo("Port forwarding stopped.")

src/warnet/k8s.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pathlib import Path
55

66
import yaml
7-
from kubernetes import client, config
7+
from kubernetes import client, config, watch
88
from kubernetes.client.models import CoreV1Event, V1PodList
99
from kubernetes.dynamic import DynamicClient
1010
from kubernetes.stream import stream
@@ -227,3 +227,21 @@ def snapshot_bitcoin_datadir(
227227

228228
except Exception as e:
229229
print(f"An error occurred: {str(e)}")
230+
231+
232+
def wait_for_caddy_ready(name, namespace, timeout=300):
233+
sclient = get_static_client()
234+
w = watch.Watch()
235+
for event in w.stream(
236+
sclient.list_namespaced_pod, namespace=namespace, timeout_seconds=timeout
237+
):
238+
pod = event["object"]
239+
if pod.metadata.name == name and pod.status.phase == "Running":
240+
conditions = pod.status.conditions or []
241+
ready_condition = next((c for c in conditions if c.type == "Ready"), None)
242+
if ready_condition and ready_condition.status == "True":
243+
print(f"Caddy pod {name} is ready.")
244+
w.stop()
245+
return True
246+
print(f"Timeout waiting for Caddy pod {name} to be ready.")
247+
return False

0 commit comments

Comments
 (0)