virt-manager on niri/Noctalia failed with 'authentication unavailable: no polkit agent available to authenticate action org.libvirt.unix.manage' - bare compositors ship no polkit agent, unlike GNOME/KDE. Two fixes: - install_session_prereqs installs polkit-gnome and wires its agent .desktop into /etc/xdg/autostart (paths overridable for testing). - niri module optionally installs the qemu/libvirt stack, enables libvirtd, and adds the user to the libvirt group: members manage qemu:///system with no polkit prompt at all (the real fix; applies after re-login).
106 lines
3.8 KiB
Bash
106 lines
3.8 KiB
Bash
# shellcheck shell=bash
|
|
#------------------------------------------
|
|
# lib/session.sh — display manager and graphical session wiring
|
|
#
|
|
# DM policy:
|
|
# * A DE module leaves its native DM alone (GNOME→gdm, Plasma→sddm, XFCE→sddm).
|
|
# * A TWM module enforces SDDM, because SDDM is the only DM that presents both
|
|
# Wayland compositors and X11 sessions in one menu. One greeter, no surprises.
|
|
#------------------------------------------
|
|
|
|
if [[ -n "${_SB_SESSION_LOADED:-}" ]]; then
|
|
return 0
|
|
fi
|
|
_SB_SESSION_LOADED=1
|
|
|
|
# Name of the active display manager ("sddm", "gdm", "lightdm"), or "" if none.
|
|
detect_display_manager() {
|
|
local link=/etc/systemd/system/display-manager.service
|
|
if [[ -L "$link" ]]; then
|
|
basename "$(readlink "$link")" | sed 's/\.service$//'
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
enable_graphical_target() {
|
|
sudo systemctl set-default graphical.target
|
|
}
|
|
|
|
# Make $1 the display manager, disabling whatever is active now.
|
|
switch_display_manager() {
|
|
local target="$1"
|
|
local current
|
|
current=$(detect_display_manager)
|
|
|
|
if [[ "$current" == "$target" ]]; then
|
|
ok "Display manager already $target."
|
|
else
|
|
if [[ -n "$current" ]]; then
|
|
info "Disabling current display manager: $current"
|
|
# disable may fail if the unit vanished; that is not fatal
|
|
sudo systemctl disable "$current" 2>/dev/null || true
|
|
fi
|
|
info "Enabling display manager: $target"
|
|
sudo systemctl enable "$target"
|
|
fi
|
|
|
|
enable_graphical_target
|
|
}
|
|
|
|
# Register a Wayland session so the DM can list it.
|
|
# $1 = identifier, $2 = display name, $3 = command
|
|
write_wayland_session() {
|
|
local id="$1" name="$2" exec_cmd="$3"
|
|
local file="/usr/share/wayland-sessions/${id}.desktop"
|
|
if [[ -f "$file" ]]; then
|
|
ok "Wayland session already registered: $id"
|
|
return 0
|
|
fi
|
|
info "Registering Wayland session: $id"
|
|
sudo mkdir -p "$(dirname "$file")"
|
|
printf '[Desktop Entry]\nName=%s\nComment=%s\nExec=%s\nType=Application\nDesktopNames=%s\n' \
|
|
"$name" "$name session" "$exec_cmd" "$id" | sudo tee "$file" >/dev/null
|
|
sudo chmod 644 "$file"
|
|
}
|
|
|
|
# Register an X11 session so the DM can list it.
|
|
write_x11_session() {
|
|
local id="$1" name="$2" exec_cmd="$3"
|
|
local file="/usr/share/xsessions/${id}.desktop"
|
|
if [[ -f "$file" ]]; then
|
|
ok "X11 session already registered: $id"
|
|
return 0
|
|
fi
|
|
info "Registering X11 session: $id"
|
|
# A bare Fedora has no X session yet, so the directory may not exist.
|
|
sudo mkdir -p "$(dirname "$file")"
|
|
printf '[Desktop Entry]\nName=%s\nComment=%s\nExec=%s\nType=Application\n' \
|
|
"$name" "$name session" "$exec_cmd" | sudo tee "$file" >/dev/null
|
|
sudo chmod 644 "$file"
|
|
}
|
|
|
|
# Common login-time plumbing every Wayland compositor wants on a bare install.
|
|
install_session_prereqs() {
|
|
install_packages \
|
|
xdg-desktop-portal \
|
|
polkit \
|
|
polkit-gnome \
|
|
pipewire \
|
|
pipewire-pulseaudio \
|
|
wireplumber
|
|
|
|
# A bare compositor (niri, MangoWC, Hyprland) has NO polkit agent: without
|
|
# one, anything needing privilege elevation (virt-manager's libvirt access,
|
|
# disks, network settings) fails with "no polkit agent available to
|
|
# authenticate". Autostart it for every graphical session via the XDG
|
|
# autostart dir the session runs.
|
|
local autostart="${XDG_AUTOSTART_DIR:-/etc/xdg/autostart}"
|
|
local desktop_src="${POLKIT_AGENT_DESKTOP:-/usr/share/applications/polkit-gnome-authentication-agent-1.desktop}"
|
|
if [[ -f "$desktop_src" ]] && [[ ! -e "$autostart/$(basename "$desktop_src")" ]]; then
|
|
info "Enabling polkit agent for compositor sessions..."
|
|
sudo mkdir -p "$autostart"
|
|
sudo ln -sf "$desktop_src" "$autostart/$(basename "$desktop_src")"
|
|
fi
|
|
}
|