Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • jirikalvoda/vm
1 result
Select Git revision
Loading items
Show changes
Commits on Source (5)
......@@ -7,13 +7,14 @@ import json
from dataclasses import dataclass
import functools
from typing import Optional
import traceback
socket_path = '.socket'
is_daemon = False
if __name__ == "__main__":
if len(sys.argv)==2 and sys.argv[1]=="server":
if len(sys.argv)>=2 and sys.argv[1]=="server":
is_daemon = True
class S():
......@@ -316,7 +317,7 @@ def create_from_img(ucred: Ucred, target: str, new_ssh: bool = True, target_name
mount_dir = target_dir+"mount/"
os.mkdir(mount_dir)
r('mount', '-o', 'loop,offset=210763776', '--type', 'ext4', target_dir+'img', mount_dir)
r('mount', '-o', 'nosymfollow,loop,offset=210763776', '--type', 'ext4', target_dir+'img', mount_dir)
try:
with open(mount_dir+"/etc/hostname", "w") as f: f.write(target_name+"\n")
if new_ssh:
......@@ -440,7 +441,7 @@ def sshfs(vm: str, user: str = None):
if os.path.isdir(mount_dir) and len(os.listdir(mount_dir)) != 0:
return
r("mkdir", "-p", mount_dir)
r("sshfs", "-o", "follow_symlinks", f"{user}@{get_ip(vm)}:/", mount_dir, "-o", f"ssh_command=ssh -i {vm_dir(vm)}/id_ed25519 -o UserKnownHostsFile={vm_dir(vm)}/known_hosts -o HostKeyAlgorithms=ssh-ed25519 -o HostKeyAlias=vm_{vm}")
r("sshfs", "-o", "transform_symlinks", f"{user}@{get_ip(vm)}:/", mount_dir, "-o", f"ssh_command=ssh -i {vm_dir(vm)}/id_ed25519 -o UserKnownHostsFile={vm_dir(vm)}/known_hosts -o HostKeyAlgorithms=ssh-ed25519 -o HostKeyAlias=vm_{vm}")
if not os.path.islink(mount_dir+'~'):
home_dir = "/root" if user == "root" else f"/home/{user}"
r("ln", "-sr", mount_dir+home_dir, mount_dir+"~")
......@@ -458,20 +459,25 @@ def sshfs_clean():
def escape_sh(*arg):
return " ".join("'" + s.replace("'", "'\"'\"'") + "'" for s in arg)
def get_vnc_client_env(vm):
vnc_client_env = os.environ.copy()
vnc_client_env["VNC_PASSWORD"] = open(vm_dir(vm)+"vnc_passwd", "r").read().strip()
return vnc_client_env
vncviewer_args = ["-FullscreenSystemKeys=0", "-AcceptClipboard=0", "-SendClipboard=0"]
@cmd
def vncapp(vm: str, cmd: str, user: str = "u"):
import random
import psutil
unit_id = random.randint(100000, 999999)
vm, user = extended_name(vm, user=user)
vm = name_to_id(vm)
display_id=random.randint(10, 50)
vnc_server = subprocess.Popen(ssh_args(vm, f"systemd-run --unit vncapp-vnc-{display_id}-{unit_id} --user -P bash -c '(cat /vnc_passwd;echo; cat /vnc_passwd; echo;echo n) | vncpasswd; vncserver :{display_id}'", user=user))
time.sleep(1)
vnc_client_env = os.environ.copy()
vnc_client_env["VNC_PASSWORD"] = open(vm_dir(vm)+"vnc_passwd", "r").read().strip()
app = subprocess.Popen(ssh_args(vm, f"systemd-run --unit vncapp-app-{display_id}-{unit_id} --user -P -E DISPLAY=:{display_id} bash -c {escape_sh(cmd)}", user=user));
vnc_client = subprocess.Popen(["vncviewer", get_ip(vm)+f":{display_id}"], env=vnc_client_env)
vnc_client = subprocess.Popen(["vncviewer", get_ip(vm)+f":{display_id}", *vncviewer_args], env=get_vnc_client_env(vm))
def on_terminate(proc):
if verbose: print(f"KILLING ALL APPS because {proc} terminated")
......@@ -488,12 +494,9 @@ def vncsession(vm: str, display_id: int =0, user: str = "u"):
import psutil
unit_id = random.randint(100000, 999999)
vm, user = extended_name(vm, user=user)
vm = name_to_id(vm)
vnc_server = subprocess.Popen(ssh_args(vm, f"systemd-run --unit vncsession-{display_id}-{unit_id} --user -P bash -c '(cat /vnc_passwd;echo; cat /vnc_passwd; echo;echo n) | vncpasswd; vncserver :{display_id}'", user=user))
vnc_client_env = os.environ.copy()
vnc_client_env["VNC_PASSWORD"] = open(vm_dir(vm)+"vnc_passwd", "r").read().strip()
time.sleep(1)
vnc_client = subprocess.Popen(["vncviewer", get_ip(vm)+f":{display_id}"], env=vnc_client_env)
vnc_client = subprocess.Popen(["vncviewer", get_ip(vm)+f":{display_id}", *vncviewer_args], env=get_vnc_client_env(vm))
def on_terminate(proc):
if verbose: print("KILLING ALL APPS")
......@@ -690,7 +693,7 @@ def modify_net(ucred, vm: str, wan: bool = False, lan: bool = False, pc: bool =
def start(ucred, vm: str):
vm = name_to_id(vm)
assert has_write_acces(ucred, vm)
if open(vm_dir(vm)+"network/boot_id", "r").read().strip() != boot_id:
if not os.path.exists(vm_dir(vm)+"network/boot_id") or open(vm_dir(vm)+"network/boot_id", "r").read().strip() != boot_id:
create_net(ucred, vm)
r("VBoxManage", "startvm", vm, "--type=headless")
if get_permanency(vm).startswith("init "):
......@@ -899,6 +902,62 @@ def run(vm: str, prog: str, *arg: tuple[str, ...], gui: bool = False, out_file:
##########################################################
def run_args(args):
if verbose: print(args)
if not args.subcommand:
parser.print_help()
else:
import inspect
f = subcommands[args.subcommand]
spec = get_spec(f)
f_kvarg = {}
f_arg = []
def process_arg(name, has_default, default):
if has_default:
if args.__dict__[name] is not None:
f_kvarg[name] = args.__dict__[name]
else:
f_arg.append(args.__dict__[name])
for i, arg in enumerate(spec.args):
has_default = spec.defaults is not None and i >= len(spec.args) - len(spec.defaults)
default = None
if has_default:
default = spec.defaults[i - len(spec.args) + len(spec.defaults)]
process_arg(arg, has_default, default)
for i, arg in enumerate(spec.kwonlyargs):
default = spec.kwonlydefaults[arg]
process_arg(arg, True, default)
if spec.varargs is not None:
arg = spec.varargs
annotation = spec.annotations.get(arg, None)
if annotation == tuple[str, ...]:
f_arg += args.__dict__[arg]
if verbose: print(f_arg, f_kvarg)
r = f(*f_arg, **f_kvarg)
if r is not None:
if isinstance(r, tuple) or isinstance(r, list):
for i in r:
print(i)
else:
print(r)
@cmd
def run_periodically(delay: int, *argv: tuple[str, ...]):
print("RUN PERIODICALLY", argv)
args = parser.parse_args(argv)
while True:
time.sleep(delay)
try:
run_args(args)
except Exception as e:
traceback.print_exception(e)
def main_daemon():
import socket
import struct
......@@ -911,7 +970,9 @@ def main_daemon():
server.bind(socket_path)
os.chmod(socket_path, 0o777)
import traceback
for arg in sys.argv[2:]:
p = subprocess.Popen([sys.argv[0], *arg.split(" ")])
try:
while True:
......@@ -949,8 +1010,6 @@ def main_daemon():
except Exception as e:
traceback.print_exception(e)
finally:
# close the connection
# remove the socket file
os.unlink(socket_path)
exit(1)
......@@ -963,48 +1022,7 @@ def main():
if args.root_folder is not None:
root_folder = args.root_folder+"/"
if verbose: print(args)
if not args.subcommand:
parser.print_help()
else:
import inspect
f = subcommands[args.subcommand]
spec = get_spec(f)
f_kvarg = {}
f_arg = []
def process_arg(name, has_default, default):
if has_default:
if args.__dict__[name] is not None:
f_kvarg[name] = args.__dict__[name]
else:
f_arg.append(args.__dict__[name])
for i, arg in enumerate(spec.args):
has_default = spec.defaults is not None and i >= len(spec.args) - len(spec.defaults)
default = None
if has_default:
default = spec.defaults[i - len(spec.args) + len(spec.defaults)]
process_arg(arg, has_default, default)
for i, arg in enumerate(spec.kwonlyargs):
default = spec.kwonlydefaults[arg]
process_arg(arg, True, default)
if spec.varargs is not None:
arg = spec.varargs
annotation = spec.annotations.get(arg, None)
if annotation == tuple[str, ...]:
f_arg += args.__dict__[arg]
if verbose: print(f_arg, f_kvarg)
r = f(*f_arg, **f_kvarg)
if r is not None:
if isinstance(r, tuple) or isinstance(r, list):
for i in r:
print(i)
else:
print(r)
run_args(args)
......
......@@ -6,7 +6,8 @@ After=network.target
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin:/home/jiri/bin
WorkingDirectory=/mnt/virtual
ExecStart=/mnt/virtual/prog/vm.py server
ExecStart=/mnt/virtual/prog/vm.py server 'run_periodically 10 -- prepare_forks --base base --count 1' 'run_periodically 30 -- clean'
Restart=always
RestartSec=10
......