mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-09-13 05:09:08 +02:00
* refactor(webtop,webtop_kde,claude_desktop): share the Selkies startup scripts All three add-ons are built on the LinuxServer Selkies base image and had independently drifted copies of the same startup scripts. claude_desktop's copies carry a set of fixes the two webtops never received, so make claude_desktop the single source and symlink the shared scripts from webtop_kde/rootfs (which webtop/rootfs already symlinks in full). Shared by symlink: 20-folders.sh, 21-gpu_permissions.sh, 80-configuration.sh, 90-ingress.sh and the six etc/nginx/includes files. Kept add-on specific: everything Claude-only stays in claude_desktop (81/82/83/84 tool installs, 85-openbox_autostart.sh, defaults/, usr/local/bin, svc-headroom), and everything webtop-only stays in webtop_kde (90-ssl.sh, helpers/microsoft-edge-stable, and the new 81-microsoft_edge.sh). To make the shared scripts add-on agnostic: - 20-folders.sh derives its default data location from the home directory the Dockerfile baked into the abc user instead of hardcoding /data/data. That yields /data/data on claude_desktop and /config/data_kde on both webtops, matching each add-on's previous behaviour exactly. - The permission_mode: bypass root guard is skipped on add-ons that do not declare that option. - 80-configuration.sh falls back to pip when the image does not ship uv. - The Microsoft Edge install moves out of 80-configuration.sh into a webtop-only 81-microsoft_edge.sh, which also absorbs the ownership fixup that used to run in 20-folders.sh before Edge was installed and so never matched anything. CI: the builder's symlink-resolution step made a single pass over a pre-computed file list, so resolving webtop/rootfs (a directory symlink) could copy the symlinks inside it verbatim, leaving links that escape the webtop build context. Verified on this tree: the old loop leaves 10 dangling symlinks under webtop/. Extract it to .github/scripts/resolve_symlinks.sh, repeat until a pass finds nothing, and run it in the PR check too, which had no resolution step at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix: guard two startup aborts found in review Both are crash paths in code added by this PR, not hardening: - 20-folders.sh: getent exits 2 when the user does not exist, and under bashio's `set -o pipefail` plus the script's `set -e` that aborts at the assignment, so the "could not read abc's home" fallback below it was unreachable. Same trap already documented in 21-gpu_permissions.sh. Verified: without the guard the shell exits 2; with it the fallback runs. - 81-microsoft_edge.sh: the ownership fixup lost the `-f` guard the original had in 20-folders.sh. Without nullglob an unmatched /usr/bin/microsoft-edge* reaches chown as a literal and `set -e` kills container startup. Now a nullglob array with a warning when empty. Also make resolve_symlinks.sh fail on a broken symlink instead of deleting it. Dropping it silently yields an image that builds clean and misbehaves at runtime; a red build is easier to diagnose. Verified both paths: the repo as-is resolves to 0 symlinks and exit 0, and an injected broken link exits 1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix: address review comments on data-location default and Edge downloads Two findings from CodeRabbit, both correctness rather than hardening: - 20-folders.sh rewrites abc's home in /etc/passwd further down, so re-reading it on the next boot returned the *previously selected* location as the image default. On a restart that reuses the container's writable layer, clearing data_location would strand the user on their old custom path instead of restoring the built-in one. Cache the value in /etc/.addon_image_home, which shares the writable layer's lifetime with the edit it compensates for: a rebuilt or recreated container starts from a pristine /etc/passwd and regenerates it. Simulated all three cases (first boot, reused container with a rewritten passwd, recreated container) under `set -e` + `set -o pipefail`. - 81-microsoft_edge.sh: both curl calls were unbounded, so a stalled packages.microsoft.com would hang cont-init.d and with it the whole add-on. Add --fail/--connect-timeout/--max-time and skip the install with a logged error when version discovery or the download fails. The desktop is useful without Edge; an add-on wedged before Selkies starts is not. Not addressed, deliberately: escaping $LOCATION/$DEFAULT_LOCATION for sed, and validating symlink targets in resolve_symlinks.sh. Both are hardening against inputs that are not reachable in normal use, both predate this PR, and the maintainer has asked to prioritise usability over that class of change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
59 lines
2.8 KiB
Bash
Executable File
59 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/with-contenv bashio
|
|
# shellcheck shell=bash
|
|
set -e
|
|
|
|
# Shared by every Selkies-based add-on in this repo (claude_desktop, webtop, webtop_kde) via a
|
|
# symlink; keep it add-on agnostic. Every option read here is guarded, so an add-on that does
|
|
# not declare a given option simply skips that block.
|
|
#
|
|
# All three images are Debian/Ubuntu-based, so apt is the only system package manager used.
|
|
if bashio::config.has_value 'additional_apps'; then
|
|
bashio::log.info "Installing additional apps :"
|
|
apt-get update -o Acquire::http::Timeout=10 -o Acquire::https::Timeout=10 &> /dev/null || bashio::log.warning "Unable to update apt package lists"
|
|
for packagestoinstall in $(bashio::config 'additional_apps' | tr ',' ' '); do
|
|
bashio::log.green "... $packagestoinstall"
|
|
apt-get install -yqq --no-install-recommends "$packagestoinstall" &> /dev/null || bashio::log.fatal "Error : $packagestoinstall not found"
|
|
done
|
|
fi
|
|
|
|
if bashio::config.has_value 'additional_pip'; then
|
|
if command -v uv &> /dev/null; then
|
|
pip_install=(uv pip install --system --break-system-packages)
|
|
else
|
|
pip_install=(pip install --break-system-packages)
|
|
fi
|
|
for p in $(bashio::config 'additional_pip' | tr ',' ' '); do
|
|
bashio::log.green "... pip: $p"
|
|
"${pip_install[@]}" "$p" || bashio::log.fatal "Error: pip package $p failed"
|
|
done
|
|
fi
|
|
|
|
if bashio::config.has_value 'TZ'; then
|
|
TIMEZONE=$(bashio::config 'TZ')
|
|
if [ -f "/usr/share/zoneinfo/$TIMEZONE" ]; then
|
|
bashio::log.info "Setting timezone to $TIMEZONE"
|
|
ln -snf "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
|
|
echo "$TIMEZONE" > /etc/timezone
|
|
else
|
|
bashio::log.fatal "Error : $TIMEZONE not found. Here is a list of valid timezones : https://manpages.ubuntu.com/manpages/focal/man3/DateTime::TimeZone::Catalog.3pm.html"
|
|
fi
|
|
fi
|
|
|
|
if bashio::config.has_value 'KEYBOARD'; then
|
|
KEYBOARD=$(bashio::config 'KEYBOARD')
|
|
bashio::log.info "Setting keyboard to $KEYBOARD"
|
|
if [ -d /var/run/s6/container_environment ]; then printf "%s" "$KEYBOARD" > /var/run/s6/container_environment/KEYBOARD; fi
|
|
grep -qxF "KEYBOARD=\"$KEYBOARD\"" ~/.bashrc 2> /dev/null || printf "%s\n" "KEYBOARD=\"$KEYBOARD\"" >> ~/.bashrc
|
|
fi
|
|
|
|
if bashio::config.has_value 'PASSWORD'; then
|
|
bashio::log.info "Setting password to the value defined in options"
|
|
PASSWORD=$(bashio::config 'PASSWORD')
|
|
passwd -d abc
|
|
echo -e "$PASSWORD\n$PASSWORD" | passwd abc
|
|
elif [[ -n "$(bashio::addon.port "3000")" ]] || [[ -n "$(bashio::addon.port "3001")" ]]; then
|
|
bashio::log.warning "SEVERE RISK IDENTIFIED"
|
|
bashio::log.warning "You are opening an external port but your password is not defined"
|
|
bashio::log.warning "You risk being hacked ! Please disable the external ports, or use a password"
|
|
fi
|