11#! /usr/bin/env bash
22set -euo pipefail
33
4+ # 忽略多组织部署时的 orphan 容器警告(同一主机运行多个组织的 runner 是正常场景)
5+ export COMPOSE_IGNORE_ORPHANS=1
6+
47ENV_FILE=" ${ENV_FILE:- .env} "
58
69# ------------------------------- load .env file -------------------------------
1316ORG=" ${ORG:- } "
1417GH_PAT=" ${GH_PAT:- } "
1518REPO=" ${REPO:- } "
16- REG_TOKEN_CACHE_FILE=" ${REG_TOKEN_CACHE_FILE:- .reg_token.cache} "
17- REG_TOKEN_CACHE_TTL=" ${REG_TOKEN_CACHE_TTL:- 300} " # seconds, default 5 minutes
1819
1920# Runner container related parameters
2021RUNNER_IMAGE=" ${RUNNER_IMAGE:- ghcr.io/ actions/ actions-runner: latest} "
@@ -38,15 +39,44 @@ RUNNER_WORKDIR="${RUNNER_WORKDIR:-}"
3839RUNNER_LABELS=" ${RUNNER_LABELS:- intel} "
3940RUNNER_BOARD=" 2"
4041DISABLE_AUTO_UPDATE=" ${DISABLE_AUTO_UPDATE:- false} "
41- # 多组织共享硬件锁:板子 runner 使用 runner-wrapper 时按锁 ID 串行。每块板子「有定义用定义的,否则用该板子默认值」,不再回退到全局 RUNNER_RESOURCE_ID,避免所有板子共一把锁导致无法并行
42- RUNNER_RESOURCE_ID=" ${RUNNER_RESOURCE_ID:- } "
4342# 板子级:未设置时用本板默认值(同类型板串行、不同类型板并行);多组织共享同一块板时显式设为相同 ID 即可
44- RUNNER_RESOURCE_ID_PHYTIUMPI=" ${RUNNER_RESOURCE_ID_PHYTIUMPI:- board-phytiumpi } "
45- RUNNER_RESOURCE_ID_ROC_RK3568_PC=" ${RUNNER_RESOURCE_ID_ROC_RK3568_PC:- board-roc-rk3568-pc } "
43+ RUNNER_RESOURCE_ID_PHYTIUMPI=" ${RUNNER_RESOURCE_ID_PHYTIUMPI:- } "
44+ RUNNER_RESOURCE_ID_ROC_RK3568_PC=" ${RUNNER_RESOURCE_ID_ROC_RK3568_PC:- } "
4645RUNNER_LOCK_DIR=" ${RUNNER_LOCK_DIR:-/ tmp/ github-runner-locks} "
4746RUNNER_LOCK_HOST_PATH=" ${RUNNER_LOCK_HOST_PATH:-/ tmp/ github-runner-locks} "
48- COMPOSE_FILE=" docker-compose.yml"
49- DOCKERFILE_HASH_FILE=" ${DOCKERFILE_HASH_FILE:- .dockerfile.sha256} "
47+ # Compose 文件名:未显式设置时自动拼入 ORG/REPO,避免同一主机多组织时文件冲突
48+ # 组织级默认:docker-compose.<org>.yml 仓库级默认:docker-compose.<org>.<repo>.yml
49+ if [[ -z " ${COMPOSE_FILE:- } " ]]; then
50+ if [[ -n " ${ORG:- } " && -n " ${REPO:- } " ]]; then
51+ COMPOSE_FILE=" docker-compose.${ORG} .${REPO} .yml"
52+ elif [[ -n " ${ORG:- } " ]]; then
53+ COMPOSE_FILE=" docker-compose.${ORG} .yml"
54+ else
55+ COMPOSE_FILE=" docker-compose.yml"
56+ fi
57+ fi
58+ # Dockerfile hash 文件名:同样根据 ORG/REPO 区分,避免多组织时 hash 冲突
59+ if [[ -z " ${DOCKERFILE_HASH_FILE:- } " ]]; then
60+ if [[ -n " ${ORG:- } " && -n " ${REPO:- } " ]]; then
61+ DOCKERFILE_HASH_FILE=" .dockerfile.${ORG} .${REPO} .sha256"
62+ elif [[ -n " ${ORG:- } " ]]; then
63+ DOCKERFILE_HASH_FILE=" .dockerfile.${ORG} .sha256"
64+ else
65+ DOCKERFILE_HASH_FILE=" .dockerfile.sha256"
66+ fi
67+ fi
68+ # REG_TOKEN_CACHE_FILE 文件名:未显式设置时自动拼入 ORG/REPO,避免同一主机多组织时文件冲突
69+ # 组织级默认:.reg_token.cache.<org> 仓库级默认:.reg_token.cache.<org>.<repo>
70+ if [[ -z " ${REG_TOKEN_CACHE_FILE:- } " ]]; then
71+ if [[ -n " ${ORG:- } " && -n " ${REPO:- } " ]]; then
72+ REG_TOKEN_CACHE_FILE=" .reg_token.cache.${ORG} .${REPO} "
73+ elif [[ -n " ${ORG:- } " ]]; then
74+ REG_TOKEN_CACHE_FILE=" .reg_token.cache.${ORG} "
75+ else
76+ REG_TOKEN_CACHE_FILE=" .reg_token.cache"
77+ fi
78+ fi
79+ REG_TOKEN_CACHE_TTL=" ${REG_TOKEN_CACHE_TTL:- 300} " # seconds, default 5 minutes
5080
5181# ------------------------------- Helpers -------------------------------
5282shell_usage () {
@@ -92,7 +122,6 @@ shell_usage() {
92122 printf " %-${KEYW} s %s\n" " RUNNER_NAME_PREFIX" " Container name prefix (default: <hostname>-<org>[-<repo>]-); auto includes ORG/REPO to avoid name conflicts"
93123 printf " %-${KEYW} s %s\n" " RUNNER_IMAGE" " Image used for compose generation (default ghcr.io/actions/actions-runner:latest)"
94124 printf " %-${KEYW} s %s\n" " RUNNER_CUSTOM_IMAGE" " Image tag used for auto-build (can override)"
95- printf " %-${KEYW} s %s\n" " RUNNER_RESOURCE_ID" " Optional global lock ID (e.g. for manual wrapper config); board vars take per-board default if unset"
96125 printf " %-${KEYW} s %s\n" " RUNNER_RESOURCE_ID_PHYTIUMPI" " Lock ID for phytiumpi board (default: board-phytiumpi); same ID = serial across runners"
97126 printf " %-${KEYW} s %s\n" " RUNNER_RESOURCE_ID_ROC_RK3568_PC" " Lock ID for roc-rk3568-pc board (default: board-roc-rk3568-pc); same ID = serial"
98127 printf " %-${KEYW} s %s\n" " RUNNER_LOCK_DIR" " Lock dir in container (default /tmp/github-runner-locks)"
@@ -102,7 +131,7 @@ shell_usage() {
102131
103132 echo
104133 echo " Tips:"
105- echo " - docker-compose.yml must exist. The script will not generate or modify it. "
134+ echo " - Compose file is auto-generated per ORG/REPO (e.g., docker-compose.<org>.yml) "
106135 echo " - Re-start/up will reuse existing volumes; Runner configuration and tool caches will not be lost."
107136}
108137
@@ -412,19 +441,51 @@ shell_get_compose_file() {
412441
413442shell_generate_compose_file () {
414443 local general_count=$1
415- # 板子级:有定义用定义的,否则用该板默认值;不同板默认不同 ID 可并行,多组织共享同一块板时显式设相同 ID
416- local res_phytiumpi=" ${RUNNER_RESOURCE_ID_PHYTIUMPI:- board-phytiumpi} "
417- local res_roc=" ${RUNNER_RESOURCE_ID_ROC_RK3568_PC:- board-roc-rk3568-pc} "
418- local runner_entrypoint_phytiumpi=" exec /home/runner/run.sh"
419- local runner_entrypoint_roc=" exec /home/runner/run.sh"
420- [[ -n " $res_phytiumpi " ]] && runner_entrypoint_phytiumpi=" exec /home/runner/runner-wrapper/runner-wrapper.sh"
421- [[ -n " $res_roc " ]] && runner_entrypoint_roc=" exec /home/runner/runner-wrapper/runner-wrapper.sh"
444+ # ════════════════════════════════════════════════════════════════
445+ # 第一步:为两种板子 runner 类型定义资源 ID
446+ # ════════════════════════════════════════════════════════════════
447+ # 硬件板 phytiumpi - 总是启用文件锁
448+ local res_phytiumpi=" ${RUNNER_RESOURCE_ID_PHYTIUMPI:- } "
449+ # 硬件板 roc - 总是启用文件锁
450+ local res_roc=" ${RUNNER_RESOURCE_ID_ROC_RK3568_PC:- } "
451+
452+ # ════════════════════════════════════════════════════════════════
453+ # 第二步:两种板子 runner 类型的 entrypoint 配置
454+ # ════════════════════════════════════════════════════════════════
455+ # 设计说明:若设置了资源 ID(RUNNER_RESOURCE_ID_*),板子 runner 使用
456+ # runner-wrapper.sh 来管理文件锁
457+ # 普通 runner 始终使用 /home/runner/run.sh(不经过 runner-wrapper)
458+ local runner_entrypoint_phytiumpi=" /home/runner/run.sh"
459+ local runner_entrypoint_roc=" /home/runner/run.sh"
460+ # 若设置了资源 ID,则改用 runner-wrapper 来处理文件锁
461+ [[ -n " $res_phytiumpi " ]] && runner_entrypoint_phytiumpi=" /home/runner/runner-wrapper/runner-wrapper.sh"
462+ [[ -n " $res_roc " ]] && runner_entrypoint_roc=" /home/runner/runner-wrapper/runner-wrapper.sh"
463+
464+ # ════════════════════════════════════════════════════════════════
465+ # 第三步:为两种板子 runner 类型准备额外的环境变量数组
466+ # ════════════════════════════════════════════════════════════════
467+ # 重复模式说明:以下两部分几乎完全相同,都是:
468+ # 1. 定义空数组:extra_env_X=()
469+ # 2. 如果有资源 ID,则添加三个环境变量:
470+ # - RUNNER_RESOURCE_ID: 用于锁机制
471+ # - RUNNER_SCRIPT: 给 runner-wrapper 使用的脚本路径
472+ # - RUNNER_LOCK_DIR: 容器内锁文件目录
473+ # 原因:两种板子 runner 都可能需要文件锁机制
422474 local extra_env_phytiumpi=()
423475 local extra_env_roc=()
476+ # 只有设置了相应的资源 ID,才为该类型 runner 添加锁相关环境变量
424477 [[ -n " $res_phytiumpi " ]] && extra_env_phytiumpi=(" RUNNER_RESOURCE_ID: \" $res_phytiumpi \" " " RUNNER_SCRIPT: \" /home/runner/run.sh\" " " RUNNER_LOCK_DIR: \" ${RUNNER_LOCK_DIR:-/ tmp/ github-runner-locks} \" " )
425478 [[ -n " $res_roc " ]] && extra_env_roc=(" RUNNER_RESOURCE_ID: \" $res_roc \" " " RUNNER_SCRIPT: \" /home/runner/run.sh\" " " RUNNER_LOCK_DIR: \" ${RUNNER_LOCK_DIR:-/ tmp/ github-runner-locks} \" " )
479+
480+ # ════════════════════════════════════════════════════════════════
481+ # 第四步:为两种板子 runner 类型准备卷挂载配置
482+ # ════════════════════════════════════════════════════════════════
483+ # 重复模式说明:以下两部分完全相同(除变量名),都实现:
484+ # 如果设置了资源 ID,则挂载主机的锁文件目录到容器内
485+ # 原因:文件锁机制需要在主机和容器间共享锁文件
426486 local extra_vol_phytiumpi=" "
427487 local extra_vol_roc=" "
488+ # 只有设置了相应的资源 ID,才为该类型 runner 挂载锁文件目录
428489 [[ -n " $res_phytiumpi " ]] && extra_vol_phytiumpi=" - ${RUNNER_LOCK_HOST_PATH:-/ tmp/ github-runner-locks} :${RUNNER_LOCK_DIR:-/ tmp/ github-runner-locks} "
429490 [[ -n " $res_roc " ]] && extra_vol_roc=" - ${RUNNER_LOCK_HOST_PATH:-/ tmp/ github-runner-locks} :${RUNNER_LOCK_DIR:-/ tmp/ github-runner-locks} "
430491
@@ -440,7 +501,7 @@ shell_generate_compose_file() {
440501 " image: \" ${RUNNER_IMAGE} \" " \
441502 " restart: unless-stopped" \
442503 " environment: &runner_env" \
443- " RUNNER_ORG_URL: \" https://github.com/arceos-hypervisor \" " \
504+ " RUNNER_ORG_URL: \" https://github.com/${ORG}${REPO : + / }${REPO} \" " \
444505 " RUNNER_TOKEN: \" ${REG_TOKEN} \" " \
445506 " RUNNER_GROUP: \" ${RUNNER_GROUP} \" " \
446507 " RUNNER_REMOVE_ON_STOP: \" false\" " \
@@ -452,10 +513,10 @@ shell_generate_compose_file() {
452513 " network_mode: host" \
453514 " privileged: true" \
454515 " " \
455- " services:" > docker-compose.yml
516+ " services:" > " ${COMPOSE_FILE} "
456517
457518 # 生成普通 runners
458- echo " # 普通 runners" >> docker-compose.yml
519+ echo " # 普通 runners" >> ${COMPOSE_FILE}
459520 for i in $( seq 1 $general_count ) ; do
460521 printf ' %s\n' \
461522 " ${RUNNER_NAME_PREFIX} runner-${i} :" \
@@ -478,13 +539,13 @@ shell_generate_compose_file() {
478539 " volumes:" \
479540 " - ${RUNNER_NAME_PREFIX} runner-${i} -data:/home/runner" \
480541 " - ${RUNNER_NAME_PREFIX} runner-${i} -udev-rules:/etc/udev/rules.d" \
481- " " >> docker-compose.yml
542+ " " >> " ${COMPOSE_FILE} "
482543 done
483544
484545 # 只有当 RUNNER_BOARD 大于 0 时才生成板子 runners
485546 if [[ " ${RUNNER_BOARD} " -gt 0 ]]; then
486547 # 生成板子 runners
487- echo " # 板子专用 runners" >> docker-compose.yml
548+ echo " # 板子专用 runners" >> " ${COMPOSE_FILE} "
488549
489550 # phytiumpi 板子配置
490551 printf ' %s\n' \
@@ -539,7 +600,7 @@ shell_generate_compose_file() {
539600 " $extra_vol_phytiumpi " \
540601 " - ${RUNNER_NAME_PREFIX} runner-phytiumpi-data:/home/runner" \
541602 " - ${RUNNER_NAME_PREFIX} runner-phytiumpi-udev-rules:/etc/udev/rules.d" \
542- " " >> docker-compose.yml
603+ " " >> " ${COMPOSE_FILE} "
543604
544605 # roc-rk3568-pc 板子配置
545606 printf ' %s\n' \
@@ -590,18 +651,18 @@ shell_generate_compose_file() {
590651 " $extra_vol_roc " \
591652 " - ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-data:/home/runner" \
592653 " - ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-udev-rules:/etc/udev/rules.d" \
593- " " >> docker-compose.yml
654+ " " >> " ${COMPOSE_FILE} "
594655 fi
595656
596657 # 生成 volumes
597- echo " volumes:" >> docker-compose.yml
658+ echo " volumes:" >> ${COMPOSE_FILE}
598659
599660 for i in $( seq 1 $general_count ) ; do
600661 printf ' %s\n' \
601662 " ${RUNNER_NAME_PREFIX} runner-${i} -data:" \
602663 " name: ${RUNNER_NAME_PREFIX} runner-${i} -data" \
603664 " ${RUNNER_NAME_PREFIX} runner-${i} -udev-rules:" \
604- " name: ${RUNNER_NAME_PREFIX} runner-${i} -udev-rules" >> docker-compose.yml
665+ " name: ${RUNNER_NAME_PREFIX} runner-${i} -udev-rules" >> " ${COMPOSE_FILE} "
605666 done
606667
607668 # 只有当 RUNNER_BOARD 大于 0 时才生成板子相关的 volumes
@@ -611,14 +672,14 @@ shell_generate_compose_file() {
611672 " ${RUNNER_NAME_PREFIX} runner-phytiumpi-data:" \
612673 " name: ${RUNNER_NAME_PREFIX} runner-phytiumpi-data" \
613674 " ${RUNNER_NAME_PREFIX} runner-phytiumpi-udev-rules:" \
614- " name: ${RUNNER_NAME_PREFIX} runner-phytiumpi-udev-rules" >> docker-compose.yml
675+ " name: ${RUNNER_NAME_PREFIX} runner-phytiumpi-udev-rules" >> " ${COMPOSE_FILE} "
615676
616677 # 为 roc-rk3568-pc 板子生成 volumes
617678 printf ' %s\n' \
618679 " ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-data:" \
619680 " name: ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-data" \
620681 " ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-udev-rules:" \
621- " name: ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-udev-rules" >> docker-compose.yml
682+ " name: ${RUNNER_NAME_PREFIX} runner-roc-rk3568-pc-udev-rules" >> " ${COMPOSE_FILE} "
622683 fi
623684}
624685
@@ -1081,9 +1142,10 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
10811142 shell_delete_all_execute " Confirm unregister of all Runners, delete all containers and volumes, and remove all generated files? [y / N] " || { echo " Operation cancelled!" ; exit 0; }
10821143 fi
10831144 for f in \
1084- " ${REG_TOKEN_CACHE_FILE} " \
1145+ " ${REG_TOKEN_CACHE_FILE} " * \
10851146 " ${DOCKERFILE_HASH_FILE} " \
1086- " $ENV_FILE " ; do
1147+ " $ENV_FILE " \
1148+ " $COMPOSE_FILE " ; do
10871149 if [[ -f " $f " ]]; then
10881150 shell_info " Removing file $f "
10891151 rm -f " $f " || true
0 commit comments