For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /guide/features/attachment.md.

动态附件生成

附件类型

类型适用题型说明
静态附件静态题、容器题上传一次,所有队伍共享
动态附件动态附件题每队单独生成,依赖 Kubernetes

工作流程

动态题加入比赛和发布时,平台会提前启动生成器。每道题默认准备 2 个实例,管理员可通过 k8s.generator_pool_size 调整,也可在比赛的生成器页面手动增加。

准备题目镜像并启动生成器

队伍初始化或重置题目,开始生成专属附件

生成器执行脚本,将该队 Flag 写入题目内容

脚本完成并输出 ZIP 附件

队伍在题目页面下载附件

生成器繁忙时任务会排队,已有可用附件时可直接下载。等待较久时,管理员可检查任务队列和生成器状态。容量配置见工作负载调度。

生成器要求

容器启动方式

题目镜像需包含 sleep、unzip 和生成脚本所需的工具。平台负责启动容器并调用脚本,镜像原有入口不会执行,因此请将题目初始化步骤放在 /root/run.sh 中。

可选上传 generator.zip

若题目上传了 generator.zip,平台会在容器内执行:

unzip -o /root/mnt/generator.zip -d /root

因此镜像还必须包含 unzip。

执行入口

平台执行命令:

/root/run.sh {team_id} {base64(base64(flag1),base64(flag2),...)}

参数说明:

  • $1:队伍 ID
  • $2:多 Flag 的二次 Base64 编码结果

输出路径

生成结果必须写入:

/root/mnt/attachments/{team_id}.zip

脚本需在 1 分钟内完成 ZIP 写入后退出,不要将生成过程放到后台。输出目录为临时目录,附件交付后会清理;队伍下载的文件名为 attachment.zip。

示例脚本

#!/bin/bash
set -euo pipefail
TEAM_ID=$1
FLAGS_B64=$2

# 解码参数并取出第一个 Flag
ENCODED_FLAGS=$(printf '%s' "$FLAGS_B64" | base64 -d)
FLAG1=$(printf '%s' "${ENCODED_FLAGS%%,*}" | base64 -d)
WORKDIR=$(mktemp -d)
trap 'rm -rf "$WORKDIR"' EXIT
printf '%s\n' "$FLAG1" > "$WORKDIR/flag.txt"

mkdir -p /root/mnt/attachments
OUTPUT="/root/mnt/attachments/${TEAM_ID}.zip"
rm -f "$OUTPUT"
zip -j "$OUTPUT" "$WORKDIR/flag.txt"

注意事项

  1. 镜像必须包含 sleep 与 unzip
  2. 脚本入口固定为 /root/run.sh,工作目录为 /root
  3. 输出文件必须是 /root/mnt/attachments/{team_id}.zip
  4. 此示例还需要 bash、base64、mktemp 和 zip;将 /root/run.sh 设置为可执行。镜像入口会被 worker 覆盖,初始化逻辑应放在脚本中
  5. 共享存储不可用时,动态附件无法生成

管理入口

生成器支持两种管理方式:

  • 全局生成器:「管理后台 → 生成器」,用于查看实例和启动题库测试生成器
  • 比赛专用生成器:「比赛 → 生成器」,为该比赛的队伍生成附件

比赛开始前可通过赛事专用生成器管理检查自动预建的实例是否 Ready,并按附件计算量增加实例。将 k8s.generator_pool_size 设为 0 时,实例完全由管理员手动管理。