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:
@@ -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"
|
||||
-4
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user