Skip to content

Commit 3748616

Browse files
committed
tighten up simln and plugin interaction
1 parent 624addc commit 3748616

File tree

4 files changed

+143
-65
lines changed

4 files changed

+143
-65
lines changed

resources/plugins/simln/charts/simln/templates/pod.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ metadata:
44
name: {{ include "mychart.fullname" . }}
55
labels:
66
app: {{ include "mychart.name" . }}
7-
mission: plugin
7+
mission: {{ .Values.name }}
88
spec:
99
initContainers:
1010
- name: "init-container"

resources/plugins/simln/simln.py

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from subprocess import run
66
from time import sleep
77

8-
from warnet.k8s import get_pods_with_label, wait_for_pod
8+
from warnet.k8s import download, get_pods_with_label, wait_for_pod
99
from warnet.plugin import _get_plugin_directory as get_plugin_directory
1010
from warnet.process import run_command
1111
from warnet.status import _get_tank_status as network_status
@@ -21,17 +21,8 @@
2121
lightning_selector = "mission=lightning"
2222

2323

24-
# @post_deploy
25-
def deploy_helm():
26-
print("SimLN Plugin ⚡")
27-
plugin_dir = get_plugin_directory()
28-
print(f"DIR: {plugin_dir}")
29-
command = f"helm upgrade --install simln {plugin_dir}/simln/charts/simln"
30-
helm_result = run_command(command)
31-
print(helm_result)
32-
33-
3424
def run_simln():
25+
"""Run a SimLN Plugin demo"""
3526
init_network()
3627
fund_wallets()
3728
wait_for_everyone_to_have_a_host()
@@ -41,43 +32,46 @@ def run_simln():
4132
log.info(warnet("bitcoin rpc tank-0000 -generate 7"))
4233
wait_for_gossip_sync(2)
4334
log.info("done waiting")
44-
pod_name = prepare_and_launch_activity()
35+
pod_name = _prepare_and_launch_activity()
4536
log.info(pod_name)
4637
wait_for_pod(pod_name, 60)
4738

4839

49-
def prepare_and_launch_activity() -> str:
50-
pods = get_pods_with_label(lightning_selector)
51-
pod_a = pods[1].metadata.name
52-
pod_b = pods[2].metadata.name
53-
log.info(f"pod_a: {pod_a}")
54-
log.info(f"pod_b: {pod_b}")
55-
sample_activity = [
56-
{"source": pod_a, "destination": pod_b, "interval_secs": 1, "amount_msat": 2000}
57-
]
40+
def _prepare_and_launch_activity() -> str:
41+
sample_activity = get_example_activity()
5842
log.info(f"Activity: {sample_activity}")
5943
pod_name = launch_activity(sample_activity)
6044
log.info("Sent command. Done.")
6145
return pod_name
6246

6347

48+
def get_example_activity() -> list[dict]:
49+
"""Get an activity representing node 2 sending msat to node 3"""
50+
pods = get_pods_with_label(lightning_selector)
51+
pod_a = pods[1].metadata.name
52+
pod_b = pods[2].metadata.name
53+
return [{"source": pod_a, "destination": pod_b, "interval_secs": 1, "amount_msat": 2000}]
54+
55+
6456
def launch_activity(activity: list[dict]) -> str:
57+
"""Launch a SimLN chart which includes the `activity`"""
6558
random_digits = "".join(random.choices("0123456789", k=10))
6659
plugin_dir = get_plugin_directory()
67-
generate_nodes_file(activity, plugin_dir / Path("simln/charts/simln/files/sim.json"))
60+
_generate_nodes_file(activity, plugin_dir / Path("simln/charts/simln/files/sim.json"))
6861
command = f"helm upgrade --install simln-{random_digits} {plugin_dir}/simln/charts/simln"
6962
log.info(f"generate activity: {command}")
7063
run_command(command)
7164
return f"simln-simln-{random_digits}"
7265

7366

7467
def init_network():
68+
"""Mine regtest coins and wait for ln nodes to come online."""
7569
log.info("Initializing network")
7670
wait_for_all_tanks_status(target="running")
7771

7872
warnet("bitcoin rpc tank-0000 createwallet miner")
7973
warnet("bitcoin rpc tank-0000 -generate 110")
80-
wait_for_predicate(lambda: int(warnet("bitcoin rpc tank-0000 getblockcount")) > 100)
74+
_wait_for_predicate(lambda: int(warnet("bitcoin rpc tank-0000 getblockcount")) > 100)
8175

8276
def wait_for_all_ln_rpc():
8377
lns = get_pods_with_label(lightning_selector)
@@ -90,10 +84,11 @@ def wait_for_all_ln_rpc():
9084
return False
9185
return True
9286

93-
wait_for_predicate(wait_for_all_ln_rpc)
87+
_wait_for_predicate(wait_for_all_ln_rpc)
9488

9589

9690
def fund_wallets():
91+
"""Fund each ln node with 10 regtest coins."""
9792
log.info("Funding wallets")
9893
outputs = ""
9994
lns = get_pods_with_label(lightning_selector)
@@ -108,6 +103,7 @@ def fund_wallets():
108103

109104

110105
def everyone_has_a_host() -> bool:
106+
"""Find out if each ln node has a host."""
111107
pods = get_pods_with_label(lightning_selector)
112108
host_havers = 0
113109
for pod in pods:
@@ -119,10 +115,10 @@ def everyone_has_a_host() -> bool:
119115

120116

121117
def wait_for_everyone_to_have_a_host():
122-
wait_for_predicate(everyone_has_a_host)
118+
_wait_for_predicate(everyone_has_a_host)
123119

124120

125-
def wait_for_predicate(predicate, timeout=5 * 60, interval=5):
121+
def _wait_for_predicate(predicate, timeout=5 * 60, interval=5):
126122
log.info(
127123
f"Waiting for predicate ({predicate.__name__}) with timeout {timeout}s and interval {interval}s"
128124
)
@@ -142,9 +138,7 @@ def wait_for_predicate(predicate, timeout=5 * 60, interval=5):
142138

143139

144140
def wait_for_all_tanks_status(target: str = "running", timeout: int = 20 * 60, interval: int = 5):
145-
"""Poll the warnet server for container status
146-
Block until all tanks are running
147-
"""
141+
"""Poll the warnet server for container status. Block until all tanks are running"""
148142

149143
def check_status():
150144
tanks = network_status()
@@ -159,10 +153,11 @@ def check_status():
159153
log.info(f"Waiting for all tanks to reach '{target}': {stats}")
160154
return target in stats and stats[target] == stats["total"]
161155

162-
wait_for_predicate(check_status, timeout, interval)
156+
_wait_for_predicate(check_status, timeout, interval)
163157

164158

165-
def wait_for_gossip_sync(expected: int):
159+
def wait_for_gossip_sync(expected: int = 2):
160+
"""Wait for any of the ln nodes to have an `expected` number of edges."""
166161
log.info(f"Waiting for sync (expecting {expected})...")
167162
current = 0
168163
while current < expected:
@@ -178,6 +173,7 @@ def wait_for_gossip_sync(expected: int):
178173

179174

180175
def warnet(cmd: str = "--help"):
176+
"""Pass a `cmd` to Warnet."""
181177
log.info(f"Executing warnet command: {cmd}")
182178
command = ["warnet"] + cmd.split()
183179
proc = run(command, capture_output=True)
@@ -186,7 +182,7 @@ def warnet(cmd: str = "--help"):
186182
return proc.stdout.decode()
187183

188184

189-
def generate_nodes_file(activity: dict, output_file: Path = Path("nodes.json")):
185+
def _generate_nodes_file(activity: list[dict], output_file: Path = Path("nodes.json")):
190186
nodes = []
191187

192188
for i in get_pods_with_label(lightning_selector):
@@ -206,8 +202,10 @@ def generate_nodes_file(activity: dict, output_file: Path = Path("nodes.json")):
206202

207203

208204
def manual_open_channels():
205+
"""Manually open channels between ln nodes 1, 2, and 3"""
206+
209207
def wait_for_two_txs():
210-
wait_for_predicate(
208+
_wait_for_predicate(
211209
lambda: json.loads(warnet("bitcoin rpc tank-0000 getmempoolinfo"))["size"] == 2
212210
)
213211

@@ -241,3 +239,13 @@ def wait_for_two_txs():
241239
wait_for_two_txs()
242240

243241
warnet("bitcoin rpc tank-0000 -generate 10")
242+
243+
244+
def list_simln_podnames() -> list[str]:
245+
"""Get a list of simln pod names"""
246+
return [pod.metadata.name for pod in get_pods_with_label("mission=simln")]
247+
248+
249+
def download_results(pod_name: str):
250+
"""Download SimLN results to the current directory"""
251+
download(pod_name, source_path=Path("/working/results"))

src/warnet/k8s.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -564,15 +564,22 @@ def write_kubeconfig(kube_config: dict, kubeconfig_path: str) -> None:
564564
raise K8sError(f"Error writing kubeconfig: {kubeconfig_path}") from e
565565

566566

567-
def download(pod_name: str, namespace: str, source_path: Path, destination_path: Path = Path(".")):
567+
def download(
568+
pod_name: str,
569+
source_path: Path,
570+
destination_path: Path = Path("."),
571+
namespace: Optional[str] = None,
572+
):
568573
"""Download the item from the `source_path` to the `destination_path`"""
569574

575+
namespace = get_default_namespace_or(namespace)
576+
570577
v1 = get_static_client()
571578

572579
target_folder = destination_path / source_path.stem
573580
os.makedirs(target_folder, exist_ok=True)
574581

575-
command = ["tar", "cf", "-", str(source_path)]
582+
command = ["tar", "cf", "-", "-C", str(source_path.parent), str(source_path.name)]
576583

577584
resp = stream(
578585
v1.connect_get_namespaced_pod_exec,
@@ -594,10 +601,9 @@ def download(pod_name: str, namespace: str, source_path: Path, destination_path:
594601
f.write(resp.read_stdout().encode("utf-8"))
595602
if resp.peek_stderr():
596603
print(resp.read_stderr())
597-
598604
resp.close()
599605

600606
with tarfile.open(tar_file, "r") as tar:
601-
tar.extractall(path=target_folder)
607+
tar.extractall(path=destination_path)
602608

603609
os.remove(tar_file)

0 commit comments

Comments
 (0)