DOMJudge 踩坑笔记

警告

本文发表于 2018 年底,DOMJudge 的代码已进行了大规模的重构,部分内容可能过时。

EC-Final 结束之后就一直是咸鱼状态。然后就自己挖了个坑,学习配置了一下 DOMjudge。

于是水一篇博文来记录一下过程中遇到的各种坑。

官网已经更新到 7.1.1 版本,以下内容可能过时,最新内容请参考此处

DOMjudge交流群

注释

Docker 还是方便,偷懒的话可以用 Docker 一键部署。

docker-compose.yaml
yaml
version: '2'
services:
  mariadb:
    image: mariadb
    restart: always
    volumes:
      - $PWD/data/mysql:/var/lib/mysql
    ports:
      - 13306:3306
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - MYSQL_ROOT_PASSWORD=adm1n
      - MYSQL_USER=domjudge
      - MYSQL_PASSWORD=passw0rd
      - MYSQL_DATABASE=domjudge
    command: --max-connections=1000
  domserver:
    image: domjudge/domserver:latest
    restart: always
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    links:
      - mariadb:mariadb
    ports:
      - 12345:80
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - MYSQL_HOST=mariadb
      - MYSQL_ROOT_PASSWORD=adm1n
      - MYSQL_USER=domjudge
      - MYSQL_PASSWORD=passw0rd
      - MYSQL_DATABASE=domjudge
  judgehost_0:
    image: domjudge/judgehost:latest
    restart: always
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    links:
      - domserver:domserver
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - DAEMON_ID=0
      - JUDGEDAEMON_USERNAME=judgehost
      - JUDGEDAEMON_PASSWORD=judgeh0st
    privileged: true
  judgehost_1:
    image: domjudge/judgehost:latest
    restart: always
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    links:
      - domserver:domserver
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - DAEMON_ID=1
      - JUDGEDAEMON_USERNAME=judgehost
      - JUDGEDAEMON_PASSWORD=judgeh0st
    privileged: true

版本与环境

版本环境
Ubuntu 16.04 LTSDOMjudge 6.0.3

DOMserver 部分

准备工作

这部分其实就是朗读了一遍文档,直接按文档搞就好了。

安装依赖包和功能

bash
sudo apt install gcc g++ make zip unzip mariadb-server \
        apache2 php php-cli libapache2-mod-php php-zip \
        php-gd php-curl php-mysql php-json php-xml php-intl php-mbstring \
        acl bsdmainutils ntp phpmyadmin python-pygments \
        libcgroup-dev linuxdoc-tools linuxdoc-tools-text \
        groff texlive-latex-recommended texlive-latex-extra \
        texlive-fonts-recommended texlive-lang-european

安装时选择 apache2

bash
sudo apt install libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev
bash
sudo phpenmod json

编译 DOMjudge

bash
wget https://www.domjudge.org/releases/domjudge-6.0.3.tar.gz
tar -zxvf domjudge-6.0.3.tar.gz
bash
cd domjudge-6.0.3
./configure --prefix=$HOME/domjudge --with-baseurl=127.0.0.1
make domserver && sudo make install-domserver
make judgehost && sudo make install-judgehost
make docs && sudo make install-docs

配置数据库

bash
cd ~/domjudge/domserver
sudo bin/dj_setup_database -u root install

配置 Web 服务器

bash
cd ~/domjudge/domserver
sudo ln -s /home/ubuntu/domjudge/domserver/etc/apache.conf /etc/apache2/conf-available/domjudge.conf
sudo a2enmod rewrite
sudo a2enconf domjudge
sudo systemctl reload apache2

这里的ubuntu是我的实际用户名。

到这里,就可以访问http://127.0.0.1/domjudge,并使用admin作为用户名和密码登陆后台了。

如果需要使用类似domjudge.example.com的形式访问,可以根据domjudge.conf中的注释,来配置虚拟服务器。

配置 MySQL

编辑/etc/mysql/my.cnf,追加内容:

ini
[mysqld]
max_connections = 1000
max_allowed_packet = 16MB
innodb_log_file_size = 48MB

其中 max_allowed_packet 数值改成两倍于题目测试数据文件的大小,innodb_log_file_size 数值改成十倍于题目测试数据文件的大小。

bash
sudo systemctl restart mysql

配置 PHP

编辑 ~/domjudge/domserver/etc/apache.conf,取消以下几行内容前的注释:

apache
<IfModule mod_php7.c>
php_value max_file_uploads      100
php_value upload_max_filesize   128M
php_value post_max_size         128M
php_value memory_limit          512M
</IfModule>

编辑 /etc/php/7.2/apache2/php.ini,搜索 date.timezone 关键字,取消其行前注释,并将其值设为 Asia/Shanghai

bash
sudo systemctl restart apache2

配置 Apache

编辑 /etc/apache2/apache2.conf,搜索 KeepAlive 关键字,将其值设为 Off,并在其后新增一行内容:

apache
MaxClients 1000
bash
sudo systemctl restart apache2

配置 DOMserver

访问 http://127.0.0.1/domjudge (或者外网IP/域名),使用用户名admin密码admin登陆。

修改 admin 密码

访问 users 页面,点 admin 用户边上的铅笔图标,在 Password 栏中输入新密码,保存。

配置设置

添加队伍和账号

  • 去年学长搞的时候是直接拿SQL语句操作数据库的。(大声
  • 先导入 teams.tsv 再导入 accounts.tsv。 文件编码要用UTF-8
  • 具体格式可以参考这个

如果使用系统默认的Group,那么teams表中的Group_ID就全部填 $3$,表示participants,其它情况按需要调整。 accounts表中的usernameteam01的形式就可以和team表对应上。(可能还有其它方法对应)

如果需要使用学校的校徽,可以放在~/domjudge/domserver/webapp/web/images/affiliations文件夹下。 图片大小需要自行调整,文件名为<ExternalID>.png。 在导入teams表的时候,在Country Code后追加一列,填写Institution External ID。 这步是阅读源代码 后猜测的,当时的实际操作是直接在数据库中的team_affiliation用SQL语句更新ExternalID的。

更正:在导入teams表的时候,如果有多个学校(即使不用校徽),必须要有 Institution External ID ,似乎是因为这部分对空值的处理有一些问题。

这部分实际上比较迷,建议研究一下DOMjudge的数据库结构和源代码,一般情况下我觉得读到这里的同学有能力自行解决。(小声

生成队伍密码

访问 home 页面,点 Manage team passwords,选中 all teamsas userdata.tsv download。 注意生成过的密码除了 userdata.tsv 不能在其他地方再被看到。

Judgehost 部分

准备工作

安装依赖包和功能

bash
sudo apt install make sudo debootstrap libcgroup-dev \
        php-cli php-curl php-json php-xml php-zip procps \
        gcc g++ openjdk-8-jre-headless \
        openjdk-8-jdk ghc fp-compiler \
        libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev \
        supervisor

编译 DOMjudge

这里只针对单独配置 Judgehost 的机器,前面 DOMserver 配置中已经同时安装了 Judgehost。

bash
cd Downloads
wget https://www.domjudge.org/releases/domjudge-6.0.3.tar.gz
bash
tar -zxvf domjudge-6.0.3.tar.gz
bash
cd domjudge-6.0.3
./configure --prefix=$HOME/domjudge --with-baseurl=127.0.0.1
make judgehost && sudo make install-judgehost

配置 Judgehost

添加用户

bash
useradd -d /nonexistent -U -M -s /bin/false domjudge-run
# 如果 judgehost 拥有多个 CPU 核心,你可以添加额外的用户来支持绑定
# 不同的 judgehost 进程到不同的 CPU 核心上,如下:
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-0
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-1
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-2
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-3
# ... 如果有更多的 CPU 核心,请自行添加更多的用户

配置 sudoers

$HOME/domjudge/judgehost/etc/sudoers-domjudge 复制到 /etc/sudoers.d/ 目录下。

bash
sudo cp $HOME/domjudge/judgehost/etc/sudoers-domjudge /etc/sudoers.d/

修改 rest 密码

使用 vim 等文本编辑器编辑 ~/domjudge/judgehost/etc/restapi.secret 这个文件。把 DOMserver 中相应文件夹下的对应文件抄一下。

构建 chroot 环境

使用 vim 等文本编辑器编辑 ~/domjudge/judgehost/bin/dj_make_chroot 脚本,将 ubuntu 镜像改为国内源。 (第 172 行)

bash
# Ubuntu mirror, modify to match closest mirror
[ -z "$DEBMIRROR" ] && DEBMIRROR="http://mirrors.aliyun.com/ubuntu/"

提示

因为这一步需要访问网络,若需要配置代理服务器请按需设置。

修改之后保存并运行此脚本。这一步会从源上下载必要的软件包,所以请耐心等待。

设置 cgroup

使用 vim 等文本编辑器编辑 /etc/default/grub 这个文件,对其中的这一行做如下修改:

bash
GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"

然后执行:

bash
update-grub

之后重启计算机

bash
cat /proc/cmdline

检查是否添加成功。

配置 supervisor

这里针对的是多核判题的配置,单核就没有管理的必要了,直接终端中运行 ~/domjudge/judgehost/bin/judgedaemon 即可。

使用 vim 等文本编辑器在 /etc/supervisor/conf.d 下新建一个文本文件叫做 judgehost.conf,写入下列内容:

ini
[program:judgehost]
command=/home/ubuntu/domjudge/judgehost/bin/judgedaemon -n %(process_num)d
autorestart=true
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/judgehost/judgehost.log
stderr_logfile=/var/log/judgehost/judgehost.err.log
numprocs=4
numprocs_start=0
  • 上面的 numprocs 应该根据实际的 CPU 核心数。
  • 根据实际情况把 ubuntu 改为对应用户名。
  • 根据实际情况配置 stdout_logfilestderr_logfile

最后,使用如下命令重新加载 supervisor :

bash
sudo systemctl restart supervisord.service
  • 启动 judgehost
bash
sudo supervisorctl start judgehost
  • 查看 judgehost 进程的运行情况:
bash
sudo supervisorctl status
  • 每次开机的时候记得执行~/domjudge/judgehost/bin/create_cgroup。否则判题的时候会因为权限不够 CE 。

Special Judge

这部分内容应该可以交给出题组来配置。
由于大部分出题人习惯(包括我自己在校赛命题时)使用 Polygon 的 testlib.h 编写 checker,所以此处给出直接将 Polygon 的 checker 搬运至 domjudge 的方法。

由于 domjudge 对于 checker 的入口参数和返回值与传统的 checker 较为不同,所以我们对 testlib.h 进行了修改以使 checker 兼容 domjudge。

内容已删除

提示

此压缩包的配置方式可能过时,现版本的 domjudge 可以不需要添加 build 脚本,直接把 checker.cpptestlib.h 打包即可。具体可以参考此处

将使用 Polygon 平台编写的 checker 放入下载的压缩包,并上传至 domjudge 后台。设置对应题目的 Compare script 即可。

Licensed under CC BY-NC-SA 4.0
最后更新于 2022 年 11 月 3 日 01:07 CST