|
|
|
|
@@ -1,7 +1,6 @@
|
|
|
|
|
#!/usr/bin/env bashio
|
|
|
|
|
#!/command/with-contenv bashio
|
|
|
|
|
# shellcheck shell=bash
|
|
|
|
|
# shellcheck disable=SC2155
|
|
|
|
|
set -e
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
bashio::log.warning "Warning - minimum configuration recommended : 2 cpu cores and 4 GB of memory. Otherwise the system will become unresponsive and crash."
|
|
|
|
|
|
|
|
|
|
@@ -10,108 +9,135 @@ unlock_sqlite_migrations() {
|
|
|
|
|
|
|
|
|
|
if ! command -v sqlite3 >/dev/null 2>&1; then
|
|
|
|
|
bashio::log.warning "sqlite3 not available; skipping SQLite migration lock check."
|
|
|
|
|
return
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! sqlite3 "$db_path" "SELECT name FROM sqlite_master WHERE type='table' AND name='knex_migrations_lock';" | grep -q "knex_migrations_lock"; then
|
|
|
|
|
return
|
|
|
|
|
# Only proceed if the DB file exists
|
|
|
|
|
if [[ ! -f "$db_path" ]]; then
|
|
|
|
|
bashio::log.warning "SQLite DB not found at $db_path; skipping migration unlock."
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# If the lock table doesn't exist yet, nothing to unlock
|
|
|
|
|
local has_table
|
|
|
|
|
has_table="$(sqlite3 "$db_path" "SELECT 1 FROM sqlite_master WHERE type='table' AND name='knex_migrations_lock' LIMIT 1;" 2>/dev/null || true)"
|
|
|
|
|
[[ "$has_table" == "1" ]] || return 0
|
|
|
|
|
|
|
|
|
|
# Ensure the lock row exists (Knex expects one row)
|
|
|
|
|
# Typical schema: (index INTEGER PRIMARY KEY, is_locked INTEGER)
|
|
|
|
|
sqlite3 "$db_path" "
|
|
|
|
|
PRAGMA busy_timeout=5000;
|
|
|
|
|
INSERT OR IGNORE INTO knex_migrations_lock(\"index\", is_locked) VALUES (1, 0);
|
|
|
|
|
" >/dev/null 2>&1 || true
|
|
|
|
|
|
|
|
|
|
local is_locked
|
|
|
|
|
is_locked=$(sqlite3 "$db_path" "SELECT is_locked FROM knex_migrations_lock LIMIT 1;" 2>/dev/null || true)
|
|
|
|
|
is_locked="$(sqlite3 "$db_path" "PRAGMA busy_timeout=5000; SELECT is_locked FROM knex_migrations_lock WHERE \"index\"=1 LIMIT 1;" 2>/dev/null || true)"
|
|
|
|
|
|
|
|
|
|
if [[ "$is_locked" == "1" ]]; then
|
|
|
|
|
bashio::log.warning "Locked SQLite migration table detected, attempting to unlock."
|
|
|
|
|
sqlite3 "$db_path" "UPDATE knex_migrations_lock SET is_locked = 0;" || bashio::log.warning "Failed to clear SQLite migration lock."
|
|
|
|
|
sqlite3 "$db_path" "
|
|
|
|
|
PRAGMA busy_timeout=5000;
|
|
|
|
|
UPDATE knex_migrations_lock SET is_locked = 0 WHERE \"index\"=1 AND is_locked=1;
|
|
|
|
|
" >/dev/null 2>&1 || bashio::log.warning "Failed to clear SQLite migration lock."
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unlock_postgres_migrations() {
|
|
|
|
|
if ! command -v psql >/dev/null 2>&1; then
|
|
|
|
|
bashio::log.warning "psql not available; skipping PostgreSQL migration lock check."
|
|
|
|
|
return
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ -z "${POSTGRES_DATABASE:-}" || -z "${POSTGRES_USER:-}" || -z "${POSTGRES_HOST:-}" ]]; then
|
|
|
|
|
bashio::log.warning "PostgreSQL configuration incomplete; skipping migration lock check."
|
|
|
|
|
return
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local pg_port="${POSTGRES_PORT:-5432}"
|
|
|
|
|
export PGPASSWORD="${POSTGRES_PASSWORD:-}"
|
|
|
|
|
|
|
|
|
|
# If table doesn't exist, skip
|
|
|
|
|
local has_table
|
|
|
|
|
has_table="$(psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc \
|
|
|
|
|
"SELECT 1 FROM information_schema.tables WHERE table_name='knex_migrations_lock' LIMIT 1;" 2>/dev/null || true)"
|
|
|
|
|
[[ "$has_table" == "1" ]] || { unset PGPASSWORD; return 0; }
|
|
|
|
|
|
|
|
|
|
# Ensure row exists
|
|
|
|
|
psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc \
|
|
|
|
|
"INSERT INTO knex_migrations_lock(\"index\", is_locked) VALUES (1, 0) ON CONFLICT (\"index\") DO NOTHING;" \
|
|
|
|
|
>/dev/null 2>&1 || true
|
|
|
|
|
|
|
|
|
|
local is_locked
|
|
|
|
|
is_locked=$(psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc "SELECT is_locked FROM knex_migrations_lock LIMIT 1;" 2>/dev/null || true)
|
|
|
|
|
is_locked="$(psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc \
|
|
|
|
|
"SELECT is_locked FROM knex_migrations_lock WHERE \"index\"=1 LIMIT 1;" 2>/dev/null || true)"
|
|
|
|
|
|
|
|
|
|
if [[ "$is_locked" == "1" ]]; then
|
|
|
|
|
bashio::log.warning "Locked PostgreSQL migration table detected, attempting to unlock."
|
|
|
|
|
psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc "UPDATE knex_migrations_lock SET is_locked = 0;" || bashio::log.warning "Failed to clear PostgreSQL migration lock."
|
|
|
|
|
psql -h "$POSTGRES_HOST" -p "$pg_port" -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" -Atqc \
|
|
|
|
|
"UPDATE knex_migrations_lock SET is_locked = 0 WHERE \"index\"=1 AND is_locked=1;" \
|
|
|
|
|
>/dev/null 2>&1 || bashio::log.warning "Failed to clear PostgreSQL migration lock."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
unset PGPASSWORD
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check data location
|
|
|
|
|
LOCATION=$(bashio::config 'data_location')
|
|
|
|
|
if [[ "$LOCATION" = "null" || -z "$LOCATION" ]]; then
|
|
|
|
|
# Default location
|
|
|
|
|
# -------------------
|
|
|
|
|
# Data location
|
|
|
|
|
# -------------------
|
|
|
|
|
LOCATION="$(bashio::config 'data_location')"
|
|
|
|
|
if [[ "$LOCATION" == "null" || -z "$LOCATION" ]]; then
|
|
|
|
|
LOCATION="/config/addons_config/joplin"
|
|
|
|
|
else
|
|
|
|
|
bashio::log.warning "Warning : a custom data location was selected, but the previous folder will NOT be copied. You need to do it manually"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Create folder
|
|
|
|
|
if [ ! -d "$LOCATION" ]; then
|
|
|
|
|
echo "Creating $LOCATION"
|
|
|
|
|
mkdir -p "$LOCATION"
|
|
|
|
|
install -d -m 0755 -o joplin -g joplin "$LOCATION" "$LOCATION/resources"
|
|
|
|
|
|
|
|
|
|
# Ensure DB exists (touch does not truncate)
|
|
|
|
|
if [[ ! -f "$LOCATION/database.sqlite" ]]; then
|
|
|
|
|
install -m 0644 -o joplin -g joplin /dev/null "$LOCATION/database.sqlite"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
touch "$LOCATION"/database.sqlite
|
|
|
|
|
# Link resources into server dir
|
|
|
|
|
ln -sfn "$LOCATION/resources" /home/joplin/packages/server/resources
|
|
|
|
|
|
|
|
|
|
if [ ! -d "$LOCATION"/resources ]; then
|
|
|
|
|
mkdir -p "$LOCATION"/resources
|
|
|
|
|
fi
|
|
|
|
|
ln -s "$LOCATION"/resources /home/joplin/packages/server
|
|
|
|
|
|
|
|
|
|
chown -R joplin:joplin "$LOCATION"
|
|
|
|
|
chmod -R 777 "$LOCATION"
|
|
|
|
|
chmod 755 "$LOCATION/database.sqlite"
|
|
|
|
|
export SQLITE_DATABASE="$LOCATION/database.sqlite"
|
|
|
|
|
|
|
|
|
|
# -------------------
|
|
|
|
|
# DB selection + unlock
|
|
|
|
|
# -------------------
|
|
|
|
|
if bashio::config.has_value 'POSTGRES_DATABASE'; then
|
|
|
|
|
bashio::log.info "Using postgres"
|
|
|
|
|
|
|
|
|
|
bashio::config.has_value 'DB_CLIENT' && export DB_CLIENT=$(bashio::config 'DB_CLIENT') && bashio::log.info 'Database client set'
|
|
|
|
|
bashio::config.has_value 'POSTGRES_PASSWORD' && export POSTGRES_PASSWORD=$(bashio::config 'POSTGRES_PASSWORD') && bashio::log.info 'Postgrep Password set'
|
|
|
|
|
bashio::config.has_value 'POSTGRES_DATABASE' && export POSTGRES_DATABASE=$(bashio::config 'POSTGRES_DATABASE') && bashio::log.info 'Postgrep Database set'
|
|
|
|
|
bashio::config.has_value 'POSTGRES_USER' && export POSTGRES_USER=$(bashio::config 'POSTGRES_USER') && bashio::log.info 'Postgrep User set'
|
|
|
|
|
bashio::config.has_value 'POSTGRES_PORT' && export POSTGRES_PORT=$(bashio::config 'POSTGRES_PORT') && bashio::log.info 'Postgrep Port set'
|
|
|
|
|
bashio::config.has_value 'POSTGRES_HOST' && export POSTGRES_HOST=$(bashio::config 'POSTGRES_HOST') && bashio::log.info 'Postgrep Host set'
|
|
|
|
|
bashio::config.has_value 'DB_CLIENT' && export DB_CLIENT="$(bashio::config 'DB_CLIENT')"
|
|
|
|
|
bashio::config.has_value 'POSTGRES_PASSWORD' && export POSTGRES_PASSWORD="$(bashio::config 'POSTGRES_PASSWORD')"
|
|
|
|
|
bashio::config.has_value 'POSTGRES_DATABASE' && export POSTGRES_DATABASE="$(bashio::config 'POSTGRES_DATABASE')"
|
|
|
|
|
bashio::config.has_value 'POSTGRES_USER' && export POSTGRES_USER="$(bashio::config 'POSTGRES_USER')"
|
|
|
|
|
bashio::config.has_value 'POSTGRES_PORT' && export POSTGRES_PORT="$(bashio::config 'POSTGRES_PORT')"
|
|
|
|
|
bashio::config.has_value 'POSTGRES_HOST' && export POSTGRES_HOST="$(bashio::config 'POSTGRES_HOST')"
|
|
|
|
|
|
|
|
|
|
unlock_postgres_migrations
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
bashio::log.info "Using sqlite"
|
|
|
|
|
unlock_sqlite_migrations "$SQLITE_DATABASE"
|
|
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
##############
|
|
|
|
|
# LAUNCH APP #
|
|
|
|
|
##############
|
|
|
|
|
# -------------------
|
|
|
|
|
# App env
|
|
|
|
|
# -------------------
|
|
|
|
|
bashio::config.has_value 'MAILER_HOST' && export MAILER_HOST="$(bashio::config 'MAILER_HOST')"
|
|
|
|
|
bashio::config.has_value 'MAILER_PORT' && export MAILER_PORT="$(bashio::config 'MAILER_PORT')"
|
|
|
|
|
bashio::config.has_value 'MAILER_SECURITY' && export MAILER_SECURITY="$(bashio::config 'MAILER_SECURITY')"
|
|
|
|
|
bashio::config.has_value 'MAILER_AUTH_USER' && export MAILER_AUTH_USER="$(bashio::config 'MAILER_AUTH_USER')"
|
|
|
|
|
bashio::config.has_value 'MAILER_AUTH_PASSWORD' && export MAILER_AUTH_PASSWORD="$(bashio::config 'MAILER_AUTH_PASSWORD')"
|
|
|
|
|
bashio::config.has_value 'MAILER_NOREPLY_NAME' && export MAILER_NOREPLY_NAME="$(bashio::config 'MAILER_NOREPLY_NAME')"
|
|
|
|
|
bashio::config.has_value 'MAILER_NOREPLY_EMAIL' && export MAILER_NOREPLY_EMAIL="$(bashio::config 'MAILER_NOREPLY_EMAIL')"
|
|
|
|
|
bashio::config.has_value 'MAILER_ENABLED' && export MAILER_ENABLED="$(bashio::config 'MAILER_ENABLED')"
|
|
|
|
|
|
|
|
|
|
# Configure app
|
|
|
|
|
bashio::config.has_value 'MAILER_HOST' && export MAILER_HOST=$(bashio::config 'MAILER_HOST') && bashio::log.info 'Mailer Host set'
|
|
|
|
|
bashio::config.has_value 'MAILER_PORT' && export MAILER_PORT=$(bashio::config 'MAILER_PORT') && bashio::log.info 'Mailer Port set'
|
|
|
|
|
bashio::config.has_value 'MAILER_SECURITY' && export MAILER_SECURITY=$(bashio::config 'MAILER_SECURITY') && bashio::log.info 'Mailer Security set'
|
|
|
|
|
bashio::config.has_value 'MAILER_AUTH_USER' && export MAILER_AUTH_USER=$(bashio::config 'MAILER_AUTH_USER') && bashio::log.info 'Mailer User set'
|
|
|
|
|
bashio::config.has_value 'MAILER_AUTH_PASSWORD' && export MAILER_AUTH_PASSWORD=$(bashio::config 'MAILER_AUTH_PASSWORD') && bashio::log.info 'Mailer Password set'
|
|
|
|
|
bashio::config.has_value 'MAILER_NOREPLY_NAME' && export MAILER_NOREPLY_NAME=$(bashio::config 'MAILER_NOREPLY_NAME') && bashio::log.info 'Mailer Noreply Name set'
|
|
|
|
|
bashio::config.has_value 'MAILER_NOREPLY_EMAIL' && export MAILER_NOREPLY_EMAIL=$(bashio::config 'MAILER_NOREPLY_EMAIL') && bashio::log.info 'Mailer Noreply Email set'
|
|
|
|
|
bashio::config.has_value 'MAILER_ENABLED' && export MAILER_ENABLED=$(bashio::config 'MAILER_ENABLED') && bashio::log.info 'Mailer Enabled set'
|
|
|
|
|
export APP_BASE_URL=$(bashio::config 'APP_BASE_URL')
|
|
|
|
|
export APP_BASE_URL="$(bashio::config 'APP_BASE_URL')"
|
|
|
|
|
export ALLOWED_HOSTS="*"
|
|
|
|
|
|
|
|
|
|
bashio::log.info 'Starting Joplin. Initial user is "admin@localhost" with password "admin"'
|
|
|
|
|
|
|
|
|
|
cd /home/joplin || true
|
|
|
|
|
npm --prefix packages/server start
|
|
|
|
|
cd /home/joplin || exit 1
|
|
|
|
|
exec npm --prefix packages/server start
|
|
|
|
|
|