Features: 1) Added validation to ensure scripts execute from project root with 'evibes' directory check; 2) Introduced color formatting and ASCII art for enhanced script output; 3) Added RAM, CPU, and disk space verification to installation scripts; 4) Ensured Docker images existence before service startup; 5) Unified spinner-based progress display in Windows and Unix scripts.
Fixes: 1) Replaced hardcoded paths with script-relative paths for better portability; 2) Corrected CPU and memory calculation logic for system checks; 3) Replaced inconsistent script formatting and error handling; 4) Resolved redundant cleanup steps post service startup. Extra: Refactored and cleaned up script logic for maintainability; added WISELESS branding across scripts for consistency; enhanced terminal output and user messaging.
This commit is contained in:
parent
6b829331c3
commit
7d1bcaa8d4
13 changed files with 681 additions and 216 deletions
12
scripts/ASCII_ART_EVIBES
Normal file
12
scripts/ASCII_ART_EVIBES
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
=== ==. ===
|
||||||
|
.=== ==: ==== ===
|
||||||
|
==== ==- ===
|
||||||
|
==== === ===
|
||||||
|
=. ==== === .== === .===== =====- .===.
|
||||||
|
.=.= == = ===: ==- === ====. :===. ==== === .==:
|
||||||
|
.=::=== -= ===. ==- === === === ====::::::=== ===-
|
||||||
|
:== === === === === === === ====.
|
||||||
|
.. === === === === === === ====
|
||||||
|
= ====- === === === .===. . :===
|
||||||
|
.= == ==- === =:========. :========. ======.
|
||||||
|
|
@ -1,26 +1,62 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
env_file='.env'
|
if [ ! -d "./evibes" ]; then
|
||||||
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
if [[ ! -f $env_file ]]; then
|
exit 1
|
||||||
echo "Error: $env_file not found in the current directory." >&2
|
|
||||||
return 1 2>/dev/null || exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while IFS= read -r line || [[ -n $line ]]; do
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
line="${line#"${line%%[![:space:]]*}"}"
|
RESET="\e[0m"
|
||||||
line="${line%"${line##*[![:space:]]}"}"
|
GRAY="\e[90m"
|
||||||
[[ -z $line || $line == \#* ]] && continue
|
|
||||||
[[ $line != *"="* ]] && continue
|
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]:-$0}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
|
printf "\e[31m❌ Could not find ASCII art at %s\e[0m\n" "$ART_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
ENV_FILE=".env"
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
|
printf "\e[31m.env file not found in the current directory.\e[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -A env_vars
|
||||||
|
declare -a keys
|
||||||
|
|
||||||
|
while IFS= read -r raw; do
|
||||||
|
line="${raw%%#*}"
|
||||||
|
line="${line%"${line##*[![:space:]]}"}"
|
||||||
|
line="${line#"${line%%[![:space:]]*}"}"
|
||||||
|
[ -z "$line" ] || [[ "$line" != *=* ]] && continue
|
||||||
key="${line%%=*}"
|
key="${line%%=*}"
|
||||||
value="${line#*=}"
|
value="${line#*=}"
|
||||||
|
if [[ "${value:0:1}" == '"' && "${value: -1}" == '"' ]] || \
|
||||||
if [[ ( $value == \"*\" && $value == *\" ) || ( $value == \'*\' && $value == *\' ) ]]; then
|
[[ "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
|
||||||
value="${value:1:-1}"
|
value="${value:1:-1}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export "$key"="$value"
|
export "$key"="$value"
|
||||||
echo "Exported $key"
|
env_vars["$key"]="$value"
|
||||||
done < "$env_file"
|
keys+=("$key")
|
||||||
|
done < "$ENV_FILE"
|
||||||
|
|
||||||
|
if [ "${#keys[@]}" -gt 0 ]; then
|
||||||
|
IFS=$'\n' sorted=($(sort <<<"${keys[*]}"))
|
||||||
|
unset IFS
|
||||||
|
formatted=""
|
||||||
|
for k in "${sorted[@]}"; do
|
||||||
|
[ -z "$formatted" ] && formatted="$k=${env_vars[$k]}" \
|
||||||
|
|| formatted="$formatted;$k=${env_vars[$k]}"
|
||||||
|
done
|
||||||
|
printf "%s\n" "$formatted"
|
||||||
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,122 +1,145 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
rand_hex() {
|
if [ ! -d "./evibes" ]; then
|
||||||
openssl rand -hex "$1"
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
}
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
|
RESET="\e[0m"
|
||||||
|
GRAY="\e[90m"
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]:-$0}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
|
printf "\e[31m❌ Could not find ASCII art at %s\e[0m\n" "$ART_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
# prompt for a value with default
|
||||||
prompt_default() {
|
prompt_default() {
|
||||||
local name="$1" default="$2" val
|
local name="$1" default="$2" result
|
||||||
read -rp "Enter $name [$default]: " val
|
read -rp "Enter $name [$default]: " result
|
||||||
printf -v "$name" '%s' "${val:-$default}"
|
printf '%s\n' "${result:-$default}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# prompt for a value, auto-generate hex if blank
|
||||||
prompt_autogen() {
|
prompt_autogen() {
|
||||||
local name="$1" bytes="$2" val
|
local name="$1" bytes="$2" result
|
||||||
read -rp "Enter $name (leave blank to auto-generate): " val
|
read -rp "Enter $name (leave blank to auto-generate): " result
|
||||||
if [[ -z "$val" ]]; then
|
if [ -z "$result" ]; then
|
||||||
printf -v "$name" '%s' "$(rand_hex "$bytes")"
|
# generate $bytes random bytes as hex
|
||||||
else
|
result="$(head -c "$bytes" /dev/urandom | od -An -tx1 | tr -d ' \n')"
|
||||||
printf -v "$name" '%s' "$val"
|
|
||||||
fi
|
fi
|
||||||
|
printf '%s\n' "$result"
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt_default EVIBES_PROJECT_NAME "eVibes"
|
if [ -f .env ]; then
|
||||||
prompt_default EVIBES_FRONTEND_DOMAIN "evibes.com"
|
printf "\e[33m.env already exists and will be overwritten.\e[0m\n"
|
||||||
prompt_default EVIBES_BASE_DOMAIN "evibes.com"
|
read -rp "Press Enter to continue or Ctrl+C to abort"
|
||||||
prompt_default SENTRY_DSN ""
|
|
||||||
prompt_default DEBUG "1"
|
|
||||||
|
|
||||||
prompt_autogen SECRET_KEY 32
|
|
||||||
prompt_autogen JWT_SIGNING_KEY 64
|
|
||||||
|
|
||||||
prompt_default ALLOWED_HOSTS "evibes.com api.evibes.com b2b.evibes.com"
|
|
||||||
prompt_default CSRF_TRUSTED_ORIGINS "https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
|
||||||
prompt_default CORS_ALLOWED_ORIGINS "$CSRF_TRUSTED_ORIGINS"
|
|
||||||
|
|
||||||
prompt_default POSTGRES_DB "evibes"
|
|
||||||
prompt_default POSTGRES_USER "evibes_user"
|
|
||||||
prompt_autogen POSTGRES_PASSWORD 16
|
|
||||||
|
|
||||||
prompt_default DBBACKUP_SFTP_HOST "Your SFTP backup host"
|
|
||||||
prompt_default DBBACKUP_SFTP_USER "The username to use to log in to that host"
|
|
||||||
prompt_default DBBACKUP_SFTP_PASS "The password to use to log in to that host"
|
|
||||||
|
|
||||||
prompt_autogen ELASTIC_PASSWORD 16
|
|
||||||
prompt_autogen REDIS_PASSWORD 16
|
|
||||||
|
|
||||||
prompt_default PROMETHEUS_USER "evibes"
|
|
||||||
prompt_autogen PROMETHEUS_PASSWORD 16
|
|
||||||
|
|
||||||
prompt_default EMAIL_BACKEND "django.core.mail.backends.smtp.EmailBackend"
|
|
||||||
prompt_default EMAIL_HOST "smtp.whatever.evibes.com"
|
|
||||||
prompt_default EMAIL_PORT "465"
|
|
||||||
prompt_default EMAIL_USE_TLS "0"
|
|
||||||
prompt_default EMAIL_USE_SSL "1"
|
|
||||||
prompt_default EMAIL_HOST_USER "your-email-user@whatever.evibes.com"
|
|
||||||
prompt_default EMAIL_FROM "$EMAIL_HOST_USER"
|
|
||||||
prompt_default EMAIL_HOST_PASSWORD "SUPERSECRETEMAILHOSTPASSWORD"
|
|
||||||
|
|
||||||
prompt_default COMPANY_NAME "eVibes, Inc."
|
|
||||||
prompt_default COMPANY_PHONE_NUMBER "+888888888888"
|
|
||||||
prompt_default COMPANY_ADDRESS "The place that does not exist"
|
|
||||||
|
|
||||||
prompt_default OPENAI_API_KEY "Haha, really?"
|
|
||||||
prompt_default ABSTRACT_API_KEY "Haha, really? x2"
|
|
||||||
prompt_default DEEPL_AUTH_KEY "Haha, really? x3"
|
|
||||||
|
|
||||||
if [[ -f .env ]]; then
|
|
||||||
read -rp ".env already exists and will be overwritten. Press ENTER to continue or Ctrl+C to abort. "
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat > .env <<EOF
|
PROJECT_NAME=$(prompt_default 'EVIBES_PROJECT_NAME' 'eVibes')
|
||||||
EVIBES_PROJECT_NAME="${EVIBES_PROJECT_NAME}"
|
FRONTEND_DOMAIN=$(prompt_default 'EVIBES_FRONTEND_DOMAIN' 'evibes.com')
|
||||||
EVIBES_FRONTEND_DOMAIN="${EVIBES_FRONTEND_DOMAIN}"
|
BASE_DOMAIN=$(prompt_default 'EVIBES_BASE_DOMAIN' 'evibes.com')
|
||||||
EVIBES_BASE_DOMAIN="${EVIBES_BASE_DOMAIN}"
|
SENTRY_DSN=$(prompt_default 'SENTRY_DSN' '')
|
||||||
SENTRY_DSN="${SENTRY_DSN}"
|
DEBUG=$(prompt_default 'DEBUG' '1')
|
||||||
DEBUG=${DEBUG}
|
|
||||||
|
|
||||||
SECRET_KEY="${SECRET_KEY}"
|
SECRET_KEY=$(prompt_autogen 'SECRET_KEY' 32)
|
||||||
JWT_SIGNING_KEY="${JWT_SIGNING_KEY}"
|
JWT_SIGNING_KEY=$(prompt_autogen 'JWT_SIGNING_KEY' 64)
|
||||||
|
|
||||||
ALLOWED_HOSTS="${ALLOWED_HOSTS}"
|
ALLOWED_HOSTS=$(prompt_default 'ALLOWED_HOSTS' 'evibes.com api.evibes.com b2b.evibes.com')
|
||||||
CSRF_TRUSTED_ORIGINS="${CSRF_TRUSTED_ORIGINS}"
|
CSRF_TRUSTED_ORIGINS=$(prompt_default 'CSRF_TRUSTED_ORIGINS' 'https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com')
|
||||||
CORS_ALLOWED_ORIGINS="${CORS_ALLOWED_ORIGINS}"
|
CORS_ALLOWED_ORIGINS="$CSRF_TRUSTED_ORIGINS"
|
||||||
|
|
||||||
POSTGRES_DB="${POSTGRES_DB}"
|
POSTGRES_DB=$(prompt_default 'POSTGRES_DB' 'evibes')
|
||||||
POSTGRES_USER="${POSTGRES_USER}"
|
POSTGRES_USER=$(prompt_default 'POSTGRES_USER' 'evibes_user')
|
||||||
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
|
POSTGRES_PASSWORD=$(prompt_autogen 'POSTGRES_PASSWORD' 16)
|
||||||
|
|
||||||
DBBACKUP_SFTP_HOST="${DBBACKUP_SFTP_HOST}"
|
DBBACKUP_SFTP_HOST=$(prompt_default 'DBBACKUP_SFTP_HOST' 'Your SFTP backup host')
|
||||||
DBBACKUP_SFTP_USER="${DBBACKUP_SFTP_USER}"
|
DBBACKUP_SFTP_USER=$(prompt_default 'DBBACKUP_SFTP_USER' 'The username to use to log in to that host')
|
||||||
DBBACKUP_SFTP_PASS="${DBBACKUP_SFTP_PASS}"
|
DBBACKUP_SFTP_PASS=$(prompt_default 'DBBACKUP_SFTP_PASS' 'The password to use to log in to that host')
|
||||||
|
|
||||||
ELASTIC_PASSWORD="${ELASTIC_PASSWORD}"
|
ELASTIC_PASSWORD=$(prompt_autogen 'ELASTIC_PASSWORD' 16)
|
||||||
|
REDIS_PASSWORD=$(prompt_autogen 'REDIS_PASSWORD' 16)
|
||||||
|
|
||||||
REDIS_PASSWORD="${REDIS_PASSWORD}"
|
PROMETHEUS_USER=$(prompt_default 'PROMETHEUS_USER' 'evibes')
|
||||||
|
PROMETHEUS_PASSWORD=$(prompt_autogen 'PROMETHEUS_PASSWORD' 16)
|
||||||
|
|
||||||
CELERY_BROKER_URL="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
EMAIL_BACKEND=$(prompt_default 'EMAIL_BACKEND' 'django.core.mail.backends.smtp.EmailBackend')
|
||||||
CELERY_RESULT_BACKEND="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
EMAIL_HOST=$(prompt_default 'EMAIL_HOST' 'smtp.whatever.evibes.com')
|
||||||
|
EMAIL_PORT=$(prompt_default 'EMAIL_PORT' '465')
|
||||||
|
EMAIL_USE_TLS=$(prompt_default 'EMAIL_USE_TLS' '0')
|
||||||
|
EMAIL_USE_SSL=$(prompt_default 'EMAIL_USE_SSL' '1')
|
||||||
|
EMAIL_HOST_USER=$(prompt_default 'EMAIL_HOST_USER' 'your-email-user@whatever.evibes.com')
|
||||||
|
EMAIL_FROM="$EMAIL_HOST_USER"
|
||||||
|
EMAIL_HOST_PASSWORD=$(prompt_default 'EMAIL_HOST_PASSWORD' 'SUPERSECRETEMAILHOSTPASSWORD')
|
||||||
|
|
||||||
PROMETHEUS_USER="${PROMETHEUS_USER}"
|
COMPANY_NAME=$(prompt_default 'COMPANY_NAME' 'eVibes, Inc.')
|
||||||
PROMETHEUS_PASSWORD="${PROMETHEUS_PASSWORD}"
|
COMPANY_PHONE_NUMBER=$(prompt_default 'COMPANY_PHONE_NUMBER' '+888888888888')
|
||||||
|
COMPANY_ADDRESS=$(prompt_default 'COMPANY_ADDRESS' 'The place that does not exist')
|
||||||
|
|
||||||
EMAIL_BACKEND="${EMAIL_BACKEND}"
|
OPENAI_API_KEY=$(prompt_default 'OPENAI_API_KEY' 'Haha, really?')
|
||||||
EMAIL_HOST="${EMAIL_HOST}"
|
ABSTRACT_API_KEY=$(prompt_default 'ABSTRACT_API_KEY' 'Haha, really? x2')
|
||||||
EMAIL_PORT="${EMAIL_PORT}"
|
DEEPL_AUTH_KEY=$(prompt_default 'DEEPL_AUTH_KEY' 'Haha, really? x3')
|
||||||
EMAIL_USE_TLS=${EMAIL_USE_TLS}
|
|
||||||
EMAIL_USE_SSL=${EMAIL_USE_SSL}
|
|
||||||
EMAIL_HOST_USER="${EMAIL_HOST_USER}"
|
|
||||||
EMAIL_HOST_PASSWORD="${EMAIL_HOST_PASSWORD}"
|
|
||||||
EMAIL_FROM="${EMAIL_FROM}"
|
|
||||||
|
|
||||||
COMPANY_NAME="${COMPANY_NAME}"
|
# Write to .env
|
||||||
COMPANY_PHONE_NUMBER="${COMPANY_PHONE_NUMBER}"
|
{
|
||||||
COMPANY_ADDRESS="${COMPANY_ADDRESS}"
|
printf 'EVIBES_PROJECT_NAME="%s"\n' "$PROJECT_NAME"
|
||||||
|
printf 'EVIBES_FRONTEND_DOMAIN="%s"\n' "$FRONTEND_DOMAIN"
|
||||||
|
printf 'EVIBES_BASE_DOMAIN="%s"\n' "$BASE_DOMAIN"
|
||||||
|
printf 'SENTRY_DSN="%s"\n' "$SENTRY_DSN"
|
||||||
|
printf 'DEBUG=%s\n\n' "$DEBUG"
|
||||||
|
|
||||||
OPENAI_API_KEY="${OPENAI_API_KEY}"
|
printf 'SECRET_KEY="%s"\n' "$SECRET_KEY"
|
||||||
ABSTRACT_API_KEY="${ABSTRACT_API_KEY}"
|
printf 'JWT_SIGNING_KEY="%s"\n\n' "$JWT_SIGNING_KEY"
|
||||||
DEEPL_AUTH_KEY="${DEEPL_AUTH_KEY}"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo ".env file generated with fresh values."
|
printf 'ALLOWED_HOSTS="%s"\n' "$ALLOWED_HOSTS"
|
||||||
|
printf 'CSRF_TRUSTED_ORIGINS="%s"\n' "$CSRF_TRUSTED_ORIGINS"
|
||||||
|
printf 'CORS_ALLOWED_ORIGINS="%s"\n\n' "$CORS_ALLOWED_ORIGINS"
|
||||||
|
|
||||||
|
printf 'POSTGRES_DB="%s"\n' "$POSTGRES_DB"
|
||||||
|
printf 'POSTGRES_USER="%s"\n' "$POSTGRES_USER"
|
||||||
|
printf 'POSTGRES_PASSWORD="%s"\n\n' "$POSTGRES_PASSWORD"
|
||||||
|
|
||||||
|
printf 'DBBACKUP_SFTP_HOST="%s"\n' "$DBBACKUP_SFTP_HOST"
|
||||||
|
printf 'DBBACKUP_SFTP_USER="%s"\n' "$DBBACKUP_SFTP_USER"
|
||||||
|
printf 'DBBACKUP_SFTP_PASS="%s"\n\n' "$DBBACKUP_SFTP_PASS"
|
||||||
|
|
||||||
|
printf 'ELASTIC_PASSWORD="%s"\n\n' "$ELASTIC_PASSWORD"
|
||||||
|
|
||||||
|
printf 'REDIS_PASSWORD="%s"\n' "$REDIS_PASSWORD"
|
||||||
|
printf 'CELERY_BROKER_URL="redis://:%s@redis:6379/0"\n' "$REDIS_PASSWORD"
|
||||||
|
printf 'CELERY_RESULT_BACKEND="redis://:%s@redis:6379/0"\n\n' "$REDIS_PASSWORD"
|
||||||
|
|
||||||
|
printf 'PROMETHEUS_USER="%s"\n' "$PROMETHEUS_USER"
|
||||||
|
printf 'PROMETHEUS_PASSWORD="%s"\n\n' "$PROMETHEUS_PASSWORD"
|
||||||
|
|
||||||
|
printf 'EMAIL_BACKEND="%s"\n' "$EMAIL_BACKEND"
|
||||||
|
printf 'EMAIL_HOST="%s"\n' "$EMAIL_HOST"
|
||||||
|
printf 'EMAIL_PORT="%s"\n' "$EMAIL_PORT"
|
||||||
|
printf 'EMAIL_USE_TLS=%s\n' "$EMAIL_USE_TLS"
|
||||||
|
printf 'EMAIL_USE_SSL=%s\n' "$EMAIL_USE_SSL"
|
||||||
|
printf 'EMAIL_HOST_USER="%s"\n' "$EMAIL_HOST_USER"
|
||||||
|
printf 'EMAIL_HOST_PASSWORD="%s"\n' "$EMAIL_HOST_PASSWORD"
|
||||||
|
printf 'EMAIL_FROM="%s"\n\n' "$EMAIL_FROM"
|
||||||
|
|
||||||
|
printf 'COMPANY_NAME="%s"\n' "$COMPANY_NAME"
|
||||||
|
printf 'COMPANY_PHONE_NUMBER="%s"\n' "$COMPANY_PHONE_NUMBER"
|
||||||
|
printf 'COMPANY_ADDRESS="%s"\n\n' "$COMPANY_ADDRESS"
|
||||||
|
|
||||||
|
printf 'OPENAI_API_KEY="%s"\n\n' "$OPENAI_API_KEY"
|
||||||
|
printf 'ABSTRACT_API_KEY="%s"\n\n' "$ABSTRACT_API_KEY"
|
||||||
|
printf 'DEEPL_AUTH_KEY="%s"\n' "$DEEPL_AUTH_KEY"
|
||||||
|
} > .env
|
||||||
|
|
||||||
|
printf "\e[32m.env file generated with fresh values.\e[0m\n"
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,63 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
if [[ ! -f .env ]]; then
|
if [ ! -d "./evibes" ]; then
|
||||||
echo "Warning: .env file not found. Exiting without running Docker steps."
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
|
RESET="\e[0m"
|
||||||
|
GRAY="\e[90m"
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
|
printf "\e[31m❌ Could not find ASCII art at %s\e[0m\n" "$ART_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
printf "\e[33m.env file not found. Exiting without running Docker steps.\e[0m\n"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cpuCount=$(nproc)
|
CPU_COUNT=$(nproc 2>/dev/null || sysctl -n hw.ncpu)
|
||||||
if (( cpuCount < 4 )); then
|
if [ "$CPU_COUNT" -lt 4 ]; then
|
||||||
echo "Error: Insufficient CPU cores: $cpuCount detected. Minimum 4 required." >&2
|
printf "\e[31mInsufficient CPU cores: %d detected. Minimum 4 required.\e[0m\n" "$CPU_COUNT"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mem_kb=$(awk '/MemTotal:/ {print $2}' /proc/meminfo)
|
if [ -f /proc/meminfo ]; then
|
||||||
totalMemGB=$(awk "BEGIN {printf \"%.2f\", $mem_kb/1024/1024}")
|
MEM_KB=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
|
||||||
if (( mem_kb < 6*1024*1024 )); then
|
MEM_GB=$(awk "BEGIN {printf \"%.2f\", ${MEM_KB}/1024/1024}")
|
||||||
echo "Error: Insufficient RAM: ${totalMemGB} GB detected. Minimum 6 GB required." >&2
|
else
|
||||||
|
MEM_BYTES=$(vm_stat | awk '/Pages free/ {print $3 * 4096}')
|
||||||
|
MEM_GB=$(awk "BEGIN {printf \"%.2f\", ${MEM_BYTES}/1024/1024/1024}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( $(echo "$MEM_GB < 6" | bc -l) )); then
|
||||||
|
printf "\e[31mInsufficient RAM: %.2fGB detected. Minimum 6 GB required.\e[0m\n" "$MEM_GB"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
avail_kb=$(df --output=avail . | tail -n1)
|
FREE_GB=$(df -BG . | awk 'NR==2 {gsub("G","",$4); print $4}')
|
||||||
freeGB=$(awk "BEGIN {printf \"%.2f\", $avail_kb/1024/1024}")
|
if [ "$FREE_GB" -lt 20 ]; then
|
||||||
if (( avail_kb < 20*1024*1024 )); then
|
printf "\e[31mInsufficient free disk space: %dGB available. Minimum 20 GB required.\e[0m\n" "$FREE_GB"
|
||||||
echo "Error: Insufficient free disk space: ${freeGB} GB available. Minimum 20 GB required." >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "System requirements met: CPU cores=${cpuCount}, RAM=${totalMemGB}GB, FreeDisk=${freeGB}GB"
|
printf "\e[32mSystem requirements met: CPU cores=%d, RAM=%.2fGB, FreeDisk=%dGB\e[0m\n" "$CPU_COUNT" "$MEM_GB" "$FREE_GB"
|
||||||
|
|
||||||
echo "Pulling related images..."
|
printf "\e[36mPulling related images…\e[0m\n"
|
||||||
docker compose pull
|
docker compose pull --ansi never
|
||||||
|
|
||||||
echo "Building the project's images..."
|
printf "\e[36mBuilding the project's images…\e[0m\n"
|
||||||
docker compose build
|
docker compose build --ansi never
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,50 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
run_cmd() {
|
if [ ! -d "./evibes" ]; then
|
||||||
local msg=$1; shift
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
printf "%s... " "$msg"
|
exit 1
|
||||||
"$@"
|
fi
|
||||||
printf "OK\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
|
RESET="\e[0m"
|
||||||
|
GRAY="\e[90m"
|
||||||
|
CYAN="\e[36m"
|
||||||
|
|
||||||
run_cmd "Stopping services (down)" \
|
SOURCE="${BASH_SOURCE[0]:-$0}"
|
||||||
docker compose down
|
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
run_cmd "Rebuilding services" \
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
docker compose build
|
printf "\e[31m❌ Could not find ASCII art at %s\e[0m\n" "$ART_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
run_cmd "Starting services" \
|
while IFS= read -r line; do
|
||||||
docker compose up -d
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
run_cmd "Applying database migrations" \
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
printf "%bStopping services…%b\n" "$CYAN" "$RESET"
|
||||||
|
docker compose down --ansi never
|
||||||
|
|
||||||
|
printf "%bRebuilding services…%b\n" "$CYAN" "$RESET"
|
||||||
|
docker compose build --ansi never
|
||||||
|
|
||||||
|
printf "%bStarting services…%b\n" "$CYAN" "$RESET"
|
||||||
|
docker compose up -d --ansi never
|
||||||
|
|
||||||
|
printf "%bApplying database migrations…%b\n" "$CYAN" "$RESET"
|
||||||
docker compose exec app poetry run python manage.py migrate --no-input
|
docker compose exec app poetry run python manage.py migrate --no-input
|
||||||
|
|
||||||
run_cmd "Collecting static files" \
|
printf "%bCollecting static files…%b\n" "$CYAN" "$RESET"
|
||||||
docker compose exec app poetry run python manage.py collectstatic --no-input
|
docker compose exec app poetry run python manage.py collectstatic --no-input
|
||||||
|
|
||||||
run_cmd "Setting default caches" \
|
printf "%bSetting default caches…%b\n" "$CYAN" "$RESET"
|
||||||
docker compose exec app poetry run python manage.py set_default_caches
|
docker compose exec app poetry run python manage.py set_default_caches
|
||||||
|
|
||||||
run_cmd "Cleaning up unused Docker data" \
|
printf "%bCleaning up unused Docker data…%b\n" "$CYAN" "$RESET"
|
||||||
docker system prune -f
|
docker system prune -f
|
||||||
|
|
||||||
echo
|
printf "\n\e[37mAll done! eVibes is up and running.\e[0m\n"
|
||||||
echo "All done! eVibes is up and running."
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,60 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Starting Docker Compose services..."
|
if [ ! -d "./evibes" ]; then
|
||||||
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
if ! docker compose up --no-build --detach --wait; then
|
|
||||||
echo "Error: Images are not pulled/built. Please run the install.sh script first." >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Containers are up and healthy."
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
|
RESET="\e[0m"
|
||||||
|
GRAY="\e[90m"
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]:-$0}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
|
printf "\e[31m❌ Could not find ASCII art at %s\e[0m\n" "$ART_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
printf "\e[32mVerifying all images are present…\e[0m\n"
|
||||||
|
|
||||||
|
if ! command -v jq >/dev/null 2>&1; then
|
||||||
|
printf "\e[31mjq is required for verifying images. Please install jq.\e[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
images=$(docker compose config --format json | jq -r '.services[]?.image // empty')
|
||||||
|
|
||||||
|
for image in $images; do
|
||||||
|
if ! docker image inspect "$image" >/dev/null 2>&1; then
|
||||||
|
printf "\e[31mRequired images not found. Please run install.sh first.\e[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf " • Found image: %s\n" "$image"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "\e[36mStarting services…\e[0m\n"
|
||||||
|
docker compose up --no-build --detach --wait --ansi never
|
||||||
|
|
||||||
|
printf "\e[36mApplying migrations…\e[0m\n"
|
||||||
|
docker compose exec app poetry run python manage.py migrate --no-input
|
||||||
|
|
||||||
|
printf "\e[36mCollecting static files…\e[0m\n"
|
||||||
|
docker compose exec app poetry run python manage.py collectstatic --no-input
|
||||||
|
|
||||||
|
printf "\e[36mSetting default caches…\e[0m\n"
|
||||||
|
docker compose exec app poetry run python manage.py set_default_caches
|
||||||
|
|
||||||
|
printf "\e[36mCleaning up…\e[0m\n"
|
||||||
|
docker compose exec app poetry run python manage.py set_default_caches
|
||||||
|
|
||||||
|
printf "\e[32mAll done! eVibes is up and running.\e[0m\n"
|
||||||
|
|
|
||||||
39
scripts/Unix/uninstall.sh
Normal file
39
scripts/Unix/uninstall.sh
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ ! -d "./evibes" ]; then
|
||||||
|
printf "\e[31m❌ Please run this script from the project's root (where the 'evibes' directory lives).\e[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PURPLE="\e[38;2;121;101;209m"
|
||||||
|
RESET="\e[0m"
|
||||||
|
GRAY="\e[90m"
|
||||||
|
CYAN="\e[36m"
|
||||||
|
RED="\e[31m"
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]:-$0}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
|
||||||
|
ART_PATH="$SCRIPT_DIR/../ASCII_ART_EVIBES"
|
||||||
|
|
||||||
|
if [ ! -f "$ART_PATH" ]; then
|
||||||
|
printf "%b❌ Could not find ASCII art at %s%b\n" "$RED" "$ART_PATH" "$RESET"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
printf "%b%s%b\n" "$PURPLE" "$line" "$RESET"
|
||||||
|
done < "$ART_PATH"
|
||||||
|
|
||||||
|
printf "\n%bby WISELESS TEAM%b\n\n" "$GRAY" "$RESET"
|
||||||
|
|
||||||
|
printf "%bKilling services…%b\n" "$CYAN" "$RESET"
|
||||||
|
docker compose down --ansi never
|
||||||
|
|
||||||
|
printf "%bCleaning up Docker data…%b\n" "$CYAN" "$RESET"
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
printf "%bRemoving related files…%b\n" "$CYAN" "$RESET"
|
||||||
|
rm -rf ./services_data ./media ./static
|
||||||
|
|
||||||
|
printf "%bBye-bye, hope you return later!%b\n" "$RED" "$RESET"
|
||||||
|
|
@ -2,6 +2,62 @@
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
|
$Spinner = @('|', '/', '-', '\')
|
||||||
|
$Colors = @('White', 'Gray')
|
||||||
|
$Delay = 100
|
||||||
|
|
||||||
|
function Invoke-Spinner
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$Arguments,
|
||||||
|
[Parameter(Mandatory)][string]$Message
|
||||||
|
)
|
||||||
|
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}… " -f $Message)
|
||||||
|
$si = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$si.FileName = "docker"
|
||||||
|
$si.Arguments = "$Arguments --ansi never"
|
||||||
|
$si.RedirectStandardOutput = $true
|
||||||
|
$si.RedirectStandardError = $true
|
||||||
|
$si.UseShellExecute = $false
|
||||||
|
$p = [System.Diagnostics.Process]::Start($si)
|
||||||
|
$i = 0
|
||||||
|
while (-not $p.HasExited)
|
||||||
|
{
|
||||||
|
$frame = $Spinner[$i % $Spinner.Length]
|
||||||
|
$col = $Colors[$i % $Colors.Length]
|
||||||
|
Write-Host -NoNewLine -ForegroundColor $col $frame
|
||||||
|
Start-Sleep -Milliseconds $Delay
|
||||||
|
Write-Host -NoNewLine "`b"
|
||||||
|
$i++
|
||||||
|
}
|
||||||
|
$p.WaitForExit()
|
||||||
|
Write-Host -ForegroundColor Green "✔"
|
||||||
|
}
|
||||||
|
|
||||||
$envFile = '.env'
|
$envFile = '.env'
|
||||||
|
|
||||||
if (-not (Test-Path $envFile))
|
if (-not (Test-Path $envFile))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,29 @@
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
function Get-RandomHex
|
function Get-RandomHex
|
||||||
{
|
{
|
||||||
param([int]$Bytes)
|
param([int]$Bytes)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,29 @@
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
if (-not (Test-Path '.env'))
|
if (-not (Test-Path '.env'))
|
||||||
{
|
{
|
||||||
Write-Warning ".env file not found. Exiting without running Docker steps."
|
Write-Warning ".env file not found. Exiting without running Docker steps."
|
||||||
|
|
@ -33,13 +56,40 @@ if ($freeGB -lt 20)
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "System requirements met:" `
|
Write-Host "System requirements met: CPU cores=$cpuCount, RAM=${totalMemGB}GB, FreeDisk=${freeGB}GB" -ForegroundColor Green
|
||||||
"CPU cores=$cpuCount," `
|
|
||||||
"RAM=${totalMemGB}GB," `
|
|
||||||
"FreeDisk=${freeGB}GB" -ForegroundColor Green
|
|
||||||
|
|
||||||
Write-Host "Pulling related images..." -ForegroundColor Green
|
$Spinner = @('|', '/', '-', '\')
|
||||||
docker compose pull
|
$Colors = @('White', 'Gray')
|
||||||
|
$Delay = 100
|
||||||
|
|
||||||
Write-Host "Building the project's images..." -ForegroundColor Green
|
function Invoke-Spinner
|
||||||
docker compose build
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$Arguments,
|
||||||
|
[Parameter(Mandatory)][string]$Message
|
||||||
|
)
|
||||||
|
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}… " -f $Message)
|
||||||
|
$si = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$si.FileName = "docker"
|
||||||
|
$si.Arguments = "$Arguments --ansi never"
|
||||||
|
$si.RedirectStandardOutput = $true
|
||||||
|
$si.RedirectStandardError = $true
|
||||||
|
$si.UseShellExecute = $false
|
||||||
|
$p = [System.Diagnostics.Process]::Start($si)
|
||||||
|
$i = 0
|
||||||
|
while (-not $p.HasExited)
|
||||||
|
{
|
||||||
|
$frame = $Spinner[$i % $Spinner.Length]
|
||||||
|
$col = $Colors[$i % $Colors.Length]
|
||||||
|
Write-Host -NoNewLine -ForegroundColor $col $frame
|
||||||
|
Start-Sleep -Milliseconds $Delay
|
||||||
|
Write-Host -NoNewline "`b"
|
||||||
|
$i++
|
||||||
|
}
|
||||||
|
$p.WaitForExit()
|
||||||
|
Write-Host -ForegroundColor Green "✔"
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-Spinner -Arguments "compose pull" -Message "Pulling related images"
|
||||||
|
Invoke-Spinner -Arguments "compose build" -Message "Building the project's images"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,28 @@
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
$Spinner = @('|', '/', '-', '\')
|
$Spinner = @('|', '/', '-', '\')
|
||||||
$Colors = @('White', 'Gray')
|
$Colors = @('White', 'Gray')
|
||||||
$Delay = 100
|
$Delay = 100
|
||||||
|
|
@ -8,53 +31,37 @@ function Invoke-Spinner
|
||||||
{
|
{
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)][string]$Arguments,
|
||||||
[string]$Arguments,
|
[Parameter(Mandatory)][string]$Message
|
||||||
|
|
||||||
[Parameter(Mandatory)]
|
|
||||||
[string]$Message
|
|
||||||
)
|
)
|
||||||
|
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}… " -f $Message)
|
||||||
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}... " -f $Message)
|
$si = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$si.FileName = "docker"
|
||||||
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
|
$si.Arguments = "$Arguments --ansi never"
|
||||||
$startInfo.FileName = "docker"
|
$si.RedirectStandardOutput = $true
|
||||||
$startInfo.Arguments = $Arguments + " --ansi never"
|
$si.RedirectStandardError = $true
|
||||||
$startInfo.RedirectStandardOutput = $true
|
$si.UseShellExecute = $false
|
||||||
$startInfo.RedirectStandardError = $true
|
$p = [System.Diagnostics.Process]::Start($si)
|
||||||
$startInfo.UseShellExecute = $false
|
|
||||||
|
|
||||||
$proc = [System.Diagnostics.Process]::Start($startInfo)
|
|
||||||
|
|
||||||
$i = 0
|
$i = 0
|
||||||
while (-not $proc.HasExited)
|
while (-not $p.HasExited)
|
||||||
{
|
{
|
||||||
$frame = $Spinner[$i % $Spinner.Length]
|
$frame = $Spinner[$i % $Spinner.Length]
|
||||||
$color = $Colors[$i % $Colors.Length]
|
$col = $Colors[$i % $Colors.Length]
|
||||||
Write-Host -NoNewLine -ForegroundColor $color $frame
|
Write-Host -NoNewLine -ForegroundColor $col $frame
|
||||||
Start-Sleep -Milliseconds $Delay
|
Start-Sleep -Milliseconds $Delay
|
||||||
Write-Host -NoNewLine "`b"
|
Write-Host -NoNewline "`b"
|
||||||
$i++
|
$i++
|
||||||
}
|
}
|
||||||
$proc.WaitForExit()
|
$p.WaitForExit()
|
||||||
|
|
||||||
Write-Host -ForegroundColor Green "✔"
|
Write-Host -ForegroundColor Green "✔"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host ""
|
Invoke-Spinner -Arguments "compose down" -Message "Stopping services"
|
||||||
Invoke-Spinner -Arguments "compose down" `
|
Invoke-Spinner -Arguments "compose build" -Message "Rebuilding services"
|
||||||
-Message "Stopping services (down)"
|
Invoke-Spinner -Arguments "compose up -d" -Message "Starting services"
|
||||||
Invoke-Spinner -Arguments "compose build" `
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py migrate --no-input" -Message "Applying database migrations"
|
||||||
-Message "Rebuilding services"
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py collectstatic --no-input" -Message "Collecting static files"
|
||||||
Invoke-Spinner -Arguments "compose up -d" `
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py set_default_caches" -Message "Setting default caches"
|
||||||
-Message "Starting services"
|
Invoke-Spinner -Arguments "system prune -f" -Message "Cleaning up unused Docker data"
|
||||||
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py migrate --no-input" `
|
|
||||||
-Message "Applying database migrations"
|
|
||||||
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py collectstatic --no-input" `
|
|
||||||
-Message "Collecting static files"
|
|
||||||
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py set_default_caches" `
|
|
||||||
-Message "Setting default caches"
|
|
||||||
Invoke-Spinner -Arguments "system prune -f" `
|
|
||||||
-Message "Cleaning up unused Docker data"
|
|
||||||
|
|
||||||
Write-Host "`nAll done! eVibes is up and running." -ForegroundColor White
|
Write-Host "`nAll done! eVibes is up and running." -ForegroundColor White
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,29 @@
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
Write-Host "Verifying all images are present…" -ForegroundColor Green
|
Write-Host "Verifying all images are present…" -ForegroundColor Green
|
||||||
|
|
||||||
$config = docker compose config --format json | ConvertFrom-Json
|
$config = docker compose config --format json | ConvertFrom-Json
|
||||||
|
|
@ -26,6 +49,43 @@ foreach ($prop in $config.services.PSObject.Properties)
|
||||||
Write-Host " • Found image: $image"
|
Write-Host " • Found image: $image"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "All images present, starting services…" -ForegroundColor Green
|
$Spinner = @('|', '/', '-', '\')
|
||||||
docker compose up --no-build --detach --wait | Out-Null
|
$Colors = @('White', 'Gray')
|
||||||
Write-Host "Containers are up and healthy." -ForegroundColor Green
|
$Delay = 100
|
||||||
|
|
||||||
|
function Invoke-Spinner
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$Arguments,
|
||||||
|
[Parameter(Mandatory)][string]$Message
|
||||||
|
)
|
||||||
|
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}… " -f $Message)
|
||||||
|
$si = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$si.FileName = "docker"
|
||||||
|
$si.Arguments = "$Arguments --ansi never"
|
||||||
|
$si.RedirectStandardOutput = $true
|
||||||
|
$si.RedirectStandardError = $true
|
||||||
|
$si.UseShellExecute = $false
|
||||||
|
$p = [System.Diagnostics.Process]::Start($si)
|
||||||
|
$i = 0
|
||||||
|
while (-not $p.HasExited)
|
||||||
|
{
|
||||||
|
$frame = $Spinner[$i % $Spinner.Length]
|
||||||
|
$col = $Colors[$i % $Colors.Length]
|
||||||
|
Write-Host -NoNewLine -ForegroundColor $col $frame
|
||||||
|
Start-Sleep -Milliseconds $Delay
|
||||||
|
Write-Host -NoNewLine "`b"
|
||||||
|
$i++
|
||||||
|
}
|
||||||
|
$p.WaitForExit()
|
||||||
|
Write-Host -ForegroundColor Green "✔"
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-Spinner -Arguments "compose up --no-build --detach --wait" -Message "Starting services"
|
||||||
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py migrate --no-input" -Message "Applying migrations"
|
||||||
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py collectstatic --no-input" -Message "Collecting static files"
|
||||||
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py set_default_caches" -Message "Setting default caches"
|
||||||
|
Invoke-Spinner -Arguments "compose exec app poetry run python manage.py set_default_caches" -Message "Cleaning up"
|
||||||
|
|
||||||
|
Write-Host "All done! eVibes is up and running." -ForegroundColor Green
|
||||||
|
|
|
||||||
67
scripts/Windows/uninstall.ps1
Normal file
67
scripts/Windows/uninstall.ps1
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path ".\evibes" -PathType Container))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Please run this script from the project's root (where the 'evibes' directory lives)." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$purple = "`e[38;2;121;101;209m"
|
||||||
|
$reset = "`e[0m"
|
||||||
|
|
||||||
|
$artPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\ASCII_ART_EVIBES'
|
||||||
|
if (-not (Test-Path $artPath))
|
||||||
|
{
|
||||||
|
Write-Host "❌ Could not find ASCII art at $artPath" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$art = Get-Content -Raw -Path $artPath
|
||||||
|
$art -split "`r?`n" | ForEach-Object {
|
||||||
|
Write-Host "$purple$_$reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nby WISELESS TEAM`n" -ForegroundColor Gray
|
||||||
|
|
||||||
|
$Spinner = @('|', '/', '-', '\')
|
||||||
|
$Colors = @('White', 'Gray')
|
||||||
|
$Delay = 100
|
||||||
|
|
||||||
|
function Invoke-Spinner
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$Arguments,
|
||||||
|
[Parameter(Mandatory)][string]$Message
|
||||||
|
)
|
||||||
|
Write-Host -NoNewLine -ForegroundColor Cyan ("{0}… " -f $Message)
|
||||||
|
$si = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$si.FileName = "docker"
|
||||||
|
$si.Arguments = "$Arguments --ansi never"
|
||||||
|
$si.RedirectStandardOutput = $true
|
||||||
|
$si.RedirectStandardError = $true
|
||||||
|
$si.UseShellExecute = $false
|
||||||
|
$p = [System.Diagnostics.Process]::Start($si)
|
||||||
|
$i = 0
|
||||||
|
while (-not $p.HasExited)
|
||||||
|
{
|
||||||
|
$frame = $Spinner[$i % $Spinner.Length]
|
||||||
|
$col = $Colors[$i % $Colors.Length]
|
||||||
|
Write-Host -NoNewLine -ForegroundColor $col $frame
|
||||||
|
Start-Sleep -Milliseconds $Delay
|
||||||
|
Write-Host -NoNewline "`b"
|
||||||
|
$i++
|
||||||
|
}
|
||||||
|
$p.WaitForExit()
|
||||||
|
Write-Host -ForegroundColor Green "✔"
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-Spinner -Arguments "compose down" -Message "Killing services"
|
||||||
|
Invoke-Spinner -Arguments "system prune -f" -Message "Cleaning up Docker data"
|
||||||
|
Write-Host -ForegroundColor Cyan "Removing related files..."
|
||||||
|
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue ./services_data
|
||||||
|
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue ./media
|
||||||
|
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue ./static
|
||||||
|
Write-Host -ForegroundColor Red "Bye-bye, hope you return later!"
|
||||||
Loading…
Reference in a new issue