mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Flock: CLI first try (starts and stops the hypervisor)
This commit is contained in:
parent
ac66a8dc00
commit
53919e8d9d
133
flock/flock-cli
Executable file
133
flock/flock-cli
Executable file
@ -0,0 +1,133 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import cbor2
|
||||
import os
|
||||
import pathlib
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
DEFAULT_RUN_PATH = pathlib.Path(f"/run/user/{os.getuid()}/flock")
|
||||
handlers = {}
|
||||
|
||||
class HandlerError(Exception):
|
||||
pass
|
||||
|
||||
def handler(fun):
|
||||
items = fun.__name__.split("_")
|
||||
|
||||
hx = handlers
|
||||
while len(items) > 1:
|
||||
if (s := items.pop(0)) not in hx:
|
||||
hx[s] = dict()
|
||||
hx = hx[s]
|
||||
|
||||
if items[0] in hx:
|
||||
raise Exception(f"Duplicate handler {fun.__name__}")
|
||||
|
||||
hx[items[0]] = fun
|
||||
|
||||
class HypervisorNonexistentError(HandlerError):
|
||||
def __init__(self, *args, **kwargs):
|
||||
return super().__init__("Hypervisor not found", *args, **kwargs)
|
||||
|
||||
class HypervisorStaleError(HandlerError):
|
||||
def __init__(self, *args, **kwargs):
|
||||
return super().__init__("Hypervisor stale", *args, **kwargs)
|
||||
|
||||
def connect(where: pathlib.Path):
|
||||
if not where.exists():
|
||||
raise HypervisorNonexistentError()
|
||||
|
||||
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
try:
|
||||
client.connect(bytes(where))
|
||||
except ConnectionRefusedError:
|
||||
raise HypervisorStaleError()
|
||||
return client
|
||||
|
||||
def ctl_path(name: str):
|
||||
return DEFAULT_RUN_PATH / f"{name}.ctl"
|
||||
|
||||
def msg(name: str, data: dict):
|
||||
try:
|
||||
ctl = connect(ctl_path(name))
|
||||
except HypervisorNonexistentError as e:
|
||||
e.add_note(f"Failed to send message {data} to {name}")
|
||||
raise e
|
||||
|
||||
ctl.sendall(cbor2.dumps(data))
|
||||
return cbor2.loads(ctl.recv(1024))
|
||||
|
||||
@handler
|
||||
def start(name: str):
|
||||
DEFAULT_RUN_PATH.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
connect(ctl := ctl_path(name))
|
||||
raise HandlerError("Hypervisor already exists")
|
||||
except HypervisorNonexistentError:
|
||||
pass
|
||||
|
||||
subprocess.run(["./flock-sim", "-s", ctl, name])
|
||||
|
||||
@handler
|
||||
def stop(name: str):
|
||||
for k,v in msg(name, { 0: None }).items():
|
||||
assert(k == -1)
|
||||
assert(v == "OK")
|
||||
|
||||
@handler
|
||||
def cleanup(name: str):
|
||||
try:
|
||||
connect(ctl := ctl_path(name))
|
||||
raise HandlerError("Hypervisor is not stale")
|
||||
except HypervisorStaleError:
|
||||
ctl.unlink()
|
||||
|
||||
@handler
|
||||
def container_start(hypervisor: str, name: str):
|
||||
print(f"start a machine {name} in {hypervisor}")
|
||||
|
||||
try:
|
||||
binname = sys.argv.pop(0)
|
||||
except Exception as e:
|
||||
raise RuntimeError from e
|
||||
|
||||
def usage(name: str):
|
||||
print(
|
||||
f"Usage: {name} <command> <args>",
|
||||
f"",
|
||||
f"Available commands:",
|
||||
f"\tstart <name> start Flock hypervisor",
|
||||
f"\t creates <name>.ctl in {DEFAULT_RUN_PATH}",
|
||||
f"\tstop <name> stop Flock hypervisor",
|
||||
f"\tcleanup <name> cleanup the control socket left behind a stale hypervisor",
|
||||
f"\tcontainer start <hypervisor> <name> start virtual machine",
|
||||
f"\tcontainer stop <hypervisor> <name> stop virtual machine",
|
||||
f"\ttelnet <hypervisor> <name> run telnet to this machine",
|
||||
sep="\n")
|
||||
|
||||
cmd = []
|
||||
hx = handlers
|
||||
while type(hx) is dict:
|
||||
try:
|
||||
hx = hx[cx := sys.argv.pop(0)]
|
||||
except (IndexError, KeyError):
|
||||
usage(binname)
|
||||
exit(2)
|
||||
|
||||
cmd.append(cx)
|
||||
|
||||
try:
|
||||
hx(*sys.argv)
|
||||
except HandlerError as e:
|
||||
print(f"Error: {e}")
|
||||
# raise e
|
||||
exit(1)
|
||||
except TypeError as e:
|
||||
usage(binname)
|
||||
print()
|
||||
print(f"Error in command {' '.join(cmd)}.")
|
||||
raise RuntimeError from e
|
||||
exit(2)
|
||||
|
Loading…
Reference in New Issue
Block a user