258 lines
7.8 KiB
Bash
258 lines
7.8 KiB
Bash
#!/bin/bash
|
||
set -e
|
||
|
||
echo "==================================="
|
||
echo "Gitea Runner Container Starting..."
|
||
echo "==================================="
|
||
|
||
# 定义路径
|
||
PERSISTENT_BIN="/data/bin"
|
||
RUNNER_PATH="$PERSISTENT_BIN/act_runner"
|
||
SYSTEM_LINK="/usr/local/bin/act_runner"
|
||
|
||
# 读取环境变量配置
|
||
ENABLE_BUILDX="${ENABLE_BUILDX:-false}"
|
||
BINFMT_METHOD="${BINFMT_METHOD:-update-binfmts}" # update-binfmts 或 tonistiigi
|
||
|
||
# 创建必要目录
|
||
mkdir -p /data/runners
|
||
mkdir -p "$PERSISTENT_BIN"
|
||
mkdir -p /var/log/supervisor
|
||
mkdir -p /var/run
|
||
|
||
# ============================================
|
||
# 初始化 Docker Buildx 支持(可选)
|
||
# ============================================
|
||
if [ "$ENABLE_BUILDX" = "true" ]; then
|
||
echo ""
|
||
echo "Initializing Docker Buildx..."
|
||
mkdir -p /data/buildx
|
||
|
||
# 启动 Docker 守护进程(如果使用主机 socket 则跳过)
|
||
if [ -S /var/run/docker.sock ]; then
|
||
echo "✓ Using host Docker socket"
|
||
else
|
||
echo "Starting Docker daemon..."
|
||
dockerd > /var/log/dockerd.log 2>&1 &
|
||
sleep 5
|
||
fi
|
||
|
||
# 等待 Docker 就绪
|
||
echo "Waiting for Docker daemon..."
|
||
for i in {1..30}; do
|
||
if docker info > /dev/null 2>&1; then
|
||
echo "✓ Docker daemon is ready"
|
||
break
|
||
fi
|
||
if [ $i -eq 30 ]; then
|
||
echo "✗ Docker daemon failed to start"
|
||
[ -f /var/log/dockerd.log ] && cat /var/log/dockerd.log
|
||
exit 1
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
# 注册 QEMU binfmt
|
||
echo ""
|
||
echo "Registering QEMU binary formats..."
|
||
|
||
if [ "$BINFMT_METHOD" = "tonistiigi" ]; then
|
||
# 使用 tonistiigi/binfmt(更可靠)
|
||
if docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 > /var/log/binfmt-install.log 2>&1; then
|
||
echo "✓ Installed binfmt via tonistiigi/binfmt"
|
||
grep -m1 "Installed" /var/log/binfmt-install.log || true
|
||
else
|
||
echo "⚠ binfmt install via tonistiigi/binfmt failed, trying local tools..."
|
||
if command -v update-binfmts > /dev/null 2>&1; then
|
||
update-binfmts --enable 2>/dev/null || true
|
||
else
|
||
echo "⚠ update-binfmts not available; multi-arch emulation may be limited"
|
||
fi
|
||
fi
|
||
else
|
||
# 使用 update-binfmts(传统方法)
|
||
update-binfmts --enable 2>/dev/null || {
|
||
echo "⚠ binfmt_misc not available, trying to mount..."
|
||
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null || true
|
||
update-binfmts --enable
|
||
}
|
||
fi
|
||
|
||
# 验证多架构支持
|
||
echo "Verifying multi-arch support..."
|
||
if docker run --rm arm64v8/alpine uname -m > /dev/null 2>&1; then
|
||
echo " ✓ arm64 support verified"
|
||
else
|
||
echo " ⚠ arm64 verification failed"
|
||
fi
|
||
|
||
if docker run --rm amd64/alpine uname -m > /dev/null 2>&1; then
|
||
echo " ✓ amd64 support verified"
|
||
else
|
||
echo " ⚠ amd64 verification failed"
|
||
fi
|
||
|
||
# 配置 Buildx
|
||
if [ ! -f "/data/buildx/.configured" ]; then
|
||
echo ""
|
||
echo "Setting up Buildx for the first time..."
|
||
|
||
# 创建 BuildKit 配置
|
||
cat > /data/buildx/buildkitd.toml <<EOF
|
||
[worker.oci]
|
||
max-parallelism = 4
|
||
EOF
|
||
|
||
# 创建 Buildx builder
|
||
docker buildx create \
|
||
--name gitea-multiarch \
|
||
--driver docker-container \
|
||
--bootstrap \
|
||
--use \
|
||
--config /data/buildx/buildkitd.toml 2>/dev/null || \
|
||
docker buildx use gitea-multiarch 2>/dev/null
|
||
|
||
# 验证
|
||
echo "Verifying Buildx..."
|
||
docker buildx inspect --bootstrap > /dev/null 2>&1
|
||
|
||
# 标记为已配置
|
||
touch /data/buildx/.configured
|
||
|
||
echo "✓ Buildx configured successfully!"
|
||
docker buildx inspect | grep "Platforms:" | head -1
|
||
else
|
||
echo "✓ Buildx already configured"
|
||
|
||
# 确保 builder 可用
|
||
docker buildx use gitea-multiarch 2>/dev/null || {
|
||
echo "⚠ Recreating Buildx builder..."
|
||
docker buildx rm gitea-multiarch 2>/dev/null || true
|
||
docker buildx create \
|
||
--name gitea-multiarch \
|
||
--driver docker-container \
|
||
--bootstrap \
|
||
--use 2>/dev/null
|
||
}
|
||
fi
|
||
|
||
echo ""
|
||
fi
|
||
|
||
# ============================================
|
||
# 检查 act_runner 安装
|
||
# ============================================
|
||
# 创建主 supervisor 配置文件
|
||
cat > /etc/supervisor/supervisord.conf <<EOF
|
||
[supervisord]
|
||
nodaemon=true
|
||
logfile=/var/log/supervisor/supervisord.log
|
||
pidfile=/var/run/supervisord.pid
|
||
|
||
[unix_http_server]
|
||
file=/var/run/supervisor.sock
|
||
chmod=0700
|
||
|
||
[supervisorctl]
|
||
serverurl=unix:///var/run/supervisor.sock
|
||
|
||
[rpcinterface:supervisor]
|
||
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||
|
||
[include]
|
||
files = /etc/supervisor/conf.d/*.conf
|
||
EOF
|
||
|
||
# 检查持久化目录中的 act_runner
|
||
if [ -f "$RUNNER_PATH" ]; then
|
||
echo "✓ Found act_runner in persistent storage"
|
||
echo " Location: $RUNNER_PATH"
|
||
|
||
if [ ! -L "$SYSTEM_LINK" ] || [ ! -e "$SYSTEM_LINK" ]; then
|
||
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
|
||
echo " Created system link: $SYSTEM_LINK -> $RUNNER_PATH"
|
||
fi
|
||
|
||
RUNNER_VERSION=$("$SYSTEM_LINK" --version 2>/dev/null || echo "unknown")
|
||
echo " Version: $RUNNER_VERSION"
|
||
elif [ -f "$SYSTEM_LINK" ]; then
|
||
echo "⚠ Found act_runner in system path, migrating to persistent storage..."
|
||
cp "$SYSTEM_LINK" "$RUNNER_PATH"
|
||
chmod +x "$RUNNER_PATH"
|
||
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
|
||
echo " ✓ Migrated to: $RUNNER_PATH"
|
||
else
|
||
echo "⚠ act_runner not installed yet!"
|
||
echo ""
|
||
echo "Please run the setup script first:"
|
||
echo " docker-compose exec gitea-runner /data/setup.sh"
|
||
echo ""
|
||
echo "Container is waiting..."
|
||
|
||
while [ ! -f "$RUNNER_PATH" ] && [ ! -f "$SYSTEM_LINK" ]; do
|
||
sleep 10
|
||
done
|
||
|
||
if [ -f "$RUNNER_PATH" ]; then
|
||
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
|
||
echo "✓ act_runner detected and linked!"
|
||
elif [ -f "$SYSTEM_LINK" ]; then
|
||
cp "$SYSTEM_LINK" "$RUNNER_PATH"
|
||
ln -sf "$RUNNER_PATH" "$SYSTEM_LINK"
|
||
echo "✓ act_runner detected and migrated!"
|
||
fi
|
||
fi
|
||
|
||
# ============================================
|
||
# 配置已注册的 Runners
|
||
# ============================================
|
||
echo ""
|
||
echo "Scanning for registered runners..."
|
||
RUNNER_COUNT=0
|
||
|
||
if [ -d "/data/runners" ]; then
|
||
for runner_dir in /data/runners/*/; do
|
||
if [ -d "$runner_dir" ]; then
|
||
runner_name=$(basename "$runner_dir")
|
||
|
||
if [ -f "$runner_dir/.runner" ] && [ -f "$runner_dir/config.yaml" ]; then
|
||
echo "Found runner: $runner_name"
|
||
|
||
cat > "/etc/supervisor/conf.d/runner-${runner_name}.conf" <<EOF
|
||
[program:runner-${runner_name}]
|
||
command=/usr/local/bin/act_runner daemon --config ${runner_dir}/config.yaml
|
||
directory=${runner_dir}
|
||
autostart=true
|
||
autorestart=true
|
||
stderr_logfile=/var/log/supervisor/runner-${runner_name}.err.log
|
||
stdout_logfile=/var/log/supervisor/runner-${runner_name}.out.log
|
||
stdout_logfile_maxbytes=50MB
|
||
stdout_logfile_backups=10
|
||
stderr_logfile_maxbytes=50MB
|
||
stderr_logfile_backups=10
|
||
user=root
|
||
environment=HOME="/root",PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||
EOF
|
||
RUNNER_COUNT=$((RUNNER_COUNT + 1))
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
|
||
if [ $RUNNER_COUNT -eq 0 ]; then
|
||
echo "⚠ No runners registered yet!"
|
||
echo ""
|
||
echo "Please run the register script to add a runner:"
|
||
echo " docker-compose exec gitea-runner /data/register.sh"
|
||
echo ""
|
||
fi
|
||
|
||
echo "Total runners configured: $RUNNER_COUNT"
|
||
echo ""
|
||
echo "==================================="
|
||
echo "Starting Supervisor..."
|
||
echo "==================================="
|
||
|
||
# 启动 supervisord
|
||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|