Peter Cai
b7b5a61286
Some applications do not work well with Sommelier especially under Sway. Rather than having them unusable, I'd rather have something that "almost" works.
130 lines
4.5 KiB
Bash
Executable file
130 lines
4.5 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"
|
|
|
|
remove_stale_container "$container_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
|
|
|
|
if [ "$(get_image_label "$image_name" net.typeblog.dobu.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
|
|
|
|
if is_in_array "$1" "${DISPLAY_SERVER_APP_ALLOWLIST[@]}"; then
|
|
log "Allowing app $1 full access to Wayland / X11 sockets"
|
|
|
|
WAYLAND_SRC="${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}"
|
|
|
|
if [ -z "$DISPLAY" ]; then
|
|
# TODO: Maybe we can just ignore Xorg in these cases
|
|
die "$$DISPLAY must be set for apps granted full Wayland / Xorg access"
|
|
fi
|
|
XORG_SRC="/tmp/.X11-unix/X${DISPLAY/:/}"
|
|
|
|
if [ ! -S "${XORG_SRC}" ] || [ ! -S "${WAYLAND_SRC}" ]; then
|
|
die "Wayland / Xorg sockets do not exist"
|
|
fi
|
|
else
|
|
# Make sure we have Sommelier running first
|
|
ensure_sommelier
|
|
WAYLAND_SRC="$DOBU_TMP/xdg_runtime/wayland-1"
|
|
XORG_SRC="$DOBU_TMP/X11-unix/X1"
|
|
fi
|
|
|
|
# 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
|
|
|
|
# Some containers want these default XDG directories to exist; make sure they do
|
|
mkdir -p "$home_path/.config"
|
|
mkdir -p "$home_path/.cache"
|
|
mkdir -p "$home_path/.local/share"
|
|
|
|
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,chown,tmpfs-mode=0700 \
|
|
--mount type=tmpfs,destination=/tmp/.X11-unix,chown,tmpfs-mode=0700 \
|
|
`# Pass through Sommelier Wayland socket` \
|
|
`# Note that XDG_RUNTIME_DIR is already set in the image` \
|
|
-v "${WAYLAND_SRC}":/xdg_runtime/wayland-0 \
|
|
-e WAYLAND_DISPLAY=wayland-0 \
|
|
`# Pass through Sommelier X11 socket` \
|
|
-v "${XORG_SRC}":/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"
|