From ec60f82e4ec690322dab2cb4309615bd41fdc198 Mon Sep 17 00:00:00 2001 From: Alexandre Date: Sat, 15 Feb 2025 09:19:49 +0100 Subject: [PATCH] Push https://github.com/alexbelgium/hassio-addons/issues/1676#issuecomment-2660778044 --- immich/CHANGELOG.md | 5 + immich/config.json | 2 + immich/rootfs/etc/cont-init.d/20-folders.sh | 4 + immich/rootfs/etc/cont-init.d/99-run.sh | 235 +++++++++++++------- 4 files changed, 164 insertions(+), 82 deletions(-) diff --git a/immich/CHANGELOG.md b/immich/CHANGELOG.md index 799d84765..99d1aeedc 100644 --- a/immich/CHANGELOG.md +++ b/immich/CHANGELOG.md @@ -1,3 +1,8 @@ +- RISK OF BREAKING CHANGE : backup both immich & postgres before starting +- RISK OF BREAKING CHANGE : rewrite and improve database creation tool using addon options (overwritting manual database creation) +- SECURITY FIX : avoid hardcoding the postgres root password and change it if was already applied +- Ensure host is reachable before starting +- Autocorrect homeassistant.local to local ip ## 1.126.1 (15-02-2025) - Update to latest version from imagegenius/docker-immich (changelog : https://github.com/imagegenius/docker-immich/releases) diff --git a/immich/config.json b/immich/config.json index b58585b5b..0ba952622 100644 --- a/immich/config.json +++ b/immich/config.json @@ -81,6 +81,7 @@ "REVERSE_GEOCODING_DUMP_DIRECTORY": "/data/.reverse-geocoding-dump/", "TRANSFORMERS_CACHE": "/data/machine-learning" }, + "hassio_api": true, "image": "ghcr.io/alexbelgium/immich-{arch}", "init": false, "map": [ @@ -121,6 +122,7 @@ "DB_PASSWORD": "str", "DB_PORT": "int", "DB_USERNAME": "str", + "DB_ROOT_PASSWORD": "str?", "DISABLE_MACHINE_LEARNING": "bool?", "JWT_SECRET": "str", "MACHINE_LEARNING_WORKERS": "int?", diff --git a/immich/rootfs/etc/cont-init.d/20-folders.sh b/immich/rootfs/etc/cont-init.d/20-folders.sh index a501f9201..16fc02cc8 100755 --- a/immich/rootfs/etc/cont-init.d/20-folders.sh +++ b/immich/rootfs/etc/cont-init.d/20-folders.sh @@ -17,9 +17,13 @@ fi if bashio::config.has_value "PUID"; then PUID="$(bashio::config 'PUID')" +else + PUID=0 fi if bashio::config.has_value "PGID"; then PGID="$(bashio::config 'PGID')" +else + PGID=0 fi bashio::log.info "Setting data location" diff --git a/immich/rootfs/etc/cont-init.d/99-run.sh b/immich/rootfs/etc/cont-init.d/99-run.sh index 22acb4550..0f39ac254 100755 --- a/immich/rootfs/etc/cont-init.d/99-run.sh +++ b/immich/rootfs/etc/cont-init.d/99-run.sh @@ -3,68 +3,166 @@ # shellcheck disable=SC2155,SC2016 set -e -################################### -# Export all addon options as env # -################################### +# Function to export options from JSON to env variables +export_options() { + local json_source="/data/options.json" + bashio::log.info "Exporting addon options from ${json_source}" -bashio::log.info "Setting variables" + # Get all keys and export their raw values + mapfile -t keys < <(jq -r 'keys[]' "${json_source}") + for key in "${keys[@]}"; do + local value + value=$(jq -r ".${key}" "${json_source}") + if bashio::config.false "verbose" || [[ "$key" == *"PASS"* ]]; then + bashio::log.blue "${key}=******" + else + bashio::log.blue "${key}='${value}'" + fi + export "${key}=${value}" + done +} -# For all keys in options.json -JSONSOURCE="/data/options.json" - -# Export keys as env variables -# echo "All addon options were exported as variables" -mapfile -t arr < <(jq -r 'keys[]' "${JSONSOURCE}") - -for KEYS in "${arr[@]}"; do - # export key - VALUE=$(jq ."$KEYS" "${JSONSOURCE}") - line="${KEYS}='${VALUE//[\"\']/}'" - # text - if bashio::config.false "verbose" || [[ "${KEYS}" == *"PASS"* ]]; then - bashio::log.blue "${KEYS}=******" - else - bashio::log.blue "$line" +# Function to check and adjust DB_HOSTNAME if necessary +check_db_hostname() { + if [[ "$DB_HOSTNAME" == "homeassistant.local" ]]; then + local host_ip + host_ip=$(bashio::network.ipv4_address) + host_ip=${host_ip%/*} + export DB_HOSTNAME="$host_ip" + bashio::log.warning "DB_HOSTNAME was set to homeassistant.local. Using detected IP: $DB_HOSTNAME" fi - # Use locally - export "${KEYS}=${VALUE//[\"\']/}" -done -###################### -# Switch of database # -###################### + if ! ping -c 1 -W 3 "$DB_HOSTNAME" >/dev/null 2>&1; then + bashio::log.warning "------------------------------------" + bashio::log.warning "DB_HOSTNAME ($DB_HOSTNAME) is not reachable." + bashio::log.warning "Please set it to the IP address of your database." + bashio::log.warning "The addon will stop until this is fixed." + bashio::log.warning "------------------------------------" + sleep 30 + bashio::addon.stop + else + echo "$DB_HOSTNAME is reachable." + fi +} -if [ -f /share/postgresql_immich.tar.gz ]; then - bashio::log.warning "Your previous database was exported to /share/postgresql_immich.tar.gz" -elif [ -d /data/postgresql ]; then - bashio::log.warning "------------------------------------" - bashio::log.warning "Internal postgres database detected, copying to /share/postgresql_immich.tar.gz" - bashio::log.warning "------------------------------------" - tar -zcvf /share/postgresql_immich.tar.gz /data/postgresql - rm -r /data/postgresql -fi +# Function to migrate internal database to external storage if needed +migrate_database() { + if [ -f /share/postgresql_immich.tar.gz ]; then + bashio::log.warning "Previous database export found at /share/postgresql_immich.tar.gz" + elif [ -d /data/postgresql ]; then + bashio::log.warning "Internal Postgres database detected. Migrating to /share/postgresql_immich.tar.gz" + tar -zcvf /share/postgresql_immich.tar.gz /data/postgresql + rm -rf /data/postgresql + fi +} -################### -# Define database # -################### +# Function to validate required configuration values +validate_config() { + local missing=false + for var in DB_USERNAME DB_HOSTNAME DB_PASSWORD DB_DATABASE_NAME DB_PORT JWT_SECRET; do + if ! bashio::config.has_value "${var}"; then + bashio::log.error "Missing required configuration: ${var}" + missing=true + fi + done + if [ "$missing" = true ]; then + bashio::exit.nok "Please ensure all required options are set." + fi +} -bashio::log.info "Defining database" -bashio::log.info "-----------------" +# Function to export DB variables to s6 environment if applicable +export_db_env() { + if [ -d /var/run/s6/container_environment ]; then + for var in DB_USERNAME DB_PASSWORD DB_DATABASE_NAME DB_PORT DB_HOSTNAME JWT_SECRET; do + printf "%s" "${!var}" > "/var/run/s6/container_environment/${var}" + done + fi +} -bashio::log.info "Connecting to external postgresql" -bashio::log.info "" +# Function to set up the root user with a secure password +setup_root_user() { + # Generate DB_ROOT_PASSWORD if not set (12-character alphanumeric). + if bashio::config.has_value "DB_ROOT_PASSWORD"; then + export DB_ROOT_PASSWORD="$(bashio::config 'DB_ROOT_PASSWORD')" + else + bashio::log.warning "DB_ROOT_PASSWORD not set. Generating a random 12-character alphanumeric password and storing it in the addon options." + export DB_ROOT_PASSWORD="$(tr -dc 'A-Za-z0-9' "/var/run/s6/container_environment/DB_ROOT_PASSWORD" + fi + fi -# Settings parameters + # Try to connect as root using the default insecure password. + if psql "postgres://root:securepassword@${DB_HOSTNAME}:${DB_PORT}/postgres" -c '\q' 2>/dev/null; then + bashio::log.info "Detected root user with default password. Updating to new DB_ROOT_PASSWORD..." + psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" < /var/run/s6/container_environment/DB_USERNAME - printf "%s" "$DB_PASSWORD" > /var/run/s6/container_environment/DB_PASSWORD - printf "%s" "$DB_DATABASE_NAME" > /var/run/s6/container_environment/DB_DATABASE_NAME - printf "%s" "$DB_PORT" > /var/run/s6/container_environment/DB_PORT - printf "%s" "$DB_HOSTNAME" > /var/run/s6/container_environment/DB_HOSTNAME - printf "%s" "$JWT_SECRET" > /var/run/s6/container_environment/JWT_SECRET -fi +export_db_env -{ - printf "%s\n" "DB_USERNAME=\"$DB_USERNAME\"" - printf "%s\n" "DB_PASSWORD=\"$DB_PASSWORD\"" - printf "%s\n" "DB_DATABASE_NAME=\"$DB_DATABASE_NAME\"" - printf "%s\n" "DB_PORT=\"$DB_PORT\"" - printf "%s\n" "DB_HOSTNAME=\"$DB_HOSTNAME\"" - printf "%s\n" "JWT_SECRET=\"$JWT_SECRET\"" -} >> ~/.bashrc - -################### -# Create database # -################### - -# Create database if does not exist -echo "CREATE ROLE root WITH LOGIN SUPERUSER CREATEDB CREATEROLE PASSWORD 'securepassword'; - CREATE DATABASE immich; CREATE USER immich WITH ENCRYPTED PASSWORD 'immich'; GRANT ALL PRIVILEGES ON DATABASE immich to immich; -\q"> setup_postgres.sql -psql "postgres://$DB_USERNAME:$DB_PASSWORD@$DB_HOSTNAME:$DB_PORT" < setup_postgres.sql || true - -# Clean -rm setup_postgres.sql +setup_root_user +setup_database