Closed agcom closed 6 months ago
I was wondering, as Kotlin is included in the worlds final programming environment (see https://docs.icpc.global/worldfinals-programming-environment/), shouldn't Kotlin be supported out of the box?
DOMjudge is besides a system used in the ICPC World finals also something on its own. So we don't always have the same content in the default installation which is used in the finals. Because kotlin is not in the default repo's (for ubuntu 22.04 there is a version though) we prefer to not have it in the chroot to keep this simple. We can help to reproduce a setup like the finals though.
The Judgehost lacks
kotlinc
,kotlin-stdlib.jar
, and other stuff required by the compiler; I have gone through the following steps to manually provide those inside the chroot environment, and make Kotlin work:* Run official DOMjudge and Judgehost Docker containers beside MariaDB, with standard setup: `sudo docker compose up`. * Run an interactive shell inside the Judgehost container: `sudo docker compose exec judgehost bash`. * Go inside the chroot environment, and switch to bash for convenience; `dj_run_chroot`; `bash`. * Install SDKMAN; `apt install curl zip unzip`; `curl -s "https://get.sdkman.io" | bash`; `source "/root/.sdkman/bin/sdkman-init.sh"`. * Install Kotlin by SDKMAN; `sdk install kotlin 1.7.21`. * Copy Kotlin installation to `/usr/lib/kotlin/`; `cp -r /root/.sdkman/candidates/kotlin/1.7.21/ /usr/lib/kotlin/`. * Go into DOMjudge admin web interface and enable Kotlin language; also, modify the Kotlin compile script (`run.sh`) and set the `KOTLIN_DIR` variable to `"/usr/lib/kotlin/bin"`, and save. * Done.
Now, that's just a hack applied to a single Judgehost container, and cumbersome to reproduce (although it is possible to make an image out of it via
sudo docker commit
command); I would like some guidance to ease the process, and ultimately apply these in the Judgehost Docker image build steps.
We don't use the docker images that often, but we do use the kotlinc
deb used at the finals. And install that in the chroot with the -i
flag, that makes this a lot easier.
* How to avoid the requirement to modify the Kotlin compile script (`run.sh`)? In other words, how to add `/usr/lib/kotlin/bin` to the `PATH` variable inside the chroot environment?
There is no clean way of doing this, but you could either create a symlink in a location which is in the PATH
or change the profile
to include this in the PATH
both are non standard changes. We prefer to stick to the FHS
guide in this case to keep it easy to change if you want a custom config. Personally I would change the run.sh
but all would be valid choices.
* Is incorporating the above steps into the `chroot-and-tar.sh` file enough to build a Judgehost Docker image with Kotlin stuff (I will try it soon and inform here, if not late)?
As far as I remember yes, you should be able to fork the repo and use the script with the changes you propose and get a container in the way how you want it. The version of
kotlin
might be a bit different from the finals though.
- What are the security concerns?
Any package you add extra is a concern, we have to select a set and picked the most popular languages at that point. I'll discuss internally if we should make a chroot based on the config of an ICPC contest.
Note that besides Docker we also have native installs, so IF we somehow make Kotlin supported by default we should have it in both, ideally by modifying the script to create a chroot.
As @vmcj already said at ICPC contests we normally use a .deb for kotlin that is packaged by the ICPC people. We can't publicly share this .deb though since it's not supposed to be used outside of ICPC contests.
The PR you created will help by the way to use Kotlin, so thanks for that!
Kotlin compiler builds can be found in their GitHub releases' assets (such as JetBrains/Kotlin/v1.7.21); building a deb out of it is an easy task.
curl
and unzip
)/usr/local/lib/kotlinc/
./usr/local/lib/kotlinc/bin/kotlinc
at /usr/local/bin/kotlinc
.Or instead, after the first step, craft a deb out of it, and pass it to dj_make_chroot
.
I couldn't find any script to create chroot for native installs; is there any? Where?
dj_make_chroot is that script
I added Kotlin compiler install steps to the chroot-and-tar.sh
script in my fork (see commit https://github.com/agcom/domjudge-packaging/commit/4ef6678cf745729761abeb947cb2ef103a6c9860), and it works.
Unrelated to Kotlin compiler, I hit the following two errors in the build/test process:
dj_make_chroot
script fails (called inside the chroot-and-tar.sh
script) with a permission denied error; see commit https://github.com/agcom/domjudge-packaging/commit/be9dfb379b90565c0694db9e6a63fa5910921e45 for more description and an applied solution; the failure won't cause the image build to stop though./scripts/start.d/10-timezone.sh: 11: cannot create /etc/php/7.?//fpm/conf.d/99-timezone.ini: Directory nonexistent
Start script 10-timezone.sh failed
I use community Docker engine version 24.0.6, and passed version 8.2.1 to the
/docker/build.sh
script.
Should I create separate issues for them? or is it just my machine?
I added Kotlin compiler install steps to the
chroot-and-tar.sh
script in my fork (see commit agcom@4ef6678), and it works.Unrelated to Kotlin compiler, I hit the following two errors in the build/test process:
dj_make_chroot
script fails (called inside thechroot-and-tar.sh
script) with a permission denied error; see commit agcom@be9dfb3 for more description and an applied solution; the failure won't cause the image build to stop though.
Yeah sure but the solution is fine, I think.
- The newly built domjudge/domserver image/container fails to startup with the following error:
/scripts/start.d/10-timezone.sh: 11: cannot create /etc/php/7.?//fpm/conf.d/99-timezone.ini: Directory nonexistent domjudge-packaging-fork-domserver-1 | [!!] Start script 10-timezone.sh failed
I think we need to use 8.?
now since we have a newer PHP.
I use community Docker engine version 24.0.6, and passed version 8.2.1 to the
/docker/build.sh
script.Should I create separate issues for them?
Sure!
I'll discuss internally if we should make a chroot based on the config of an ICPC contest.
Any updates @vmcj?
If Kotlin is not going to be added to DOMjudge by default, I am willing to write a document on how to add Kotlin to various installations (all kinda share the same steps).
I'll discuss internally if we should make a chroot based on the config of an ICPC contest.
Any updates @vmcj?
If Kotlin is not going to be added to DOMjudge by default, I am willing to write a document on how to add Kotlin to various installations (all kinda share the same steps).
Yes, I have a local branch somewhere to install the older kotlin but it requires a bit more work.
Feel free to write something up, I think the wiki would be fine for this.
I wrote something up and I was wondering how should I contribute it to the DOMjudge wiki? Should I just create a PR like this one https://github.com/DOMjudge/domjudge/pull/969?
Posting it here is fine.
DOMjudge has a default set of languages but it is possible to add your own.
Every submission is ran in an isolated container so the best way to test a new language is to first get the new language installed in the container via the options of dj_make_chroot
; start this container with dj_run_chroot
and test if you can compile and run some default programs to verify that everything can work; when this works, start to build the run/build scripts by looking at similar languages which already exist in DOMjudge and create the language with you own build/run scripts.
Default DOMjudge will mount only a limited set of directories and those does not include the /tmp/
directory which is used by R for example; therefore, in case of such failures, check if the tmp directory can be set with an environment variable, or extend the chroot-startstop.sh
, or look into CREATE_WRITABLE_TEMP_DIR
defined here. Be aware that providing writable directories opens up a security hole where the submission may write data into and pass information from one test-case-run to the next.
Kotlin is an officially supported programming language in the programming environment of the ICPC world finals.
To add the Kotlin programming language to a DOMjudge installation, first, the Kotlin command-line compiler should be installed in the chroot environment of the judgehosts (see Installation of the judgehosts - creating a chroot environment | DOMjudge documentation).
If there is an already running instance of judgehost, access its terminal and unzip the Kotlin compiler in its chroot environment directory (usually /chroot/domjudge/
); optionally, for automatic Kotlin compiler discovery in the Kotlin run script, include the extracted bin/kotlinc
in the PATH
variable of the chroot environment (can be done by creating a symbolic link to the extracted bin/kotlinc
inside a directory already included in the PATH
); TL;DR, for example:
# A judgehost terminal
CHROOTDIR="/chroot/domjudge"
KOTLIN_VERSION="1.7.21"
# Download the Kotlin compiler zip.
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip"
# Unzip the Kotlin compiler inside the chroot environment.
unzip -qq -d "$CHROOTDIR/usr/local/lib/" "./kotlin-compiler-$KOTLIN_VERSION.zip"
# Include bin/kotlinc in the PATH variable of the chroot environment by creating a symbolic link.
chroot "$CHROOTDIR/" ln -s "/usr/local/lib/kotlinc/bin/kotlinc" "/usr/local/bin/kotlinc"
# Optionally as a cleanup step, remove the downloaded zip file.
rm "./kotlin-compiler-$KOTLIN_VERSION.zip"
You can also modify the judgehost install scripts to add Kotlin; simply edit the misc_tools/dj_make_chroot.in
script (this raw script can be found a release tarball or git sources) and add something like the above in an appropriate place; for example, after installing debs (this line), add:
...
# Install Kotlin
KOTLIN_VERSION="1.7.21"
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip"
unzip -qq -d "$CHROOTDIR/usr/local/lib/" "./kotlin-compiler-$KOTLIN_VERSION.zip"
in_chroot "ln -s \"/usr/local/lib/kotlinc/bin/kotlinc\" \"/usr/local/bin/kotlinc\""
rm "./kotlin-compiler-$KOTLIN_VERSION.zip"
...
If you want a judgehost Docker image with Kotlin, modify the docker/judgehost/chroot-and-tar.sh
script in the DOMjudge packaging repository, such as:
#!/bin/bash
# Usage: https://github.com/DOMjudge/domjudge/blob/main/misc-tools/dj_make_chroot.in#L58-L87
/opt/domjudge/judgehost/bin/dj_make_chroot
CHROOTDIR="/chroot/domjudge"
KOTLIN_VERSION="1.7.21"
echo "Downloading Kotlin compiler"
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip" -P /
echo "Extracting Kotlin compiler"
unzip -qq -d "/chroot/domjudge/usr/local/lib/" "/kotlin-compiler-$KOTLIN_VERSION.zip"
chroot "$CHROOTDIR" ln -s "/usr/local/lib/kotlinc/bin/kotlinc" "/usr/local/bin/kotlinc"
rm "/kotlin-compiler-$KOTLIN_VERSION.zip"
echo "Done setting up Kotlin"
cd /
echo "[..] Compressing chroot"
tar -czpf /chroot.tar.gz --exclude=/chroot/tmp --exclude=/chroot/proc --exclude=/chroot/sys --exclude=/chroot/mnt --exclude=/chroot/media --exclude=/chroot/dev --one-file-system /chroot
echo "[..] Compressing judge"
tar -czpf /judgehost.tar.gz /opt/domjudge/judgehost
Then run docker/build.sh
to build judgehost and domserver images, or docker/build-judgehost.sh
after manually downloading the DOMjudge source (first steps of the docker/build.sh
), to build only the judgehost image:
# In the DOMjudge packaging repository root.
cd docker/
DOMJUDGE_VERSION="8.2.2"
wget --quiet "https://www.domjudge.org/releases/domjudge-${DOMJUDGE_VERSION}.tar.gz" -O "./domjudge.tar.gz"
./build-judgehost.sh "localhost/domjudge/judgehost:${DOMJUDGE_VERSION}-kotlin"
After successfully installing the Kotlin command-line compiler on judgehosts, Kotlin language should be enabled in the DOMjudge Jury interface for submissions:
kt
from "Disabled languages"; if it is already in "Enabled languages", then you are done.A heads-up about the default kt
run script: if the DOMjudge version is in range 8.2.0 to 8.2.2 (both inclusive), the automatic Kotlin compiler directory discovery might fail if kotlinc
is a symbolic link; one solution is to manually fill-in the KOTLIN_DIR
variable in the run script; another solution is to update the run script to its latest commit.
The run script can be edited in the DOMjudge Jury interface: "Languages" -
kt
- "Compile script / kt" - Content / run.
@agcom I'll close this issue, I've added your text to the wiki and we'll discuss on the next hackathon what to do in the future with kotlin in the judgehost.
Adding a new language
DOMjudge has a default set of languages but it is possible to add your own.
Every submission is ran in an isolated container so the best way to test a new language is to first get the new language installed in the container via the options of
dj_make_chroot
; start this container withdj_run_chroot
and test if you can compile and run some default programs to verify that everything can work; when this works, start to build the run/build scripts by looking at similar languages which already exist in DOMjudge and create the language with you own build/run scripts.Default DOMjudge will mount only a limited set of directories and those does not include the
/tmp/
directory which is used by R for example; therefore, in case of such failures, check if the tmp directory can be set with an environment variable, or extend thechroot-startstop.sh
, or look intoCREATE_WRITABLE_TEMP_DIR
defined here. Be aware that providing writable directories opens up a security hole where the submission may write data into and pass information from one test-case-run to the next.Kotlin
...
It just came into my attention 👀, I also revamped the prologue :point_up:, but it wasn't added to the wiki; I thought maybe you haven't noticed it, therefore, commenting.
I was wondering, as Kotlin is included in the worlds final programming environment (see https://docs.icpc.global/worldfinals-programming-environment/), shouldn't Kotlin be supported out of the box?
The Judgehost lacks
kotlinc
,kotlin-stdlib.jar
, and other stuff required by the compiler; I have gone through the following steps to manually provide those inside the chroot environment, and make Kotlin work:sudo docker compose up
.sudo docker compose exec judgehost bash
.dj_run_chroot
;bash
.apt install curl zip unzip
;curl -s "https://get.sdkman.io" | bash
;source "/root/.sdkman/bin/sdkman-init.sh"
.sdk install kotlin 1.7.21
./usr/lib/kotlin/
;cp -r /root/.sdkman/candidates/kotlin/1.7.21/ /usr/lib/kotlin/
.run.sh
) and set theKOTLIN_DIR
variable to"/usr/lib/kotlin/bin"
, and save.Now, that's just a hack applied to a single Judgehost container, and cumbersome to reproduce (although it is possible to make an image out of it via
sudo docker commit
command); I would like some guidance to ease the process, and ultimately apply these in the Judgehost Docker image build steps.run.sh
)? In other words, how to add/usr/lib/kotlin/bin
to thePATH
variable inside the chroot environment?chroot-and-tar.sh
file enough to build a Judgehost Docker image with Kotlin stuff (I will try it soon and inform here, if not late)?