remoteRF-server 0.1.72__tar.gz → 0.1.74__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/PKG-INFO +4 -2
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/README.md +3 -1
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/pyproject.toml +1 -1
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_tunnel_server.py +65 -4
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/grpc_server.py +188 -1
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/PKG-INFO +4 -2
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/setup.cfg +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/api_token.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_connection.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_location.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/list_string.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/process_arg.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/host/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_directory_store.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/acc_perms.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/cert_provider.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/device_manager.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/reservation.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/rpc_manager.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_cli.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_handler.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/serverrf_cli.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/tools/__init__.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/tools/gen_certs.py +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/requires.txt +0 -0
- {remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: remoteRF-server
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.74
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
Requires-Dist: grpcio
|
|
6
6
|
Requires-Dist: protobuf
|
|
@@ -346,7 +346,9 @@ todo:
|
|
|
346
346
|
<!-- Testing functionality (disregarding Host pipeline) -->
|
|
347
347
|
<!-- Clean up serverrf CLI + basic documentation for all commands, usergroups, export codes by CSV. -->
|
|
348
348
|
|
|
349
|
-
HostRF meta data -> push upon connection + retry connection on host side.
|
|
349
|
+
<!-- HostRF meta data -> push upon connection + retry connection on host side. -->
|
|
350
|
+
|
|
351
|
+
Host ID (NEEDS TO BE UNIQUE AND TELL THE HOST THAT) (or if device also does it as well.)
|
|
350
352
|
|
|
351
353
|
ServerRF display meta data as part of devices list / reservation + online/activity status (appended into device name) + (plus host side warning if the device id is NOT globally unique!)
|
|
352
354
|
|
|
@@ -335,7 +335,9 @@ todo:
|
|
|
335
335
|
<!-- Testing functionality (disregarding Host pipeline) -->
|
|
336
336
|
<!-- Clean up serverrf CLI + basic documentation for all commands, usergroups, export codes by CSV. -->
|
|
337
337
|
|
|
338
|
-
HostRF meta data -> push upon connection + retry connection on host side.
|
|
338
|
+
<!-- HostRF meta data -> push upon connection + retry connection on host side. -->
|
|
339
|
+
|
|
340
|
+
Host ID (NEEDS TO BE UNIQUE AND TELL THE HOST THAT) (or if device also does it as well.)
|
|
339
341
|
|
|
340
342
|
ServerRF display meta data as part of devices list / reservation + online/activity status (appended into device name) + (plus host side warning if the device id is NOT globally unique!)
|
|
341
343
|
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_tunnel_server.py
RENAMED
|
@@ -51,6 +51,31 @@ LOG_MODE = "OFF" # <-- change this
|
|
|
51
51
|
|
|
52
52
|
_LOG_LOCK = threading.Lock()
|
|
53
53
|
|
|
54
|
+
HOST_ID_RE = re.compile(r"^[A-Za-z0-9_.-]{1,64}$") # adjust if you want
|
|
55
|
+
|
|
56
|
+
class HostIdConflictError(RuntimeError):
|
|
57
|
+
def __init__(self, host_id: str, *, age_ms: int, replace_after_ms: int) -> None:
|
|
58
|
+
super().__init__(
|
|
59
|
+
f"host_id '{host_id}' already in use (last heartbeat {age_ms}ms ago). "
|
|
60
|
+
f"Try again after {replace_after_ms}ms or fix the conflicting host config."
|
|
61
|
+
)
|
|
62
|
+
self.host_id = host_id
|
|
63
|
+
self.age_ms = age_ms
|
|
64
|
+
self.replace_after_ms = replace_after_ms
|
|
65
|
+
|
|
66
|
+
def _validate_host_id(raw: str) -> str:
|
|
67
|
+
hid = (raw or "").strip()
|
|
68
|
+
if not hid:
|
|
69
|
+
raise ValueError("Missing host_id (set HOST_ID in host.env; do not auto-generate).")
|
|
70
|
+
if hid == "unknown-host":
|
|
71
|
+
raise ValueError("host_id cannot be 'unknown-host' (set HOST_ID in host.env).")
|
|
72
|
+
if not HOST_ID_RE.fullmatch(hid):
|
|
73
|
+
raise ValueError(
|
|
74
|
+
"Invalid host_id. Allowed: 1..64 chars of [A-Za-z0-9_.-]. "
|
|
75
|
+
f"Got: {hid!r}"
|
|
76
|
+
)
|
|
77
|
+
return hid
|
|
78
|
+
|
|
54
79
|
def _ts() -> str:
|
|
55
80
|
t = time.time()
|
|
56
81
|
sec = int(t)
|
|
@@ -387,12 +412,25 @@ class HostTunnelRegistry:
|
|
|
387
412
|
# directory/status mutators
|
|
388
413
|
# ---------------------------
|
|
389
414
|
|
|
390
|
-
def register_host(
|
|
415
|
+
def register_host(
|
|
416
|
+
self,
|
|
417
|
+
host_id: str,
|
|
418
|
+
session: HostSession,
|
|
419
|
+
*,
|
|
420
|
+
replace_if_stale_ms: int = 15_000, # tweak: how long without heartbeat before we allow replacement
|
|
421
|
+
) -> None:
|
|
391
422
|
info(f"[registry] register_host: host_id={host_id!r}")
|
|
423
|
+
|
|
392
424
|
with self._lock:
|
|
393
425
|
old = self._hosts.get(host_id)
|
|
394
|
-
if old is not None:
|
|
395
|
-
|
|
426
|
+
if old is not None and old.alive:
|
|
427
|
+
age_ms = int(now_ms() - int(getattr(old, "last_heartbeat_ms", 0) or 0))
|
|
428
|
+
if age_ms < replace_if_stale_ms:
|
|
429
|
+
# conflict: someone else is already using this host_id
|
|
430
|
+
raise HostIdConflictError(host_id, age_ms=age_ms, replace_after_ms=replace_if_stale_ms)
|
|
431
|
+
|
|
432
|
+
# stale: allow replacement
|
|
433
|
+
warn(f"[registry] register_host: replacing STALE session host_id={host_id!r} age_ms={age_ms}")
|
|
396
434
|
old.close()
|
|
397
435
|
|
|
398
436
|
self._hosts[host_id] = session
|
|
@@ -823,7 +861,28 @@ class HostTunnelServicer(host_tunnel_pb2_grpc.HostTunnelServicer):
|
|
|
823
861
|
|
|
824
862
|
if which == "hello":
|
|
825
863
|
hello = frame.hello
|
|
826
|
-
|
|
864
|
+
raw = str(getattr(hello, "host_id", "") or "")
|
|
865
|
+
try:
|
|
866
|
+
host_id = _validate_host_id(raw)
|
|
867
|
+
except ValueError as e:
|
|
868
|
+
error(f"[inbound] invalid hello.host_id peer={peer} err={e}")
|
|
869
|
+
fatal["code"] = "INVALID_ARGUMENT"
|
|
870
|
+
fatal["details"] = str(e)
|
|
871
|
+
stop.set()
|
|
872
|
+
return
|
|
873
|
+
|
|
874
|
+
ver = str(getattr(hello, "version", "") or "")
|
|
875
|
+
info(f"[inbound] HELLO host_id={host_id!r} version={ver!r} peer={peer}")
|
|
876
|
+
|
|
877
|
+
session = HostSession(host_id)
|
|
878
|
+
try:
|
|
879
|
+
self.registry.register_host(host_id, session, replace_if_stale_ms=15_000)
|
|
880
|
+
except HostIdConflictError as e:
|
|
881
|
+
error(f"[inbound] HostIdConflictError host_id={host_id!r} err={e}")
|
|
882
|
+
fatal["code"] = "ALREADY_EXISTS"
|
|
883
|
+
fatal["details"] = str(e)
|
|
884
|
+
stop.set()
|
|
885
|
+
return
|
|
827
886
|
ver = str(getattr(hello, "version", "") or "")
|
|
828
887
|
info(f"[inbound] HELLO host_id={host_id!r} version={ver!r} peer={peer}")
|
|
829
888
|
|
|
@@ -976,6 +1035,8 @@ class HostTunnelServicer(host_tunnel_pb2_grpc.HostTunnelServicer):
|
|
|
976
1035
|
error(f"[Connect] aborting stream peer={peer} code={code} details={details}")
|
|
977
1036
|
if code == "ALREADY_EXISTS":
|
|
978
1037
|
context.abort(grpc.StatusCode.ALREADY_EXISTS, details)
|
|
1038
|
+
if code == "INVALID_ARGUMENT":
|
|
1039
|
+
context.abort(grpc.StatusCode.INVALID_ARGUMENT, details)
|
|
979
1040
|
context.abort(grpc.StatusCode.UNKNOWN, details)
|
|
980
1041
|
|
|
981
1042
|
if session is None:
|
|
@@ -445,6 +445,187 @@ def _cmd_devices_status() -> None:
|
|
|
445
445
|
" online=", Sty.DEFAULT, f"{ds.online}", Sty.GREEN if ds.online else Sty.RED,
|
|
446
446
|
" last_seen=", Sty.DEFAULT, f"{_fmt_ms_ago(ds.last_seen_ms)} ago", Sty.BLUE
|
|
447
447
|
)
|
|
448
|
+
|
|
449
|
+
from typing import Iterable
|
|
450
|
+
import contextlib
|
|
451
|
+
|
|
452
|
+
def _repo_root_guess() -> Path:
|
|
453
|
+
"""
|
|
454
|
+
Best-effort: find <repo>/src/... and return <repo>.
|
|
455
|
+
Fallback: walk up a few levels from this file.
|
|
456
|
+
"""
|
|
457
|
+
p = Path(__file__).resolve()
|
|
458
|
+
for parent in p.parents:
|
|
459
|
+
if parent.name == "src":
|
|
460
|
+
return parent.parent
|
|
461
|
+
# fallback
|
|
462
|
+
return p.parents[3] if len(p.parents) >= 4 else p.parent
|
|
463
|
+
|
|
464
|
+
def _host_state_dirs() -> list[Path]:
|
|
465
|
+
"""
|
|
466
|
+
Places host-directory persistence might live in your codebase:
|
|
467
|
+
- User config dir: ~/.config/remoterf (REMOTERF_CONFIG_DIR override)
|
|
468
|
+
- Repo-local: <repo>/.config
|
|
469
|
+
- Server config dir you referenced: <repo>/src/remoteRF_server/config (because of .env.host_directory)
|
|
470
|
+
"""
|
|
471
|
+
cands = [
|
|
472
|
+
_cfg_dir(),
|
|
473
|
+
_repo_root_guess() / ".config",
|
|
474
|
+
(Path(__file__).resolve().parent.parent / "config"), # <repo>/src/remoteRF_server/config
|
|
475
|
+
]
|
|
476
|
+
|
|
477
|
+
out: list[Path] = []
|
|
478
|
+
seen: set[str] = set()
|
|
479
|
+
for d in cands:
|
|
480
|
+
try:
|
|
481
|
+
rp = str(d.resolve())
|
|
482
|
+
except Exception:
|
|
483
|
+
rp = str(d)
|
|
484
|
+
if rp not in seen:
|
|
485
|
+
seen.add(rp)
|
|
486
|
+
out.append(d)
|
|
487
|
+
return out
|
|
488
|
+
|
|
489
|
+
def _host_state_files() -> list[Path]:
|
|
490
|
+
"""
|
|
491
|
+
Exact files your HostTunnelRegistry has historically used.
|
|
492
|
+
Also includes a conservative glob for future additions.
|
|
493
|
+
"""
|
|
494
|
+
files: list[Path] = []
|
|
495
|
+
for d in _host_state_dirs():
|
|
496
|
+
files.append(d / "host_directory.env")
|
|
497
|
+
files.append(d / "host_directory_meta.env")
|
|
498
|
+
# If you later add more persisted host-dir files, keep them discoverable.
|
|
499
|
+
try:
|
|
500
|
+
for p in sorted(d.glob("host_directory*.env")):
|
|
501
|
+
files.append(p)
|
|
502
|
+
except Exception:
|
|
503
|
+
pass
|
|
504
|
+
|
|
505
|
+
out: list[Path] = []
|
|
506
|
+
seen: set[str] = set()
|
|
507
|
+
for p in files:
|
|
508
|
+
try:
|
|
509
|
+
rp = str(p.resolve())
|
|
510
|
+
except Exception:
|
|
511
|
+
rp = str(p)
|
|
512
|
+
if rp not in seen:
|
|
513
|
+
seen.add(rp)
|
|
514
|
+
out.append(p)
|
|
515
|
+
return out
|
|
516
|
+
|
|
517
|
+
def _cmd_hosts_persisted() -> None:
|
|
518
|
+
files = _host_state_files()
|
|
519
|
+
found_any = False
|
|
520
|
+
printf("Host directory (persisted) state files:", Sty.BOLD)
|
|
521
|
+
for p in files:
|
|
522
|
+
if p.exists():
|
|
523
|
+
found_any = True
|
|
524
|
+
try:
|
|
525
|
+
size = p.stat().st_size
|
|
526
|
+
except Exception:
|
|
527
|
+
size = -1
|
|
528
|
+
printf(" - ", Sty.DEFAULT, f"{p}", Sty.MAGENTA, f" ({size} bytes)", Sty.GRAY)
|
|
529
|
+
else:
|
|
530
|
+
printf(" - ", Sty.DEFAULT, f"{p}", Sty.GRAY, " (missing)", Sty.GRAY)
|
|
531
|
+
if not found_any:
|
|
532
|
+
printf(" (none found)", Sty.GRAY)
|
|
533
|
+
|
|
534
|
+
def _try_clear_registry_in_memory(reg: object) -> list[str]:
|
|
535
|
+
"""
|
|
536
|
+
Best-effort in-memory wipe without knowing exact internals.
|
|
537
|
+
Uses registry lock if present.
|
|
538
|
+
"""
|
|
539
|
+
cleared: list[str] = []
|
|
540
|
+
|
|
541
|
+
lock = getattr(reg, "_lock", None)
|
|
542
|
+
acquired = False
|
|
543
|
+
try:
|
|
544
|
+
if lock is not None and hasattr(lock, "acquire") and hasattr(lock, "release"):
|
|
545
|
+
lock.acquire()
|
|
546
|
+
acquired = True
|
|
547
|
+
|
|
548
|
+
# common private dict fields
|
|
549
|
+
for attr in (
|
|
550
|
+
"_hosts",
|
|
551
|
+
"_devices",
|
|
552
|
+
"_host_by_id",
|
|
553
|
+
"_device_by_id",
|
|
554
|
+
"_device_routes",
|
|
555
|
+
"_routes",
|
|
556
|
+
"_sessions",
|
|
557
|
+
"_host_sessions",
|
|
558
|
+
):
|
|
559
|
+
d = getattr(reg, attr, None)
|
|
560
|
+
if isinstance(d, dict):
|
|
561
|
+
d.clear()
|
|
562
|
+
cleared.append(attr)
|
|
563
|
+
|
|
564
|
+
# common private sets/lists
|
|
565
|
+
for attr in ("_connected", "_online_hosts"):
|
|
566
|
+
s = getattr(reg, attr, None)
|
|
567
|
+
if isinstance(s, set):
|
|
568
|
+
s.clear()
|
|
569
|
+
cleared.append(attr)
|
|
570
|
+
|
|
571
|
+
# if there is an explicit method, prefer it (won’t hurt if absent)
|
|
572
|
+
for meth in ("clear", "reset", "wipe", "wipe_all", "wipe_state"):
|
|
573
|
+
fn = getattr(reg, meth, None)
|
|
574
|
+
if callable(fn):
|
|
575
|
+
try:
|
|
576
|
+
fn()
|
|
577
|
+
cleared.append(f"{meth}()")
|
|
578
|
+
except Exception:
|
|
579
|
+
pass
|
|
580
|
+
|
|
581
|
+
finally:
|
|
582
|
+
if acquired:
|
|
583
|
+
try:
|
|
584
|
+
lock.release()
|
|
585
|
+
except Exception:
|
|
586
|
+
pass
|
|
587
|
+
|
|
588
|
+
return cleared
|
|
589
|
+
|
|
590
|
+
def _cmd_hosts_wipe(*, yes: bool = False) -> None:
|
|
591
|
+
# confirm
|
|
592
|
+
if not yes:
|
|
593
|
+
try:
|
|
594
|
+
resp = session.prompt(stylize("Type 'wipe-hosts' to confirm wiping persisted host state: ", Sty.RED))
|
|
595
|
+
except KeyboardInterrupt:
|
|
596
|
+
printf("Cancelled.", Sty.GRAY)
|
|
597
|
+
return
|
|
598
|
+
if (resp or "").strip().lower() != "wipe-hosts":
|
|
599
|
+
printf("Wipe aborted.", Sty.GRAY)
|
|
600
|
+
return
|
|
601
|
+
|
|
602
|
+
# delete persisted files
|
|
603
|
+
files = [p for p in _host_state_files() if p.exists()]
|
|
604
|
+
if not files:
|
|
605
|
+
printf("No persisted host directory files found to wipe.", Sty.GRAY)
|
|
606
|
+
else:
|
|
607
|
+
for p in files:
|
|
608
|
+
try:
|
|
609
|
+
p.unlink()
|
|
610
|
+
printf("Deleted: ", Sty.DEFAULT, f"{p}", Sty.MAGENTA)
|
|
611
|
+
except Exception as e:
|
|
612
|
+
printf("ERROR deleting: ", Sty.RED, f"{p} -> {e}", Sty.DEFAULT)
|
|
613
|
+
return
|
|
614
|
+
|
|
615
|
+
# clear in-memory registry (so you don’t have to restart for live state)
|
|
616
|
+
global TUNNEL_REGISTRY
|
|
617
|
+
reg = TUNNEL_REGISTRY
|
|
618
|
+
if reg is None:
|
|
619
|
+
printf("Host tunnel registry not initialized; persisted files wiped only.", Sty.GRAY)
|
|
620
|
+
else:
|
|
621
|
+
cleared = _try_clear_registry_in_memory(reg)
|
|
622
|
+
if cleared:
|
|
623
|
+
printf("Cleared in-memory registry fields: ", Sty.DEFAULT, ", ".join(cleared), Sty.GRAY)
|
|
624
|
+
else:
|
|
625
|
+
printf("WARNING: Could not confirm in-memory registry clear (unknown internals). Restart server if needed.", Sty.YELLOW)
|
|
626
|
+
|
|
627
|
+
printf("Host state wipe complete.", Sty.GREEN)
|
|
628
|
+
printf("NOTE: If hosts reconnect, persisted files will be recreated.", Sty.GRAY)
|
|
448
629
|
|
|
449
630
|
# def help():
|
|
450
631
|
# printf("/------- HELP -------/", Sty.BOLD)
|
|
@@ -571,6 +752,7 @@ def help() -> None:
|
|
|
571
752
|
|
|
572
753
|
printf("Host Tunnel (live):", Sty.BOLD)
|
|
573
754
|
printf(" hosts status ", Sty.MAGENTA, "- Live host online/last_seen/devices", Sty.DEFAULT)
|
|
755
|
+
printf(" hosts wipe ", Sty.MAGENTA, "- Wipe persisted host directory state (and clear in-memory)", Sty.DEFAULT)
|
|
574
756
|
printf(" devices status ", Sty.MAGENTA, "- Live device online/last_seen/route", Sty.DEFAULT)
|
|
575
757
|
print()
|
|
576
758
|
|
|
@@ -669,7 +851,6 @@ def server_input(inpu: str) -> bool:
|
|
|
669
851
|
# ---- host tunnel ----
|
|
670
852
|
"hosts status": lambda: _stay(_cmd_hosts_status),
|
|
671
853
|
"host status": lambda: _stay(_cmd_hosts_status),
|
|
672
|
-
"tunnel hosts": lambda: _stay(_cmd_hosts_status),
|
|
673
854
|
|
|
674
855
|
"devices status": lambda: _stay(_cmd_devices_status),
|
|
675
856
|
"tunnel devices": lambda: _stay(_cmd_devices_status),
|
|
@@ -679,6 +860,12 @@ def server_input(inpu: str) -> bool:
|
|
|
679
860
|
|
|
680
861
|
fn = DISPATCH.get(cmd)
|
|
681
862
|
if fn is None:
|
|
863
|
+
# allow: "hosts wipe" and "hosts wipe -y"
|
|
864
|
+
if cmd.startswith("hosts wipe"):
|
|
865
|
+
yes = ("-y" in cmd.split()) or ("--yes" in cmd.split())
|
|
866
|
+
_cmd_hosts_wipe(yes=yes)
|
|
867
|
+
return True
|
|
868
|
+
|
|
682
869
|
printf("Unknown command: ", Sty.RED, f"{inpu}", Sty.DEFAULT)
|
|
683
870
|
printf("Type ", Sty.DEFAULT, "help", Sty.MAGENTA, " to see commands.", Sty.DEFAULT)
|
|
684
871
|
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: remoteRF-server
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.74
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
Requires-Dist: grpcio
|
|
6
6
|
Requires-Dist: protobuf
|
|
@@ -346,7 +346,9 @@ todo:
|
|
|
346
346
|
<!-- Testing functionality (disregarding Host pipeline) -->
|
|
347
347
|
<!-- Clean up serverrf CLI + basic documentation for all commands, usergroups, export codes by CSV. -->
|
|
348
348
|
|
|
349
|
-
HostRF meta data -> push upon connection + retry connection on host side.
|
|
349
|
+
<!-- HostRF meta data -> push upon connection + retry connection on host side. -->
|
|
350
|
+
|
|
351
|
+
Host ID (NEEDS TO BE UNIQUE AND TELL THE HOST THAT) (or if device also does it as well.)
|
|
350
352
|
|
|
351
353
|
ServerRF display meta data as part of devices list / reservation + online/activity status (appended into device name) + (plus host side warning if the device id is NOT globally unique!)
|
|
352
354
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/__init__.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_host_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/__init__.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/ansi_codes.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/api_token.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_connection.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_location.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/list_string.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/process_arg.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_directory_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/cert_provider.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/device_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_cli.py
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-0.1.72 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/top_level.txt
RENAMED
|
File without changes
|