Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Meier, Moritz
labc
Commits
386bfcf1
Commit
386bfcf1
authored
1 month ago
by
Moritz
Browse files
Options
Download
Email Patches
Plain Diff
Push everything before creating a fork.
parent
ec0dc038
main
No related merge requests found
Pipeline
#11588
pending with stage
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
.gitignore
+1
-0
.gitignore
pyproject.toml
+4
-4
pyproject.toml
src/labc/cli.py
+12
-61
src/labc/cli.py
src/labc/config/general.conf.toml
+3
-3
src/labc/config/general.conf.toml
src/labc/control.py
+29
-14
src/labc/control.py
src/labc/router.py
+1
-1
src/labc/router.py
tox.ini
+1
-1
tox.ini
with
51 additions
and
84 deletions
+51
-84
.gitignore
+
1
-
0
View file @
386bfcf1
...
...
@@ -21,3 +21,4 @@ run-remote
.jupyter
.coverage
public
playground
This diff is collapsed.
Click to expand it.
pyproject.toml
+
4
-
4
View file @
386bfcf1
...
...
@@ -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
"
...
...
This diff is collapsed.
Click to expand it.
src/labc/cli.py
+
12
-
61
View file @
386bfcf1
...
...
@@ -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
():
...
...
This diff is collapsed.
Click to expand it.
src/labc/config/general.conf.toml
+
3
-
3
View file @
386bfcf1
[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]
This diff is collapsed.
Click to expand it.
src/labc/control.py
+
29
-
14
View file @
386bfcf1
...
...
@@ -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
.
s
et_timer
()
self
.
s
hutdown_task
.
cancel
()
This diff is collapsed.
Click to expand it.
src/labc/router.py
+
1
-
1
View file @
386bfcf1
...
...
@@ -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."""
"""Che
c
ks 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
,
...]:
...
...
This diff is collapsed.
Click to expand it.
tox.ini
+
1
-
1
View file @
386bfcf1
[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]
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets