clan join: init
This commit is contained in:
@@ -3,7 +3,7 @@ import sys
|
|||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from . import config, create, machines, secrets, vms, webui
|
from . import config, create, join, machines, secrets, vms, webui
|
||||||
from .errors import ClanError
|
from .errors import ClanError
|
||||||
from .ssh import cli as ssh_cli
|
from .ssh import cli as ssh_cli
|
||||||
|
|
||||||
@@ -30,6 +30,9 @@ def create_parser(prog: Optional[str] = None) -> argparse.ArgumentParser:
|
|||||||
)
|
)
|
||||||
create.register_parser(parser_create)
|
create.register_parser(parser_create)
|
||||||
|
|
||||||
|
parser_join = subparsers.add_parser("join", help="join a remote clan")
|
||||||
|
join.register_parser(parser_join)
|
||||||
|
|
||||||
parser_config = subparsers.add_parser("config", help="set nixos configuration")
|
parser_config = subparsers.add_parser("config", help="set nixos configuration")
|
||||||
config.register_parser(parser_config)
|
config.register_parser(parser_config)
|
||||||
|
|
||||||
|
|||||||
35
pkgs/clan-cli/clan_cli/join/__init__.py
Normal file
35
pkgs/clan-cli/clan_cli/join/__init__.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# !/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import urllib
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
def join(args: argparse.Namespace) -> None:
|
||||||
|
# start webui in background
|
||||||
|
uri = args.flake_uri.removeprefix("clan://")
|
||||||
|
subprocess.run(
|
||||||
|
["clan", "webui", f"/join?flake={urllib.parse.quote_plus(uri)}"],
|
||||||
|
# stdout=sys.stdout,
|
||||||
|
# stderr=sys.stderr,
|
||||||
|
)
|
||||||
|
print(f"joined clan {args.flake_uri}")
|
||||||
|
|
||||||
|
|
||||||
|
# takes a (sub)parser and configures it
|
||||||
|
def register_parser(
|
||||||
|
parser: Optional[argparse.ArgumentParser],
|
||||||
|
) -> None:
|
||||||
|
if parser is None:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="join a remote clan",
|
||||||
|
)
|
||||||
|
|
||||||
|
# inject callback function to process the input later
|
||||||
|
parser.set_defaults(func=join)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"flake_uri",
|
||||||
|
help="flake uri to join",
|
||||||
|
type=str,
|
||||||
|
)
|
||||||
@@ -19,7 +19,9 @@ def fastapi_is_not_installed(_: argparse.Namespace) -> NoReturn:
|
|||||||
|
|
||||||
def register_parser(parser: argparse.ArgumentParser) -> None:
|
def register_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
parser.add_argument("--port", type=int, default=2979, help="Port to listen on")
|
parser.add_argument("--port", type=int, default=2979, help="Port to listen on")
|
||||||
parser.add_argument("--host", type=str, default="::1", help="Host to listen on")
|
parser.add_argument(
|
||||||
|
"--host", type=str, default="localhost", help="Host to listen on"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-open", action="store_true", help="Don't open the browser", default=False
|
"--no-open", action="store_true", help="Don't open the browser", default=False
|
||||||
)
|
)
|
||||||
@@ -46,6 +48,14 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
|
|||||||
choices=["critical", "error", "warning", "info", "debug", "trace"],
|
choices=["critical", "error", "warning", "info", "debug", "trace"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"sub_url",
|
||||||
|
type=str,
|
||||||
|
default="/",
|
||||||
|
nargs="?",
|
||||||
|
help="Sub url to open in the browser",
|
||||||
|
)
|
||||||
|
|
||||||
# Set the args.func variable in args
|
# Set the args.func variable in args
|
||||||
if start_server is None:
|
if start_server is None:
|
||||||
parser.set_defaults(func=fastapi_is_not_installed)
|
parser.set_defaults(func=fastapi_is_not_installed)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from clan_cli.errors import ClanError
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def open_browser(base_url: str) -> None:
|
def open_browser(base_url: str, sub_url: str) -> None:
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
try:
|
try:
|
||||||
@@ -28,7 +28,8 @@ def open_browser(base_url: str) -> None:
|
|||||||
break
|
break
|
||||||
except OSError:
|
except OSError:
|
||||||
time.sleep(i)
|
time.sleep(i)
|
||||||
proc = _open_browser(base_url, tmpdir)
|
url = f"{base_url}/{sub_url.removeprefix('/')}"
|
||||||
|
proc = _open_browser(url, tmpdir)
|
||||||
try:
|
try:
|
||||||
proc.wait()
|
proc.wait()
|
||||||
print("Browser closed")
|
print("Browser closed")
|
||||||
@@ -38,7 +39,7 @@ def open_browser(base_url: str) -> None:
|
|||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
def _open_browser(base_url: str, tmpdir: str) -> subprocess.Popen:
|
def _open_browser(url: str, tmpdir: str) -> subprocess.Popen:
|
||||||
for browser in ("firefox", "iceweasel", "iceape", "seamonkey"):
|
for browser in ("firefox", "iceweasel", "iceape", "seamonkey"):
|
||||||
if shutil.which(browser):
|
if shutil.which(browser):
|
||||||
cmd = [
|
cmd = [
|
||||||
@@ -48,13 +49,13 @@ def _open_browser(base_url: str, tmpdir: str) -> subprocess.Popen:
|
|||||||
"--new-instance",
|
"--new-instance",
|
||||||
"--profile",
|
"--profile",
|
||||||
tmpdir,
|
tmpdir,
|
||||||
base_url,
|
url,
|
||||||
]
|
]
|
||||||
print(" ".join(cmd))
|
print(" ".join(cmd))
|
||||||
return subprocess.Popen(cmd)
|
return subprocess.Popen(cmd)
|
||||||
for browser in ("chromium", "chromium-browser", "google-chrome", "chrome"):
|
for browser in ("chromium", "chromium-browser", "google-chrome", "chrome"):
|
||||||
if shutil.which(browser):
|
if shutil.which(browser):
|
||||||
return subprocess.Popen([browser, f"--app={base_url}"])
|
return subprocess.Popen([browser, f"--app={url}"])
|
||||||
raise ClanError("No browser found")
|
raise ClanError("No browser found")
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ def start_server(args: argparse.Namespace) -> None:
|
|||||||
if args.dev:
|
if args.dev:
|
||||||
stack.enter_context(spawn_node_dev_server(args.dev_host, args.dev_port))
|
stack.enter_context(spawn_node_dev_server(args.dev_host, args.dev_port))
|
||||||
|
|
||||||
open_url = f"http://{args.dev_host}:{args.dev_port}"
|
base_url = f"http://{args.dev_host}:{args.dev_port}"
|
||||||
host = args.dev_host
|
host = args.dev_host
|
||||||
if ":" in host:
|
if ":" in host:
|
||||||
host = f"[{host}]"
|
host = f"[{host}]"
|
||||||
@@ -109,10 +110,10 @@ def start_server(args: argparse.Namespace) -> None:
|
|||||||
# )
|
# )
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
open_url = f"http://[{args.host}]:{args.port}"
|
base_url = f"http://{args.host}:{args.port}"
|
||||||
|
|
||||||
if not args.no_open:
|
if not args.no_open:
|
||||||
Thread(target=open_browser, args=(open_url,)).start()
|
Thread(target=open_browser, args=(base_url, args.sub_url)).start()
|
||||||
|
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
"clan_cli.webui.app:app",
|
"clan_cli.webui.app:app",
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ python3.pkgs.buildPythonApplication {
|
|||||||
desktopItems = [
|
desktopItems = [
|
||||||
(makeDesktopItem {
|
(makeDesktopItem {
|
||||||
name = "clan";
|
name = "clan";
|
||||||
exec = "clan";
|
exec = "clan join %u";
|
||||||
desktopName = "CLan Manager";
|
desktopName = "CLan Manager";
|
||||||
startupWMClass = "clan";
|
startupWMClass = "clan";
|
||||||
mimeTypes = [ "x-scheme-handler/clan" ];
|
mimeTypes = [ "x-scheme-handler/clan" ];
|
||||||
|
|||||||
Reference in New Issue
Block a user