dobu/dobu-run.sh
Peter Cai 92285258b0 steam: Allow the use of sub-namespaces
...and add a seccomp_unsafe profile just for these apps.

Steam Runtime uses Bubblewrap to isolate the games on its own. There is
no way to make Bubblewrap work in our containers other than to allow
unprivileged namespaces inside them.
2023-06-07 15:44:19 -04:00

109 lines
3.8 KiB
Bash
Executable file

#!/usr/bin/env bash
script_path="$(dirname "$(realpath "$0")")"
. "$script_path/functions.sh"
assert_prerequisites
[ -z "$1" ] && die "Expecting 1 argument"
image_name="$(relative_path_to_image_name "apps/$1")"
# image_name is of the form dobu/xxxx, while for containers we want dobu-xxx
container_name="${image_name/\//-}"
home_path="$HOMEDIR_STORAGE/$1"
log "Image name: $image_name"
log "Container name: $container_name"
log "Home directory path: $home_path"
assert_image_exists "$image_name"
if container_exists "$container_name"; then
log "$container_name is already running; re-executing entrypoint command"
log "If this is not desired, please stop the application or run \`podman stop $container_name\` manually"
podman exec -d "$container_name" $(container_entrypoint "$container_name")
exit 0
fi
# Load app control file because some apps require run-time customization
# TODO: Maybe these things should really be container labels?
[ -f "$script_path/apps/$1/control" ] && . "$script_path/apps/$1/control"
if [ "$UNSAFE_I_KNOW_WHAT_I_AM_DOING_ALLOW_NAMESPACES" == "true" ]; then
log "Enabling sub-namespaces support inside this container"
log "This is considered UNSAFE; DO NOT USE if the app inside container does not do its own sandboxing"
log "DO NOT USE if you don't trust sandboxing done by the app inside"
update_podman_security_args "seccomp_unsafe.json"
fi
if [[ -n $PULSE_SERVER ]]; then # remove prefix
host_pulse=${PULSE_SERVER#unix:}
else # default guess
host_pulse=$XDG_RUNTIME_DIR/pulse/native
fi
# Make sure we have Sommelier running first
ensure_sommelier
# Prepare $HOME for the container
if [ ! -d "$home_path" ]; then
if [ "$HOMEDIR_IS_BTRFS" == "true" ]; then
log "Creating $home_path as a btrfs subvolume"
btrfs subvol create "$home_path"
else
log "Creating $home_path"
mkdir -p "$home_path"
fi
fi
extra_args=""
# Check if we should allow /dev/input access
if is_in_array "$1" "${DEV_INPUT_APP_ALLOWLIST[@]}"; then
if [ -z "${DEV_INPUT_DEVICE_ALLOWLIST+x}" ]; then
log "Granting full /dev/input access"
log "Set DEV_INPUT_DEVICE_ALLOWLIST for more fine-grained control"
extra_args="$extra_args -v /dev/input:/dev/input"
else
for device in "${DEV_INPUT_DEVICE_ALLOWLIST[@]}"; do
device=$(realpath /dev/input/"$device")
[[ ! "$device" =~ ^/dev/input/ ]] && continue
log "Granting access to input device $device"
extra_args="$extra_args -v $device:$device"
done
fi
fi
# The fun part: start the container!
# Don't detach like we did with Sommelier, though
podman run --rm "${podman_security_args[@]}" --name "$container_name" \
`# Create tmpfs mountpoints for runtime directories` \
--mount type=tmpfs,destination=/xdg_runtime \
--mount type=tmpfs,destination=/tmp/.X11-unix \
`# Pass through Sommelier Wayland socket` \
`# Note that XDG_RUNTIME_DIR is already set in the image` \
-v "$DOBU_TMP/xdg_runtime/wayland-1":/xdg_runtime/wayland-0 \
-e WAYLAND_DISPLAY=wayland-0 \
`# Pass through Sommelier X11 socket` \
-v "$DOBU_TMP/X11-unix/X1":/tmp/.X11-unix/X0 \
-e DISPLAY=:0 \
`# DRM render nodes` \
-v /dev/dri:/dev/dri \
`# Pass through PulseAudio` \
-v "$host_pulse":/xdg_runtime/pulse/native \
-e PULSE_SERVER=unix:/xdg_runtime/pulse/native \
`# $HOME` \
-v "$home_path":/home/user \
`# Miscellaneous` \
-e XDG_SESSION_TYPE=wayland \
-e TZ="$(date +%Z)" \
`# SHM is needed by some browser engines (such as CEF used by Steam)`\
--shm-size=1G \
`# Scaling parameters` \
-e GDK_SCALE="$GDK_SCALE" \
-e QT_SCALE_FACTOR="$QT_SCALE_FACTOR" \
-e QT_SCREEN_SCALE_FACTORS="$QT_SCREEN_SCALE_FACTORS" \
-e QT_AUTO_SCREEN_SCALE_FACTOR="$QT_AUTO_SCREEN_SCALE_FACTOR" \
`# Use podman's init stub inside the container for better control` \
--init \
$extra_args "$image_name"