ch-runner: add wayland-proxy
This commit is contained in:
parent
e077ad6858
commit
660bda3a4a
4 changed files with 183 additions and 19 deletions
|
|
@ -5,6 +5,28 @@
|
||||||
modulesPath,
|
modulesPath,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
uvmsPkgs = pkgs.callPackage ../pkgs { };
|
||||||
|
waylandSock = "/run/user/1000/wayland-1";
|
||||||
|
env = {
|
||||||
|
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||||
|
WAYLAND_DISPLAY = "wayland-1";
|
||||||
|
|
||||||
|
MESA_LOADER_DRIVER_OVERRIDE = "zink";
|
||||||
|
|
||||||
|
# WAYLAND_DEBUG = "1";
|
||||||
|
# WAYLAND_DEBUG_PROXY = "1";
|
||||||
|
|
||||||
|
ELECTRON_OZONE_PLATFORM_HINT = "wayland";
|
||||||
|
MOZ_ENABLE_WAYLAND = "1";
|
||||||
|
QT_QPA_PLATFORM = "wayland"; # Qt Applications
|
||||||
|
GDK_BACKEND = "wayland"; # GTK Applications
|
||||||
|
XDG_SESSION_TYPE = "wayland"; # Electron Applications
|
||||||
|
SDL_VIDEODRIVER = "wayland";
|
||||||
|
CLUTTER_BACKEND = "wayland";
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
};
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../profiles/all.nix
|
../profiles/all.nix
|
||||||
|
|
@ -18,30 +40,117 @@
|
||||||
vmapps.enable = true;
|
vmapps.enable = true;
|
||||||
_module.args.inputs = import ../npins;
|
_module.args.inputs = import ../npins;
|
||||||
|
|
||||||
# following microvm.nix:
|
# boot.isContainer = true;
|
||||||
|
# boot.initrd.enable = true;
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
boot.initrd.systemd.enable = true;
|
boot.initrd.systemd.enable = true;
|
||||||
|
services.logrotate.enable = false;
|
||||||
|
services.udisks2.enable = false;
|
||||||
|
system.tools.nixos-generate-config.enable = false;
|
||||||
|
# system.activationScripts.specialfs = lib.mkForce "";
|
||||||
|
systemd.coredump.enable = false;
|
||||||
|
# networking.firewall.enable = false;
|
||||||
|
powerManagement.enable = false;
|
||||||
|
boot.kexec.enable = false;
|
||||||
|
# console.enable = false;
|
||||||
|
# system.switch.enable = false;
|
||||||
|
# services.udev.packages = lib.mkDefault [ ];
|
||||||
|
services.resolved.enable = false;
|
||||||
|
systemd.services.generate-shutdown-ramfs.enable = lib.mkForce false;
|
||||||
|
systemd.services.systemd-remount-fs.enable = lib.mkForce false;
|
||||||
|
systemd.services.systemd-pstore.enable = lib.mkForce false;
|
||||||
|
systemd.services.lastlog2-import.enable = lib.mkForce false;
|
||||||
|
systemd.services.suid-sgid-wrappers.enable = lib.mkForce false;
|
||||||
|
|
||||||
fileSystems."/" = lib.mkDefault {
|
fileSystems."/" = lib.mkDefault {
|
||||||
device = "rootfs"; # how does this work? does this assign a label to the tmpfs?
|
device = "rootfs"; # how does this work? does this assign a label to the tmpfs?
|
||||||
fsType = "tmpfs";
|
fsType = "tmpfs";
|
||||||
options = [ "size=20%,mode=0755" ];
|
options = [ "size=20%,mode=0755" ];
|
||||||
neededForBoot = true;
|
neededForBoot = true;
|
||||||
};
|
};
|
||||||
boot.initrd.systemd.settings.Manager.DefaultTimeoutStartSec = 30;
|
boot.initrd.systemd.settings.Manager.DefaultTimeoutStartSec = 5;
|
||||||
systemd.settings.Manager.DefaultTimeoutStopSec = 10;
|
systemd.settings.Manager.DefaultTimeoutStopSec = 10;
|
||||||
networking.useNetworkd = true;
|
networking.useNetworkd = true;
|
||||||
networking.nftables.enable = true;
|
networking.nftables.enable = true;
|
||||||
|
|
||||||
uvms.cloud-hypervisor.enable = true;
|
uvms.cloud-hypervisor.enable = true;
|
||||||
|
|
||||||
|
systemd.sysusers.enable = false;
|
||||||
|
services.userborn.enable = true; # nikstur it
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
|
users.groups.user = { };
|
||||||
|
users.users.user = {
|
||||||
|
isNormalUser = true;
|
||||||
|
password = "hacktheplanet!";
|
||||||
|
extraGroups = [
|
||||||
|
"video"
|
||||||
|
"render"
|
||||||
|
];
|
||||||
|
};
|
||||||
users.users.root.password = "hacktheplanet!";
|
users.users.root.password = "hacktheplanet!";
|
||||||
services.getty.autologinUser = "root";
|
|
||||||
|
|
||||||
systemd.services."suid-sgid-wrappers".serviceConfig = {
|
systemd.services."suid-sgid-wrappers".serviceConfig = {
|
||||||
StandardOutput = "journal+console";
|
StandardOutput = "journal+console";
|
||||||
StandardError = "journal+console";
|
StandardError = "journal+console";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.variables = env;
|
||||||
|
systemd.globalEnvironment = env;
|
||||||
|
systemd.tmpfiles.settings."10-xdg" = {
|
||||||
|
${env.XDG_RUNTIME_DIR}.d = {
|
||||||
|
user = "user";
|
||||||
|
group = "user";
|
||||||
|
mode = "0755";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.sockets."wayland-proxy" = {
|
||||||
|
listenStreams = [
|
||||||
|
waylandSock
|
||||||
|
];
|
||||||
|
socketConfig = {
|
||||||
|
SocketUser = "user";
|
||||||
|
SocketGroup = "user";
|
||||||
|
FileDescriptorName = "wayland";
|
||||||
|
};
|
||||||
|
wantedBy = [ "sockets.target" ];
|
||||||
|
partOf = [ "wayland-proxy.service" ];
|
||||||
|
};
|
||||||
|
systemd.services."wayland-proxy" = {
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
User = "user";
|
||||||
|
Group = "user";
|
||||||
|
ExecStart = "${lib.getExe pkgs.wayland-proxy-virtwl} --virtio-gpu";
|
||||||
|
# ExecStart = "${lib.getExe uvmsPkgs.wl-cross-domain-proxy} --listen-fd --filter-global wp_presentation";
|
||||||
|
ExecStartPre = [
|
||||||
|
"+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128"
|
||||||
|
];
|
||||||
|
StandardOutput = "journal+console";
|
||||||
|
StandardError = "journal+console";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fonts.enableDefaultPackages = true;
|
||||||
|
|
||||||
|
systemd.services."terminal" = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "wayland-proxy.service" ];
|
||||||
|
after = [ "wayland-proxy.service" ];
|
||||||
|
environment = env;
|
||||||
|
serviceConfig = {
|
||||||
|
User = "user";
|
||||||
|
WorkingDirectory = "/home/user";
|
||||||
|
ExecStart = lib.getExe pkgs.alacritty;
|
||||||
|
StandardOutput = "journal+console";
|
||||||
|
StandardError = "journal+console";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
boot.kernelModules = [
|
||||||
|
"drm"
|
||||||
|
"virtio_gpu"
|
||||||
|
];
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
|
||||||
# TODO: cmdline, kernel, initrd, fileSystems
|
# TODO: cmdline, kernel, initrd, fileSystems
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,7 @@ let
|
||||||
getBin
|
getBin
|
||||||
;
|
;
|
||||||
|
|
||||||
package = pkgs.cloud-hypervisor.overrideAttrs (oldAttrs: {
|
package = uvmsPkgs.cloud-hypervisor-gpu;
|
||||||
patches = oldAttrs.patches or [ ] ++ [
|
|
||||||
# ../patches/ch.patch
|
|
||||||
];
|
|
||||||
buildType = "debug";
|
|
||||||
dontStrip = true;
|
|
||||||
});
|
|
||||||
uvmsPkgs = pkgs.callPackage ../pkgs { };
|
uvmsPkgs = pkgs.callPackage ../pkgs { };
|
||||||
|
|
||||||
chSettingsFile = (pkgs.formats.json { }).generate "vm.json" cfg.settings;
|
chSettingsFile = (pkgs.formats.json { }).generate "vm.json" cfg.settings;
|
||||||
|
|
@ -279,11 +273,20 @@ in
|
||||||
(lib.getBin pkgs.virtiofsd)
|
(lib.getBin pkgs.virtiofsd)
|
||||||
(lib.getBin pkgs.bubblewrap)
|
(lib.getBin pkgs.bubblewrap)
|
||||||
(lib.getBin pkgs.strace)
|
(lib.getBin pkgs.strace)
|
||||||
|
(lib.getBin pkgs.crosvm)
|
||||||
uvmsPkgs.taps
|
uvmsPkgs.taps
|
||||||
];
|
];
|
||||||
|
|
||||||
superviseVm = getExe superviseVm';
|
superviseVm = getExe superviseVm';
|
||||||
superviseVm' = pkgs.writers.writePython3Bin "supervise-vm" { } ''
|
superviseVm' = pkgs.writers.writePython3Bin "supervise-vm" { } ''
|
||||||
|
# NOTE: This would have been bash,
|
||||||
|
# and this was execlineb previously,
|
||||||
|
# but it was just easier to reason in terms of context managers
|
||||||
|
# and try-except-finally branches for the cleanup bit,
|
||||||
|
# than in terms of traps or such.
|
||||||
|
# Treat this as bash.
|
||||||
|
# Treat this as throwaway shitcode.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import socket
|
import socket
|
||||||
|
|
@ -320,8 +323,10 @@ in
|
||||||
**{
|
**{
|
||||||
k: v
|
k: v
|
||||||
for k, v in os.environ.items()
|
for k, v in os.environ.items()
|
||||||
if k.startswith("RUST")
|
if k.startswith("RUST_")
|
||||||
or k.startswith("WAYLAND")
|
or k.startswith("WAYLAND")
|
||||||
|
or k.startswith("XDG_")
|
||||||
|
or k.startswith("DBUS_")
|
||||||
or k in [
|
or k in [
|
||||||
"TAPS_SOCK",
|
"TAPS_SOCK",
|
||||||
]
|
]
|
||||||
|
|
@ -356,6 +361,8 @@ in
|
||||||
|
|
||||||
|
|
||||||
def alive_after(proc, timeout):
|
def alive_after(proc, timeout):
|
||||||
|
if proc is None:
|
||||||
|
return False
|
||||||
if proc.returncode is not None:
|
if proc.returncode is not None:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
|
|
@ -410,6 +417,7 @@ in
|
||||||
kwargs["stdin"] = kwargs.get("stdin", subprocess.DEVNULL)
|
kwargs["stdin"] = kwargs.get("stdin", subprocess.DEVNULL)
|
||||||
kwargs["stdout"] = kwargs.get("stdout", subprocess.DEVNULL)
|
kwargs["stdout"] = kwargs.get("stdout", subprocess.DEVNULL)
|
||||||
kwargs["stderr"] = kwargs.get("stderr", subprocess.DEVNULL)
|
kwargs["stderr"] = kwargs.get("stderr", subprocess.DEVNULL)
|
||||||
|
proc = None
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
args,
|
args,
|
||||||
|
|
@ -421,6 +429,7 @@ in
|
||||||
finally:
|
finally:
|
||||||
if alive_after(proc, 0.125):
|
if alive_after(proc, 0.125):
|
||||||
proc.terminate()
|
proc.terminate()
|
||||||
|
if proc is not None:
|
||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|
@ -550,7 +559,7 @@ in
|
||||||
*args,
|
*args,
|
||||||
bind=[self.prefix],
|
bind=[self.prefix],
|
||||||
# Probably just need the path to vmlinux
|
# Probably just need the path to vmlinux
|
||||||
ro_bind=("/nix/store",), # A give up
|
ro_bind=["/nix/store"], # I give up
|
||||||
unshare_net=False,
|
unshare_net=False,
|
||||||
shell=False,
|
shell=False,
|
||||||
stderr=None,
|
stderr=None,
|
||||||
|
|
@ -575,6 +584,35 @@ in
|
||||||
if os.path.exists(p):
|
if os.path.exists(p):
|
||||||
os.remove(p)
|
os.remove(p)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def start_gpu(
|
||||||
|
self,
|
||||||
|
):
|
||||||
|
sock_path = self.prefix + "/gpu.sock"
|
||||||
|
args = [
|
||||||
|
SOCKETBINDER_PATH,
|
||||||
|
"-b", "1",
|
||||||
|
sock_path,
|
||||||
|
"s6-ipcserverd",
|
||||||
|
"-1c1",
|
||||||
|
# "${lib.getExe pkgs.strace}", # noqa: E501
|
||||||
|
# "-Z",
|
||||||
|
# "-ff",
|
||||||
|
"${lib.getExe pkgs.crosvm}", # noqa: E501
|
||||||
|
"--no-syslog",
|
||||||
|
"device", "gpu",
|
||||||
|
"--fd", "0",
|
||||||
|
"--wayland-sock",
|
||||||
|
f'{PASSTHRU_ENV["XDG_RUNTIME_DIR"]}/{PASSTHRU_ENV["WAYLAND_DISPLAY"]}', # noqa: E501
|
||||||
|
"--params",
|
||||||
|
"{ \"context-types\": \"cross-domain:virgl2:venus\" }",
|
||||||
|
]
|
||||||
|
with self.popen(
|
||||||
|
*args,
|
||||||
|
stderr=None,
|
||||||
|
) as proc, removing(sock_path):
|
||||||
|
yield proc, sock_path
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def start_virtiofsd(
|
def start_virtiofsd(
|
||||||
self,
|
self,
|
||||||
|
|
@ -652,11 +690,26 @@ in
|
||||||
f()
|
f()
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def removing(*paths):
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
for p in paths:
|
||||||
|
if os.path.exists(p):
|
||||||
|
os.remove(p)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args, args_next = parser.parse_known_args()
|
args, args_next = parser.parse_known_args()
|
||||||
preprocess_args(args)
|
preprocess_args(args)
|
||||||
|
|
||||||
|
send_dir = PASSTHRU_ENV["HOME"] + f"/send/{args.vm}"
|
||||||
|
|
||||||
|
os.makedirs(send_dir, exist_ok=True)
|
||||||
os.makedirs(args.prefix, exist_ok=True)
|
os.makedirs(args.prefix, exist_ok=True)
|
||||||
|
os.makedirs(args.prefix + "/pts", exist_ok=True)
|
||||||
|
|
||||||
ps = Processes(
|
ps = Processes(
|
||||||
prefix=args.prefix,
|
prefix=args.prefix,
|
||||||
vm=args.vm,
|
vm=args.vm,
|
||||||
|
|
@ -670,13 +723,14 @@ in
|
||||||
|
|
||||||
with ExitStack() as cleanup:
|
with ExitStack() as cleanup:
|
||||||
|
|
||||||
send_dir = PASSTHRU_ENV["HOME"] + f"/send/{args.vm}"
|
|
||||||
os.makedirs(send_dir, exist_ok=True)
|
|
||||||
vfsd, vfsd_path = cleanup.enter_context(
|
vfsd, vfsd_path = cleanup.enter_context(
|
||||||
ps.start_virtiofsd(
|
ps.start_virtiofsd(
|
||||||
send_dir,
|
send_dir,
|
||||||
tag="send",
|
tag="send",
|
||||||
))
|
))
|
||||||
|
gpud, gpud_path = cleanup.enter_context(
|
||||||
|
ps.start_gpu()
|
||||||
|
)
|
||||||
|
|
||||||
ch = cleanup.enter_context(ps.run_ch())
|
ch = cleanup.enter_context(ps.run_ch())
|
||||||
ps.exec(*ch_remote, "create", args.vm_config)
|
ps.exec(*ch_remote, "create", args.vm_config)
|
||||||
|
|
@ -686,6 +740,7 @@ in
|
||||||
"id=wan,fd=3,mac=00:00:00:00:00:01")
|
"id=wan,fd=3,mac=00:00:00:00:00:01")
|
||||||
|
|
||||||
ps.exec(*ch_remote, "add-fs", f"tag=send,socket={vfsd_path},id=send")
|
ps.exec(*ch_remote, "add-fs", f"tag=send,socket={vfsd_path},id=send")
|
||||||
|
ps.exec(*ch_remote, "add-gpu", f"socket={gpud_path}")
|
||||||
ps.exec(*ch_remote, "boot")
|
ps.exec(*ch_remote, "boot")
|
||||||
ps.exec(*ch_remote, "info")
|
ps.exec(*ch_remote, "info")
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -212,9 +212,9 @@ in
|
||||||
''} %i";
|
''} %i";
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.initrd.systemd.settings.Manager.DefaultTimeoutStartSec = 30;
|
boot.initrd.systemd.settings.Manager.DefaultTimeoutStartSec = lib.mkDefault 30;
|
||||||
systemd.settings.Manager.DefaultTimeoutStopSec = 10;
|
systemd.settings.Manager.DefaultTimeoutStopSec = lib.mkDefault 10;
|
||||||
systemd.services."user@".serviceConfig.TimeoutStopSec = 10;
|
systemd.services."user@".serviceConfig.TimeoutStopSec = lib.mkDefault 10;
|
||||||
|
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ mkShell.override { stdenv = stdenvNoCC; } {
|
||||||
];
|
];
|
||||||
packages =
|
packages =
|
||||||
map lib.getBin [
|
map lib.getBin [
|
||||||
cloud-hypervisor
|
uvmPkgs.cloud-hypervisor-gpu
|
||||||
virtiofsd
|
virtiofsd
|
||||||
crosvm # virtio-gpu
|
crosvm # virtio-gpu
|
||||||
npins
|
npins
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue