remoteRF-server 0.1.73__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.
Files changed (42) hide show
  1. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/PKG-INFO +1 -1
  2. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/pyproject.toml +1 -1
  3. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/grpc_server.py +188 -1
  4. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/PKG-INFO +1 -1
  5. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/README.md +0 -0
  6. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/setup.cfg +0 -0
  7. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/__init__.py +0 -0
  8. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/__init__.py +0 -0
  9. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/__init__.py +0 -0
  10. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
  11. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
  12. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
  13. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
  14. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/__init__.py +0 -0
  15. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
  16. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/api_token.py +0 -0
  17. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_connection.py +0 -0
  18. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/db_location.py +0 -0
  19. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/list_string.py +0 -0
  20. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/common/utils/process_arg.py +0 -0
  21. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/__init__.py +0 -0
  22. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
  23. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
  24. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/host/__init__.py +0 -0
  25. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_directory_store.py +0 -0
  26. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/host/host_tunnel_server.py +0 -0
  27. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/__init__.py +0 -0
  28. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/acc_perms.py +0 -0
  29. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/cert_provider.py +0 -0
  30. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/device_manager.py +0 -0
  31. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/reservation.py +0 -0
  32. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/rpc_manager.py +0 -0
  33. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_cli.py +0 -0
  34. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/server/user_group_handler.py +0 -0
  35. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/serverrf_cli.py +0 -0
  36. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/tools/__init__.py +0 -0
  37. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server/tools/gen_certs.py +0 -0
  38. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
  39. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
  40. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
  41. {remoterf_server-0.1.73 → remoterf_server-0.1.74}/src/remoteRF_server.egg-info/requires.txt +0 -0
  42. {remoterf_server-0.1.73 → 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.73
3
+ Version: 0.1.74
4
4
  Description-Content-Type: text/markdown
5
5
  Requires-Dist: grpcio
6
6
  Requires-Dist: protobuf
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "remoteRF-server"
7
- version = "0.1.73"
7
+ version = "0.1.74"
8
8
  dependencies = [
9
9
  "grpcio",
10
10
  "protobuf",
@@ -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.73
3
+ Version: 0.1.74
4
4
  Description-Content-Type: text/markdown
5
5
  Requires-Dist: grpcio
6
6
  Requires-Dist: protobuf