|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +# === 可配置 === |
| 5 | +IMAGE="ghcr.io/universaloj/uoj-judger:latest" |
| 6 | +NETWORK="uoj-system_default" |
| 7 | +UOJ_HOST_NAME="uoj-web" # 与 UOJ 主容器在同一网络下的容器名;用名字避免写死 IP |
| 8 | +MYSQL_CONT="uoj-db" # MySQL 容器名 |
| 9 | +MYSQL_DB="app_uoj233" |
| 10 | +MYSQL_USER="root" |
| 11 | +MYSQL_PASS="root" |
| 12 | +JUDGER_PASS_DEFAULT="changeme" # 如果不想每台都不同,就用统一密码 |
| 13 | +CPU_LIMIT="" # 例如 "--cpus=1.0" |
| 14 | +MEM_LIMIT="" # 例如 "--memory=1g" |
| 15 | + |
| 16 | +# 用法: ./spawn_judgers.sh 数量 前缀(可选) 密码(可选) |
| 17 | +COUNT="${1:-3}" |
| 18 | +NAME_PREFIX="${2:-judger}" |
| 19 | +JUDGER_PASS="${3:-$JUDGER_PASS_DEFAULT}" |
| 20 | + |
| 21 | +mkdir -p confs |
| 22 | + |
| 23 | +# 确保网络存在 |
| 24 | +docker network inspect "$NETWORK" >/dev/null 2>&1 || docker network create "$NETWORK" |
| 25 | + |
| 26 | +for i in $(seq 1 "$COUNT"); do |
| 27 | + NAME="${NAME_PREFIX}${i}" |
| 28 | + CONF="confs/conf-${NAME}.json" |
| 29 | + |
| 30 | + # 生成每台评测机的 conf.json |
| 31 | + cat > "$CONF" <<EOF |
| 32 | +{ |
| 33 | + "uoj_protocol": "http", |
| 34 | + "uoj_host": "${UOJ_HOST_NAME}", |
| 35 | + "judger_name": "${NAME}", |
| 36 | + "judger_password": "${JUDGER_PASS}", |
| 37 | + "socket_port": 2333, |
| 38 | + "socket_password": "${JUDGER_PASS}" |
| 39 | +} |
| 40 | +EOF |
| 41 | + |
| 42 | + # 如已存在,先删容器(不删镜像) |
| 43 | + if docker ps -a --format '{{.Names}}' | grep -q "^${NAME}$"; then |
| 44 | + docker rm -f "${NAME}" >/dev/null |
| 45 | + fi |
| 46 | + |
| 47 | + # 拉起容器:共享同一镜像,外挂只读 conf,限制资源(按需启用) |
| 48 | + docker run -d --name "${NAME}" \ |
| 49 | + --cap-add SYS_PTRACE \ |
| 50 | + --restart=always \ |
| 51 | + --network "${NETWORK}" \ |
| 52 | + -v "$(pwd)/${CONF}:/opt/uoj_judger/.conf.json:ro" \ |
| 53 | + $CPU_LIMIT $MEM_LIMIT \ |
| 54 | + --entrypoint /bin/bash \ |
| 55 | + "${IMAGE}" -lc '/opt/up; touch /opt/uoj_judger/log/judge.log; tail -F /opt/uoj_judger/log/judge.log /opt/uoj_judger/log/judge_client.log 2>/dev/null || sleep infinity' |
| 56 | + |
| 57 | + # 取容器 IP(在自定义网络下) |
| 58 | + IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${NAME}") |
| 59 | + |
| 60 | + # 写入 MySQL(入库一次即可) |
| 61 | + docker exec -i "${MYSQL_CONT}" \ |
| 62 | + mysql -u"${MYSQL_USER}" -p"${MYSQL_PASS}" "${MYSQL_DB}" \ |
| 63 | + -e "INSERT INTO judger_info (judger_name, password, ip) VALUES ('${NAME}', '${JUDGER_PASS}', '${IP}') |
| 64 | + ON DUPLICATE KEY UPDATE password=VALUES(password), ip=VALUES(ip);" |
| 65 | + |
| 66 | + echo "Launched ${NAME} at ${IP}" |
| 67 | +done |
| 68 | + |
| 69 | +echo "Done." |
0 commit comments