port service manager to s6
still a lot of cleanup to do (e.g. support dbus service types), but it boots to a usable desktop
This commit is contained in:
@@ -79,6 +79,8 @@ in
|
|||||||
"powertop"
|
"powertop"
|
||||||
"pstree"
|
"pstree"
|
||||||
"ripgrep"
|
"ripgrep"
|
||||||
|
"s6"
|
||||||
|
"s6-rc" # service manager
|
||||||
"screen"
|
"screen"
|
||||||
"smartmontools" # smartctl
|
"smartmontools" # smartctl
|
||||||
# "socat"
|
# "socat"
|
||||||
@@ -763,6 +765,9 @@ in
|
|||||||
|
|
||||||
rustc = {};
|
rustc = {};
|
||||||
|
|
||||||
|
s6 = {};
|
||||||
|
s6-rc = {};
|
||||||
|
|
||||||
sane-open-desktop.sandbox.enable = false; #< trivial script, and all our deps are sandboxed
|
sane-open-desktop.sandbox.enable = false; #< trivial script, and all our deps are sandboxed
|
||||||
sane-open-desktop.suggestedPrograms = [
|
sane-open-desktop.suggestedPrograms = [
|
||||||
"gdbus"
|
"gdbus"
|
||||||
|
@@ -16,7 +16,10 @@ let
|
|||||||
export XDG_CURRENT_DESKTOP=sway
|
export XDG_CURRENT_DESKTOP=sway
|
||||||
|
|
||||||
echo "launching sway (sway.desktop)..." | ${systemd-cat} --identifier=sway
|
echo "launching sway (sway.desktop)..." | ${systemd-cat} --identifier=sway
|
||||||
exec ${configuredSway}/bin/sway 2>&1 | ${systemd-cat} --identifier=sway
|
# delete DISPLAY-related vars from env before launch, else sway will try to connect to a remote display.
|
||||||
|
# (consider: nested sway sessions, where sway actually has a reason to read these)
|
||||||
|
exec env -u DISPLAY -u WAYLAND_DISPLAY \
|
||||||
|
${configuredSway}/bin/sway 2>&1 | ${systemd-cat} --identifier=sway
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
pkgs.symlinkJoin {
|
pkgs.symlinkJoin {
|
||||||
@@ -194,6 +197,7 @@ in
|
|||||||
# bind ALL of ~/.config/sway into the sandbox instead of just the individual configs.
|
# bind ALL of ~/.config/sway into the sandbox instead of just the individual configs.
|
||||||
# this way `swaymsg -- reload` can work even if the fd for ~/.config/sway/config changes.
|
# this way `swaymsg -- reload` can work even if the fd for ~/.config/sway/config changes.
|
||||||
".config/sway"
|
".config/sway"
|
||||||
|
".config/s6"
|
||||||
];
|
];
|
||||||
sandbox.extraConfig = [
|
sandbox.extraConfig = [
|
||||||
"--sane-sandbox-keep-namespace" "pid"
|
"--sane-sandbox-keep-namespace" "pid"
|
||||||
@@ -218,26 +222,50 @@ in
|
|||||||
xwayland = if config.sane.programs.xwayland.enabled then "enable" else "disable";
|
xwayland = if config.sane.programs.xwayland.enabled then "enable" else "disable";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.sway-session = {
|
env.XDG_CURRENT_DESKTOP = "sway";
|
||||||
description = "sway-session: active iff sway desktop environment is baseline operational";
|
# TODO: don't hardcode user id!
|
||||||
documentation = [
|
env.SWAYSOCK = "/run/user/1000/sway-ipc.sock";
|
||||||
"https://github.com/swaywm/sway/issues/7862"
|
# TODO: ensure this is reliable? might not work across sway restarts, etc.
|
||||||
"https://github.com/alebastr/sway-systemd"
|
env.DISPLAY = ":0";
|
||||||
];
|
env.WAYLAND_DISPLAY = "wayland-1";
|
||||||
|
|
||||||
# we'd like to start graphical-session after sway is ready, but it's marked `RefuseManualStart` because Lennart.
|
# services.sway-session = {
|
||||||
# instead, create `sway-session.service` which `bindsTo` `graphical-session.target`.
|
# description = "sway-session: active iff sway desktop environment is baseline operational";
|
||||||
# we can manually start `sway-session`, and the `bindsTo` means that it will start `graphical-session`,
|
# documentation = [
|
||||||
# and then track `graphical-session`s state (that is: it'll stop when graphical-session stops).
|
# "https://github.com/swaywm/sway/issues/7862"
|
||||||
#
|
# "https://github.com/alebastr/sway-systemd"
|
||||||
# additionally, set `ConditionEnvironment` to guard that the sway environment variables *really have* been imported into systemd.
|
# ];
|
||||||
unitConfig.ConditionEnvironment = "SWAYSOCK";
|
|
||||||
# requiredBy = [ "graphical-session.target" ];
|
|
||||||
before = [ "graphical-session.target" ];
|
|
||||||
bindsTo = [ "graphical-session.target" ];
|
|
||||||
|
|
||||||
|
# # we'd like to start graphical-session after sway is ready, but it's marked `RefuseManualStart` because Lennart.
|
||||||
|
# # instead, create `sway-session.service` which `bindsTo` `graphical-session.target`.
|
||||||
|
# # we can manually start `sway-session`, and the `bindsTo` means that it will start `graphical-session`,
|
||||||
|
# # and then track `graphical-session`s state (that is: it'll stop when graphical-session stops).
|
||||||
|
# #
|
||||||
|
# # additionally, set `ConditionEnvironment` to guard that the sway environment variables *really have* been imported into systemd.
|
||||||
|
# unitConfig.ConditionEnvironment = "SWAYSOCK";
|
||||||
|
# # requiredBy = [ "graphical-session.target" ];
|
||||||
|
# before = [ "graphical-session.target" ];
|
||||||
|
# bindsTo = [ "graphical-session.target" ];
|
||||||
|
|
||||||
|
# serviceConfig = {
|
||||||
|
# ExecStart = "${pkgs.coreutils}/bin/true";
|
||||||
|
# Type = "oneshot";
|
||||||
|
# RemainAfterExit = true;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
# services.sway-session = {
|
||||||
|
# description = "sway-session: meta-service for everything wanted by sway (after launch)";
|
||||||
|
# wants = [ "graphical-session.target" ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
services.sway = {
|
||||||
|
description = "sway: launch it";
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
ExecStart = "${cfg.package}/bin/sway";
|
||||||
|
# ExecStart = "${lib.getBin pkgs.glib}/bin/gio launch sway.desktop";
|
||||||
|
# ExecStart = "${pkgs.sane-open-desktop}/bin/sane-open-desktop sway.desktop";
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
};
|
};
|
||||||
|
@@ -258,6 +258,10 @@ exec --no-startup-id dbus-update-activation-environment --systemd PATH XDG_DATA_
|
|||||||
# signal to systemd that sway is active,
|
# signal to systemd that sway is active,
|
||||||
# and therefore let it start any downstream services (e.g. apps that would like to auto-start)
|
# and therefore let it start any downstream services (e.g. apps that would like to auto-start)
|
||||||
# see `systemctl --user cat sway-session` for links to docs
|
# see `systemctl --user cat sway-session` for links to docs
|
||||||
exec --no-startup-id systemctl start --user sway-session.service
|
# exec --no-startup-id systemctl start --user sway-session.service
|
||||||
|
|
||||||
|
# TODO: remove this. likely, the variables above can/should be set *before* launching the service manager at all.
|
||||||
|
# and if need be we can replace this line with a "notify ready" signal to the service manager instead.
|
||||||
|
exec --no-startup-id s6-rc -l $HOME/.config/s6/live start graphical-session
|
||||||
|
|
||||||
@extra_lines@
|
@extra_lines@
|
||||||
|
@@ -119,15 +119,28 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# lib.mkAfter so that launching the DE happens *after* any other .profile setup.
|
fs.".profile".symlink.text = lib.mkMerge [
|
||||||
# alternatively, we could recurse: exec a new login shell with some env-var signalling to not launch the DE,
|
(lib.mkBefore ''
|
||||||
# run with `-c "{cfg.afterLogin}"`
|
primarySessionCommands=()
|
||||||
fs.".profile".symlink.text = lib.mkAfter ''
|
initPrimarySession() {
|
||||||
# if already running a desktop environment, or if running from ssh, then `tty` will show /dev/pts/NN.
|
for c in "''${primarySessionCommands[@]}"; do
|
||||||
if [ "$(tty)" = "/dev/${tty}" ]; then
|
eval "$c"
|
||||||
${tryLaunchDefaultDesktop}/bin/tryLaunchDefaultDesktop
|
done
|
||||||
fi
|
}
|
||||||
'';
|
'')
|
||||||
|
# lib.mkAfter so that launching the DE happens *after* any other .profile setup.
|
||||||
|
(lib.mkAfter ''
|
||||||
|
# if already running a desktop environment, or if running from ssh, then `tty` will show /dev/pts/NN.
|
||||||
|
if [ "$(tty)" = "/dev/${tty}" ]; then
|
||||||
|
if (( ''${#primarySessionCommands[@]} )); then
|
||||||
|
echo "launching primary session commands in ${builtins.toString cfg.config.delay}s: ''${primarySessionCommands[*]}"
|
||||||
|
# if the `sleep` call here is `Ctrl+C'd`, then it'll exit false and the desktop isn't launched.
|
||||||
|
sleep ${builtins.toString cfg.config.delay} && \
|
||||||
|
initPrimarySession
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
# N.B.: this sandboxing applies to `unl0kr` itself -- the on-screen-keyboard;
|
# N.B.: this sandboxing applies to `unl0kr` itself -- the on-screen-keyboard;
|
||||||
# NOT to the wrapper which invokes `login`.
|
# NOT to the wrapper which invokes `login`.
|
||||||
|
@@ -59,19 +59,19 @@ in
|
|||||||
wantedBy = [ "graphical-session.target" ];
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart="${cfg.package}/libexec/xdg-desktop-portal";
|
# tracking issue for having xdg-desktop-portal locate portals via more standard directories, obviating this var:
|
||||||
|
# - <https://github.com/flatpak/xdg-desktop-portal/issues/603>
|
||||||
|
# i can actually almost omit it today; problem is that if you don't set it it'll look for `sway-portals.conf` in ~/.config/xdg-desktop-portal
|
||||||
|
# but then will check its *own* output dir for {gtk,wlr}.portal.
|
||||||
|
# arguable if that's a packaging bug, or limitation...
|
||||||
|
ExecStart=''env XDG_DESKTOP_PORTAL_DIR="$HOME/.config/xdg-desktop-portal" ${cfg.package}/libexec/xdg-desktop-portal'';
|
||||||
Type = "dbus";
|
Type = "dbus";
|
||||||
BusName = "org.freedesktop.portal.Desktop";
|
BusName = "org.freedesktop.portal.Desktop";
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
};
|
};
|
||||||
|
|
||||||
# tracking issue for having xdg-desktop-portal locate portals via more standard directories, obviating this var:
|
# environment.XDG_DESKTOP_PORTAL_DIR = "%E/xdg-desktop-portal";
|
||||||
# - <https://github.com/flatpak/xdg-desktop-portal/issues/603>
|
|
||||||
# i can actually almost omit it today; problem is that if you don't set it it'll look for `sway-portals.conf` in ~/.config/xdg-desktop-portal
|
|
||||||
# but then will check its *own* output dir for {gtk,wlr}.portal.
|
|
||||||
# arguable if that's a packaging bug, or limitation...
|
|
||||||
environment.XDG_DESKTOP_PORTAL_DIR = "%E/xdg-desktop-portal";
|
|
||||||
|
|
||||||
# environment.G_MESSAGES_DEBUG = "all"; #< also applies to all apps launched by the portal
|
# environment.G_MESSAGES_DEBUG = "all"; #< also applies to all apps launched by the portal
|
||||||
};
|
};
|
||||||
|
@@ -103,7 +103,7 @@ let
|
|||||||
inherit name;
|
inherit name;
|
||||||
run = service.serviceConfig.ExecStart;
|
run = service.serviceConfig.ExecStart;
|
||||||
depends = service.wants ++ builtins.attrNames (
|
depends = service.wants ++ builtins.attrNames (
|
||||||
lib.filterAttrs (_: cfg: lib.elem name cfg.wantedBy) services
|
lib.filterAttrs (_: cfg: lib.elem name cfg.wantedBy || lib.elem "${name}.service" cfg.wantedBy) services
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
services
|
services
|
||||||
@@ -131,7 +131,46 @@ in
|
|||||||
sources = genServices (s6SvcsFromConfigServices (implicitServices // config.services));
|
sources = genServices (s6SvcsFromConfigServices (implicitServices // config.services));
|
||||||
in {
|
in {
|
||||||
fs.".config/s6/sources".symlink.target = sources;
|
fs.".config/s6/sources".symlink.target = sources;
|
||||||
fs.".config/s6/compiled".symlink.target = compileServices sources;
|
# N.B.: `compiled` needs to be writable (for locks -- maybe i can use symlinks to dodge this someday),
|
||||||
|
# so write this nearby and copy it over to `compiled` later
|
||||||
|
fs.".config/s6/compiled-static".symlink.target = compileServices sources;
|
||||||
|
|
||||||
|
fs.".profile".symlink.text = ''
|
||||||
|
function startS6() {
|
||||||
|
local S6_TARGET="''${1:-default}"
|
||||||
|
|
||||||
|
local COMPILED=$HOME/.config/s6/compiled
|
||||||
|
local LIVE=$HOME/.config/s6/live
|
||||||
|
local SCANDIR=$HOME/.config/s6/scandir
|
||||||
|
|
||||||
|
rm -rf $SCANDIR
|
||||||
|
mkdir $SCANDIR
|
||||||
|
s6-svscan $SCANDIR &
|
||||||
|
local SVSCAN=$!
|
||||||
|
|
||||||
|
# the scandir is just links back into the compiled dir,
|
||||||
|
# so the compiled dir therefore needs to be writable:
|
||||||
|
rm -rf $COMPILED
|
||||||
|
cp --dereference -R $COMPILED-static $COMPILED
|
||||||
|
chmod -R 0700 $COMPILED
|
||||||
|
|
||||||
|
s6-rc-init -c $COMPILED -l $LIVE -d $SCANDIR
|
||||||
|
|
||||||
|
# echo default: deps
|
||||||
|
# s6-rc-db -c $COMPILED contents default
|
||||||
|
# echo graphical-session: deps
|
||||||
|
# s6-rc-db -c $COMPILED contents graphical-session
|
||||||
|
|
||||||
|
if [ -n "$S6_TARGET" ]; then
|
||||||
|
s6-rc -l $LIVE start "$S6_TARGET"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "s6 initialized: Ctrl+C to stop"
|
||||||
|
wait $SVSCAN
|
||||||
|
}
|
||||||
|
|
||||||
|
primarySessionCommands+=('startS6 &')
|
||||||
|
'';
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user