379 lines
13 KiB
Bash
379 lines
13 KiB
Bash
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
BASE_DIR="$(cd "$(dirname "$0")"/.. && pwd)"
|
|
LOG_DIR="$BASE_DIR/logs"
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
PY_BIN=""
|
|
PIP_BIN=""
|
|
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
ver="$(python3 -c 'import sys;print("{}{}".format(sys.version_info.major,sys.version_info.minor))')"
|
|
if [ "$ver" -ge 37 ]; then
|
|
if [ ! -d "$BASE_DIR/.venv" ]; then
|
|
python3 -m venv "$BASE_DIR/.venv"
|
|
fi
|
|
PY_BIN="$BASE_DIR/.venv/bin/python"
|
|
PIP_BIN="$BASE_DIR/.venv/bin/pip"
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$PY_BIN" ]; then
|
|
CONDA_DIR="$BASE_DIR/.miniconda"
|
|
if [ ! -d "$CONDA_DIR" ]; then
|
|
url="https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh"
|
|
tmp="$BASE_DIR/miniconda.sh"
|
|
if command -v wget >/dev/null 2>&1; then
|
|
wget -qO "$tmp" "$url"
|
|
else
|
|
curl -fsSL -o "$tmp" "$url"
|
|
fi
|
|
bash "$tmp" -b -p "$CONDA_DIR"
|
|
rm -f "$tmp"
|
|
fi
|
|
ENV_DIR="$BASE_DIR/.conda-env"
|
|
if [ ! -d "$ENV_DIR" ]; then
|
|
"$CONDA_DIR/bin/conda" create -y -p "$ENV_DIR" python=3.8
|
|
fi
|
|
PY_BIN="$ENV_DIR/bin/python"
|
|
PIP_BIN="$ENV_DIR/bin/pip"
|
|
fi
|
|
|
|
"$PIP_BIN" install -U pip
|
|
REQ_MAIN="$BASE_DIR/ZeroCodeProject/apis/ZeroCodeMain/requirements.txt"
|
|
REQ_TEMP="$BASE_DIR/ZeroCodeProject/apis/temp_api/requirements.txt"
|
|
if [ -f "$REQ_TEMP" ]; then
|
|
"$PIP_BIN" install -r "$REQ_TEMP"
|
|
fi
|
|
if [ "${INSTALL_MAIN_REQ:-0}" != "0" ] && [ -f "$REQ_MAIN" ]; then
|
|
"$PIP_BIN" install -r "$REQ_MAIN"
|
|
fi
|
|
# Force urllib3 < 2 for OpenSSL 1.0.x/1.1.0 environments
|
|
"$PIP_BIN" install 'urllib3<2' || true
|
|
|
|
MYSQL_BIND="${MYSQL_BIND:-127.0.0.1}"
|
|
# Default DB credentials
|
|
DB_USER="${DB_USER:-test_user}"
|
|
DB_PASSWORD="${DB_PASSWORD:-your_password}"
|
|
DB_NAME="${DB_NAME:-zero_code_new}"
|
|
DB_HOST="${DB_HOST:-127.0.0.1}"
|
|
DB_PORT="${DB_PORT:-3306}"
|
|
# Fix misplaced bind-address in client config and ensure mysqld picks correct bind
|
|
if [ -f "/etc/mysql/conf.d/mysql.cnf" ]; then
|
|
if grep -q "bind-address" "/etc/mysql/conf.d/mysql.cnf"; then
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
sudo sed -i '/bind-address/d' /etc/mysql/conf.d/mysql.cnf || true
|
|
else
|
|
sed -i '/bind-address/d' /etc/mysql/conf.d/mysql.cnf || true
|
|
fi
|
|
fi
|
|
fi
|
|
SERVER_CONF_DIR=""
|
|
if [ -d "/etc/mysql/mysql.conf.d" ]; then
|
|
SERVER_CONF_DIR="/etc/mysql/mysql.conf.d"
|
|
elif [ -d "/etc/mysql/mariadb.conf.d" ]; then
|
|
SERVER_CONF_DIR="/etc/mysql/mariadb.conf.d"
|
|
fi
|
|
if command -v sudo >/dev/null 2>&1 && [ -n "$SERVER_CONF_DIR" ]; then
|
|
sudo bash -c "printf '[mysqld]\nbind-address = %s\n' '$MYSQL_BIND' > '$SERVER_CONF_DIR/bind.cnf'" || true
|
|
fi
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
sudo mkdir -p /var/run/mysqld && sudo chown mysql:mysql /var/run/mysqld || true
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
sudo systemctl restart mysql || sudo systemctl restart mariadb || true
|
|
else
|
|
sudo service mysql restart || sudo service mariadb restart || true
|
|
fi
|
|
else
|
|
mkdir -p /var/run/mysqld && chown mysql:mysql /var/run/mysqld || true
|
|
service mysql restart || service mariadb restart || true
|
|
fi
|
|
|
|
DB_JSON="$BASE_DIR/ZeroCodeProject/apis/ZeroCodeMain/dependency/api_config/project_settings.json"
|
|
export DB_JSON
|
|
read_vars=$("$PY_BIN" - <<'PY'
|
|
import json,sys,os
|
|
p=os.environ.get('DB_JSON')
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
def val(k,default):
|
|
return d.get(k,default)
|
|
e=val('ENGINE','')
|
|
h=val('HOST','127.0.0.1')
|
|
port=val('PORT','3306')
|
|
n=val('NAME','zero_code')
|
|
u=val('USER','root')
|
|
pw=val('PASSWORD','')
|
|
print('\n'.join([
|
|
f"ENGINE={e}",
|
|
f"HOST={h}",
|
|
f"PORT={port}",
|
|
f"NAME={n}",
|
|
f"USER={u}",
|
|
f"PASSWORD={pw}",
|
|
]))
|
|
PY
|
|
)
|
|
eval "$read_vars"
|
|
|
|
# Normalize ZeroCodeMain DB config to MySQL
|
|
env DB_JSON="$DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ['DB_JSON']
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
e=d.get('ENGINE','')
|
|
name=d.get('NAME','zero_code')
|
|
host=d.get('HOST','127.0.0.1')
|
|
port=d.get('PORT','3306')
|
|
user=d.get('USER','zerocode')
|
|
pw=d.get('PASSWORD','')
|
|
if host=='localhost': host='127.0.0.1'
|
|
if e!='django.db.backends.mysql':
|
|
d['ENGINE']='django.db.backends.mysql'
|
|
d['NAME']=name
|
|
d['HOST']=host
|
|
d['PORT']=port
|
|
d['USER']=user
|
|
d['PASSWORD']=pw
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
|
|
# Override from environment if provided (applies to ZeroCodeMain)
|
|
if [ -n "${DB_USER:-}" ] || [ -n "${DB_PASSWORD:-}" ] || [ -n "${DB_NAME:-}" ] || [ -n "${DB_HOST:-}" ] || [ -n "${DB_PORT:-}" ]; then
|
|
env new_user="${DB_USER:-$USER}" new_pass="${DB_PASSWORD:-$PASSWORD}" new_name="${DB_NAME:-$NAME}" new_host="${DB_HOST:-$HOST}" new_port="${DB_PORT:-$PORT}" DB_JSON="$DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ['DB_JSON']
|
|
u=os.environ['new_user']
|
|
pw=os.environ['new_pass']
|
|
n=os.environ['new_name']
|
|
h=os.environ['new_host']
|
|
pt=os.environ['new_port']
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
d['ENGINE']='django.db.backends.mysql'
|
|
d['USER']=u
|
|
d['PASSWORD']=pw
|
|
d['NAME']=n
|
|
d['HOST']=h
|
|
d['PORT']=pt
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
USER="${DB_USER:-$USER}"
|
|
PASSWORD="${DB_PASSWORD:-$PASSWORD}"
|
|
NAME="${DB_NAME:-$NAME}"
|
|
HOST="${DB_HOST:-$HOST}"
|
|
PORT="${DB_PORT:-$PORT}"
|
|
fi
|
|
|
|
if [ "$ENGINE" = "django.db.backends.mysql" ]; then
|
|
if [ "$USER" = "root" ]; then
|
|
new_user="${DB_USER:-zerocode}"
|
|
if [ -n "${DB_PASSWORD:-}" ]; then
|
|
new_pass="$DB_PASSWORD"
|
|
else
|
|
if command -v tr >/dev/null 2>&1; then
|
|
new_pass="$(tr -dc 'A-Za-z0-9_@#%!' < /dev/urandom | head -c 20)"
|
|
else
|
|
new_pass="Zc$(date +%s)Pwd"
|
|
fi
|
|
fi
|
|
env new_user="$new_user" new_pass="$new_pass" DB_JSON="$DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ.get('DB_JSON')
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
u=os.environ.get('new_user','zerocode')
|
|
pw=os.environ.get('new_pass','ZcDefaultPwd')
|
|
d['USER']=u
|
|
d['PASSWORD']=pw
|
|
d['HOST']='127.0.0.1'
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
USER="$new_user"
|
|
PASSWORD="$new_pass"
|
|
HOST="127.0.0.1"
|
|
fi
|
|
SQL_DB="CREATE DATABASE IF NOT EXISTS \`$NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
|
SQL_GRANT_1="GRANT ALL PRIVILEGES ON \`$NAME\`.* TO '$USER'@'127.0.0.1' IDENTIFIED BY '$PASSWORD';"
|
|
SQL_GRANT_2="GRANT ALL PRIVILEGES ON \`$NAME\`.* TO '$USER'@'localhost' IDENTIFIED BY '$PASSWORD';"
|
|
SQL_FLUSH="FLUSH PRIVILEGES;"
|
|
if command -v sudo >/dev/null 2>&1 && sudo -n true >/dev/null 2>&1; then
|
|
sudo mysql --no-defaults -e "$SQL_DB CREATE USER IF NOT EXISTS '$USER'@'127.0.0.1' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'localhost' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'%' IDENTIFIED BY '$PASSWORD'; $SQL_GRANT_1 $SQL_GRANT_2 $SQL_FLUSH" || true
|
|
elif [ -n "${MYSQL_ROOT_PWD:-}" ]; then
|
|
mysql --protocol=TCP -h "${HOST:-127.0.0.1}" -P "${PORT:-3306}" -uroot -p"$MYSQL_ROOT_PWD" --no-defaults -e "$SQL_DB CREATE USER IF NOT EXISTS '$USER'@'127.0.0.1' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'localhost' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'%' IDENTIFIED BY '$PASSWORD'; $SQL_GRANT_1 $SQL_GRANT_2 $SQL_FLUSH" || true
|
|
else
|
|
mysql --protocol=TCP -h "${HOST:-127.0.0.1}" -P "${PORT:-3306}" -uroot --no-defaults -e "$SQL_DB CREATE USER IF NOT EXISTS '$USER'@'127.0.0.1' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'localhost' IDENTIFIED BY '$PASSWORD'; CREATE USER IF NOT EXISTS '$USER'@'%' IDENTIFIED BY '$PASSWORD'; $SQL_GRANT_1 $SQL_GRANT_2 $SQL_FLUSH" || true
|
|
fi
|
|
fi
|
|
|
|
TEMP_DB_JSON="$BASE_DIR/ZeroCodeProject/apis/temp_api/dependency/api_config/project_settings.json"
|
|
export TEMP_DB_JSON
|
|
temp_vars=$("$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ.get('TEMP_DB_JSON')
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
def val(k,default):
|
|
return d.get(k,default)
|
|
e=val('ENGINE','')
|
|
h=val('HOST','127.0.0.1')
|
|
port=val('PORT','3306')
|
|
n=val('NAME','zero_code')
|
|
u=val('USER','root')
|
|
pw=val('PASSWORD','')
|
|
print('\n'.join([
|
|
f"T_ENGINE={e}",
|
|
f"T_HOST={h}",
|
|
f"T_PORT={port}",
|
|
f"T_NAME={n}",
|
|
f"T_USER={u}",
|
|
f"T_PASSWORD={pw}",
|
|
]))
|
|
PY
|
|
)
|
|
eval "$temp_vars"
|
|
|
|
# Normalize temp_api DB config to MySQL
|
|
env TEMP_DB_JSON="$TEMP_DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ['TEMP_DB_JSON']
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
e=d.get('ENGINE','')
|
|
name=d.get('NAME','zero_code')
|
|
host=d.get('HOST','127.0.0.1')
|
|
port=d.get('PORT','3306')
|
|
user=d.get('USER','zerocode')
|
|
pw=d.get('PASSWORD','')
|
|
if host=='localhost': host='127.0.0.1'
|
|
if e!='django.db.backends.mysql':
|
|
d['ENGINE']='django.db.backends.mysql'
|
|
d['NAME']=name
|
|
d['HOST']=host
|
|
d['PORT']=port
|
|
d['USER']=user
|
|
d['PASSWORD']=pw
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
# Override from environment if provided (applies to temp_api)
|
|
if [ -n "${DB_USER:-}" ] || [ -n "${DB_PASSWORD:-}" ] || [ -n "${DB_NAME:-}" ] || [ -n "${DB_HOST:-}" ] || [ -n "${DB_PORT:-}" ]; then
|
|
env new_user="${DB_USER:-$T_USER}" new_pass="${DB_PASSWORD:-$T_PASSWORD}" new_name="${DB_NAME:-$T_NAME}" new_host="${DB_HOST:-$T_HOST}" new_port="${DB_PORT:-$T_PORT}" TEMP_DB_JSON="$TEMP_DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ['TEMP_DB_JSON']
|
|
u=os.environ['new_user']
|
|
pw=os.environ['new_pass']
|
|
n=os.environ['new_name']
|
|
h=os.environ['new_host']
|
|
pt=os.environ['new_port']
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
d['ENGINE']='django.db.backends.mysql'
|
|
d['USER']=u
|
|
d['PASSWORD']=pw
|
|
d['NAME']=n
|
|
d['HOST']=h
|
|
d['PORT']=pt
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
T_USER="${DB_USER:-$T_USER}"
|
|
T_PASSWORD="${DB_PASSWORD:-$T_PASSWORD}"
|
|
T_NAME="${DB_NAME:-$T_NAME}"
|
|
T_HOST="${DB_HOST:-$T_HOST}"
|
|
T_PORT="${DB_PORT:-$T_PORT}"
|
|
fi
|
|
if [ "$T_ENGINE" = "django.db.backends.mysql" ]; then
|
|
if [ "$T_USER" = "root" ]; then
|
|
t_new_user="${DB_USER:-$USER}"
|
|
[ -z "$t_new_user" ] && t_new_user="zerocode"
|
|
t_new_pass="${DB_PASSWORD:-$PASSWORD}"
|
|
[ -z "$t_new_pass" ] && t_new_pass="Zc$(date +%s)Pwd"
|
|
env new_user="$t_new_user" new_pass="$t_new_pass" TEMP_DB_JSON="$TEMP_DB_JSON" "$PY_BIN" - <<'PY'
|
|
import json,os
|
|
p=os.environ.get('TEMP_DB_JSON')
|
|
try:
|
|
with open(p,'r') as f:
|
|
d=json.load(f)
|
|
except Exception:
|
|
d={}
|
|
u=os.environ.get('new_user','zerocode')
|
|
pw=os.environ.get('new_pass','ZcDefaultPwd')
|
|
d['USER']=u
|
|
d['PASSWORD']=pw
|
|
d['HOST']='127.0.0.1'
|
|
with open(p,'w') as f:
|
|
json.dump(d,f,indent=2,ensure_ascii=False)
|
|
PY
|
|
T_USER="$t_new_user"
|
|
T_PASSWORD="$t_new_pass"
|
|
T_HOST="127.0.0.1"
|
|
fi
|
|
SQL_DB_T="CREATE DATABASE IF NOT EXISTS \`$T_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
|
SQL_GRANT_T1="GRANT ALL PRIVILEGES ON \`$T_NAME\`.* TO '$T_USER'@'127.0.0.1' IDENTIFIED BY '$T_PASSWORD';"
|
|
SQL_GRANT_T2="GRANT ALL PRIVILEGES ON \`$T_NAME\`.* TO '$T_USER'@'localhost' IDENTIFIED BY '$T_PASSWORD';"
|
|
SQL_FLUSH_T="FLUSH PRIVILEGES;"
|
|
if command -v sudo >/dev/null 2>&1 && sudo -n true >/dev/null 2>&1; then
|
|
sudo mysql --no-defaults -e "$SQL_DB_T CREATE USER IF NOT EXISTS '$T_USER'@'127.0.0.1' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'localhost' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'%' IDENTIFIED BY '$T_PASSWORD'; $SQL_GRANT_T1 $SQL_GRANT_T2 $SQL_FLUSH_T" || true
|
|
elif [ -n "${MYSQL_ROOT_PWD:-}" ]; then
|
|
mysql --protocol=TCP -h "${T_HOST:-127.0.0.1}" -P "${T_PORT:-3306}" -uroot -p"$MYSQL_ROOT_PWD" --no-defaults -e "$SQL_DB_T CREATE USER IF NOT EXISTS '$T_USER'@'127.0.0.1' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'localhost' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'%' IDENTIFIED BY '$T_PASSWORD'; $SQL_GRANT_T1 $SQL_GRANT_T2 $SQL_FLUSH_T" || true
|
|
else
|
|
mysql --protocol=TCP -h "${T_HOST:-127.0.0.1}" -P "${T_PORT:-3306}" -uroot --no-defaults -e "$SQL_DB_T CREATE USER IF NOT EXISTS '$T_USER'@'127.0.0.1' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'localhost' IDENTIFIED BY '$T_PASSWORD'; CREATE USER IF NOT EXISTS '$T_USER'@'%' IDENTIFIED BY '$T_PASSWORD'; $SQL_GRANT_T1 $SQL_GRANT_T2 $SQL_FLUSH_T" || true
|
|
fi
|
|
fi
|
|
|
|
MYSQL_CHECK=0
|
|
env MYSQL_HOST="$HOST" MYSQL_PORT="$PORT" MYSQL_USER="$USER" MYSQL_PASS="$PASSWORD" "$PY_BIN" - <<'PY' && MYSQL_CHECK=1 || MYSQL_CHECK=0
|
|
import os
|
|
import pymysql
|
|
h=os.environ.get('MYSQL_HOST','127.0.0.1')
|
|
p=int(os.environ.get('MYSQL_PORT','3306'))
|
|
u=os.environ.get('MYSQL_USER','zerocode')
|
|
pw=os.environ.get('MYSQL_PASS','')
|
|
conn=pymysql.connect(host=h,port=p,user=u,password=pw,connect_timeout=3)
|
|
conn.close()
|
|
PY
|
|
|
|
cd "$BASE_DIR/ZeroCodeProject/apis/temp_api"
|
|
if [ -d "$BASE_DIR/main_package" ]; then
|
|
export PYTHONPATH="$BASE_DIR/main_package:$PYTHONPATH"
|
|
fi
|
|
"$PY_BIN" manage.py migrate
|
|
cd "$BASE_DIR/ZeroCodeProject/apis/ZeroCodeMain"
|
|
if [ -d "$BASE_DIR/main_package" ]; then
|
|
export PYTHONPATH="$BASE_DIR/main_package:$PYTHONPATH"
|
|
fi
|
|
# Resolve possible inconsistent history by migrating users before admin
|
|
"$PY_BIN" manage.py migrate admin zero || true
|
|
"$PY_BIN" manage.py migrate users || true
|
|
# Ensure BaseApi base tables exist
|
|
"$PY_BIN" manage.py makemigrations BaseApi || true
|
|
"$PY_BIN" manage.py migrate
|
|
|
|
echo ready |