Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions networks/6_node_bitcoin/defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
collectLogs: true
metricsExport: true

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi

image:
repository: bitcoindevproject/bitcoin
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "27.0"

config: |2+
regtest=1
checkmempool=0
acceptnonstdtxn=1
debuglogfile=0
logips=1
logtimemicros=1
capturemessages=1
fallbackfee=0.00001000
listen=1

[regtest]
rpcuser=user
rpcpassword=password
rpcport=18443
rpcallowip=0.0.0.0/0
rpcbind=0.0.0.0

zmqpubrawblock=tcp://0.0.0.0:28332
zmqpubrawtx=tcp://0.0.0.0:28333
10 changes: 10 additions & 0 deletions networks/6_node_bitcoin/network.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
nodes:
- name: tank-0001
config:
image:
tag: "26.0"
- name: tank-0002
- name: tank-0003
- name: tank-0004
- name: tank-0005
- name: tank-0006
44 changes: 2 additions & 42 deletions src/warnet/cli/k8s.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import os
import subprocess
from importlib.resources import files

from kubernetes import client, config
from kubernetes.dynamic import DynamicClient

from .process import run_command

WAR_MANIFESTS = files("manifests")


Expand Down Expand Up @@ -32,46 +32,6 @@ def get_mission(mission):
return crew


def run_command(command, stream_output=False, env=None):
# Merge the current environment with the provided env
full_env = os.environ.copy()
if env:
# Convert all env values to strings (only a safeguard)
env = {k: str(v) for k, v in env.items()}
full_env.update(env)

if stream_output:
process = subprocess.Popen(
["/bin/bash", "-c", command],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
universal_newlines=True,
env=full_env,
)

for line in iter(process.stdout.readline, ""):
print(line, end="")

process.stdout.close()
return_code = process.wait()

if return_code != 0:
print(f"Command failed with return code {return_code}")
return False
return True
else:
result = subprocess.run(
command, shell=True, capture_output=True, text=True, executable="/bin/bash"
)
if result.returncode != 0:
print(f"Error: {result.stderr}")
return False
print(result.stdout)
return True


def create_namespace() -> dict:
return {"apiVersion": "v1", "kind": "Namespace", "metadata": {"name": "warnet"}}

Expand Down
2 changes: 2 additions & 0 deletions src/warnet/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# from .ln import ln
from .network import network
from .network2 import network2
from .scenarios import scenarios

QUICK_START_PATH = files("scripts").joinpath("quick_start.sh")
Expand All @@ -26,6 +27,7 @@ def cli():
cli.add_command(image)
# cli.add_command(ln)
cli.add_command(network)
cli.add_command(network2)
cli.add_command(scenarios)


Expand Down
2 changes: 1 addition & 1 deletion src/warnet/cli/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
create_namespace,
delete_namespace,
deploy_base_configurations,
run_command,
set_kubectl_context,
)
from .process import run_command

DEFAULT_GRAPH_FILE = files("graphs").joinpath("default.graphml")
WAR_MANIFESTS = files("manifests")
Expand Down
63 changes: 63 additions & 0 deletions src/warnet/cli/network2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import os
import tempfile
from pathlib import Path

import click
import yaml

from .process import run_command

NETWORK_DIR = Path("networks")
DEFAULT_NETWORK = "6_node_bitcoin"
NETWORK_FILE = "network.yaml"
DEFAULTS_FILE = "defaults.yaml"
HELM_COMMAND = "helm upgrade --install --create-namespace"
BITCOIN_CHART_LOCATION = "./resources/charts/bitcoincore"
NAMESPACE = "warnet"


@click.group(name="network2")
def network2():
"""Network commands"""


@network2.command()
@click.argument("network_name", default=DEFAULT_NETWORK)
@click.option("--network", default="warnet", show_default=True)
@click.option("--logging/--no-logging", default=False)
def start2(network_name: str, logging: bool, network: str):
"""Start a warnet with topology loaded from <network_name> into [network]"""
full_path = os.path.join(NETWORK_DIR, network_name)
network_file_path = os.path.join(full_path, NETWORK_FILE)
defaults_file_path = os.path.join(full_path, DEFAULTS_FILE)

network_file = {}
with open(network_file_path) as f:
network_file = yaml.safe_load(f)

for node in network_file["nodes"]:
print(f"Starting node: {node.get('name')}")
try:
temp_override_file_path = ""
node_name = node.get("name")
node_config_override = node.get("config")

cmd = f"{HELM_COMMAND} {node_name} {BITCOIN_CHART_LOCATION} --namespace {NAMESPACE} -f {defaults_file_path}"

if node_config_override:
with tempfile.NamedTemporaryFile(
mode="w", suffix=".yaml", delete=False
) as temp_file:
yaml.dump(node_config_override, temp_file)
temp_override_file_path = temp_file.name
cmd = f"{cmd} -f {temp_override_file_path}"

if not run_command(cmd, stream_output=True):
print(f"Failed to run Helm command: {cmd}")
return
except Exception as e:
print(f"Error: {e}")
return
finally:
if temp_override_file_path:
Path(temp_override_file_path).unlink()
42 changes: 42 additions & 0 deletions src/warnet/cli/process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os
import subprocess


def run_command(command, stream_output=False, env=None):
# Merge the current environment with the provided env
full_env = os.environ.copy()
if env:
# Convert all env values to strings (only a safeguard)
env = {k: str(v) for k, v in env.items()}
full_env.update(env)

if stream_output:
process = subprocess.Popen(
["/bin/bash", "-c", command],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
universal_newlines=True,
env=full_env,
)

for line in iter(process.stdout.readline, ""):
print(line, end="")

process.stdout.close()
return_code = process.wait()

if return_code != 0:
print(f"Command failed with return code {return_code}")
return False
return True
else:
result = subprocess.run(
command, shell=True, capture_output=True, text=True, executable="/bin/bash"
)
if result.returncode != 0:
print(f"Error: {result.stderr}")
return False
print(result.stdout)
return True