Skip to content

Commit 632d00d

Browse files
committed
add logging to network.start
1 parent 017f9b6 commit 632d00d

File tree

3 files changed

+119
-8
lines changed

3 files changed

+119
-8
lines changed

src/warnet/cli/main.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from rich import print as richprint
77

88
from .bitcoin import bitcoin
9-
from .cluster import cluster
109
from .graph import graph
1110
from .image import image
1211
from .ln import ln
@@ -22,7 +21,6 @@ def cli():
2221

2322

2423
cli.add_command(bitcoin)
25-
cli.add_command(cluster)
2624
cli.add_command(graph)
2725
cli.add_command(image)
2826
cli.add_command(ln)

src/warnet/cli/network.py

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import json
21
import tempfile
2+
import xml.etree.ElementTree as ET
33
from importlib.resources import files
44
from pathlib import Path
55

@@ -34,9 +34,9 @@ def set_kubectl_context(namespace: str):
3434

3535
@network.command()
3636
@click.argument("graph_file", default=DEFAULT_GRAPH_FILE, type=click.Path())
37-
@click.option("--force", default=False, is_flag=True, type=bool)
3837
@click.option("--network", default="warnet", show_default=True)
39-
def start(graph_file: Path, force: bool, network: str):
38+
@click.option("--logging/--no-logging", default=False)
39+
def start(graph_file: Path, logging: bool, network: str):
4040
"""
4141
Start a warnet with topology loaded from a <graph_file> into [network]
4242
"""
@@ -76,6 +76,13 @@ def start(graph_file: Path, force: bool, network: str):
7676
print(
7777
"Warning: Failed to set kubectl context. You may need to manually switch to the warnet namespace."
7878
)
79+
80+
if logging:
81+
helm_result = setup_logging_helm()
82+
if helm_result:
83+
print("Helm charts installed successfully.")
84+
else:
85+
print("Failed to install Helm charts.")
7986
else:
8087
print(f"Failed to start warnet '{network}'.")
8188
finally:
@@ -92,6 +99,9 @@ def down(network: str):
9299
# Delete the namespace
93100
command = f"kubectl delete namespace {network}"
94101
result = run_command(command, stream_output=True)
102+
# TODO: Fix this
103+
command = "kubectl delete namespace warnet-logging"
104+
result = run_command(command, stream_output=True)
95105

96106
if result:
97107
print(f"Warnet '{network}' has been successfully brought down and the namespace deleted.")
@@ -145,6 +155,11 @@ def generate_kubernetes_yaml(graph: nx.Graph) -> list:
145155
kubernetes_objects.append(namespace)
146156

147157
for node, data in graph.nodes(data=True):
158+
# Create a ConfigMap for each node
159+
config = generate_node_config(node, data)
160+
config_map = create_config_map(node, config)
161+
kubernetes_objects.append(config_map)
162+
148163
# Create a deployment for each node
149164
deployment = create_node_deployment(node, data)
150165
kubernetes_objects.append(deployment)
@@ -163,7 +178,6 @@ def create_namespace() -> dict:
163178
def create_node_deployment(node: int, data: dict) -> dict:
164179
image = data.get("image", "bitcoindevproject/bitcoin:27.0")
165180
version = data.get("version", "27.0")
166-
bitcoin_config = data.get("bitcoin_config", "")
167181

168182
return {
169183
"apiVersion": "v1",
@@ -180,10 +194,17 @@ def create_node_deployment(node: int, data: dict) -> dict:
180194
"image": image,
181195
"env": [
182196
{"name": "BITCOIN_VERSION", "value": version},
183-
{"name": "BITCOIN_CONFIG", "value": bitcoin_config},
197+
],
198+
"volumeMounts": [
199+
{
200+
"name": "config",
201+
"mountPath": "/root/.bitcoin/bitcoin.conf",
202+
"subPath": "bitcoin.conf",
203+
}
184204
],
185205
}
186-
]
206+
],
207+
"volumes": [{"name": "config", "configMap": {"name": f"bitcoin-config-node-{node}"}}],
187208
},
188209
}
189210

@@ -198,3 +219,94 @@ def create_node_service(node: int) -> dict:
198219
"ports": [{"port": 8333, "targetPort": 8333}],
199220
},
200221
}
222+
223+
224+
def setup_logging_helm():
225+
"""
226+
Run the required Helm commands for setting up Grafana, Prometheus, and Loki.
227+
"""
228+
helm_commands = [
229+
"helm repo add grafana https://grafana.github.io/helm-charts",
230+
"helm repo add prometheus-community https://prometheus-community.github.io/helm-charts",
231+
"helm repo update",
232+
f"helm upgrade --install --namespace warnet-logging --create-namespace --values {WAR_MANIFESTS}/loki_values.yaml loki grafana/loki --version 5.47.2",
233+
"helm upgrade --install --namespace warnet-logging promtail grafana/promtail",
234+
"helm upgrade --install --namespace warnet-logging prometheus prometheus-community/kube-prometheus-stack --namespace warnet-logging --set grafana.enabled=false",
235+
f"helm upgrade --install --namespace warnet-logging loki-grafana grafana/grafana --values {WAR_MANIFESTS}/grafana_values.yaml",
236+
]
237+
238+
for command in helm_commands:
239+
result = run_command(command, stream_output=True)
240+
if not result:
241+
print(f"Failed to run Helm command: {command}")
242+
return False
243+
return True
244+
245+
246+
@network.command()
247+
@click.argument("graph_file", default=DEFAULT_GRAPH_FILE, type=click.Path(exists=True))
248+
def connect(graph_file: Path):
249+
"""
250+
Connect nodes based on the edges defined in the graph file.
251+
"""
252+
# Parse the GraphML file
253+
tree = ET.parse(graph_file)
254+
root = tree.getroot()
255+
256+
# Find all edge elements
257+
edges = root.findall(".//{http://graphml.graphdrawing.org/xmlns}edge")
258+
259+
for edge in edges:
260+
source = edge.get("source")
261+
target = edge.get("target")
262+
263+
# Construct the kubectl command
264+
command = f"kubectl exec -it warnet-node-{source} -- bitcoin-cli -rpcuser=user -rpcpassword=password addnode warnet-node-{target}-service:8333 add"
265+
266+
print(f"Connecting node {source} to node {target}")
267+
result = run_command(command, stream_output=True)
268+
269+
if result:
270+
print(f"Successfully connected node {source} to node {target}")
271+
else:
272+
print(f"Failed to connect node {source} to node {target}")
273+
274+
print("All connections attempted.")
275+
276+
277+
def generate_node_config(node: int, data: dict) -> str:
278+
base_config = """
279+
regtest=1
280+
checkmempool=0
281+
acceptnonstdtxn=1
282+
debuglogfile=0
283+
logips=1
284+
logtimemicros=1
285+
capturemessages=1
286+
fallbackfee=0.00001000
287+
listen=1
288+
289+
[regtest]
290+
rpcuser=user
291+
rpcpassword=password
292+
rpcport=18443
293+
rpcallowip=0.0.0.0/0
294+
rpcbind=0.0.0.0
295+
296+
zmqpubrawblock=tcp://0.0.0.0:28332
297+
zmqpubrawtx=tcp://0.0.0.0:28333
298+
"""
299+
node_specific_config = data.get("bitcoin_config", "")
300+
return f"{base_config}\n{node_specific_config}"
301+
302+
303+
def create_config_map(node: int, config: str) -> dict:
304+
return {
305+
"apiVersion": "v1",
306+
"kind": "ConfigMap",
307+
"metadata": {
308+
"name": f"bitcoin-config-node-{node}",
309+
"namespace": "warnet",
310+
},
311+
"data": {"bitcoin.conf": config},
312+
}

src/warnet/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ def create_cycle_graph(n: int, version: str, bitcoin_conf: str | None, random_ve
435435
graph.nodes[node]["build_args"] = ""
436436
graph.nodes[node]["exporter"] = False
437437
graph.nodes[node]["collect_logs"] = False
438+
graph.nodes[node]["resources"] = None
438439

439440
convert_unsupported_attributes(graph)
440441
return graph

0 commit comments

Comments
 (0)