Commit 386bfcf1 authored by Moritz's avatar Moritz
Browse files

Push everything before creating a fork.

parent ec0dc038
No related merge requests found
Pipeline #11588 pending with stage
Showing with 51 additions and 84 deletions
+51 -84
......@@ -21,3 +21,4 @@ run-remote
.jupyter
.coverage
public
playground
......@@ -9,17 +9,17 @@ dependencies = [
"aio-net-events",
"anyio",
"click",
"click-aliases",
"click-help-colors",
"colorlog",
"platformdirs",
"prettytable",
"psutil",
"python-daemon>=3.0.1",
"pyroute2>=0.7.12",
"python-daemon",
"pyroute2",
"setproctitle",
"toml",
"websockets<=13.1",
"click-aliases>=1.0.5",
"websockets",
]
readme = "README.md"
requires-python = ">= 3.7"
......
......@@ -94,7 +94,6 @@ def main(ctx, config_files, host, port, debug):
conf["port"] = port
@main.command(help="Start the control-node.")
@click.option("--daemon", "-d", "run_as_daemon", is_flag=True, help="Run server in the background.")
@click.pass_context
......@@ -173,9 +172,10 @@ def show():
host, port = conf['host'], conf['port']
if not labc.control.is_running(host, port):
print(f"No control-node running on {host}:{port}")
raise click.Abort
@show.command(aliases=["ls"])
@show.command(aliases=["ls"], help="Print linkstate as json.")
def linkstate():
conf = get_config().control
packet = {
......@@ -184,11 +184,19 @@ def linkstate():
}
reply = labc.client.sendrecv(conf['host'], conf['port'], packet)
linkstate = reply['result']
linkstate.sort()
# sort output so it is displayed equally across instances
for _, _, control_links, client_links in linkstate:
control_links.sort()
client_links.sort()
print(json.dumps(linkstate, indent=4))
@show.command()
def graph():
@show.command(help="Return dot-code of the connection graph.")
@click.option("--local", "-l", 'local_', is_flag=True, help="Do not make routed calls, for this request.")
def graph(local_):
conf = get_config().control
packet = {
"type": "control-request",
......@@ -226,63 +234,6 @@ def connections():
print("\n".join(lines))
#@main.command(help="Show status of the labc network.")
#@click.argument("what")
#@click.option("--local", "-l", 'local_', is_flag=True, help="Do not make routed calls, for this request.")
#@click.pass_context
def show_(ctx, what, local_):
conf = get_config().control
what = what.lower()
host, port = conf['host'], conf['port']
if not labc.control.is_running(host, port):
print(f"No control-node running on {host}:{port}")
elif what == "linkstate":
packet = {
"type": "control-request",
"name": "get-link-state",
}
reply = labc.client.sendrecv(host, port, packet)
linkstate = reply['result']
print(json.dumps(linkstate, indent=4))
elif what == "graph":
packet = {
"type": "control-request",
"name": "get-link-state",
}
reply = labc.client.sendrecv(host, port, packet)
linkstate = reply['result']
if not local_:
regs = labc.api.get_registrations()
subs = labc.api.get_subscriptions()
control_info = labc.api.get_control_info()
else:
regs, subs, control_info = [], [], []
dot_code = labc.router.LinkState.to_dot(linkstate, control_info, regs, subs)
print(dot_code)
elif what in ['conn', 'connections']:
packet = {
'type': 'control-request',
'name': 'get-connections',
}
reply = labc.client.sendrecv(host, port, packet)
result = reply['result']
lines = []
for cid, conns in result.items():
lines.append(cid)
for loc, rem in conns:
lines.append(f"\t{loc} -> {rem}")
print("\n".join(lines))
@show.command(aliases=['subs'])
def subscriptions():
......
[control]
node-id = ""
node-alias = ""
host = "0.0.0.0"
port = 55555
......@@ -12,7 +12,7 @@ hops = 32
# subnetwork discovery methods
scan_network_interfaces = true
use_broadcast = true
scan_tailscale = true
scan_tailscale = true
scan_hostsfile = false
scan_route = false
......@@ -25,4 +25,4 @@ scan_route = false
max_host_identifier_size = 8
# if no host-specific port is specified use these remote ports.
remote_ports = [55555, 55556, 55557, 55558]
remote_ports = [55555] #[55555, 55556, 55557, 55558]
......@@ -70,7 +70,8 @@ class ControlNode:
def __init__(self, **conf) -> None:
self.creation_time = get_utc_timestamp()
self.node_id = conf['node-id'] or str(uuid.uuid1())
self.node_id = str(uuid.uuid1())
self.node_alias = conf['node-alias']
self.host = conf['host']
self.port = conf['port']
self.task_group: TaskGroup
......@@ -141,7 +142,7 @@ class ControlNode:
asyncio.current_task().set_name("ControlNode.run")
log.debug(f"Control-node-id is {self.node_id}")
log.debug(f"Control-node-id is \"{self.node_id}\"")
async with anyio.create_task_group() as tg:
self.task_group = tg
......@@ -267,9 +268,9 @@ class ControlNode:
log.info(f"Conosumer stopped: from {conn.remote_address} on {conn.local_address}.")
async def connect(self, host: str, port: int) -> None:
""" Create a connection task to another control-node.
"""
Create a connection task to another control-node.
"""
addr_ = ipaddress.ip_address(host)
if int(addr_) == 0:
......@@ -315,7 +316,11 @@ class ControlNode:
log.debug(f"Linkstate exchange with: {remote_node_id}")
# update router with new node
self.router.update(self.node_id, self.conman.state_id, self.conman.control_connections, self.conman.client_connections)
self.router.update(
nid = self.node_id,
sid = self.conman.state_id,
links = self.conman.control_connections,
clients = self.conman.client_connections)
# receive global linkstate and update router
remote_link_state = ensure_decode(await conn.recv())
......@@ -783,12 +788,12 @@ class ControlNode:
'type': 'state-update',
'flood': bool(flood),
}
if updated_links is not None:
pkt['link-state'] = self.router.link_state.serializable(updated_links)
if updated_regs is not None:
pkt['reg-state'] = self.registrations.serializable(updated_regs)
if updated_subs is not None:
pkt['sub-state'] = self.subscriptions.serializable(updated_subs)
#if updated_links is not None:
pkt['link-state'] = self.router.link_state.serializable(updated_links)
#if updated_regs is not None:
pkt['reg-state'] = self.registrations.serializable(updated_regs)
#if updated_subs is not None:
pkt['sub-state'] = self.subscriptions.serializable(updated_subs)
return pkt
async def debugging_loop(self, conn):
......@@ -829,11 +834,21 @@ class ControlNode:
await conn.send(traceback.format_exc())
def set_shutdown_timer(self, delay):
def set_shutdown_timer(self, delay: float):
"""
If no clients are connected to the control node, it should shut down autonomously.
"""
async def _shutdown_timer():
self.shutdown_time_event.set()
self.shutdown_task = self.task_group.start_soon(
asyncio.sleep, delay,
_shutdown_timer,
name="Shutdown-Timer",
)
def cancel_shutdown_timer(self):
self.set_timer()
self.shutdown_task.cancel()
......@@ -133,7 +133,7 @@ class LinkState:
self._remove_unconnected_nodes()
def check_update(self, node: str, sid: int) -> bool:
"""Cheks if a state should be updated."""
"""Checks if a state should be updated."""
return (node not in self.control_node_links) or (self.state_ids[node] < sid)
def bulk_update(self, linkstate: SerLinkState) -> Tuple[str, ...]:
......
[tox]
envlist = py37, py38, py39, py310, py311, py312, pypy38, pypy39, pypy310
envlist = py37, py38, py39, py310, py311, py312, py313, pypy38, pypy39, pypy310, pypy311
skip_missing_interpreters = false
[uv-venv-runner]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment