diff --git a/Dockerfile b/Dockerfile
index a5ec6e83..df447264 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,7 +4,7 @@ FROM ghcr.io/linuxserver/baseimage-alpine:3.22 AS frontend
RUN \
echo "**** install build packages ****" && \
- apk add --no-cache \
+ apk add \
cmake \
git \
nodejs \
@@ -16,24 +16,29 @@ RUN \
https://github.com/selkies-project/selkies.git \
/src && \
cd /src && \
- git checkout -f 89e39cf7d58c8f7c87ac5922b56b84f745ddeeab
+ git checkout -f 29466e687d2dbed57f657e47b69fab217a81ef1f
RUN \
- echo "**** build frontend ****" && \
- cd /src && \
- cd addons/gst-web-core && \
- npm install && \
- npm run build && \
- cp dist/selkies-core.js ../selkies-dashboard/src && \
- cd ../selkies-dashboard && \
+ echo "**** build shared core library ****" && \
+ cd /src/addons/gst-web-core && \
npm install && \
npm run build && \
- mkdir dist/src dist/nginx && \
- cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
- cp ../gst-web-core/nginx/* dist/nginx/ && \
- cp -r ../gst-web-core/dist/jsdb dist/ && \
+ echo "**** build multiple dashboards ****" && \
+ DASHBOARDS="selkies-dashboard selkies-dashboard-zinc selkies-dashboard-wish" && \
mkdir /buildout && \
- cp -ar dist/* /buildout/
+ for DASH in $DASHBOARDS; do \
+ cd /src/addons/$DASH && \
+ cp ../gst-web-core/dist/selkies-core.js src/ && \
+ npm install && \
+ npm run build && \
+ mkdir -p dist/src dist/nginx && \
+ cp ../gst-web-core/dist/selkies-core.js dist/src/ && \
+ cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
+ cp ../gst-web-core/nginx/* dist/nginx/ && \
+ cp -r ../gst-web-core/dist/jsdb dist/ && \
+ mkdir -p /buildout/$DASH && \
+ cp -ar dist/* /buildout/$DASH/; \
+ done
# Runtime stage
FROM ghcr.io/linuxserver/baseimage-fedora:42
@@ -168,7 +173,7 @@ RUN \
echo "**** install selkies ****" && \
curl -o \
/tmp/selkies.tar.gz -L \
- "https://github.com/selkies-project/selkies/archive/89e39cf7d58c8f7c87ac5922b56b84f745ddeeab.tar.gz" && \
+ "https://github.com/selkies-project/selkies/archive/29466e687d2dbed57f657e47b69fab217a81ef1f.tar.gz" && \
cd /tmp && \
tar xf selkies.tar.gz && \
cd selkies-* && \
@@ -210,6 +215,9 @@ RUN \
-e 's|| \n|' \
-e 's|4|1|' \
/etc/xdg/openbox/rc.xml && \
+ sed -i \
+ 's/--startup/--replace --startup/g' \
+ /usr/bin/openbox-session && \
echo "**** user perms ****" && \
echo "abc:abc" | chpasswd && \
usermod -s /bin/bash abc && \
@@ -251,7 +259,7 @@ RUN \
# add local files
COPY /root /
-COPY --from=frontend /buildout /usr/share/selkies/www
+COPY --from=frontend /buildout /usr/share/selkies
COPY --from=xvfb / /
# ports and volumes
diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64
index 442ac2dd..a3c1ec39 100644
--- a/Dockerfile.aarch64
+++ b/Dockerfile.aarch64
@@ -4,7 +4,7 @@ FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.22 AS frontend
RUN \
echo "**** install build packages ****" && \
- apk add --no-cache \
+ apk add \
cmake \
git \
nodejs \
@@ -16,24 +16,29 @@ RUN \
https://github.com/selkies-project/selkies.git \
/src && \
cd /src && \
- git checkout -f 89e39cf7d58c8f7c87ac5922b56b84f745ddeeab
+ git checkout -f 29466e687d2dbed57f657e47b69fab217a81ef1f
RUN \
- echo "**** build frontend ****" && \
- cd /src && \
- cd addons/gst-web-core && \
- npm install && \
- npm run build && \
- cp dist/selkies-core.js ../selkies-dashboard/src && \
- cd ../selkies-dashboard && \
+ echo "**** build shared core library ****" && \
+ cd /src/addons/gst-web-core && \
npm install && \
npm run build && \
- mkdir dist/src dist/nginx && \
- cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
- cp ../gst-web-core/nginx/* dist/nginx/ && \
- cp -r ../gst-web-core/dist/jsdb dist/ && \
+ echo "**** build multiple dashboards ****" && \
+ DASHBOARDS="selkies-dashboard selkies-dashboard-zinc selkies-dashboard-wish" && \
mkdir /buildout && \
- cp -ar dist/* /buildout/
+ for DASH in $DASHBOARDS; do \
+ cd /src/addons/$DASH && \
+ cp ../gst-web-core/dist/selkies-core.js src/ && \
+ npm install && \
+ npm run build && \
+ mkdir -p dist/src dist/nginx && \
+ cp ../gst-web-core/dist/selkies-core.js dist/src/ && \
+ cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
+ cp ../gst-web-core/nginx/* dist/nginx/ && \
+ cp -r ../gst-web-core/dist/jsdb dist/ && \
+ mkdir -p /buildout/$DASH && \
+ cp -ar dist/* /buildout/$DASH/; \
+ done
# Runtime stage
FROM ghcr.io/linuxserver/baseimage-fedora:arm64v8-42
@@ -166,7 +171,7 @@ RUN \
echo "**** install selkies ****" && \
curl -o \
/tmp/selkies.tar.gz -L \
- "https://github.com/selkies-project/selkies/archive/89e39cf7d58c8f7c87ac5922b56b84f745ddeeab.tar.gz" && \
+ "https://github.com/selkies-project/selkies/archive/29466e687d2dbed57f657e47b69fab217a81ef1f.tar.gz" && \
cd /tmp && \
tar xf selkies.tar.gz && \
cd selkies-* && \
@@ -208,6 +213,9 @@ RUN \
-e 's|| \n|' \
-e 's|4|1|' \
/etc/xdg/openbox/rc.xml && \
+ sed -i \
+ 's/--startup/--replace --startup/g' \
+ /usr/bin/openbox-session && \
echo "**** user perms ****" && \
echo "abc:abc" | chpasswd && \
usermod -s /bin/bash abc && \
@@ -249,7 +257,7 @@ RUN \
# add local files
COPY /root /
-COPY --from=frontend /buildout /usr/share/selkies/www
+COPY --from=frontend /buildout /usr/share/selkies
COPY --from=xvfb / /
# ports and volumes
diff --git a/root/defaults/default.conf b/root/defaults/default.conf
index b82d5d6d..50c45c0f 100644
--- a/root/defaults/default.conf
+++ b/root/defaults/default.conf
@@ -4,7 +4,7 @@ server {
listen 3000 default_server;
listen [::]:3000 default_server;
location SUBFOLDER {
- alias /usr/share/selkies/www/;
+ alias /usr/share/selkies/web/;
index index.html index.htm;
try_files $uri $uri/ =404;
}
@@ -42,11 +42,15 @@ server {
fancyindex on;
fancyindex_footer SUBFOLDERnginx/footer.html;
fancyindex_header SUBFOLDERnginx/header.html;
- alias REPLACE_HOME/Desktop/;
+ alias REPLACE_DOWNLOADS_PATH/;
+ if (-f $request_filename) {
+ add_header Content-Disposition "attachment";
+ add_header X-Content-Type-Options "nosniff";
+ }
}
error_page 500 502 503 504 /50x.html;
location = SUBFOLDER50x.html {
- root /usr/share/selkies/www/;
+ root /usr/share/selkies/web/;
}
}
@@ -58,7 +62,7 @@ server {
ssl_certificate /config/ssl/cert.pem;
ssl_certificate_key /config/ssl/cert.key;
location SUBFOLDER {
- alias /usr/share/selkies/www/;
+ alias /usr/share/selkies/web/;
index index.html index.htm;
try_files $uri $uri/ =404;
}
@@ -96,12 +100,14 @@ server {
fancyindex on;
fancyindex_footer SUBFOLDERnginx/footer.html;
fancyindex_header SUBFOLDERnginx/header.html;
- alias REPLACE_HOME/Desktop/;
+ alias REPLACE_DOWNLOADS_PATH/;
+ if (-f $request_filename) {
+ add_header Content-Disposition "attachment";
+ add_header X-Content-Type-Options "nosniff";
+ }
}
error_page 500 502 503 504 /50x.html;
location = SUBFOLDER50x.html {
- root /usr/share/selkies/www/;
+ root /usr/share/selkies/web/;
}
}
-
-
diff --git a/root/etc/s6-overlay/s6-rc.d/init-nginx/run b/root/etc/s6-overlay/s6-rc.d/init-nginx/run
index 74fcceb7..b98b523a 100755
--- a/root/etc/s6-overlay/s6-rc.d/init-nginx/run
+++ b/root/etc/s6-overlay/s6-rc.d/init-nginx/run
@@ -9,6 +9,10 @@ CHPORT="${CUSTOM_HTTPS_PORT:-3001}"
CWS="${CUSTOM_WS_PORT:-8082}"
CUSER="${CUSTOM_USER:-abc}"
SFOLDER="${SUBFOLDER:-/}"
+FILE_MANAGER_PATH="${FILE_MANAGER_PATH:-$HOME/Desktop}"
+DASHBOARD="${DASHBOARD:-selkies-dashboard}"
+SELKIES_FILE_TRANSFERS="${SELKIES_FILE_TRANSFERS:-upload,download}"
+HARDEN_DESKTOP="${HARDEN_DESKTOP:-false}"
# create self signed cert
if [ ! -f "/config/ssl/cert.pem" ]; then
@@ -28,8 +32,11 @@ sed -i "s/3000/$CPORT/g" ${NGINX_CONFIG}
sed -i "s/3001/$CHPORT/g" ${NGINX_CONFIG}
sed -i "s/CWS/$CWS/g" ${NGINX_CONFIG}
sed -i "s|SUBFOLDER|$SFOLDER|g" ${NGINX_CONFIG}
-sed -i "s|REPLACE_HOME|$HOME|g" ${NGINX_CONFIG}
-s6-setuidgid abc mkdir -p $HOME/Desktop
+sed -i "s|REPLACE_DOWNLOADS_PATH|$FILE_MANAGER_PATH|g" ${NGINX_CONFIG}
+s6-setuidgid abc mkdir -p ${FILE_MANAGER_PATH}
+if [[ $SELKIES_FILE_TRANSFERS != *"download"* ]] || [[ ${HARDEN_DESKTOP,,} == "true" ]]; then
+ sed -i '/files {/,/^ }/d' ${NGINX_CONFIG}
+fi
if [ ! -z ${DISABLE_IPV6+x} ]; then
sed -i '/listen \[::\]/d' ${NGINX_CONFIG}
fi
@@ -44,7 +51,34 @@ if [ ! -z ${DEV_MODE+x} ]; then
${NGINX_CONFIG}
fi
-# copy favicon
+# set dashboard and icon
+rm -Rf \
+ /usr/share/selkies/web
+cp -a \
+ /usr/share/selkies/$DASHBOARD \
+ /usr/share/selkies/web
+sed -i "s|REPLACE_DOWNLOADS_PATH|$FILE_MANAGER_PATH|g" /usr/share/selkies/web/nginx/footer.html
+cp \
+ /usr/share/selkies/www/icon.png \
+ /usr/share/selkies/web/favicon.ico
cp \
/usr/share/selkies/www/icon.png \
- /usr/share/selkies/www/favicon.ico
+ /usr/share/selkies/web/icon.png
+# manifest creation
+echo "{
+ \"name\": \"${TITLE}\",
+ \"short_name\": \"${TITLE}\",
+ \"manifest_version\": 2,
+ \"version\": \"1.0.0\",
+ \"display\": \"fullscreen\",
+ \"background_color\": \"#000000\",
+ \"theme_color\": \"#000000\",
+ \"icons\": [
+ {
+ \"src\": \"icon.png\",
+ \"type\": \"image/png\",
+ \"sizes\": \"180x180\"
+ }
+ ],
+ \"start_url\": \"/\"
+}" > /usr/share/selkies/web/manifest.json
diff --git a/root/etc/s6-overlay/s6-rc.d/init-selkies-config/run b/root/etc/s6-overlay/s6-rc.d/init-selkies-config/run
index 146a3d26..ee31f48a 100755
--- a/root/etc/s6-overlay/s6-rc.d/init-selkies-config/run
+++ b/root/etc/s6-overlay/s6-rc.d/init-selkies-config/run
@@ -1,69 +1,208 @@
#!/usr/bin/with-contenv bash
# default file copies first run
-if [[ ! -f /config/.config/openbox/autostart ]]; then
- mkdir -p /config/.config/openbox
- cp /defaults/autostart /config/.config/openbox/autostart
- chown -R abc:abc /config/.config/openbox
+mkdir -p "$HOME/.config"
+chown abc:abc "$HOME/.config"
+if [[ ! -f "$HOME/.config/openbox/autostart" ]]; then
+ mkdir -p "$HOME/.config/openbox"
+ cp /defaults/autostart "$HOME/.config/openbox/autostart"
+ chown abc:abc "$HOME/.config/openbox" "$HOME/.config/openbox/autostart"
fi
-if [[ ! -f /config/.config/openbox/menu.xml ]]; then
- mkdir -p /config/.config/openbox && \
- cp /defaults/menu.xml /config/.config/openbox/menu.xml && \
- chown -R abc:abc /config/.config
+if [[ ! -f "$HOME/.config/openbox/menu.xml" ]]; then
+ mkdir -p "$HOME/.config/openbox" && \
+ cp /defaults/menu.xml "$HOME/.config/openbox/menu.xml"
+ chown abc:abc "$HOME/.config/openbox" "$HOME/.config/openbox/menu.xml"
fi
# XDG Home
-printf "${HOME}/.XDG" > /run/s6/container_environment/XDG_RUNTIME_DIR
-if [ ! -d "${HOME}/.XDG" ]; then
- mkdir -p ${HOME}/.XDG
- chown abc:abc ${HOME}/.XDG
+if [ ! -d "$HOME/.XDG" ]; then
+ mkdir -p "$HOME/.XDG"
+ chown abc:abc "$HOME/.XDG"
fi
+printf "$HOME/.XDG" > /run/s6/container_environment/XDG_RUNTIME_DIR
-# Locale Support
+# locale Support
if [ ! -z ${LC_ALL+x} ]; then
printf "${LC_ALL%.UTF-8}" > /run/s6/container_environment/LANGUAGE
printf "${LC_ALL}" > /run/s6/container_environment/LANG
fi
-# Remove window borders
-if [[ ! -z ${NO_DECOR+x} ]] && [[ ! -f /decorlock ]]; then
- sed -i \
- 's|| no \n|' \
- /etc/xdg/openbox/rc.xml
- touch /decorlock
+# hardening flags
+if [[ ${HARDEN_DESKTOP,,} == "true" ]]; then
+ export DISABLE_OPEN_TOOLS="true"
+ export DISABLE_SUDO="true"
+ export DISABLE_TERMINALS="true"
+ # application hardening if unset
+ if [ -z ${SELKIES_FILE_TRANSFERS+x} ]; then
+ printf "" > /run/s6/container_environment/SELKIES_FILE_TRANSFERS
+ fi
+ if [ -z ${SELKIES_COMMAND_ENABLED+x} ]; then
+ printf "false" > /run/s6/container_environment/SELKIES_COMMAND_ENABLED
+ fi
+ if [ -z ${SELKIES_UI_SIDEBAR_SHOW_FILES+x} ]; then
+ printf "false" > /run/s6/container_environment/SELKIES_UI_SIDEBAR_SHOW_FILES
+ fi
+ if [ -z ${SELKIES_UI_SIDEBAR_SHOW_APPS+x} ]; then
+ printf "false" > /run/s6/container_environment/SELKIES_UI_SIDEBAR_SHOW_APPS
+ fi
+fi
+if [[ ${HARDEN_OPENBOX,,} == "true" ]]; then
+ export DISABLE_CLOSE_BUTTON="true"
+ export DISABLE_MOUSE_BUTTONS="true"
+ export HARDEN_KEYBINDS="true"
+ if [ -z ${RESTART_APP+x} ]; then
+ export RESTART_APP=true
+ printf "true" > /run/s6/container_environment/RESTART_APP
+ fi
fi
-# Fullscreen everything in openbox unless the user explicitly disables it
-if [[ ! -z ${NO_FULL+x} ]] && [[ ! -f /fulllock ]]; then
- sed -i \
- 's|yes||g' \
- /etc/xdg/openbox/rc.xml
- touch /fulllock
+# disable open tools
+xdg_open_path=$(which xdg-open 2>/dev/null)
+exo_open_path=$(which exo-open 2>/dev/null)
+if [[ ${DISABLE_OPEN_TOOLS,,} == "true" ]]; then
+ echo "[ls.io-init] Disabling xdg-open and exo-open"
+ [ -n "$xdg_open_path" ] && chmod 0000 "$xdg_open_path"
+ [ -n "$exo_open_path" ] && chmod 0000 "$exo_open_path"
+else
+ [ -n "$xdg_open_path" ] && chmod 755 "$xdg_open_path"
+ [ -n "$exo_open_path" ] && chmod 755 "$exo_open_path"
fi
-# Add proot-apps
-if [ ! -f "${HOME}/.local/bin/proot-apps" ]; then
- mkdir -p ${HOME}/.local/bin/
- cp /proot-apps/* ${HOME}/.local/bin/
- echo 'export PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc
- chown abc:abc \
- ${HOME}/.bashrc \
- ${HOME}/.local/ \
- ${HOME}/.local/bin \
- ${HOME}/.local/bin/{ncat,proot-apps,proot,jq,pversion}
-elif ! diff -q /proot-apps/pversion ${HOME}/.local/bin/pversion > /dev/null; then
- cp /proot-apps/* ${HOME}/.local/bin/
- chown abc:abc ${HOME}/.local/bin/{ncat,proot-apps,proot,jq,pversion}
+# disable sudo
+sudo_path=$(which sudo 2>/dev/null)
+if [[ ${DISABLE_SUDO,,} == "true" ]]; then
+ echo "[ls.io-init] Disabling sudo binary and corrupting sudoers config"
+ [ -n "$sudo_path" ] && chmod 0000 "$sudo_path"
+ sed -i "s/NOPASSWD/CORRUPT_FILE/g" /etc/sudoers
+else
+ [ -n "$sudo_path" ] && chmod 4755 "$sudo_path"
+ sed -i "s/CORRUPT_FILE/NOPASSWD/g" /etc/sudoers
fi
+# disable terminals and menu entries
+USER_MENU_DIR="$HOME/.config/openbox"
+USER_MENU_XML="$USER_MENU_DIR/menu.xml"
+USER_MENU_BAK="$USER_MENU_DIR/menu.xml.bak"
+TERMINAL_NAMES=("xterm" "st" "stterm" "uxterm" "lxterminal" "gnome-terminal" "konsole" "xfce4-terminal" "terminator")
+if [ -f "$USER_MENU_XML" ] && [ ! -f "$USER_MENU_BAK" ]; then
+ echo "[ls.io-init] Creating initial backup of menu.xml"
+ cp "$USER_MENU_XML" "$USER_MENU_BAK"
+ chown abc:abc "$USER_MENU_BAK"
+fi
+if [[ ${DISABLE_TERMINALS,,} == "true" ]]; then
+ echo "[ls.io-init] Disabling terminal binaries and removing from menu"
+ [ -f "$USER_MENU_BAK" ] && cp "$USER_MENU_BAK" "$USER_MENU_XML"
+ for term_name in "${TERMINAL_NAMES[@]}"; do
+ term_path=$(which "$term_name" 2>/dev/null)
+ if [ -n "$term_path" ]; then
+ chmod 0000 "$term_path"
+ escaped_path=$(echo "$term_path" | sed 's/[&/\]/\\&/g')
+ sed -i "/${escaped_path}<\/command>/d" "$USER_MENU_XML"
+ fi
+ done
+ chown abc:abc "$USER_MENU_XML"
+else
+ if [ -f "$USER_MENU_BAK" ]; then
+ cp "$USER_MENU_BAK" "$USER_MENU_XML"
+ chown abc:abc "$USER_MENU_XML"
+ fi
+ for term_name in "${TERMINAL_NAMES[@]}"; do
+ term_path=$(which "$term_name" 2>/dev/null)
+ if [ -n "$term_path" ] && [ ! -x "$term_path" ]; then
+ chmod 755 "$term_path"
+ fi
+ done
+fi
+# lock down autostart file if auto restart is enabled
+AUTOSTART_SCRIPT="$HOME/.config/openbox/autostart"
+if [ -f "$AUTOSTART_SCRIPT" ]; then
+ if [[ ${RESTART_APP,,} == "true" ]]; then
+ echo "[ls.io-init] RESTART_APP is set. Setting autostart owner to root and making read-only for user"
+ chown root:abc "$AUTOSTART_SCRIPT"
+ chmod 550 "$AUTOSTART_SCRIPT"
+ else
+ chown abc:abc "$AUTOSTART_SCRIPT"
+ chmod 644 "$AUTOSTART_SCRIPT"
+ fi
+fi
+
+# openbox tweaks
+SYS_RC_XML="/etc/xdg/openbox/rc.xml"
+SYS_RC_BAK="/etc/xdg/openbox/rc.xml.bak"
+if [ ! -f "$SYS_RC_BAK" ]; then
+ echo "[ls.io-init] Creating initial backup of system rc.xml"
+ cp "$SYS_RC_XML" "$SYS_RC_BAK"
+fi
+cp "$SYS_RC_BAK" "$SYS_RC_XML"
+if [[ -n "${DISABLE_CLOSE_BUTTON}" ]]; then
+ echo "[ls.io-init] Disabling close button"
+ sed -i '//s/C//' "$SYS_RC_XML"
+fi
+if [[ ${DISABLE_MOUSE_BUTTONS,,} == "true" ]]; then
+ echo "[ls.io-init] Disabling right and middle mouse clicks"
+ sed -i -e '//d' \
+ -e '//d' "$SYS_RC_XML"
+fi
+if [[ ! -z ${NO_DECOR+x} ]]; then
+ echo "[ls.io-init] Removing window decorations"
+ sed -i '//a \ no' "$SYS_RC_XML"
+fi
+if [[ ! -z ${NO_FULL+x} ]]; then
+ echo "[ls.io-init] Disabling maximization"
+ sed -i '/yes<\/maximized>/d' "$SYS_RC_XML"
+fi
+if [[ ${HARDEN_KEYBINDS,,} == "true" ]]; then
+ echo "[ls.io-init] Disabling dangerous keybinds"
+ KEYS_TO_DISABLE=(
+ "A-F4"
+ "A-Escape"
+ "A-space"
+ "W-e"
+ )
+ for key in "${KEYS_TO_DISABLE[@]}"; do
+ sed -i "//{s/^/ /}" "$SYS_RC_XML"
+ done
+fi
+
+# disable user rc path if config is hardened
+USER_RC_XML="$HOME/.config/openbox/rc.xml"
+if [[ ${DISABLE_MOUSE_BUTTONS,,} == "true" || ${HARDEN_KEYBINDS,,} == "true" ]]; then
+ echo "[ls.io-init] Locking user rc.xml to prevent security overrides"
+ mkdir -p "$(dirname $USER_RC_XML)"
+ chown abc:abc "$(dirname $USER_RC_XML)"
+ cp "$SYS_RC_XML" "$USER_RC_XML"
+ chown root:abc "$USER_RC_XML"
+ chmod 444 "$USER_RC_XML"
+else
+ if [ -f "$USER_RC_XML" ] && [ "$(stat -c '%U' $USER_RC_XML)" == "root" ]; then
+ echo "[ls.io-init] Hardening disabled, removing locked user rc.xml"
+ rm -f "$USER_RC_XML"
+ fi
+fi
+
+# add proot-apps
+proot_updated=false
+if [ ! -f "$HOME/.local/bin/proot-apps" ]; then
+ mkdir -p "$HOME/.local/bin/"
+ cp /proot-apps/* "$HOME/.local/bin/"
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc"
+ proot_updated=true
+elif ! diff -q /proot-apps/pversion "$HOME/.local/bin/pversion" > /dev/null; then
+ cp /proot-apps/* "$HOME/.local/bin/"
+ proot_updated=true
+fi
+if [ "$proot_updated" = true ]; then
+ chown -R abc:abc "$HOME/.local"
+ [ -f "$HOME/.bashrc" ] && chown abc:abc "$HOME/.bashrc"
+fi
# set env based on vars
if [[ -z ${NO_GAMEPAD+x} ]]; then
printf "/usr/lib/selkies_joystick_interposer.so:/opt/lib/libudev.so.1.0.0-fake" > /run/s6/container_environment/LD_PRELOAD
fi
-# JS folder setup
+# js folder setup
mkdir -pm1777 /dev/input
touch /tmp/selkies_js.log
mknod /dev/input/js0 c 13 0
@@ -75,22 +214,3 @@ mknod /dev/input/event1001 c 13 1065
mknod /dev/input/event1002 c 13 1066
mknod /dev/input/event1003 c 13 1067
chmod 777 /dev/input/js* /dev/input/event* /tmp/selkies*
-
-# Manifest creation
-echo "{
- \"name\": \"${TITLE}\",
- \"short_name\": \"${TITLE}\",
- \"manifest_version\": 2,
- \"version\": \"1.0.0\",
- \"display\": \"fullscreen\",
- \"background_color\": \"#000000\",
- \"theme_color\": \"#000000\",
- \"icons\": [
- {
- \"src\": \"icon.png\",
- \"type\": \"image/png\",
- \"sizes\": \"180x180\"
- }
- ],
- \"start_url\": \"/\"
-}" > /usr/share/selkies/www/manifest.json
diff --git a/root/etc/s6-overlay/s6-rc.d/init-video/run b/root/etc/s6-overlay/s6-rc.d/init-video/run
index aaf9dfd7..82213b08 100755
--- a/root/etc/s6-overlay/s6-rc.d/init-video/run
+++ b/root/etc/s6-overlay/s6-rc.d/init-video/run
@@ -33,3 +33,54 @@ do
fi
fi
done
+
+# check if nvidia gpu is present
+if which nvidia-smi > /dev/null 2>&1 && ls -A /dev/dri 2>/dev/null; then
+ # nvidia-container-toolkit may not place files correctly, so we set them up here
+ echo "**** NVIDIA GPU detected ****"
+ OPENCL_ICDS=$(find /etc/OpenCL/vendors -name '*nvidia*.icd' 2>/dev/null)
+ # if no opencl icd found
+ if [ -z "${OPENCL_ICDS}" ]; then
+ echo "**** Setting up OpenCL ICD for NVIDIA ****"
+ mkdir -pm755 /etc/OpenCL/vendors/
+ echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd
+ fi
+ # find vulkan icds
+ ICDS=$(find /usr/share/vulkan/icd.d /etc/vulkan/icd.d -name '*nvidia*.json' 2>/dev/null)
+ # if no icd found
+ if [ -z "${ICDS}" ]; then
+ echo "**** Setting up Vulkan ICD for NVIDIA ****"
+ # get vulkan api version
+ VULKAN_API_VERSION=$(ldconfig -p | grep "libvulkan.so" | awk '{print $NF}' | xargs readlink | grep -oE "[0-9]+\.[0-9]+\.[0-9]+")
+ # Fallback if pipeline fails
+ if [ -z "${VULKAN_API_VERSION}" ]; then
+ # version 1.1 or greater allows vulkan-loader to load the driver's dynamic library
+ VULKAN_API_VERSION="1.1.0"
+ fi
+ mkdir -pm755 /etc/vulkan/icd.d/
+ cat > /etc/vulkan/icd.d/nvidia_icd.json << EOF
+{
+ "file_format_version" : "1.0.0",
+ "ICD": {
+ "library_path": "libGLX_nvidia.so.0",
+ "api_version" : "${VULKAN_API_VERSION}"
+ }
+}
+EOF
+ fi
+ # find glvnd egl_vendor files
+ EGLS=$(find /usr/share/glvnd/egl_vendor.d /etc/glvnd/egl_vendor.d -name '*nvidia*.json' 2>/dev/null)
+ # if no egl_vendor file found
+ if [ -z "${EGLS}" ]; then
+ echo "**** Setting up EGL vendor file for NVIDIA ****"
+ mkdir -pm755 /etc/glvnd/egl_vendor.d/
+ cat > /etc/glvnd/egl_vendor.d/10_nvidia.json << EOF
+{
+ "file_format_version" : "1.0.0",
+ "ICD": {
+ "library_path": "libEGL_nvidia.so.0"
+ }
+}
+EOF
+ fi
+fi
diff --git a/root/etc/s6-overlay/s6-rc.d/svc-de/run b/root/etc/s6-overlay/s6-rc.d/svc-de/run
index b2d53d01..ef8f0007 100755
--- a/root/etc/s6-overlay/s6-rc.d/svc-de/run
+++ b/root/etc/s6-overlay/s6-rc.d/svc-de/run
@@ -1,9 +1,11 @@
#!/usr/bin/with-contenv bash
# set sane resolution before starting apps
-s6-setuidgid abc xrandr --newmode "1024x768" 63.50 1024 1072 1176 1328 768 771 775 798 -hsync +vsync
-s6-setuidgid abc xrandr --addmode screen "1024x768"
-s6-setuidgid abc xrandr --output screen --mode "1024x768" --dpi 96
+if ! s6-setuidgid abc xrandr | grep -q "1024x768"; then
+ s6-setuidgid abc xrandr --newmode "1024x768" 63.50 1024 1072 1176 1328 768 771 775 798 -hsync +vsync
+ s6-setuidgid abc xrandr --addmode screen "1024x768"
+ s6-setuidgid abc xrandr --output screen --mode "1024x768" --dpi 96
+fi
# set xresources
if [ -f "${HOME}/.Xresources" ]; then
diff --git a/root/etc/s6-overlay/s6-rc.d/svc-watchdog/dependencies.d/init-services b/root/etc/s6-overlay/s6-rc.d/svc-watchdog/dependencies.d/init-services
new file mode 100644
index 00000000..e69de29b
diff --git a/root/etc/s6-overlay/s6-rc.d/svc-watchdog/run b/root/etc/s6-overlay/s6-rc.d/svc-watchdog/run
new file mode 100755
index 00000000..33056625
--- /dev/null
+++ b/root/etc/s6-overlay/s6-rc.d/svc-watchdog/run
@@ -0,0 +1,32 @@
+#!/usr/bin/with-contenv bash
+
+if [[ ${RESTART_APP,,} != "true" ]]; then
+ exec sleep infinity
+fi
+
+# monitor loop for autostart
+AUTOSTART_CMD="sh $HOME/.config/openbox/autostart"
+while true; do
+ if pgrep -o -u abc -f "$AUTOSTART_CMD" > /dev/null; then
+ echo "SVC Watchdog: Initial process detected. Starting active monitoring."
+ break
+ fi
+ sleep 2
+done
+last_known_pid=""
+while true; do
+ current_pid=$(pgrep -o -u abc -f "$AUTOSTART_CMD")
+ if [ -z "$current_pid" ]; then
+ if [ -n "$last_known_pid" ]; then
+ echo "SVC Watchdog: Application process (PID: $last_known_pid) has terminated. Restarting..."
+ else
+ echo "SVC Watchdog: Application not running. Attempting to start..."
+ fi
+ s6-setuidgid abc $AUTOSTART_CMD &
+ last_known_pid=""
+ elif [ "$current_pid" != "$last_known_pid" ]; then
+ echo "SVC Watchdog: Application process found with PID: $current_pid. Monitoring..."
+ last_known_pid="$current_pid"
+ fi
+ sleep 1
+done
diff --git a/root/etc/s6-overlay/s6-rc.d/svc-watchdog/type b/root/etc/s6-overlay/s6-rc.d/svc-watchdog/type
new file mode 100644
index 00000000..5883cff0
--- /dev/null
+++ b/root/etc/s6-overlay/s6-rc.d/svc-watchdog/type
@@ -0,0 +1 @@
+longrun
diff --git a/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-watchdog b/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-watchdog
new file mode 100644
index 00000000..e69de29b