南昌大学第九届程序设计竞赛——技术组日记
前言
自入校以来,这是我参与的第三届校赛,校赛也从之前的QOJ,换成Hydro,再到与 ICPC 对称的Domjudge+ICPC Image选手机环境,每一步都是在给后人踩坑(笑),总之先讲一下今年发生的事情吧。
Day -1
选手机镜像下发
找到机房的老师,确定了在可以批量下发 Linux 磁盘镜像,配合云桌面系统可以做到批量部署还原后,我选择了该镜像作为比赛选手机用镜像:2026 ICPC WF Image
做桌面需要先使用其中一台机器,将镜像应用到硬盘中。这里配合 `arch linux live OS` 使用 `dd` 去应用磁盘镜像。
注意到该镜像只有 32GiB 的分区空间,因此如果你应用了该表会导致 GPT 分区紊乱从而无法扩容分区,若无此需求则直接烧录即可,但如果你需要进行扩容,则在运行 `dd` 应用磁盘镜像后,须通过 `cfdisk` 等工具修复 GPT 分区表。
当烧录完镜像后,此时该镜像具有两个默认账号:
icpc:具有root权限的账户,密码为passw0rd
team:比赛账户,密码为contest,文档说具有sudo权限,但实际上并没有该权限。
接下来需要登录icpc账户,通过sudo su进入root账户,第一件事就是passwd给账户。要注意这个密码只是备用,实际上最后是通过ssh去远程登录的。
设置完后将准备好的密钥录入到/root/.ssh/authorized_keys中,以方便稍后使用 `ansible`` 批量远控。
在大赛环境中,使用Ansible去大批量远控几乎是唯一的选择,其易用性和完整的文档加上兼容性,在比赛场景中基本上用它是没错的。
但要注意hosts的使用方式,以及密钥是否已经正常应用。
将以上的工作做完后,选手机的实机操作便到此为止。
部署完该镜像后,此时其他两位同学也来到了机房,开始部署 Domjudge。
Domjudge部署
这里和@HeartFireY问了一下,决定配置方案采取Domjudge手动安装 +Docker容器运行judgehost的方式。
由于Docker毕竟是一个轻量化容器环境,而judgehost需要工作在一个chroot环境下,最好的方式还是使用实机安装,通过手动解包选手机镜像做出一个和选手机统一的编译环境,同时避免性能损失。
前往Domjudge下载最新构建版,这个压缩包包含了Domjudge、judgehost和一些文档与实用脚本。
按照安装文档,先安装依赖:
sudo apt install libcgroup-dev make acl zip unzip pv mariadb-server nginx \
php php-ds php-fpm php-gd php-cli php-intl php-mbstring php-mysql \
php-curl php-json php-xml php-zip composer ntp python3-yaml php-bcmath如果没有如make等,转为安装build-essential,或通过sudo apt install aptitude让aptitude安装。
接下来准备数据库,数据库使用MariaDB,安装完后保存root用户的登录凭据,会在接下来的步骤中使用。
下载的归档文件,解压后前往根目录。
运行示例命令进行安装:
./configure --prefix=/opt/domjudge --with-baseurl='http://contest/'
make domserver
sudo make install-domserver--prefix指定了安装的目录,这里便是把Domjudge安装在了/opt/domjudge下。--with-baseurl='http://contest/'也很关键,它指定了接下来的很多东西,包括你的文档和你的反代使用的链接。要记住这个链接,稍后反代会使用这个链接。
安装好后进入你的安装目录,此时这里应该存在一个 `bin` 文件夹,使用内的 `dj_setup_database` 脚本配置数据库:
dj_setup_database genpass
dj_setup_database [-u ] [-p |-r] install其中这里的-u与-p分别是你之前存储的root用户登录凭据。
哦对了,提一嘴,这里的凭据可以在安装目录下的etc/dbpasswords.secret文件中找到。不过你都有root了……
接下来需要配置反代,Domjudge提供了nginx的反代文件,按照官网往里塞就行:
ln -s /etc/nginx-conf /etc/nginx/sites-enabled/domjudge
ln -s /etc/domjudge-fpm.conf /etc/php/8.4/fpm/pool.d/domjudge.conf
# Edit the files /etc/nginx/sites-enabled/domjudge and
# /etc/php/8.4/fpm/pool.d/domjudge.conf to your needs
service php8.4-fpm reload
service nginx reload当然它也提供了Apache web server的配置,但因为用惯了nginx所以没研究。
当你配完之后应该就可以访问http://contest/domjudge便可以访问了。如果不需要/domjudge前缀,去etc/nginx-inner里面改,该定义在这里面。
登录domjudge的管理面板,默认账户在etc/initial_admin_password.secret寻找。接下来去后台给评测机创建若干个judgehost类型的账号,等等docker容器鉴权用
Domjudge judgehost 部署
因为这里是judgehost部署,所以单命令启动:
docker run -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup --name judgehost-0 --hostname judgedaemon-0 \
-e DAEMON_ID=0 \
-e DOMSERVER_BASEURL=http://contest/ \
-e JUDGEDAEMON_USERNAME= \
-e JUDGEDAEMON_PASSWORD= \
domjudge/judgehost:latest这里要注意两个点:
宿主机必须开启
cgroup,不开启则judgehost无法工作;DAEMON_ID在文档中是说明标明该judgehost的守护程序编号,但问题是该编号同时指定了该judgehost跑在哪个 CPU 核心上,因此绝对不允许设置该值超过宿主机的 CPU 核心编号,不然会跑不起来。
到这里,Domjudge部署完毕。
制作账号
账号的格式在此章节是有说明的。处理好队伍的所属关系和队伍类型即可。这次校赛榜单爆炸的主要原因就是因为在这个地方错误的创建了 177 个名为Participant的队伍类型,从而导致前台的参赛者和CDP全部都无法正常读取信息(警钟敲烂啊)。
这里要配置 IP 登录,因此在account的文件内必须要加入ip字段以配置其自动登录,同时要在管理后台开启 IP 登录功能。
Day 0
来到正赛,这里同样要警钟敲烂。一定一定要在开赛前 1-2 小时前开始推送远程部署脚本,不然就等部分机器失败后继续 retry……直到开赛后都无法正常登录。
赛时没出大问题,唯一奇怪的点是当有部分选手写死循环或无限递归时桌面会直接卡死,但后台却可以正常通过 ssh 访问进去,这一部分的原因需要查询一下。
当比赛经过 4 小时后,开始准备 CDP 文件,该文件的标准请看此章节。为什么要做该文件,因为后续的滚榜环节强需求该文件。
但有一个问题是,由于之前 177 个Participant的问题,导致实际上的event-feed文件已经被污染了,无法正常的识别。想起来我们技术组写过的 Resolver 可以正常解析这种损坏的event-feed,因此直接用了,效果还是很好。
总结
这次比赛,成功落地,很 OK。但小问题需要注意,最好下次校赛不要再犯这样的错误。
碎碎念
你知道,作为技术组,有一个特权是什么吗?答案是疯狂的塞私货。
左边立绘的出处:

