mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-06-16 04:19:13 +02:00
This commit is contained in:
@@ -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)
|
## 1.126.1 (15-02-2025)
|
||||||
- Update to latest version from imagegenius/docker-immich (changelog : https://github.com/imagegenius/docker-immich/releases)
|
- Update to latest version from imagegenius/docker-immich (changelog : https://github.com/imagegenius/docker-immich/releases)
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
"REVERSE_GEOCODING_DUMP_DIRECTORY": "/data/.reverse-geocoding-dump/",
|
"REVERSE_GEOCODING_DUMP_DIRECTORY": "/data/.reverse-geocoding-dump/",
|
||||||
"TRANSFORMERS_CACHE": "/data/machine-learning"
|
"TRANSFORMERS_CACHE": "/data/machine-learning"
|
||||||
},
|
},
|
||||||
|
"hassio_api": true,
|
||||||
"image": "ghcr.io/alexbelgium/immich-{arch}",
|
"image": "ghcr.io/alexbelgium/immich-{arch}",
|
||||||
"init": false,
|
"init": false,
|
||||||
"map": [
|
"map": [
|
||||||
@@ -121,6 +122,7 @@
|
|||||||
"DB_PASSWORD": "str",
|
"DB_PASSWORD": "str",
|
||||||
"DB_PORT": "int",
|
"DB_PORT": "int",
|
||||||
"DB_USERNAME": "str",
|
"DB_USERNAME": "str",
|
||||||
|
"DB_ROOT_PASSWORD": "str?",
|
||||||
"DISABLE_MACHINE_LEARNING": "bool?",
|
"DISABLE_MACHINE_LEARNING": "bool?",
|
||||||
"JWT_SECRET": "str",
|
"JWT_SECRET": "str",
|
||||||
"MACHINE_LEARNING_WORKERS": "int?",
|
"MACHINE_LEARNING_WORKERS": "int?",
|
||||||
|
|||||||
@@ -17,9 +17,13 @@ fi
|
|||||||
|
|
||||||
if bashio::config.has_value "PUID"; then
|
if bashio::config.has_value "PUID"; then
|
||||||
PUID="$(bashio::config 'PUID')"
|
PUID="$(bashio::config 'PUID')"
|
||||||
|
else
|
||||||
|
PUID=0
|
||||||
fi
|
fi
|
||||||
if bashio::config.has_value "PGID"; then
|
if bashio::config.has_value "PGID"; then
|
||||||
PGID="$(bashio::config 'PGID')"
|
PGID="$(bashio::config 'PGID')"
|
||||||
|
else
|
||||||
|
PGID=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
bashio::log.info "Setting data location"
|
bashio::log.info "Setting data location"
|
||||||
|
|||||||
@@ -3,68 +3,166 @@
|
|||||||
# shellcheck disable=SC2155,SC2016
|
# shellcheck disable=SC2155,SC2016
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
###################################
|
# Function to export options from JSON to env variables
|
||||||
# Export all addon options as env #
|
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
|
# Function to check and adjust DB_HOSTNAME if necessary
|
||||||
JSONSOURCE="/data/options.json"
|
check_db_hostname() {
|
||||||
|
if [[ "$DB_HOSTNAME" == "homeassistant.local" ]]; then
|
||||||
# Export keys as env variables
|
local host_ip
|
||||||
# echo "All addon options were exported as variables"
|
host_ip=$(bashio::network.ipv4_address)
|
||||||
mapfile -t arr < <(jq -r 'keys[]' "${JSONSOURCE}")
|
host_ip=${host_ip%/*}
|
||||||
|
export DB_HOSTNAME="$host_ip"
|
||||||
for KEYS in "${arr[@]}"; do
|
bashio::log.warning "DB_HOSTNAME was set to homeassistant.local. Using detected IP: $DB_HOSTNAME"
|
||||||
# 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"
|
|
||||||
fi
|
fi
|
||||||
# Use locally
|
|
||||||
export "${KEYS}=${VALUE//[\"\']/}"
|
|
||||||
done
|
|
||||||
|
|
||||||
######################
|
if ! ping -c 1 -W 3 "$DB_HOSTNAME" >/dev/null 2>&1; then
|
||||||
# Switch of database #
|
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
|
# Function to migrate internal database to external storage if needed
|
||||||
bashio::log.warning "Your previous database was exported to /share/postgresql_immich.tar.gz"
|
migrate_database() {
|
||||||
elif [ -d /data/postgresql ]; then
|
if [ -f /share/postgresql_immich.tar.gz ]; then
|
||||||
bashio::log.warning "------------------------------------"
|
bashio::log.warning "Previous database export found at /share/postgresql_immich.tar.gz"
|
||||||
bashio::log.warning "Internal postgres database detected, copying to /share/postgresql_immich.tar.gz"
|
elif [ -d /data/postgresql ]; then
|
||||||
bashio::log.warning "------------------------------------"
|
bashio::log.warning "Internal Postgres database detected. Migrating to /share/postgresql_immich.tar.gz"
|
||||||
tar -zcvf /share/postgresql_immich.tar.gz /data/postgresql
|
tar -zcvf /share/postgresql_immich.tar.gz /data/postgresql
|
||||||
rm -r /data/postgresql
|
rm -rf /data/postgresql
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
###################
|
# Function to validate required configuration values
|
||||||
# Define database #
|
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"
|
# Function to export DB variables to s6 environment if applicable
|
||||||
bashio::log.info "-----------------"
|
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"
|
# Function to set up the root user with a secure password
|
||||||
bashio::log.info ""
|
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' </dev/urandom | head -c12)"
|
||||||
|
bashio::config "DB_ROOT_PASSWORD" "${DB_ROOT_PASSWORD}"
|
||||||
|
|
||||||
# Check if values exist
|
# Store generated password in the s6 environment if available
|
||||||
if ! bashio::config.has_value 'DB_USERNAME' && \
|
if [ -d /var/run/s6/container_environment ]; then
|
||||||
! bashio::config.has_value 'DB_HOSTNAME' && \
|
printf "%s" "${DB_ROOT_PASSWORD}" > "/var/run/s6/container_environment/DB_ROOT_PASSWORD"
|
||||||
! bashio::config.has_value 'DB_PASSWORD' && \
|
fi
|
||||||
! bashio::config.has_value 'DB_DATABASE_NAME' && \
|
fi
|
||||||
! bashio::config.has_value 'JWT_SECRET' && \
|
|
||||||
! bashio::config.has_value 'DB_PORT'; then
|
|
||||||
bashio::exit.nok "Please make sure that the following options are set : DB_USERNAME, DB_HOSTNAME, DB_PASSWORD, DB_DATABASE_NAME, DB_PORT"
|
|
||||||
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}" <<EOF
|
||||||
|
ALTER ROLE root WITH PASSWORD '${DB_ROOT_PASSWORD}';
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
# Check if the root user exists.
|
||||||
|
if ! psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" -tAc "SELECT 1 FROM pg_roles WHERE rolname='root'" | grep -q 1; then
|
||||||
|
bashio::log.info "Root user does not exist. Creating root user with DB_ROOT_PASSWORD..."
|
||||||
|
psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" <<EOF
|
||||||
|
CREATE ROLE root WITH LOGIN SUPERUSER CREATEDB CREATEROLE PASSWORD '${DB_ROOT_PASSWORD}';
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
bashio::log.info "Root user exists with a non-default password. No migration needed."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to set up the database
|
||||||
|
setup_database() {
|
||||||
|
bashio::log.info "Setting up external PostgreSQL database..."
|
||||||
|
|
||||||
|
# Ensure the user exists (or create/update if necessary)
|
||||||
|
if ! psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}/postgres" -tAc \
|
||||||
|
"SELECT 1 FROM pg_roles WHERE rolname='${DB_USERNAME}';" | grep -q 1; then
|
||||||
|
bashio::log.info "User ${DB_USERNAME} does not exist. Creating it now..."
|
||||||
|
psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" <<EOF
|
||||||
|
CREATE USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
bashio::log.info "User ${DB_USERNAME} already exists. Updating password..."
|
||||||
|
psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" <<EOF
|
||||||
|
ALTER USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure the database exists (or create it if necessary)
|
||||||
|
if ! psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}/postgres" -tAc \
|
||||||
|
"SELECT 1 FROM pg_database WHERE datname='${DB_DATABASE_NAME}';" | grep -q 1; then
|
||||||
|
bashio::log.info "Database ${DB_DATABASE_NAME} does not exist. Creating it now..."
|
||||||
|
psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" <<EOF
|
||||||
|
CREATE DATABASE ${DB_DATABASE_NAME} OWNER ${DB_USERNAME};
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
bashio::log.info "Database ${DB_DATABASE_NAME} already exists. Ensuring proper permissions..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure the user has the correct privileges
|
||||||
|
psql "postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOSTNAME}:${DB_PORT}" <<EOF
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE ${DB_DATABASE_NAME} TO ${DB_USERNAME};
|
||||||
|
ALTER DATABASE ${DB_DATABASE_NAME} OWNER TO ${DB_USERNAME};
|
||||||
|
EOF
|
||||||
|
|
||||||
|
bashio::log.info "Database setup complete."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
# Main script execution #
|
||||||
|
#########################
|
||||||
|
|
||||||
|
export_options
|
||||||
|
check_db_hostname
|
||||||
|
migrate_database
|
||||||
|
validate_config
|
||||||
|
|
||||||
|
# Reload DB configuration from the addon options (this ensures we have the correct values)
|
||||||
export DB_USERNAME=$(bashio::config 'DB_USERNAME')
|
export DB_USERNAME=$(bashio::config 'DB_USERNAME')
|
||||||
export DB_HOSTNAME=$(bashio::config 'DB_HOSTNAME')
|
export DB_HOSTNAME=$(bashio::config 'DB_HOSTNAME')
|
||||||
export DB_PASSWORD=$(bashio::config 'DB_PASSWORD')
|
export DB_PASSWORD=$(bashio::config 'DB_PASSWORD')
|
||||||
@@ -72,34 +170,7 @@ export DB_DATABASE_NAME=$(bashio::config 'DB_DATABASE_NAME')
|
|||||||
export DB_PORT=$(bashio::config 'DB_PORT')
|
export DB_PORT=$(bashio::config 'DB_PORT')
|
||||||
export JWT_SECRET=$(bashio::config 'JWT_SECRET')
|
export JWT_SECRET=$(bashio::config 'JWT_SECRET')
|
||||||
|
|
||||||
# Export variables
|
export_db_env
|
||||||
if [ -d /var/run/s6/container_environment ]; then
|
|
||||||
printf "%s" "$DB_USERNAME" > /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
|
|
||||||
|
|
||||||
{
|
setup_root_user
|
||||||
printf "%s\n" "DB_USERNAME=\"$DB_USERNAME\""
|
setup_database
|
||||||
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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user