mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
123 lines
4.7 KiB
Bash
123 lines
4.7 KiB
Bash
#!/bin/bash
|
|
|
|
# Function for printing error messages and exiting
|
|
function exit_with_error() {
|
|
echo "❌ $1"
|
|
exit 1
|
|
}
|
|
|
|
# Function for checking required files
|
|
function check_file_exists() {
|
|
[ ! -f "$1" ] && exit_with_error "$1 file not found"
|
|
}
|
|
|
|
# Check required files
|
|
check_file_exists "/db/model.py"
|
|
check_file_exists "alembic.ini"
|
|
check_file_exists "env.py"
|
|
check_file_exists "script.py.mako"
|
|
|
|
# Check required environment variables
|
|
[ -z "$DATABASE" ] && exit_with_error "DATABASE environment variable is not set"
|
|
[ -z "$DATABASE_URI" ] && exit_with_error "DATABASE_URI environment variable is not set"
|
|
[ -z "$TAG" ] && exit_with_error "TAG environment variable is not set"
|
|
[ -z "$NEXT_TAG" ] && exit_with_error "NEXT_TAG environment variable is not set"
|
|
[ -z "$ONLY_UPDATE" ] && exit_with_error "ONLY_UPDATE environment variable is not set"
|
|
|
|
# Validate database type
|
|
case "$DATABASE" in
|
|
sqlite|mariadb|mysql|postgresql|oracle)
|
|
;;
|
|
*)
|
|
exit_with_error "Unsupported database type: $DATABASE"
|
|
;;
|
|
esac
|
|
|
|
# Create symlink so alembic resolves {db}_versions -> versions
|
|
# (env.py overrides version_locations to "{db}_versions" but the mount is at "versions")
|
|
ln -sf versions "${DATABASE}_versions" 2>/dev/null || true
|
|
|
|
# Test database connection
|
|
echo "🔗 Testing database connection..."
|
|
python3 -c "from sqlalchemy import create_engine; create_engine('${DATABASE_URI}').connect()" || exit_with_error "Unable to connect to the database at $DATABASE_URI"
|
|
echo "✅ Database connection successful"
|
|
|
|
# Download the next tag model file
|
|
echo "📥 Downloading the model file for version $NEXT_TAG"
|
|
if ! curl -f -s -o /db/model.py "https://raw.githubusercontent.com/bunkerity/bunkerweb/refs/tags/v${NEXT_TAG}/src/common/db/model.py"; then
|
|
echo "⚠️ Failed to download model file, using latest_model.py instead"
|
|
if [ -f "latest_model.py" ]; then
|
|
mv latest_model.py /db/model.py || exit_with_error "Failed to move latest_model.py to /db/model.py"
|
|
else
|
|
exit_with_error "Neither model download nor latest_model.py are available"
|
|
fi
|
|
fi
|
|
|
|
# Verify the downloaded file is not an error page
|
|
if grep -q "404: Not Found" "/db/model.py"; then
|
|
rm -f /db/model.py
|
|
if [ -f "latest_model.py" ]; then
|
|
mv latest_model.py /db/model.py || exit_with_error "Failed to move latest_model.py to /db/model.py"
|
|
else
|
|
exit_with_error "Neither model download nor latest_model.py are available"
|
|
fi
|
|
fi
|
|
|
|
# Apply all existing migrations to bring the DB from the initial schema
|
|
# (created by the scheduler at the first tag) to the latest already-covered version.
|
|
if ls versions/*.py &>/dev/null; then
|
|
echo "🔄 Applying existing migrations..."
|
|
if [[ "$DATABASE" == "postgresql" ]]; then
|
|
# PostgreSQL: apply one at a time because some migrations use
|
|
# execute_with_new_transaction() which opens a second DB connection
|
|
# and deadlocks during bulk upgrade head.
|
|
while true; do
|
|
output=$(alembic upgrade +1 2>&1)
|
|
rc=$?
|
|
echo "$output"
|
|
# If no migration was applied, we've reached head — done
|
|
if ! echo "$output" | grep -q "Running upgrade"; then
|
|
break
|
|
fi
|
|
# A migration was attempted but alembic failed
|
|
if [[ $rc -ne 0 ]]; then
|
|
exit_with_error "Failed to apply existing migrations"
|
|
fi
|
|
done
|
|
else
|
|
# sqlite/mariadb/mysql: bulk apply is safe and fast
|
|
alembic upgrade head || exit_with_error "Failed to apply existing migrations"
|
|
fi
|
|
echo "✅ Existing migrations applied"
|
|
fi
|
|
|
|
if [ "$ONLY_UPDATE" -eq 0 ]; then
|
|
echo "🦃 Auto-generating the migration script to upgrade from $TAG to $NEXT_TAG"
|
|
|
|
# Generate the migration script
|
|
alembic revision --autogenerate -m "Upgrade to version $NEXT_TAG" --version-path versions || exit_with_error "Failed to create migration script for $DATABASE. Check alembic configuration or database connection."
|
|
|
|
# Set ownership for alembic directory (optional step)
|
|
if command -v chown &>/dev/null; then
|
|
echo "🔧 Setting ownership for alembic directory"
|
|
chown -R "$UID:$GID" versions || echo "⚠️ Failed to change ownership, continuing..."
|
|
else
|
|
echo "⚠️ 'chown' command not available, skipping ownership adjustment"
|
|
fi
|
|
|
|
# Apply the new migration to update the database
|
|
echo "🔄 Applying the new migration..."
|
|
alembic upgrade head || exit_with_error "Failed to apply the migration to the latest version"
|
|
|
|
echo "✅ Migration script created successfully"
|
|
else
|
|
# Set ownership for alembic directory (optional step)
|
|
if command -v chown &>/dev/null; then
|
|
echo "🔧 Setting ownership for alembic directory"
|
|
chown -R "$UID:$GID" versions || echo "⚠️ Failed to change ownership, continuing..."
|
|
else
|
|
echo "⚠️ 'chown' command not available, skipping ownership adjustment"
|
|
fi
|
|
|
|
echo "✅ All migrations already applied"
|
|
fi
|