cubercsl

DOMjudge 踩坑笔记
EC-Final 结束之后就一直是咸鱼状态。然后就自己挖了个坑,学习配置了一下DOMjudge。于是水一篇博文来记...
扫描右侧二维码阅读全文
28
2018/12

DOMjudge 踩坑笔记

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

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

版本与环境

版本环境
Ubuntu 16.04 LTSDOMjudge 6.0.3

官网已经更新到 7.0. 版本,以下内容可能过时。

Docker 还是好用哦,嫌麻烦的可以直接用官方的镜像。

docker-compose.yml

version: '2'
services:
  mariadb:
    image: mariadb
    restart: always
    volumes:
      - /home/ubuntu/domjudge/data/mysql:/var/lib/mysql
    ports:
      - 13306:3306
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - MYSQL_ROOT_PASSWORD=<password>
      - MYSQL_USER=domjudge
      - MYSQL_PASSWORD=<password>
      - 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:
      - 8000:80
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - MYSQL_HOST=mariadb
      - MYSQL_ROOT_PASSWORD=<password>
      - MYSQL_USER=domjudge
      - MYSQL_PASSWORD=<password>
      - MYSQL_DATABASE=domjudge
      - DJ_DB_INSTALL_BARE=1
  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=<password>
    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=<password>
    privileged: true
  judgehost_2:
    image: domjudge/judgehost:latest
    restart: always
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    links:
      - domserver:domserver
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - DAEMON_ID=2
      - JUDGEDAEMON_USERNAME=judgehost
      - JUDGEDAEMON_PASSWORD=<password>
    privileged: true
  judgehost_3:
    image: domjudge/judgehost:latest
    restart: always
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    links:
      - domserver:domserver
    environment:
      - CONTAINER_TIMEZONE=Asia/Shanghai
      - DAEMON_ID=3
      - JUDGEDAEMON_USERNAME=judgehost
      - JUDGEDAEMON_PASSWORD=<password>
    privileged: true

DOMserver 部分

准备工作

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

安装依赖包和功能

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

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

编译 DOMjudge

wget https://www.domjudge.org/releases/domjudge-6.0.3.tar.gz
tar -zxvf domjudge-6.0.3.tar.gz
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

配置数据库

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

配置 Web 服务器

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,追加内容:

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

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

sudo systemctl restart mysql

配置 PHP

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

<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

sudo systemctl restart apache2

配置 Apache

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

MaxClients 1000
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 部分

准备工作

安装依赖包和功能

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。

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

配置 Judgehost

添加用户

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/ 目录下。

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 行)

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

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

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

设置 cgroup

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

GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"

然后执行:

update-grub

之后重启计算机

cat /proc/cmdline

检查是否添加成功。

配置 supervisor

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

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

[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 :

sudo systemctl restart supervisord.service
  • 启动 judgehost
sudo supervisorctl start judgehost
  • 查看 judgehost 进程的运行情况:
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。

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

最后修改:2019 年 07 月 12 日 09 : 29 PM
如果觉得我的文章对你有用,请随意赞赏

15 条评论

  1. cslbb

    bnlsc

  2. 0GGmr0

    cslnb

  3. 17

    cslnb

    1. cubercsl
      @17

      你怎么回事

  4. compute

    cslnb

    1. cubercsl
      @compute

      嘻嘻嘻

  5. outside

    搜资料竟然搜到了蔡队的博客OωO,还是同款主题|´・ω・)ノ

    1. cubercsl
      @outside

      嘻嘻嘻~

  6. sumover

    能讲讲judgehost相关的API么...或者说怎么在远程判题

    1. cubercsl
      @sumover

      在远程的判题机上配置相应的 restapi.secret 文件,可以在 domserver 的 etc 目录下找到,复制过去就好。把里面的节点的 localhost 改成你 server 对应的 IP 地址,后面的密码保持不变就好。

  7. MySakure

    搜资料竟然搜到了蔡队的博客

    1. cubercsl
      @MySakure

      啊?domjudge的资料嘛

  8. kench

    集体换handsome主题是什么鬼阿233333~

    1. cubercsl
      @kench

      因为kench牛逼!

      1. kench
        @cubercsl

        emmmmmm,我当初就不该在群里吹handsome(

发表评论 取消回复