Files
steam-shared-library/scripts/activate.sh
Felix Förtsch 1ece944a45 initial implementation: multi-user Steam shared library via bwrap overlay
Share one Steam game library across multiple Linux users with fully
isolated Proton prefixes. Uses bubblewrap to create a per-user kernel
overlay on /opt/steam/steamapps/compatdata/ so game files stay shared
while Proton prefixes are isolated per user, with no compatibility
tool selection or per-game configuration required.

Includes:
- steam-shared launcher that sets up the per-user overlay and execs
  Steam inside a bwrap mount namespace
- activate/uninstall scripts plus an add-user helper for steamshare
  group membership
- permission watcher (steam-fix-perms.path/.service) to keep ACLs
  correct under pressure-vessel's restrictive mode bits
- .desktop override that routes the system Steam launcher through
  steam-shared
- Nix flake exposing activate, uninstall, and add-user packages
- design doc and implementation plan covering the approach
2026-04-15 09:53:09 +02:00

117 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# activate.sh — set up the shared Steam library system
# Requires sudo. Idempotent — safe to re-run.
set -euo pipefail
STEAM_GROUP="steamshare"
STEAM_DIR="/opt/steam"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# --- preflight ---
if [[ $EUID -ne 0 ]]; then
echo "error: run this script with sudo" >&2
exit 1
fi
if ! command -v bwrap &>/dev/null; then
echo "error: bubblewrap (bwrap) is not installed" >&2
echo " arch/cachyos: pacman -S bubblewrap" >&2
echo " debian/ubuntu: apt install bubblewrap" >&2
exit 1
fi
echo "[1/7] Group"
if ! getent group "$STEAM_GROUP" >/dev/null; then
groupadd "$STEAM_GROUP"
echo " created group $STEAM_GROUP"
else
echo " group $STEAM_GROUP exists"
fi
echo "[2/7] Shared library directory"
mkdir -p "$STEAM_DIR/steamapps/compatdata"
find "$STEAM_DIR" -type d -exec chmod 2775 {} +
chown -R root:"$STEAM_GROUP" "$STEAM_DIR"
setfacl -R -m g:"$STEAM_GROUP":rwx "$STEAM_DIR"
setfacl -dR -m g:"$STEAM_GROUP":rwx "$STEAM_DIR"
echo " $STEAM_DIR ready (setgid + ACLs)"
echo "[3/7] Clean stale compatdata prefixes"
# Only wipe compatdata contents on first activation. Re-running activate.sh
# on a live system would otherwise delete every user's Proton prefixes
# (they live inside compatdata/<appid>/pfx, not in the per-user overlay
# until the game is launched at least once under the shared-library setup).
# A launcher at /usr/local/bin/steam-shared is proof the system has been
# activated before — skip the wipe in that case.
if [[ -e /usr/local/bin/steam-shared ]]; then
echo " skipped (steam-shared already installed — refusing to wipe live prefixes)"
else
# remove all contents inside compatdata app dirs (not the dirs themselves —
# Steam recreates empty ones and they're harmless as lower-layer placeholders)
find "$STEAM_DIR/steamapps/compatdata" -mindepth 2 -delete 2>/dev/null || true
echo " compatdata cleaned"
fi
echo "[4/7] Install launcher"
install -m 755 "$PROJECT_DIR/scripts/steam-shared.sh" /usr/local/bin/steam-shared
echo " /usr/local/bin/steam-shared installed"
echo "[5/7] Install .desktop override"
mkdir -p /usr/local/share/applications
install -m 644 "$PROJECT_DIR/desktop/steam.desktop" /usr/local/share/applications/steam.desktop
echo " .desktop override installed"
echo "[6/7] Install permission watcher"
install -m 755 "$PROJECT_DIR/scripts/fix-perms.sh" /usr/local/bin/steam-fix-perms
cat > /etc/systemd/system/steam-fix-perms.service << 'UNIT'
[Unit]
Description=Fix shared Steam library permissions after pressure-vessel changes
[Service]
Type=oneshot
ExecStart=/usr/local/bin/steam-fix-perms
UNIT
cat > /etc/systemd/system/steam-fix-perms.path << UNIT
[Unit]
Description=Watch shared Steam library for permission changes
[Path]
PathChanged=$STEAM_DIR/steamapps/common
PathChanged=$STEAM_DIR/steamapps/shadercache
TriggerLimitIntervalSec=10
TriggerLimitBurst=1
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload
systemctl enable --now steam-fix-perms.path
echo " permission watcher enabled"
echo "[7/7] Fix current permissions"
bash "$PROJECT_DIR/scripts/fix-perms.sh"
echo " permissions fixed"
echo
echo "========================================"
echo " Activation complete."
echo
echo " Shared library: $STEAM_DIR"
echo " Launcher: /usr/local/bin/steam-shared"
echo " Desktop file: /usr/local/share/applications/steam.desktop"
echo
echo " To add a user:"
echo " sudo usermod -aG $STEAM_GROUP <username>"
echo " (user must log out and back in)"
echo
echo " Each user must:"
echo " 1. Launch Steam (it uses the shared library launcher automatically)"
echo " 2. Steam → Settings → Storage → add $STEAM_DIR"
echo " 3. Use any Proton version — isolation is automatic"
echo "========================================"