Refactor SteamOS session management and launcher scripts

- Removed obsolete launch_desktop.sh and launch_session.sh scripts.
- Introduced new steam-launcher script to handle Steam launching and session tracking.
- Added steam-short-session-tracker for monitoring short Steam sessions and triggering repairs.
- Created steamos and steamos-session scripts for managing the SteamOS session.
- Implemented steamos-session-select for switching between Gamescope and Plasma sessions.
- Updated SDDM configuration for autologin and session management.
- Added new systemd services and targets for managing Gamescope and Steam sessions.
- Created desktop entries and icons for ALVR and SteamOS shortcuts.
- Enhanced logging and error handling across scripts.
- Cleaned up unused systemd slice and service files.
- Updated Ansible playbook to reflect new configurations and file structures.
This commit is contained in:
2025-12-01 17:25:18 +01:00
parent edbe8fbf6f
commit b4f4fe2f07
33 changed files with 518 additions and 345 deletions
@@ -0,0 +1,149 @@
#!/bin/bash
set -euo pipefail
LOG_FILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOG_FILE"; }
CONF_FILE="$HOME/.config/gamescope/gamescope.conf"
[ -f "$CONF_FILE" ] && source "$CONF_FILE"
FRAMERATE=${FRAMERATE:-60}
RESOLUTION=${RESOLUTION:-1920x1080}
WIDTH="${RESOLUTION%x*}"
HEIGHT="${RESOLUTION#*x}"
export __GL_GSYNC_ALLOWED=1
export __GL_VRR_ALLOWED=1
export __GL_SHADER_DISK_CACHE=1
export __GL_SYNC_TO_VBLANK=0
export LIBVA_DRIVER_NAME=nvidia
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export NVD_BACKEND=direct
# export __GL_THREADED_OPTIMIZATIONS=1
GAMESCOPE_BIN="$(command -v gamescope || true)"
if [ -z "$GAMESCOPE_BIN" ]; then
log "ERROR: gamescope not found in PATH"
exit 127
fi
HDR_FLAG=""
if [[ "$HDR_ENABLED" == "1" || "$HDR_ENABLED" == "true" || "$HDR_ENABLED" == "yes" ]]; then
HDR_FLAG="--hdr-enabled"
log "HDR flag added: --hdr-enabled"
else
log "HDR disabled, no HDR flag added"
fi
# Create run directory file for startup and stats sockets
# shellcheck disable=SC2030 # (broken warning)
tmpdir="$([[ -n ${XDG_RUNTIME_DIR+x} ]] && mktemp -p "$XDG_RUNTIME_DIR" -d -t gamescope.XXXXXXX)"
socket="${tmpdir:+$tmpdir/startup.socket}"
stats="${tmpdir:+$tmpdir/stats.pipe}"
# Fail early if we don't have a proper runtime directory setup
# shellcheck disable=SC2031 # (broken warning)
if [[ -z $tmpdir || -z ${XDG_RUNTIME_DIR+x} ]]; then
echo >&2 "!! Failed to find run directory in which to create stats session sockets (is \$XDG_RUNTIME_DIR set?)"
exit 0
fi
# Chromium (and therefore Steam) ignore XCursor and use on the GTK config
kwriteconfig6 --file gtk-3.0/settings.ini --group Settings --key gtk-cursor-theme-name steam
# Workaround for Steam login issue while Steam client change propagates out of Beta
touch ~/.steam/root/config/SteamAppData.vdf || true
# Increase open file limit for gamescope session
ulimit -n 524288
# 1048576 = 1M - passing it like that omits the 'M' suffix - xargs removes whitespace
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
minimum_free_disk_space_needed_megs=500
if [[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]]; then
echo >&2 "gamescope-session: not enough disk space to proceed, trying to find game to delete"
find ~/.local/share/Steam/steamapps/common/ -mindepth 1 -maxdepth 1 -type d -printf "%T@ %p\0" | sort -n -z | while IFS= read -r -d $'\0' line; do
timestamp=${line%% *}
game_folder=${line#* }
[[ -d $game_folder ]] || continue
acf=$(grep -F -- "$(basename -- "$game_folder")" ~/.local/share/Steam/steamapps/*.acf | grep \"installdir\" | cut -d: -f1)
[[ -e "$acf" ]] || continue
echo >&2 "gamescope-session: deleting $(basename "$game_folder")"
appid=$(basename "$acf" | cut -d_ -f2 | cut -d. -f1)
# TODO leave a note for Steam to display UI to explain what happened, if this logic stays
# intentionally leave compatdata; could be unclouded save files there
rm -rf --one-file-system -- "$game_folder" "$acf" ~/.local/share/Steam/steamapps/shadercache/"$appid"
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
[[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]] || break
done
fi
export GAMESCOPE_STATS="$stats"
mkfifo -- "$stats"
mkfifo -- "$socket"
# Attempt to claim global session if we're the first one running (e.g. /run/1000/gamescope)
linkname="gamescope-stats"
# shellcheck disable=SC2031 # (broken warning)
sessionlink="${XDG_RUNTIME_DIR:+$XDG_RUNTIME_DIR/}${linkname}" # Account for XDG_RUNTIME_DIR="" (notfragileatall)
lockfile="$sessionlink".lck
exec 9>"$lockfile" # Keep as an fd such that the lock lasts as long as the session if it is taken
if flock -n 9 && rm -f "$sessionlink" && ln -sf "$tmpdir" "$sessionlink"; then
# Took the lock. Don't blow up if those commands fail, though.
echo >&2 "Claimed global gamescope stats session at \"$sessionlink\""
else
echo >&2 "!! Failed to claim global gamescope stats session"
fi
read_gamescope_env() {
log "Waiting for gamescope to provide DISPLAY and GAMESCOPE_WAYLAND_DISPLAY via socket..."
if read -r -t 3 response_x_display response_wl_display <> "$socket"; then
log "Received gamescope environment:"
log " DISPLAY=$response_x_display"
log " GAMESCOPE_WAYLAND_DISPLAY=$response_wl_display"
export DISPLAY="$response_x_display"
export GAMESCOPE_WAYLAND_DISPLAY="$response_wl_display"
# Sync environment variables to systemd, then notify we are ready to launch subsequent services
log "Storing gamescope environment for systemd..."
env > $XDG_RUNTIME_DIR/gamescope-environment
systemd-notify --ready
fi
}
# Spawned in parallel to read values from gamescope
(read_gamescope_env &)
log "Starting Gamescope session..."
# Build gamescope argument array for safe quoting and readability
GAMESCOPE_ARGS=(
--generate-drm-mode fixed
--fade-out-duration 200
--cursor-scale-height 720
-f
-W "$WIDTH" -H "$HEIGHT"
-w "$WIDTH" -h "$HEIGHT"
--rt --mangoapp -e -R "$socket" -T "$stats"
)
# Append HDR flag if enabled
if [ -n "${HDR_FLAG:-}" ]; then
GAMESCOPE_ARGS+=("$HDR_FLAG")
fi
export XDG_CURRENT_DESKTOP=gamescope
export XDG_SESSION_TYPE=wayland
export DESKTOP_SESSION=gamescope
log "Launching Gamescope: $GAMESCOPE_BIN ${GAMESCOPE_ARGS[*]} -- $*"
sudo setcap 'CAP_SYS_NICE=eip' "$GAMESCOPE_BIN"
exec "$GAMESCOPE_BIN" "${GAMESCOPE_ARGS[@]}" >>"$LOG_FILE" 2>&1
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
LOGFILE="$HOME/.local/logs/gamescope.log"
export PATH="$HOME/.local/bin:$PATH"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOGFILE"; }
# SDDM sets this to wayland but apps using Gamescope must use x11
export XDG_SESSION_TYPE=x11
# Update the enviroment with DESKTOP_SESSION and all XDG variables
log "Updating systemd user environment with XDG variables"
dbus-update-activation-environment --systemd DESKTOP_SESSION `env | grep ^XDG_ | cut -d = -f 1`
# This makes it so that xdg-desktop-portal doesn't find any portal implementations and doesn't start them and makes
# them crash/exit because the dbus env has no DISPLAY. In turn this causes dbus calls to the portal which don't rely
# on implementations to hang (such as SDL talking to the real time portal)
# Plasma resets this variable when it starts
systemctl --user set-environment XDG_DESKTOP_PORTAL_DIR=""
# Remove these as they prevent gamescope-session from starting correctly
systemctl --user unset-environment DISPLAY XAUTHORITY
# If this shell script is killed then stop gamescope-session
trap 'systemctl --user stop gamescope-session.target' HUP INT TERM
# Start gamescope-session and wait
log "Starting Gamescope Session"
systemctl --user --wait start gamescope-session.target &
wait
log "Gamescope Session Ended - Performing Final Cleanup"
# The 'wait' above blocks until gamescope-session.target stops
# We want to wait until *everything* has finished. We know systemd will have
# queued a stop job on graphical-session-pre aleady
# by also queuing up a job we can block until that completes
systemctl --user stop graphical-session-pre.target
log "Gamescope Session Ended - Cleanup Complete"
@@ -12,11 +12,7 @@ if [ -z "$DESKTOP_BIN" ]; then
fi
export XDG_CURRENT_DESKTOP=plasma
export XDG_SESSION_TYPE=wayland
export XDG_DATA_DIRS=/usr/local/share/:/usr/share/
export XDG_CONFIG_DIRS=/usr/local/etc/xdg:/etc/xdg
export XDG_CURRENT_DESKTOP=KDE
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export QT_QPA_PLATFORM=wayland
export GDK_BACKEND=wayland
@@ -1,24 +0,0 @@
#!/bin/bash
set -euo pipefail
LOGFILE="$HOME/.local/logs/desktop.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOGFILE"; }
log "Starting Desktop session..."
DESKTOP_SESSION_BIN="$(command -v startplasma-wayland || true)"
if [ -z "$DESKTOP_SESSION_BIN" ]; then
log "ERROR: startplasma-wayland not found in PATH"
exit 127
fi
log "Launching Desktop: $DESKTOP_SESSION_BIN"
exec "$DESKTOP_SESSION_BIN" >>"$LOGFILE" 2>&1 &
sleep 5
systemd-run --user --slice=sunshine.slice --scope sunshine >>"$LOGFILE" 2>&1 || {
log "ERROR: Failed to start Sunshine"
exit 1
} &
tail -f /dev/null
@@ -1,100 +0,0 @@
#!/bin/bash
set -euo pipefail
LOG_FILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOG_FILE"; }
start_gamescope() {
log "Starting Gamescope session..."
CONF_FILE="$HOME/.config/gamescope/gamescope.conf"
[ -f "$CONF_FILE" ] && source "$CONF_FILE"
FRAMERATE=${FRAMERATE:-60}
RESOLUTION=${RESOLUTION:-1920x1080}
WIDTH="${RESOLUTION%x*}"
HEIGHT="${RESOLUTION#*x}"
export __GL_GSYNC_ALLOWED=1
export __GL_VRR_ALLOWED=1
export __GL_SHADER_DISK_CACHE=1
export __GL_SYNC_TO_VBLANK=0
export LIBVA_DRIVER_NAME=nvidia
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export NVD_BACKEND=direct
# export __GL_THREADED_OPTIMIZATIONS=1
GAMESCOPE_BIN="$(command -v gamescope || true)"
if [ -z "$GAMESCOPE_BIN" ]; then
log "ERROR: gamescope not found in PATH"
exit 127
fi
HDR_FLAG=""
if [[ "$HDR_ENABLED" == "1" || "$HDR_ENABLED" == "true" || "$HDR_ENABLED" == "yes" ]]; then
HDR_FLAG="--hdr-enabled"
log "HDR flag added: --hdr-enabled"
else
log "HDR disabled, no HDR flag added"
fi
# Build gamescope argument array for safe quoting and readability
GAMESCOPE_ARGS=(
--generate-drm-mode fixed
--fade-out-duration 200
--cursor-scale-height 720
-f
-W "$WIDTH" -H "$HEIGHT"
-w "$WIDTH" -h "$HEIGHT"
--rt --mangoapp -e
-r "$FRAMERATE"
)
# Append HDR flag if enabled
if [ -n "${HDR_FLAG:-}" ]; then
GAMESCOPE_ARGS+=("$HDR_FLAG")
fi
export XDG_CURRENT_DESKTOP=gamescope
export XDG_SESSION_TYPE=wayland
export DESKTOP_SESSION=gamescope
log "Launching Gamescope: $GAMESCOPE_BIN ${GAMESCOPE_ARGS[*]} -- $*"
sudo setcap 'CAP_SYS_NICE=eip' "$GAMESCOPE_BIN"
# Execute gamescope inside a DBus session, preserving proper argument quoting
exec dbus-run-session -- "$GAMESCOPE_BIN" "${GAMESCOPE_ARGS[@]}" -- "$@" >>"$LOG_FILE" 2>&1
}
start_kwin() {
log "Starting KWin session..."
KWIN_BIN="$(command -v kwin_wayland || true)"
if [ -z "$KWIN_BIN" ]; then
log "ERROR: kwin_wayland not found in PATH"
exit 127
fi
export XDG_CURRENT_DESKTOP=plasma
export XDG_SESSION_TYPE=wayland
export DESKTOP_SESSION=plasma-wayland
# Ensure we don't run nested; width/height/fullscreen are for the windowed backend.
unset DISPLAY WAYLAND_DISPLAY
KWIN_ARGS="--drm --exit-with-session"
log "Launching KWin (DRM): $KWIN_BIN ${KWIN_ARGS} $*"
exec dbus-run-session -- "$KWIN_BIN" ${KWIN_ARGS} "$@" >>"$LOG_FILE" 2>&1
}
export XDG_SEAT=seat0
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export XDG_DATA_DIRS=/usr/local/share/:/usr/share/
export XDG_CONFIG_DIRS=/usr/local/etc/xdg:/etc/xdg
if [[ -f "$HOME/.desktop-session-plasma" ]]; then
log "Plasma session selected."
rm "$HOME/.desktop-session-plasma"
start_kwin /usr/local/bin/launch_kde.sh
else
log "Gamescope session selected."
start_gamescope /usr/local/bin/launch_steam.sh
fi
@@ -145,4 +145,4 @@ if systemctl --user is-active --quiet sunshine.scope; then
fi
log "Steam session ended."
exit "$status"
exit "$status"
@@ -0,0 +1,77 @@
#!/bin/bash
short_session_tracker_file="/tmp/steamos-short-session-tracker"
short_session_start_file="/tmp/steamos-short-session-start"
short_session_duration=60
short_session_count_before_reset=3
do_repair() {
# This should really be part of the steam launcher as `steam --repair` or similar, but we presently only have
# `steam --reset` which is too heavy of a hammer.
echo >&2 "steam-short-session-tracker: Re-bootstrapping steam from OS copy."
# at this point, might as well make sure we won't relaunch on a sideloaded build
rm -f -- "$HOME/devkit-game/devkit-steam"
mkdir -p ~/.local/share/Steam
# remove some caches and stateful things known to cause Steam to fail to start if corrupt
rm -rf --one-file-system ~/.local/share/Steam/config/widevine
# cleanup the steam config dir, i.e. ~/.steam. We should try to preserve registry.vdf if possible
steam_config_dir="$HOME/.steam"
steam_config_backup_dir="$HOME/dot-steam.bak.$(date +%s)"
registry_vdf="$steam_config_dir/registry.vdf"
registry_backup_vdf="$steam_config_backup_dir/.steam/registry.vdf"
mv "$steam_config_dir" "$steam_config_backup_dir"
mkdir -p "$steam_config_dir"
cp -f "$registry_backup_vdf" "$registry_vdf" || true
# restore clean copy of binaries from RO partition
tar xf /usr/lib/steam/bootstraplinux_ubuntu12_32.tar.xz -C ~/.local/share/Steam
# rearm
rm "$short_session_tracker_file"
}
handle_started() {
short_session_count=$(< "$short_session_tracker_file" wc -l)
touch $short_session_start_file
if [[ "$short_session_count" -ge "$short_session_count_before_reset" ]]; then
echo >&2 "steam-short-session-tracker: Steam failed to start $short_session_count_before_reset times within $short_session_duration seconds"
if [ -f "$HOME/.config/inhibit-short-session-tracker" ]; then
echo >&2 "steam-short-session-tracker: Auto-repair disabled by config. Remove ~/.config/inhibit-short-session-tracker to re-enable"
return
fi
do_repair
fi
}
handle_stopped() {
seconds_since_started=$(($(date +%s) - $(date +%s -r "$short_session_start_file")))
if [[ "seconds_since_started" -lt "$short_session_duration" ]]; then
echo "frog" >> "$short_session_tracker_file"
else
rm "$short_session_tracker_file"
fi
}
case "$1" in
--track-started)
echo "steam-short-session-tracker: Tracking Steam start (unimplemented)"
# handle_started
;;
--track-stopped)
echo "steam-short-session-tracker: Tracking Steam stop (unimplemented)"
# handle_stopped
;;
--repair-now)
echo "steam-short-session-tracker: Performing immediate repair (unimplemented)"
# do_repair
;;
*)
echo "Usage: $0 --track-started | --track-stopped | --repair-now"
exit 1
;;
esac
exit 0
@@ -0,0 +1,14 @@
#!/bin/bash
set -euo pipefail
LOG_FILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOG_FILE"; }
if [[ -f "$HOME/.desktop-session-plasma" ]]; then
log "Plasma session selected."
rm "$HOME/.desktop-session-plasma"
exec /usr/bin/startplasma-wayland
else
log "Gamescope session selected."
exec /usr/local/bin/launch-gamescope
fi
@@ -0,0 +1,26 @@
# #!/bin/bash
set -euo pipefail
LOG_FILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOG_FILE"; }
env > $XDG_RUNTIME_DIR/steamos-environment
log "Starting SteamOS Session"
while true; do
systemctl --user --wait start steamos.service
wait_status=$?
log "Graphical session service exited with status $wait_status"
if [ $wait_status -ne 0 ]; then
log "Graphical session service exited with error; ending loop."
break
fi
if [ -f "$HOME/.steamos-session-switch" ]; then
log "Graphical session service exited; switch file present -> restarting..."
rm "$HOME/.steamos-session-switch"
continue
fi
log "Graphical session service exited; switch file absent -> ending loop."
break
done
sleep 5
log "SteamOS Session Ended"
@@ -4,6 +4,11 @@ LOGFILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOGFILE"; }
die() { echo >&2 "!! $*"; exit 1; }
# File this script will modify
CONF_FILE="/etc/sddm.conf.d/zz-steamos-autologin.conf"
session="${1:-gamescope}"
case "$session" in
@@ -23,18 +28,12 @@ case "$session" in
;;
esac
if systemctl --user is-active --quiet sunshine.scope; then
log "Stopping sunshine.scope"
systemctl --user stop sunshine.scope
fi
if systemctl --user is-active --quiet steam.scope; then
log "Stopping steam.scope"
systemctl --user stop steam.scope
fi
if systemctl --user is-active --quiet plasma.scope; then
log "Stopping plasma.scope"
systemctl --user stop plasma.scope
fi
sleep 5
log "Restarting graphical session service..."
systemctl --user restart session.service
log "Signaling session switch..."
touch "$HOME/.steamos-session-switch"
# It is possible to get things remaining from the previous session if SDDM is sigkilled by root systemd
# and our units are still running in the user systemd
systemctl --user stop gamescope-session.target
systemctl --user stop plasma-workspace.target
systemctl --user reset-failed
@@ -1,4 +0,0 @@
#!/bin/bash
set -euo pipefail
systemctl --user start steamos.target
@@ -0,0 +1,7 @@
[General]
DisplayServer=wayland
[Autologin]
Relogin=true
Session=steamos.desktop
User={{ user_name }}
@@ -0,0 +1,8 @@
[Desktop Entry]
Name=ALVR
Comment=Linux Virtual Reality
Exec=/opt/alvr/bin/alvr_dashboard
Icon=alvr.png
Terminal=false
Type=Application
Categories=Game;
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

@@ -0,0 +1,8 @@
[Desktop Entry]
Name=SteamOS
Comment=Switch to SteamOS
Exec=/usr/local/bin/steamos-session-select
Icon=steamos.png
Terminal=false
Type=Application
Categories=Game;
@@ -1,3 +0,0 @@
[Slice]
CPUWeight=100
AllowedCPUs={{ general_cores }}
@@ -0,0 +1,11 @@
[Unit]
Description=mangoapp
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=exec
ExecStart=/usr/bin/mangoapp
Restart=always
EnvironmentFile=%t/gamescope-environment
TimeoutStopSec=5
@@ -0,0 +1,17 @@
[Unit]
Description=Gamescope Session
Before=graphical-session.target
PartOf=graphical-session.target
Wants=graphical-session-pre.target
After=graphical-session-pre.target
RefuseManualStart=yes
[Service]
TimeoutStartSec=5
TimeoutStopSec=10
ExecStart=gamescope-session
Type=notify
NotifyAccess=all
# Make Steam's srt-logger write to the journal with it's own prefixes
Environment=SRT_LOG_TO_JOURNAL=1
Slice=session.slice
@@ -0,0 +1,13 @@
[Unit]
Description=Gamescope Session
Requires=graphical-session.target
BindsTo=graphical-session.target
After=graphical-session.target
Requires=gamescope-session.service
BindsTo=gamescope-session.service
Upholds=steam-launcher.service
Wants=ibus-gamescope.service
Wants=gamescope-mangoapp.service
@@ -0,0 +1,12 @@
[Unit]
Description=Wrapper for Ibus
PartOf=graphical-session.target
After=graphical-session.target
[Service]
Type=dbus
ExecStart=/usr/bin/ibus-daemon -r --panel=disable --emoji-extension=disable
BusName=org.freedesktop.IBus
EnvironmentFile=%t/gamescope-environment
Slice=session.slice
TimeoutStopSec=5
@@ -1,7 +0,0 @@
[Unit]
Description=User graphical session service
After=steamos.target
[Service]
ExecStart=/usr/bin/bash /usr/local/bin/launch_session.sh
Restart=on-failure
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Core Session Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=100
@@ -0,0 +1,22 @@
[Unit]
Description=Steam Launcher
After=gamescope-session.target
PartOf=gamescope-session.target
[Service]
ExecStart=steam-launcher
# Track short sessions to trigger a repair after enough failures
ExecStartPre=steam-short-session-tracker --track-started
ExecStopPost=steam-short-session-tracker --track-stopped
# To close properly we need to kill the child of the steam wrapper, as the wrapper itself does not forward signals
ExecStop=/bin/bash -c 'kill -TERM $(pgrep -P $MAINPID || echo $MAINPID)'
# Disable the term signal sent from systemd, as we we handle it manually above
# But still want systemd to kill the entire cgroup on timeout
KillSignal=SIGCONT
KillMode=mixed
TimeoutStopSec=60
Type=exec
EnvironmentFile=%t/gamescope-environment
@@ -1,3 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Core Session Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=100
AllowedCPUs={{ general_cores }}
CPUWeight=100
@@ -1,10 +1,8 @@
[Unit]
Description=SteamOS user graphical session service
After=graphical-session.target systemd-user-sessions.service
Description=User graphical session service
After=graphical-session.target
[Service]
ExecStart=/usr/bin/bash /usr/local/bin/steamos.sh
ExecStart=/usr/local/bin/steamos
EnvironmentFile=%t/steamos-environment
Restart=on-failure
[Install]
WantedBy=default.target
@@ -1,15 +0,0 @@
[Unit]
Description=SteamOS Target
Requires=graphical-session.target
BindsTo=graphical-session.target
After=graphical-session.target
PropagatesStopTo=graphical-session.target
Requires=session.service
BindsTo=session.service
# Wants=ibus-gamescope.service
# Wants=steam-notif-daemon.service
# Wants=gamescope-xbindkeys.service
# Wants=galileo-mura-setup.service
# Wants=gamescope-mangoapp.service
@@ -1,3 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Core Session Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=100
AllowedCPUs={{ sunshine_cores }}
CPUWeight=100
@@ -0,0 +1,8 @@
[Desktop Entry]
Encoding=UTF-8
Name=SteamOS
Comment=SteamOS graphical session
Exec=/usr/local/bin/steamos-session
Icon=steamicon.png
Type=Application
DesktopNames=gamescope
@@ -66,6 +66,7 @@ ufw_outgoing_traffic:
- 9090 # Prometheus
ufw_default_forward_policy: "ACCEPT"
fw_loopback_traffic_deny: false
ipv4_sysctl_settings:
net.ipv4.ip_forward: 1
@@ -51,8 +51,11 @@ ufw_outgoing_traffic:
- 123 # NTP
- 443 # HTTPS
- 853 # DNS over TLS
- 139 # Samba
- 445 # Samba
ufw_default_forward_policy: "ACCEPT"
fw_loopback_traffic_deny: false
ipv4_sysctl_settings:
net.ipv4.ip_forward: 1
+39 -160
View File
@@ -9,9 +9,6 @@
systemd_user_dir: "/home/{{ user_name }}/.config/systemd/user"
systemd_system_dir: "/etc/systemd/system"
grub_cfg: "/etc/default/grub"
system_cores: "0,8"
general_cores: "2-7,10-15"
sunshine_cores: "1,9"
screen_resolution: "{{ lookup('env', 'GAME_RESOLUTION') | d('1920x1080', true) }}"
screen_width: "{{ screen_resolution.split('x')[0] }}"
screen_height: "{{ screen_resolution.split('x')[1] }}"
@@ -27,8 +24,6 @@
- fbdev=1
- mitigations=off
- threadirqs
- nohz_full=1-7,9-15
- rcu_nocbs=1-7,9-15
- drm.edid_firmware=DP-1:edid/aoc28e850.bin
- video=DP-1:e
- acpi_enforce_resources=lax
@@ -63,140 +58,6 @@
- lizardbyte/stable
- atim/heroic-games-launcher
# --- CachyOS Kernel (conditional) ---
- name: Detect supported x86_64 ISA levels
ansible.builtin.shell:
cmd: |
set -euo pipefail;
/lib64/ld-linux-x86-64.so.2 --help | grep -F "(supported, searched)"
register: glibc_loader_help
changed_when: false
failed_when: false
- name: Determine CPU support for CachyOS kernel
ansible.builtin.set_fact:
has_x86_64_v3: "{{ ('x86-64-v3' in glibc_loader_help.stdout) or ('x86_64_v3' in glibc_loader_help.stdout) }}"
has_x86_64_v2: "{{ ('x86-64-v2' in glibc_loader_help.stdout) or ('x86_64_v2' in glibc_loader_help.stdout) }}"
- name: Debug CPU ISA detection
ansible.builtin.debug:
msg: "CPU supports x86_64_v3: {{ has_x86_64_v3 }}, x86_64_v2: {{ has_x86_64_v2 }}"
- name: Enable CachyOS COPR repository (kernel)
become: true
community.general.copr:
name: bieszczaders/kernel-cachyos
state: enabled
when: has_x86_64_v3 | bool or has_x86_64_v2 | bool
- name: Enable CachyOS COPR repository (addons)
become: true
community.general.copr:
name: bieszczaders/kernel-cachyos-addons
state: enabled
when: has_x86_64_v3 | bool or has_x86_64_v2 | bool
- name: Install CachyOS kernel for x86_64_v3 CPUs
become: true
ansible.builtin.dnf:
name:
- pesign
- openssl
- kernel-devel
- mokutil
- keyutils
- kernel-cachyos
- kernel-cachyos-devel
state: present
when: has_x86_64_v3 | bool
- name: Ensures user is on /etc/pesign/users
become: true
ansible.builtin.lineinfile:
path: /etc/pesign/users
line: "{{ ansible_user }}"
state: present
when: has_x86_64_v3 | bool
notify: Run pesign
- name: Run /usr/libexec/pesign/pesign-authorize
become: true
ansible.builtin.command: /usr/libexec/pesign/pesign-authorize
when: has_x86_64_v3 | bool
changed_when: false
# - name: Generate certificate for CachyOS kernel signing
# become: true
# ansible.builtin.shell: |
# openssl req -new -x509 -newkey rsa:2048 -keyout "key.pem" \
# -outform DER -out "cert.der" -nodes -days 36500 \
# -subj "/CN=CachyOS Secure Boot/" && \
# openssl pkcs12 -export -out key.p12 -inkey key.pem -in cert.der
# when: has_x86_64_v3 | bool
# changed_when: false
# args:
# executable: /bin/bash
# creates:
# - key.pem
# - cert.der
# - key.p12
# - name: Inform user to enroll MOK key
# ansible.builtin.debug:
# msg: |
# Please enroll the MOK key for kernel module signing on next reboot.
# Run:
# sudo certutil -A -i cert.der -n "CachyOS Secure Boot" -d /etc/pki/pesign/ -t "Pu,Pu,Pu" && \
# sudo pk12util -i key.p12 -d /etc/pki/pesign
# sudo mokutil --import cert.der' if not prompted automatically.
# when: has_x86_64_v3 | bool
- name: Create /etc/kernel/postinst.d directory
become: true
ansible.builtin.file:
path: /etc/kernel/postinst.d
state: directory
owner: root
group: root
mode: "0755"
- name: Enable Automatically signing kernel updates
become: true
ansible.builtin.copy:
dest: /etc/kernel/postinst.d/00-signing
owner: root
group: root
mode: "0755"
content: |
#!/bin/sh
set -e
KERNEL_IMAGE="$2"
MOK_KEY_NICKNAME="CachyOS Secure Boot"
if [ "$#" -ne "2" ] ; then
echo "Wrong count of command line arguments. This is not meant to be called directly." >&2
exit 1
fi
if [ ! -x "$(command -v pesign)" ] ; then
echo "pesign not executable. Bailing." >&2
exit 1
fi
if [ ! -w "$KERNEL_IMAGE" ] ; then
echo "Kernel image $KERNEL_IMAGE is not writable." >&2
exit 1
fi
echo "Signing $KERNEL_IMAGE..."
pesign --certificate "$MOK_KEY_NICKNAME" --in "$KERNEL_IMAGE" --sign --out "$KERNEL_IMAGE.signed"
mv "$KERNEL_IMAGE.signed" "$KERNEL_IMAGE"
- name: Install CachyOS LTS kernel for x86_64_v2-only CPUs
become: true
ansible.builtin.dnf:
name:
- kernel-cachyos-lts
- kernel-cachyos-lts-devel-matched
state: present
when: (not has_x86_64_v3 | bool) and (has_x86_64_v2 | bool)
- name: Ensure core gaming and streaming packages are installed
become: true
ansible.builtin.dnf:
@@ -351,16 +212,11 @@
state: stopped
loop:
- gdm.service
- sddm.service
- bluetooth.service
- ModemManager.service
- cups.service
- avahi-daemon.service
- chronyd.service
- NetworkManager-wait-online.service
- geoclue.service
- smartd.service
- upower.service
# System actions
- name: Install Systemd system files
@@ -398,26 +254,26 @@
mode: "0755"
loop:
- /root/.local/logs
- "{{ systemd_system_dir }}/getty@tty1.service.d"
- name: Create override for getty on tty1
- name: Copy wayland session files for SDDM
become: true
ansible.builtin.copy:
dest: "{{ systemd_system_dir }}/getty@tty1.service.d/override.conf"
src: "{{ item }}"
dest: "/usr/share/wayland-sessions/{{ item | basename }}"
owner: root
group: root
mode: "0644"
content: |
[Service]
ExecStart=
ExecStart=-/usr/bin/agetty --autologin {{ user_name }} --noclear %I $TERM
Type=idle
loop: "{{ query('fileglob', 'game_station/wayland-sessions/*') }}"
- name: Enable user lingering for game user
- name: Install SDDM configuration for auto-login
become: true
ansible.builtin.command: loginctl enable-linger {{ user_name }}
changed_when: false
failed_when: false
ansible.builtin.template:
src: "{{ item }}"
dest: "/etc/sddm.conf.d/{{ item | basename }}"
owner: root
group: root
mode: "0644"
loop: "{{ query('fileglob', 'game_station/sddm.conf/*') }}"
- name: Create log file for Jupiter BIOS update (dummy file)
become: true
@@ -475,6 +331,8 @@
- "{{ user_config_dir }}/steam-rom-manager/userData"
- "/home/{{ user_name }}/.local/logs"
- "/home/{{ user_name }}/.local/run"
- "/home/{{ user_name }}/.local/share/applications"
- "/home/{{ user_name }}/.local/share/icons"
- "/home/{{ user_name }}/Emulation"
- "/home/{{ user_name }}/Emulation/snes"
- "/home/{{ user_name }}/Emulation/psp"
@@ -618,14 +476,35 @@
owner: "{{ user_name }}"
group: "{{ user_name }}"
- name: Enable User session service login
- name: Copy shortcuts to remote host
become: true
ansible.builtin.copy:
src: "{{ item }}"
dest: "/home/{{ user_name }}/.local/share/applications/{{ item | basename }}"
owner: "{{ user_name }}"
group: "{{ user_name }}"
mode: "0644"
loop: "{{ query('fileglob', 'game_station/shortcuts/*.desktop') }}"
- name: Copy icons to remote host
become: true
ansible.builtin.copy:
src: "{{ item }}"
dest: "/home/{{ user_name }}/.local/share/icons/{{ item | basename }}"
owner: "{{ user_name }}"
group: "{{ user_name }}"
mode: "0644"
loop: "{{ query('fileglob', 'game_station/shortcuts/icons/*.png') }}"
- name: Enable Required services
become: true
become_user: "{{ user_name }}"
ansible.builtin.systemd:
name: steamos.service
name: "{{ item }}"
enabled: true
state: started
scope: user
loop:
- sddm.service
handlers:
- name: Update grub
+3 -2
View File
@@ -18,8 +18,9 @@ locals {
# DNS
dns_nameservers = [
"193.110.81.0",
"185.253.5.0"
"192.168.0.252",
"1.1.1.1",
"8.8.8.8"
]
override_hosts = [