Skip to content

Commit b0c3a86

Browse files
committed
hooked up network start to helm
1 parent 0913c8d commit b0c3a86

File tree

7 files changed

+166
-48
lines changed

7 files changed

+166
-48
lines changed

networks/6_node_bitcoin/defaults.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
collectLogs: true
2+
metricsExport: true
3+
4+
resources: {}
5+
# We usually recommend not to specify default resources and to leave this as a conscious
6+
# choice for the user. This also increases chances charts run on environments with little
7+
# resources, such as Minikube. If you do want to specify resources, uncomment the following
8+
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
9+
# limits:
10+
# cpu: 100m
11+
# memory: 128Mi
12+
# requests:
13+
# cpu: 100m
14+
# memory: 128Mi
15+
16+
image:
17+
repository: bitcoindevproject/bitcoin
18+
pullPolicy: IfNotPresent
19+
# Overrides the image tag whose default is the chart appVersion.
20+
tag: "27.0"
21+
22+
config: |2+
23+
regtest=1
24+
checkmempool=0
25+
acceptnonstdtxn=1
26+
debuglogfile=0
27+
logips=1
28+
logtimemicros=1
29+
capturemessages=1
30+
fallbackfee=0.00001000
31+
listen=1
32+
33+
[regtest]
34+
rpcuser=user
35+
rpcpassword=password
36+
rpcport=18443
37+
rpcallowip=0.0.0.0/0
38+
rpcbind=0.0.0.0
39+
40+
zmqpubrawblock=tcp://0.0.0.0:28332
41+
zmqpubrawtx=tcp://0.0.0.0:28333

networks/6_node_bitcoin/network.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
nodes:
2+
- name: tank-0001
3+
config:
4+
image:
5+
tag: "26.0"
6+
- name: tank-0002
7+
- name: tank-0003
8+
- name: tank-0004
9+
- name: tank-0005
10+
- name: tank-0006

src/warnet/cli/k8s.py

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import os
2-
import subprocess
3-
from importlib.resources import files
41
import json
2+
from importlib.resources import files
53
from typing import Any, Dict
64

75
from kubernetes import client, config
86
from kubernetes.dynamic import DynamicClient
97

8+
from .process import stream_command
9+
1010
WAR_MANIFESTS = files("manifests")
1111

1212

@@ -40,37 +40,6 @@ def get_edges():
4040
return json.loads(configmap.data["data"])
4141

4242

43-
def run_command(command) -> str:
44-
result = subprocess.run(
45-
command, shell=True, capture_output=True, text=True, executable="/bin/bash"
46-
)
47-
if result.returncode != 0:
48-
raise Exception(result.stderr)
49-
return result.stdout
50-
51-
52-
def stream_command(command, env=None) -> bool:
53-
process = subprocess.Popen(
54-
["/bin/bash", "-c", command],
55-
stdout=subprocess.PIPE,
56-
stderr=subprocess.STDOUT,
57-
text=True,
58-
bufsize=1,
59-
universal_newlines=True,
60-
)
61-
62-
for line in iter(process.stdout.readline, ""):
63-
print(line, end="")
64-
65-
process.stdout.close()
66-
return_code = process.wait()
67-
68-
if return_code != 0:
69-
print(f"Command failed with return code {return_code}")
70-
return False
71-
return True
72-
73-
7443
def create_kubernetes_object(
7544
kind: str, metadata: Dict[str, Any], spec: Dict[str, Any] = None
7645
) -> Dict[str, Any]:

src/warnet/cli/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
# from .ln import ln
1313
from .network import network
14+
from .network2 import network2
1415
from .scenarios import scenarios
1516

1617
QUICK_START_PATH = files("scripts").joinpath("quick_start.sh")
@@ -26,6 +27,7 @@ def cli():
2627
cli.add_command(image)
2728
# cli.add_command(ln)
2829
cli.add_command(network)
30+
cli.add_command(network2)
2931
cli.add_command(scenarios)
3032

3133

src/warnet/cli/network.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@
88
import networkx as nx
99
import yaml
1010
from rich import print
11+
1112
from .bitcoin import _rpc
1213
from .k8s import (
1314
apply_kubernetes_yaml,
15+
create_kubernetes_object,
1416
create_namespace,
1517
delete_namespace,
1618
deploy_base_configurations,
17-
run_command,
18-
stream_command,
19-
set_kubectl_context,
20-
create_kubernetes_object,
2119
get_edges,
22-
get_mission
20+
get_mission,
21+
set_kubectl_context,
2322
)
2423

24+
from .process import stream_command
25+
2526
DEFAULT_GRAPH_FILE = files("graphs").joinpath("default.graphml")
2627
WAR_MANIFESTS = files("manifests")
2728

@@ -77,9 +78,7 @@ def create_node_deployment(node: int, data: dict) -> Dict[str, Any]:
7778
"name": f"warnet-tank-{node}",
7879
"namespace": "warnet",
7980
"labels": {"app": "warnet", "mission": "tank", "index": str(node)},
80-
"annotations": {
81-
"data": json.dumps(data)
82-
}
81+
"annotations": {"data": json.dumps(data)},
8382
},
8483
spec={
8584
"containers": [
@@ -134,11 +133,7 @@ def create_config_map(node: int, config: str) -> Dict[str, Any]:
134133
def create_edges_map(graph):
135134
edges = []
136135
for src, dst, data in graph.edges(data=True):
137-
edges.append({
138-
"src": src,
139-
"dst": dst,
140-
"data": data
141-
})
136+
edges.append({"src": src, "dst": dst, "data": data})
142137
config_map = create_kubernetes_object(
143138
kind="ConfigMap",
144139
metadata={
@@ -234,6 +229,7 @@ def connected():
234229
"""Determine if all p2p conenctions defined in graph are established"""
235230
print(_connected())
236231

232+
237233
def _connected():
238234
tanks = get_mission("tank")
239235
edges = get_edges()
@@ -263,11 +259,15 @@ def status():
263259
# TODO: make it a pretty table
264260
print(_status())
265261

262+
266263
def _status():
267264
tanks = get_mission("tank")
268265
stats = []
269266
for tank in tanks:
270-
status = {"tank_index": tank.metadata.labels["index"], "bitcoin_status": tank.status.phase.lower()}
267+
status = {
268+
"tank_index": tank.metadata.labels["index"],
269+
"bitcoin_status": tank.status.phase.lower(),
270+
}
271271
stats.append(status)
272272
return stats
273273

src/warnet/cli/network2.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import os
2+
import tempfile
3+
from pathlib import Path
4+
5+
import click
6+
import yaml
7+
8+
from .process import run_command
9+
10+
NETWORK_DIR = Path("networks")
11+
DEFAULT_NETWORK = "6_node_bitcoin"
12+
NETWORK_FILE = "network.yaml"
13+
DEFAULTS_FILE = "defaults.yaml"
14+
HELM_COMMAND = "helm upgrade --install --create-namespace"
15+
BITCOIN_CHART_LOCATION = "./resources/charts/bitcoincore"
16+
NAMESPACE = "warnet"
17+
18+
19+
@click.group(name="network2")
20+
def network2():
21+
"""Network commands"""
22+
23+
24+
@network2.command()
25+
@click.argument("network_name", default=DEFAULT_NETWORK)
26+
@click.option("--network", default="warnet", show_default=True)
27+
@click.option("--logging/--no-logging", default=False)
28+
def start2(network_name: str, logging: bool, network: str):
29+
"""Start a warnet with topology loaded from <network_name> into [network]"""
30+
full_path = os.path.join(NETWORK_DIR, network_name)
31+
network_file_path = os.path.join(full_path, NETWORK_FILE)
32+
defaults_file_path = os.path.join(full_path, DEFAULTS_FILE)
33+
34+
network_file = {}
35+
with open(network_file_path) as f:
36+
network_file = yaml.safe_load(f)
37+
38+
for node in network_file["nodes"]:
39+
print(f"Starting node: {node.get('name')}")
40+
try:
41+
temp_override_file_path = ""
42+
node_name = node.get("name")
43+
node_config_override = node.get("config")
44+
45+
cmd = f"{HELM_COMMAND} {node_name} {BITCOIN_CHART_LOCATION} --namespace {NAMESPACE} -f {defaults_file_path}"
46+
47+
if node_config_override:
48+
with tempfile.NamedTemporaryFile(
49+
mode="w", suffix=".yaml", delete=False
50+
) as temp_file:
51+
yaml.dump(node_config_override, temp_file)
52+
temp_override_file_path = temp_file.name
53+
cmd = f"{cmd} -f {temp_override_file_path}"
54+
55+
if not run_command(cmd, stream_output=True):
56+
print(f"Failed to run Helm command: {cmd}")
57+
return
58+
except Exception as e:
59+
print(f"Error: {e}")
60+
return
61+
finally:
62+
if temp_override_file_path:
63+
Path(temp_override_file_path).unlink()

src/warnet/cli/process.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import subprocess
3+
4+
5+
def run_command(command) -> str:
6+
result = subprocess.run(
7+
command, shell=True, capture_output=True, text=True, executable="/bin/bash"
8+
)
9+
if result.returncode != 0:
10+
raise Exception(result.stderr)
11+
return result.stdout
12+
13+
14+
def stream_command(command, env=None) -> bool:
15+
process = subprocess.Popen(
16+
["/bin/bash", "-c", command],
17+
stdout=subprocess.PIPE,
18+
stderr=subprocess.STDOUT,
19+
text=True,
20+
bufsize=1,
21+
universal_newlines=True,
22+
)
23+
24+
for line in iter(process.stdout.readline, ""):
25+
print(line, end="")
26+
27+
process.stdout.close()
28+
return_code = process.wait()
29+
30+
if return_code != 0:
31+
print(f"Command failed with return code {return_code}")
32+
return False
33+
return True

0 commit comments

Comments
 (0)