[BREAKING] Provide runtime environment systemd services from munix
These services evolve as munix evolves, so they should not be part of the system closures themselves. Mount them into /run/systemd instead. (Yes, making /run/systemd/system a symlink to RO files is unfortunate, that could be changed in the future. FS prep code is annoying too..)
This commit is contained in:
parent
604ebc1356
commit
38a96b79b3
18 changed files with 125 additions and 112 deletions
|
|
@ -10,6 +10,7 @@
|
|||
libkrun,
|
||||
muvm,
|
||||
sidebus-broker,
|
||||
wl-cross-domain-proxy,
|
||||
pkgs,
|
||||
}:
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ mkShell {
|
|||
passt
|
||||
bubblewrap
|
||||
sidebus-broker
|
||||
wl-cross-domain-proxy
|
||||
]
|
||||
++ (with pkgs; [
|
||||
meson
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
munix = pkgs.callPackage ./packages/munix {
|
||||
mesa = self'.packages.mesa;
|
||||
muvm = self'.packages.muvm;
|
||||
wl-cross-domain-proxy = self'.packages.wl-cross-domain-proxy;
|
||||
sidebus-broker = sidebus.packages.${system}.sidebus-broker;
|
||||
};
|
||||
|
||||
|
|
@ -130,6 +131,7 @@
|
|||
devShells.default = pkgs.callPackage ./devShells {
|
||||
libkrun = self'.packages.libkrun;
|
||||
muvm = self'.packages.muvm;
|
||||
wl-cross-domain-proxy = self'.packages.wl-cross-domain-proxy;
|
||||
sidebus-broker = sidebus.packages.${system}.sidebus-broker;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ fn main() -> Result<(), std::io::Error> {
|
|||
std::fs::write("/run/localtime", &localtime)?;
|
||||
std::fs::write("/run/resolv.conf", &resolv_conf)?;
|
||||
std::fs::write("/run/machine-id", &gen_machine_id())?;
|
||||
std::fs::create_dir("/run/systemd")?;
|
||||
std::os::unix::fs::symlink("/opt/systemd", "/run/systemd/system")?;
|
||||
std::os::unix::fs::symlink(&closure, "/run/current-system")?;
|
||||
if let Ok(tmp_graphics) =
|
||||
std::fs::read(format!("{closure}/etc/tmpfiles.d/graphics-driver.conf"))
|
||||
|
|
|
|||
10
munix
10
munix
|
|
@ -2,8 +2,10 @@
|
|||
SCRIPT_PATH=$(dirname $(realpath -s $0))
|
||||
MUVM_PATH=$(dirname $(which muvm))
|
||||
PASST_PATH=$(dirname $(which passt))
|
||||
WL_PROXY_PATH=$(dirname $(which wl-cross-domain-proxy))
|
||||
HOST_OPENGL_DRIVER=/run/opengl-driver
|
||||
: "${MICROVM_DEFAULT_COMMAND:=bash}"
|
||||
: "${MUNIX_SYSTEMD_UNITS:="${SCRIPT_PATH}/systemd"}"
|
||||
MICROVM_CLOSURE=
|
||||
MICROVM_COMMAND=()
|
||||
MICROVM_UID=1337
|
||||
|
|
@ -41,6 +43,7 @@ while [ "$#" -gt 0 ]; do
|
|||
--munix-bin-dir) SCRIPT_PATH="$2"; shift 2;;
|
||||
--muvm-bin-dir) MUVM_PATH="$2"; shift 2;;
|
||||
--passt-bin-dir) PASST_PATH="$2"; shift 2;;
|
||||
--wl-proxy-bin-dir) WL_PROXY_PATH="$2"; shift 2;;
|
||||
--) shift 1; MICROVM_COMMAND+=("$@"); break;;
|
||||
-*) echo "munix: unknown option: $1" >&2; exit 1;;
|
||||
*)
|
||||
|
|
@ -68,6 +71,11 @@ if [ "$PASST_PATH" = "" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$WL_PROXY_PATH" = "" ]; then
|
||||
echo "munix: wl-cross-domain-proxy not found, provide a --wl-proxy-bin-dir or fix \$PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$HOST_OPENGL_DRIVER" ]; then
|
||||
echo "munix: host graphics driver not found, provide a --host-opengl-driver" >&2
|
||||
exit 1
|
||||
|
|
@ -227,10 +235,12 @@ bwrap --unshare-all --share-net \
|
|||
--ro-bind "$MUVM_PATH" /run/munix/muvm \
|
||||
--ro-bind "$PASST_PATH" /run/munix/passt \
|
||||
--ro-bind "$SCRIPT_PATH/micro-activate" /opt/bin/micro-activate \
|
||||
--ro-bind "$WL_PROXY_PATH/wl-cross-domain-proxy" /opt/bin/wl-cross-domain-proxy \
|
||||
--ro-bind "$MUVM_PATH/muvm-guest" /opt/bin/muvm-remote \
|
||||
--ro-bind "$MUVM_PATH/muvm-guest" /opt/bin/muvm-configure-network \
|
||||
--ro-bind "$MUVM_PATH/muvm-guest" /opt/bin/muvm-pwbridge \
|
||||
--ro-bind "$MUVM_PATH/muvm-guest" /opt/bin/muvm-dbusbridge \
|
||||
--ro-bind "$MUNIX_SYSTEMD_UNITS" /opt/systemd \
|
||||
--symlink "$MICROVM_CLOSURE/etc" /etc \
|
||||
--symlink "$MICROVM_CLOSURE/sw/bin/sh" /bin/sh \
|
||||
--symlink "$MICROVM_CLOSURE/sw/bin/env" /usr/bin/env \
|
||||
|
|
|
|||
|
|
@ -9,12 +9,6 @@
|
|||
...
|
||||
}:
|
||||
let
|
||||
useTTY = {
|
||||
TTYPath = "/dev/hvc0";
|
||||
StandardOutput = "tty";
|
||||
StandardInput = "tty";
|
||||
StandardError = "tty";
|
||||
};
|
||||
runtimeDir = "/run/vm-user";
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
in
|
||||
|
|
@ -171,95 +165,6 @@ in
|
|||
|
||||
systemd.settings.Manager.DefaultEnvironment = "XDG_RUNTIME_DIR=${runtimeDir}";
|
||||
|
||||
systemd.services.muvm-remote = {
|
||||
enable = true;
|
||||
description = "microVM Application runner";
|
||||
onFailure = [ "exit.target" ];
|
||||
onSuccess = [ "exit.target" ];
|
||||
wants = [ "sockets.target" ];
|
||||
after = [ "sockets.target" ];
|
||||
wantedBy = [ "microvm.target" ];
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
PassEnvironment = [
|
||||
"MESA_LOADER_DRIVER_OVERRIDE"
|
||||
"MUVM_REMOTE_CONFIG"
|
||||
# "KRUN_CONFIG"
|
||||
|
||||
"TERM"
|
||||
"XDG_SESSION_TYPE"
|
||||
"SDL_VIDEODRIVER"
|
||||
"QT_QPA_PLATFORM"
|
||||
"_JAVA_AWT_WM_NONREPARENTING"
|
||||
"ELECTRON_OZONE_PLATFORM_HINT"
|
||||
"GTK_USE_PORTAL"
|
||||
"QT_QPA_PLATFORMTHEME"
|
||||
];
|
||||
Environment = [
|
||||
"WAYLAND_DISPLAY=wayland-1"
|
||||
"DBUS_SESSION_BUS_ADDRESS=unix:path=${runtimeDir}/dbus.sock"
|
||||
"PATH=/run/current-system/sw/bin"
|
||||
];
|
||||
User = "appvm";
|
||||
Group = "appvm";
|
||||
ExecStartPre = "+/run/current-system/sw/bin/chown appvm:appvm ${runtimeDir}";
|
||||
ExecStart = "/opt/bin/muvm-remote";
|
||||
ExecStopPost = ''+${pkgs.python3}/bin/python -c "import os,fcntl,struct;print(os.getenv('EXIT_STATUS', '1'));fcntl.ioctl(os.open('/', os.O_RDONLY), 0x7602, int(os.getenv('EXIT_STATUS', '1')))"'';
|
||||
}
|
||||
// useTTY;
|
||||
};
|
||||
|
||||
systemd.services.muvm-configure-network = {
|
||||
enable = true;
|
||||
description = "microVM Network configuration";
|
||||
wantedBy = [ "microvm.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.ExecStart = "/opt/bin/muvm-configure-network";
|
||||
};
|
||||
|
||||
systemd.sockets.muvm-pwbridge = {
|
||||
enable = true;
|
||||
description = "PipeWire cross-domain proxy socket";
|
||||
wantedBy = [ "microvm.target" ];
|
||||
partOf = [ "muvm-pwbridge.service" ];
|
||||
listenStreams = [ "${runtimeDir}/pipewire-0" ];
|
||||
socketConfig = {
|
||||
SocketUser = "appvm";
|
||||
SocketGroup = "appvm";
|
||||
};
|
||||
};
|
||||
systemd.services.muvm-pwbridge = {
|
||||
enable = true;
|
||||
description = "PipeWire cross-domain proxy";
|
||||
requires = [ "muvm-pwbridge.socket" ];
|
||||
serviceConfig.Type = "exec";
|
||||
serviceConfig.ExecStart = "/opt/bin/muvm-pwbridge";
|
||||
};
|
||||
|
||||
systemd.sockets.wayland-proxy = {
|
||||
enable = true;
|
||||
description = "Wayland cross-domain proxy socket";
|
||||
wantedBy = [ "microvm.target" ];
|
||||
partOf = [ "wayland-proxy.service" ];
|
||||
listenStreams = [ "${runtimeDir}/wayland-1" ];
|
||||
socketConfig = {
|
||||
SocketUser = "appvm";
|
||||
SocketGroup = "appvm";
|
||||
FileDescriptorName = "wayland";
|
||||
};
|
||||
};
|
||||
systemd.services.wayland-proxy = {
|
||||
enable = true;
|
||||
description = "Wayland cross-domain proxy";
|
||||
requires = [ "wayland-proxy.socket" ];
|
||||
serviceConfig = {
|
||||
ExecStartPre = "+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128";
|
||||
ExecStart = "${self.packages.${system}.wl-cross-domain-proxy}/bin/wl-cross-domain-proxy --listen-fd --filter-global wp_presentation";
|
||||
User = "appvm";
|
||||
Group = "appvm";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.sockets.session-bus = {
|
||||
enable = true;
|
||||
description = "D-Bus session bus socket";
|
||||
|
|
@ -281,20 +186,6 @@ in
|
|||
Group = "appvm";
|
||||
};
|
||||
};
|
||||
systemd.services.session-bus-bridge = {
|
||||
enable = true;
|
||||
description = "D-Bus session bus";
|
||||
wantedBy = ["microvm.target"];
|
||||
requires = ["session-bus.socket" "session-bus.service"];
|
||||
after = ["session-bus.service"];
|
||||
serviceConfig = {
|
||||
Environment = ["DBUS_SESSION_BUS_ADDRESS=unix:path=${runtimeDir}/dbus.sock"];
|
||||
ExecStartPre = "+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128";
|
||||
ExecStart = "/opt/bin/muvm-dbusbridge";
|
||||
User = "appvm";
|
||||
Group = "appvm";
|
||||
};
|
||||
};
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
hardware.graphics.package = self.packages.${system}.mesa;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
{ stdenv, writeScriptBin, symlinkJoin, makeWrapper, muvm, passt, bubblewrap, sidebus-broker, mesa, rustc }:
|
||||
{ stdenv, writeScriptBin, symlinkJoin, makeWrapper, muvm, passt, bubblewrap, sidebus-broker, wl-cross-domain-proxy, mesa, rustc }:
|
||||
|
||||
let
|
||||
munixScript = (writeScriptBin "munix" (builtins.readFile ../../munix)).overrideAttrs(old: {
|
||||
buildCommand = "${old.buildCommand}\n patchShebangs $out";
|
||||
});
|
||||
munixSystemd = stdenv.mkDerivation {
|
||||
name = "munix-systemd";
|
||||
src = ../../systemd;
|
||||
dontUnpack = true;
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -aR $src/* $out
|
||||
'';
|
||||
};
|
||||
microActivate = stdenv.mkDerivation {
|
||||
name = "micro-activate";
|
||||
src = ../../micro-activate.rs;
|
||||
|
|
@ -19,9 +28,9 @@ let
|
|||
};
|
||||
in symlinkJoin {
|
||||
name = "munix";
|
||||
paths = [ munixScript microActivate muvm passt bubblewrap sidebus-broker ];
|
||||
paths = [ munixScript microActivate muvm passt bubblewrap sidebus-broker wl-cross-domain-proxy ];
|
||||
buildInputs = [ makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/munix --prefix PATH : $out/bin --set FALLBACK_OPENGL_DRIVER ${mesa}
|
||||
wrapProgram $out/bin/munix --prefix PATH : $out/bin --set FALLBACK_OPENGL_DRIVER ${mesa} --set MUNIX_SYSTEMD_UNITS ${munixSystemd}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
../muvm-configure-network.service
|
||||
1
systemd/microvm.target.wants/muvm-remote.service
Normal file
1
systemd/microvm.target.wants/muvm-remote.service
Normal file
|
|
@ -0,0 +1 @@
|
|||
../muvm-remote.service
|
||||
1
systemd/microvm.target.wants/pipewire-bridge.socket
Normal file
1
systemd/microvm.target.wants/pipewire-bridge.socket
Normal file
|
|
@ -0,0 +1 @@
|
|||
../pipewire-bridge.socket
|
||||
1
systemd/microvm.target.wants/session-bus-bridge.service
Normal file
1
systemd/microvm.target.wants/session-bus-bridge.service
Normal file
|
|
@ -0,0 +1 @@
|
|||
../session-bus-bridge.service
|
||||
1
systemd/microvm.target.wants/wayland-bridge.socket
Normal file
1
systemd/microvm.target.wants/wayland-bridge.socket
Normal file
|
|
@ -0,0 +1 @@
|
|||
../wayland-bridge.socket
|
||||
6
systemd/muvm-configure-network.service
Normal file
6
systemd/muvm-configure-network.service
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[Unit]
|
||||
Description=microVM Network configuration
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/bin/muvm-configure-network
|
||||
33
systemd/muvm-remote.service
Normal file
33
systemd/muvm-remote.service
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
[Unit]
|
||||
After=sockets.target
|
||||
Description=microVM Application runner
|
||||
OnFailure=exit.target
|
||||
OnSuccess=exit.target
|
||||
Wants=sockets.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
# Environment="LOCALE_ARCHIVE=/nix/store/1hilqf0v1nm2w8xj87pwpm0rgq6lvhlv-glibc-locales-2.42-47/lib/locale/locale-archive"
|
||||
# Environment="TZDIR=/nix/store/80izpiglrlqv2zb7rd7m5274k2dr142l-tzdata-2025c/share/zoneinfo"
|
||||
Environment=WAYLAND_DISPLAY=wayland-1
|
||||
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/vm-user/dbus.sock
|
||||
Environment=PATH=/run/current-system/sw/bin
|
||||
PassEnvironment=MESA_LOADER_DRIVER_OVERRIDE
|
||||
PassEnvironment=MUVM_REMOTE_CONFIG
|
||||
PassEnvironment=TERM
|
||||
PassEnvironment=XDG_SESSION_TYPE
|
||||
PassEnvironment=SDL_VIDEODRIVER
|
||||
PassEnvironment=QT_QPA_PLATFORM
|
||||
PassEnvironment=_JAVA_AWT_WM_NONREPARENTING
|
||||
PassEnvironment=ELECTRON_OZONE_PLATFORM_HINT
|
||||
PassEnvironment=GTK_USE_PORTAL
|
||||
PassEnvironment=QT_QPA_PLATFORMTHEME
|
||||
ExecStartPre=+/run/current-system/sw/bin/chown appvm:appvm /run/vm-user
|
||||
ExecStart=/opt/bin/muvm-remote
|
||||
ExecStopPost=+/nix/store/ygzfhw5nxrn7qqfqmz2s9p6cikcjqqkh-python3-3.13.11/bin/python -c "import os,fcntl,struct;print(os.getenv('EXIT_STATUS', '1'));fcntl.ioctl(os.open('/', os.O_RDONLY), 0x7602, int(os.getenv('EXIT_STATUS', '1')))"
|
||||
User=appvm
|
||||
Group=appvm
|
||||
StandardError=tty
|
||||
StandardInput=tty
|
||||
StandardOutput=tty
|
||||
TTYPath=/dev/hvc0
|
||||
12
systemd/pipewire-bridge.service
Normal file
12
systemd/pipewire-bridge.service
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=PipeWire VM bridge
|
||||
Requires=pipewire-bridge.socket
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStart=/opt/bin/muvm-pwbridge
|
||||
|
||||
# Environment=RUST_LOG=debug
|
||||
# StandardError=tty
|
||||
# StandardOutput=tty
|
||||
# TTYPath=/dev/hvc0
|
||||
8
systemd/pipewire-bridge.socket
Normal file
8
systemd/pipewire-bridge.socket
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[Unit]
|
||||
Description=PipeWire VM bridge socket
|
||||
PartOf=pipewire-bridge.service
|
||||
|
||||
[Socket]
|
||||
SocketGroup=appvm
|
||||
SocketUser=appvm
|
||||
ListenStream=/run/vm-user/pipewire-0
|
||||
11
systemd/session-bus-bridge.service
Normal file
11
systemd/session-bus-bridge.service
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[Unit]
|
||||
After=session-bus.service
|
||||
Description=D-Bus VM integration bridge
|
||||
Requires=session-bus.socket session-bus.service
|
||||
|
||||
[Service]
|
||||
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/vm-user/dbus.sock
|
||||
ExecStartPre=+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128
|
||||
ExecStart=/opt/bin/muvm-dbusbridge
|
||||
Group=appvm
|
||||
User=appvm
|
||||
13
systemd/wayland-bridge.service
Normal file
13
systemd/wayland-bridge.service
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=Wayland VM bridge
|
||||
Requires=wayland-bridge.socket
|
||||
|
||||
[Service]
|
||||
ExecStartPre=+/run/current-system/sw/bin/chmod 0666 /dev/dri/card0 /dev/dri/renderD128
|
||||
ExecStart=/opt/bin/wl-cross-domain-proxy --listen-fd --filter-global wp_presentation
|
||||
User=appvm
|
||||
Group=appvm
|
||||
|
||||
StandardError=tty
|
||||
StandardOutput=tty
|
||||
TTYPath=/dev/hvc0
|
||||
9
systemd/wayland-bridge.socket
Normal file
9
systemd/wayland-bridge.socket
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Wayland VM bridge socket
|
||||
PartOf=wayland-bridge.service
|
||||
|
||||
[Socket]
|
||||
FileDescriptorName=wayland
|
||||
SocketGroup=appvm
|
||||
SocketUser=appvm
|
||||
ListenStream=/run/vm-user/wayland-1
|
||||
Loading…
Add table
Add a link
Reference in a new issue