diff --git a/lib/session.sh b/lib/session.sh index 72d6e60..421b2d2 100644 --- a/lib/session.sh +++ b/lib/session.sh @@ -82,10 +82,58 @@ write_x11_session() { # Common login-time plumbing every Wayland compositor wants on a bare install. install_session_prereqs() { + # polkit-kde ships the agent (polkit-gnome is orphaned, EPEL-only). + # BUT Fedora's autostart .desktop carries X-systemd-skip=true (and a + # OnlyShowIn on some versions): niri starts apps via systemd's + # xdg-desktop-autostart.target, which honors those flags -> agent never + # starts in a niri session (VM-proven twice). Fighting .desktop semantics + # is fragile, so we ship our own user unit bound to + # graphical-session.target, which niri/Hyprland/MangoWC all bring up. install_packages \ xdg-desktop-portal \ polkit \ + polkit-kde \ pipewire \ pipewire-pulseaudio \ wireplumber + + local unit_dir="/etc/systemd/user" + if [[ ! -f "$unit_dir/polkit-agent.service" ]]; then + info "Installing polkit-agent user unit (compositor-safe)..." + sudo mkdir -p "$unit_dir" + sudo tee "$unit_dir/polkit-agent.service" >/dev/null <<'UNIT' +[Unit] +Description=PolicyKit Authentication Agent (for bare compositors) +PartOf=graphical-session.target + +[Service] +# polkit-kde's binary on Fedora (kf6 path). Restart in case the agent dies +# before the session settles. +ExecStart=/usr/libexec/kf6/polkit-kde-authentication-agent-1 +Restart=on-failure +RestartSec=2 + +[Install] +WantedBy=graphical-session.target +UNIT + fi + + # Enable per-user: preset-all would also do, but be explicit. This is a + # global unit dir; each user links it at first login via the preset. + if [[ ! -f /etc/systemd/user/graphical-session.target.wants/polkit-agent.service ]]; then + sudo mkdir -p /etc/systemd/user/graphical-session.target.wants + sudo ln -sf ../polkit-agent.service \ + /etc/systemd/user/graphical-session.target.wants/polkit-agent.service + fi + + # libvirt group: members manage qemu:///system without a polkit prompt. + # Without this, virt-manager dies on "access denied by policy" even with + # a working agent (VM-proven). Idempotent; applies after re-login. + if pkg_installed libvirt; then + local real_user="${SUDO_USER:-$USER}" + if ! id -nG "$real_user" 2>/dev/null | grep -qw libvirt; then + info "Adding $real_user to the libvirt group (re-login to apply)..." + sudo usermod -aG libvirt "$real_user" + fi + fi } diff --git a/setup.sh b/setup.sh index 4a99070..8437f72 100755 --- a/setup.sh +++ b/setup.sh @@ -533,6 +533,21 @@ run_advanced_menu() { install_category_pkgs() { local cat="$1"; shift case "$cat" in + Virtualisation) + # qemu:///system without password prompts: libvirt group + enabled + # daemon. Only when the picked packages actually use libvirt. + local wants_libvirt=false item + for item in "$@"; do + [[ "$item" == *libvirt* || "$item" == *virt-manager* || "$item" == *virt-install* ]] && wants_libvirt=true + done + if $wants_libvirt; then + local real_user="${SUDO_USER:-$USER}" + info "Enabling libvirtd and adding $real_user to the libvirt group..." + sudo systemctl enable --now libvirtd 2>/dev/null || true + sudo usermod -aG libvirt "$real_user" || true + warn "libvirt group membership applies after re-login." + fi + ;; Browsers) local needs_chrome=false needs_brave=false item for item in "$@"; do