2018 ACM-ICPC 沈阳站现场赛环境配置记录

Bittersweet2018-10-30,更新于 2019-8-22
本文最后更新于 1369 天前(2019-8-22),其中的信息可能已经有所发展或者不再适用于现阶段。
本文全长 2915 字,全部读完大约需要 9 分钟。

这里是 NEU_Bittersweet,2018年 ICPC 沈阳站现场赛的技术负责人之一。

今年的现场赛尝试性地使用了 Ubuntu 18.04 和 domjudge,尽可能地向 World Final 看齐,虽然踩了一些坑、也有一些小遗憾,但是总体上来说给选手们的体验还是不错的w

感谢和我一起肝环境配置的黑猫、yuki、念、WYJ、大腿、海之树等技术组的同学们,感谢萌萌哒出题人 qls、tls和 cls 给我们带来的精彩题目,感谢刘老师提供的千兆交换机,感谢现场的工作人员和志愿者们(志愿者真是太棒啦!正赛那一天比赛结束后,选手不用离场,志愿者们花了不到 5min 就把全场的选手机回收完毕,体验极佳!),也感谢参赛选手对我们工作中出现的失误的理解和包容w

好啦,感谢时间到此结束,接下来是踩坑记录(


0. 硬件

热身赛前一天的周五晚上,当我配置好服务器准备进行大批量网络安装 Ubuntu 的时候,从 1 号机开始网络启动,却无论如何都找不到 DHCP server…… 排查了好久好久,尝试了各种办法,最终得出结论:第一排的交换机和总交换机都坏了……当时已经是晚上六七点,负责现场网络的工作人员已经走了,只好麻烦刘老师借来了几台新的千兆交换机,换上之后故障解决。现场赛的交换机们都是有一些年头的了,像是第一排交换机,在一开始只开一台机器进行网络安装测试的时候表现完全正常,但是在打开了第一排五六台机器同时进行安装的时候,即高负载的情况下,就会挂掉……所以希望以后负责的学弟学妹在负责网络的工作人员离开之前先完整地测试一下网络硬件情况,或者让他们提供几台备用交换机,防止被硬件问题坑。


1. 软件

1.0 Ubuntu 18.04 LTS 网络无人值守批量安装

因为这一次现场赛需要将所有的选手机和服务器以及评测机都升级成Ubuntu 18.04,所以需要批量重装系统。2016 年的做法是给志愿者们发安装 U 盘,然后手工一台一台去重装……可以想象既耗时又耗力。之前我尝试过网络安装 Centos,所以这一次决定试一下网络安装 Ubuntu。

去 Google 了一圈,找到了这一篇很棒的博文 (https://www.voidking.com/2018/05/10/deve-ubuntu-auto-install),对照官方的英文安装文档 (https://help.ubuntu.com/lts/installation-guide/index.html),终于成功的摸索出了安装方法。

1.0.0 网络安装服务器系统的安装

服务器系统为了保持一致就选择 Ubuntu 18.04 吧,当然服务器需要使用 U 盘手动安装,这个就不再赘述了。系统安装完成之后连接网络,进行一次更新:sudo apt-get update -y && sudo apt-get upgrade -y

1.0.1 DHCP Server 的配置

安装 isc-dhcp-server:sudo apt-get install isc-dhcp-server -y

接下来进行网卡和 ip 的配置,我们这里假设服务器的 ip 已经手动指定为 192.168.1.252/24,网卡接口为 eth0,那么接下来修改 dhcp 的配置文件,指定网卡:sudo vim /etc/default/isc-dhcp-server,定位到最底部,修改为 INTERFACES="eth0"

之后修改 dhcp server 的配置文件:sudo vim /etc/dhcp/dhcpd.conf,定位到最底部,追加:

allow booting;
allow bootp;
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.1 192.168.1.230;
    option subnet-mask 255.255.255.0;
    option routers 192.168.1.252;
    option broadcast-address 192.168.1.255;
    filename "pxelinux.0";
    next-server 192.168.1.252;
}

其中, filename "pxelinux.0"; 指定 PXE 启动文件名 next-server 192.168.1.252; 指定 PXE 服务器和 TFTP 服务器的地址 allow booting;allow bootp; 来自于官方安装文档

配置完成之后,使用 sudo systemctl restart isc-dhcp-server 重启 DHCP 服务器,并使用 sudo systemctl status isc-dhcp-server 保证 DHCP 服务处于正常运行状态。

1.0.2 TFTP Server 的配置

安装 tftpd-hpa:sudo apt-get install tftpd-hpa -y

给根目录添加读写权限:sudo chmod -R 777 /var/lib/tftpboot/

接下来,下载 Ubuntu 的网络启动镜像,下载官方链接 (http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/installer-amd64/current/images/netboot/) 的 netboot.tar.gz 即可。下载解压之后,修改其中 netboot/ubuntu-installer/amd64/boot-screens/txt.cfg 的内容如下,具体细节可参考官方安装文档:

default install
label install
	menu label ^Install
	menu default
	kernel ubuntu-installer/amd64/linux
	append auto=true priority=critical url=http://192.168.1.252/preseed.txt vga=788 initrd=ubuntu-installer/amd64/initrd.gz --- quiet 
label cli
	menu label ^Command-line install
	kernel ubuntu-installer/amd64/linux
	append tasks=standard pkgsel/language-pack-patterns= pkgsel/install-language-support=false vga=788 initrd=ubuntu-installer/amd64/initrd.gz --- quiet

最后,将网络启动文件复制到 TFTP 根目录即可:sudo cp -r netboot/* /var/lib/tftpboot/

1.0.3 Apache 的配置

安装 apache:sudo apt-get install apache2 -y

将 Ubuntu 安装镜像中的 base file image 放置到 Web 根目录。具体做法为解压 Ubuntu 的安装 iso 文件,复制其中的 casper 文件夹到 /var/www/html 下,最后在浏览器中测试 http://192.168.1.252/casper/filesystem.squashfs 的可访问性。

1.0.4 Squid 代理服务器的配置

之所以配置 squid 代理服务器,是因为选手机在网络安装的时候将借助代理访问 Ubuntu 的软件源(我使用的是清华大学的源,http://mirrors.tuna.tsinghua.edu.cn/ubuntu)。使用 squid,借助其缓存机制,可以在安装完一台选手机之后,使缓存命中率达到100%,极大地减小外网访问负载,提高网络安装速度。

安装 squid:sudo apt-get install squid -y

之后更改 squid 的配置,将其缓存大小和并发数提高,具体步骤请 Google,在此不再赘述。

1.0.5 preseed 文件的配置

Ubuntu 的网络安装器支持自动安装的方法之一就是从 preseed 文件来读取预先设置好的安装配置信息。当然,因为是网络安装,所以我们在实际安装过程中仍然需要手动配置一下网络,但是在网络配置之后的过程就是全自动的啦。这里贴出我所使用的 preseed 文件供参考 (http://pw.qwqq.pw/p0buox7tj) 在真正网络安装之前,请根据自己的需求对 preseed 文件做出相应修改,关于 preseed 文件的详细信息可以参考官方英文安装文档的附录 A。

另外,我的 preseed 文件的最后调用了两个自定义脚本来配置自动登录和用户 home 文件夹,在这里给出脚本的代码:

配置自动登录 (set_autologin.sh):

#!/bin/bash
# Creator: Bittersweet NEUACM
# Time:    2018/10/16 22:26

if [ -z "$1" ]; then
    echo "Usage: set_autologin "
    exit 1
fi
MYUSER=$1

# Set auto login
ALFILE="/etc/gdm3/custom.conf"
rm -f $ALFILE
echo "[daemon]" >> $ALFILE
echo "AutomaticLoginEnable=true" >> $ALFILE
echo "AutomaticLogin=$MYUSER" >> $ALFILE
echo "" >> $ALFILE
echo "[security]" >> $ALFILE
echo "" >> $ALFILE
echo "[xdmcp]" >> $ALFILE
echo "" >> $ALFILE
echo "[chooser]" >> $ALFILE
echo "" >> $ALFILE
echo "[debug]" >> $ALFILE
echo "" >> $ALFILE

配置 home 文件夹 (init_home.sh):

#!/bin/bash
# Creator: Bittersweet NEUACM
# Time:    2018/10/18 19:23

if [ -z "$1" ]; then
    echo "Usage: init_home "
    exit 1
fi
MYUSER=$1

# assert that /tmp/home.tar.xz contains new home directory
rm -rf /home/$MYUSER
mkdir /home/$MYUSER
tar -xf /tmp/home.tar.xz -C /home/$MYUSER
chown -R $MYUSER /home/$MYUSER
chmod +x /home/$MYUSER/Desktop/*.desktop

这里需要提前获取一个配置好的干净的用户 home 文件夹压缩包,用于快速配置用户的桌面布局和设置,以及用于热身赛后的环境重置。保存在 home 文件夹里的内容包括但不限于:系统偏好设置(锁屏时间、壁纸等等),桌面图标及其布局(这个非常实用,可以提前帮选手排列好图标),左侧启动器的图标及其布局,Codeblocks 的偏好设置(编译器参数等),Firefox 的偏好设置(主页等,可以将主页设置为 DOMJudge 选手界面),ssh 的密钥(~/.ssh/authorized_keys,配置好密钥可以实现服务器批量 ssh 选手机进行远程操作),等等。

为了获取一个配置好的干净的 home 文件夹,我使用的方法是,首先通过网络安装一台选手机,然后在这台选手机上配置好锁屏时间、桌面图标、启动器图标、Codeblocks 设置、Firefox 设置、ssh 的密钥等等,然后清除 bash 的历史记录(~/.bash_history),之后使用终端对用户的 home 打包。

1.0.6 一切就绪

经过前面的配置,一切准备工作就完成啦。接下来可以找到一台选手机,开机的时候选择网络启动,手动输入网络配置,然后静静地欣赏全自动安装。安装完成之后,仔细检查一下各项配置是否都正确,IDE 和编辑器能否正常使用。若检查无误,则可以开始批量部署啦。

这里有个小技巧,在自动安装的过程中,并不是时时刻刻都在访问网络的,安装器第二步会先通过网络获取基本工具,然后安装基本工具,第三步会先通过网络获取 preseed 里面配置好的软件包(桌面环境和 IDE 等),之后安装这些软件包(这个过程是最耗时的)。可以看出来,在安装器第三步前半段是网络密集型任务,后半段是 CPU 密集型任务。因此我们可以进行流水线作业:首先打开十台机器,待它们进行到第三步后半段的时候,再去启动新的十台机器。这样可以实现网络的错峰和资源的最大化利用。

1.1 DOMJudge 的相关配置

本次负责 DOMJudge 配置的主要是黑猫,所以我这里也无法给出具体细节啦。请自行参考官方文档 (https://www.domjudge.org/documentation) 中的 Administrator’s manual 进行配置。

2019-03-19 更新

滚榜使用的 resolver 可以通过设置 ICPC_FONT 环境变量来指定滚榜使用的字体,从而实现中文队名的显示,例:

# Windows
ICPC_FONT="Microsoft YaHei" ./resolver.bat xxx.xml

# Linux
export ICPC_FONT="Microsoft YaHei" && ./resolver.sh xxx.xml

2019-08-22 梨子:

由于博客更换后端,评论没法迁移过来,之前本文下的评论粘贴如下:

comment.png
除特殊说明以外,本网站文章采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。