Initial commit
This commit is contained in:
201
seed.sh
Executable file
201
seed.sh
Executable file
@@ -0,0 +1,201 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# seed.sh - Run db:seed with elevated MySQL privileges
|
||||
#
|
||||
# This script temporarily overrides the database connection to use admin
|
||||
# credentials for operations that require DROP/CREATE permissions.
|
||||
#
|
||||
# Usage:
|
||||
# ./seed.sh <password> # Uses 'root' as username
|
||||
# ./seed.sh <username> <password> # Uses specified username
|
||||
#
|
||||
# IMPORTANT: If your password contains special characters like ( ) > < | & ! $
|
||||
# you must wrap it in single quotes to prevent bash from interpreting them.
|
||||
#
|
||||
# Examples:
|
||||
# ./seed.sh 'mypassword'
|
||||
# ./seed.sh root 'mypassword'
|
||||
# ./seed.sh 'p@ss(word)!23'
|
||||
#
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
printf "${GREEN}=== Database Seeder with Admin Privileges ===${NC}\n\n"
|
||||
|
||||
# Parse arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
printf "${YELLOW}Usage:${NC}\n"
|
||||
printf " ./seed.sh '<password>' # Uses 'root' as username\n"
|
||||
printf " ./seed.sh <username> '<password>' # Uses specified username\n\n"
|
||||
printf "${YELLOW}IMPORTANT:${NC} Wrap password in single quotes if it contains special characters.\n\n"
|
||||
printf "${YELLOW}Examples:${NC}\n"
|
||||
printf " ./seed.sh 'mypassword'\n"
|
||||
printf " ./seed.sh root 'mypassword'\n"
|
||||
printf " ./seed.sh 'p@ss(word)!23'\n"
|
||||
exit 1
|
||||
elif [ $# -eq 1 ]; then
|
||||
DB_USER="root"
|
||||
DB_PASS="$1"
|
||||
elif [ $# -eq 2 ]; then
|
||||
DB_USER="$1"
|
||||
DB_PASS="$2"
|
||||
else
|
||||
printf "${RED}Error: Too many arguments.${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf "${GREEN}Running db:seed...${NC}\n\n"
|
||||
|
||||
# Drop all tables directly via mysql CLI before seeding.
|
||||
# This is necessary because MariaDB 10.11 denies bulk DROP via PDO even with
|
||||
# correct database-level grants (works fine via the mysql CLI client).
|
||||
DB_APP_USER=$(grep '^DB_USERNAME' .env | cut -d'=' -f2 | tr -d '"')
|
||||
DB_APP_PASS=$(grep '^DB_PASSWORD' .env | cut -d'=' -f2 | tr -d '"')
|
||||
DB_APP_HOST=$(grep '^DB_HOST' .env | cut -d'=' -f2 | tr -d '"')
|
||||
DB_APP_PORT=$(grep '^DB_PORT' .env | cut -d'=' -f2 | tr -d '"')
|
||||
DB_NAME=$(grep '^DB_DATABASE' .env | cut -d'=' -f2 | tr -d '"')
|
||||
|
||||
# Temporarily grant full privileges so migrations and seeder can run.
|
||||
# Per-table immutability restrictions will be re-applied at the end of this script.
|
||||
mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" -e "
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER ON \`${DB_NAME}\`.* TO '${DB_APP_USER}'@'localhost';
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER ON \`${DB_NAME}\`.* TO '${DB_APP_USER}'@'127.0.0.1';
|
||||
FLUSH PRIVILEGES;
|
||||
" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "${RED}Failed to grant temporary full access. Aborting.${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
printf "${GREEN}Temporary full access granted for seeding.${NC}\n"
|
||||
TABLES=$(mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" \
|
||||
-N -e "SELECT CONCAT('\`',table_name,'\`') FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null | tr '\n' ',')
|
||||
if [ -n "$TABLES" ]; then
|
||||
TABLES="${TABLES%,}" # remove trailing comma
|
||||
printf "${GREEN}Dropping all tables...${NC}\n"
|
||||
mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
|
||||
-e "SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS ${TABLES}; SET FOREIGN_KEY_CHECKS=1;" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "${RED}Failed to drop tables.${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
printf "${GREEN}All tables dropped.${NC}\n"
|
||||
fi
|
||||
|
||||
# Run migrations first (fresh DB has no tables)
|
||||
printf "${GREEN}Running migrations...${NC}\n"
|
||||
php artisan migrate --force
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "${RED}Migrations failed.${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
printf "\n"
|
||||
|
||||
# Remove profile photos
|
||||
rm -rf storage/app/public/profile-photos/*
|
||||
mkdir -p storage/app/public/profile-photos
|
||||
|
||||
# Prevent the profiles:mark-inactive cron from running during seeding by creating
|
||||
# a maintenance mode flag. Laravel's schedule:run checks for maintenance mode.
|
||||
printf "${GREEN}Enabling maintenance mode to prevent cron jobs during seeding...${NC}\n"
|
||||
php artisan down --quiet 2>/dev/null || true
|
||||
|
||||
# Grant SELECT on Cyclos source database BEFORE db:seed so the seeder's
|
||||
# migrate:cyclos prompts can access it. Must happen before db:seed.
|
||||
printf "\n${GREEN}Cyclos source database...${NC}\n"
|
||||
printf "${YELLOW}To import a Cyclos dump first, run:${NC}\n"
|
||||
printf " mysql -h 127.0.0.1 -u root -p -e \"CREATE DATABASE IF NOT EXISTS cyclos_db CHARACTER SET utf8mb3;\"\n"
|
||||
printf " mysql -h 127.0.0.1 -u root -p --force cyclos_db < cyclos_dump.sql\n"
|
||||
printf "${YELLOW}Note: Use --force to skip non-critical errors (e.g. Cyclos statistics views).${NC}\n"
|
||||
printf "${YELLOW}Note: Do NOT use GUI tools like Antares or TablePlus — they corrupt binary BLOB data.${NC}\n\n"
|
||||
CYCLOS_DB=""
|
||||
while true; do
|
||||
printf "Enter the Cyclos source database name (leave empty to skip): "
|
||||
read CYCLOS_DB
|
||||
if [ -z "$CYCLOS_DB" ]; then
|
||||
break
|
||||
fi
|
||||
# Check if the database exists
|
||||
DB_EXISTS=$(mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" \
|
||||
-N -e "SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name='${CYCLOS_DB}';" 2>/dev/null)
|
||||
if [ "$DB_EXISTS" = "1" ]; then
|
||||
mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" -e "
|
||||
GRANT SELECT ON \`${CYCLOS_DB}\`.* TO '${DB_APP_USER}'@'localhost';
|
||||
GRANT SELECT ON \`${CYCLOS_DB}\`.* TO '${DB_APP_USER}'@'127.0.0.1';
|
||||
FLUSH PRIVILEGES;
|
||||
" 2>/dev/null
|
||||
printf "${GREEN}SELECT granted on ${CYCLOS_DB}.${NC}\n"
|
||||
break
|
||||
else
|
||||
printf "${RED}Database '${CYCLOS_DB}' not found. Available databases:${NC}\n"
|
||||
mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" \
|
||||
-N -e "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" 2>/dev/null | sed 's/^/ - /'
|
||||
fi
|
||||
done
|
||||
|
||||
# Run artisan db:seed. If CYCLOS_DB is set, pass it via env so the seeder
|
||||
# skips the "migrate cyclos?" prompt and uses the already-known DB name.
|
||||
if [ -n "$CYCLOS_DB" ]; then
|
||||
CYCLOS_DB="$CYCLOS_DB" php artisan db:seed
|
||||
else
|
||||
php artisan db:seed
|
||||
fi
|
||||
|
||||
# Register any unregistered models as love reactants
|
||||
printf "\n${GREEN}Registering unregistered reactants...${NC}\n"
|
||||
php artisan tinker --execute="
|
||||
App\Models\Call::whereNull('love_reactant_id')->get()->each(fn(\$c) => \$c->registerAsLoveReactant());
|
||||
App\Models\Post::whereNull('love_reactant_id')->get()->each(fn(\$p) => \$p->registerAsLoveReactant());
|
||||
echo 'Done.';
|
||||
"
|
||||
|
||||
# Fix profile-photos directory ownership so web server (www-data) can read files
|
||||
printf "\n${GREEN}Fixing profile-photos ownership...${NC}\n"
|
||||
chown -R r:www-data storage/app/public/profile-photos/
|
||||
|
||||
# Re-apply transaction immutability restrictions AFTER seeding.
|
||||
# create-restricted-db-user-safe.sh drops and recreates the user with correct
|
||||
# per-table grants (no UPDATE/DELETE on transactions/transaction_types).
|
||||
# It must run after seeding (not before) so the seeder has full access.
|
||||
# It must run before re-granting the Cyclos SELECT (which it would otherwise remove).
|
||||
printf "\n${GREEN}Re-applying transaction immutability restrictions...${NC}\n"
|
||||
printf "Enter the app DB password to recreate the restricted user (or press Enter to skip): "
|
||||
read -s IMMUTABILITY_PASS
|
||||
printf "\n"
|
||||
if [ -n "$IMMUTABILITY_PASS" ]; then
|
||||
sudo ./scripts/create-restricted-db-user-safe.sh "$DB_APP_USER" "$IMMUTABILITY_PASS"
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "${RED}Failed to re-apply immutability restrictions.${NC}\n"
|
||||
elif [ -n "$CYCLOS_DB" ]; then
|
||||
# Re-grant Cyclos SELECT since create-restricted-db-user-safe.sh recreated the user
|
||||
mysql -h "$DB_APP_HOST" -P "$DB_APP_PORT" -u "$DB_USER" -p"$DB_PASS" -e "
|
||||
GRANT SELECT ON \`${CYCLOS_DB}\`.* TO '${DB_APP_USER}'@'localhost';
|
||||
GRANT SELECT ON \`${CYCLOS_DB}\`.* TO '${DB_APP_USER}'@'127.0.0.1';
|
||||
FLUSH PRIVILEGES;
|
||||
" 2>/dev/null
|
||||
printf "${GREEN}SELECT re-granted on ${CYCLOS_DB} after immutability setup.${NC}\n"
|
||||
fi
|
||||
else
|
||||
printf "${YELLOW}Skipped. Run manually: sudo ./scripts/create-restricted-db-user-safe.sh${NC}\n"
|
||||
fi
|
||||
|
||||
# Bring application back online
|
||||
printf "\n${GREEN}Disabling maintenance mode...${NC}\n"
|
||||
php artisan up --quiet 2>/dev/null || true
|
||||
|
||||
printf "\n${GREEN}=== Seeding complete ===${NC}\n"
|
||||
|
||||
# If a Cyclos migration was run, offer to verify it
|
||||
if [ -n "$CYCLOS_DB" ]; then
|
||||
printf "\n"
|
||||
printf "Run the Cyclos migration verification script? [Y/n]: "
|
||||
read RUN_VERIFY
|
||||
if [ -z "$RUN_VERIFY" ] || [ "$RUN_VERIFY" = "y" ] || [ "$RUN_VERIFY" = "Y" ]; then
|
||||
php artisan verify:cyclos-migration
|
||||
else
|
||||
printf "${YELLOW}Skipped. Run manually: php artisan verify:cyclos-migration${NC}\n"
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user