# domjudge-cli
`domjudge-cli` is a command-line tool to set up and manage coding contests on **DOMjudge**.
It enables you to **declaratively define infrastructure, contests, problems, and teams** using simple configuration files.
Built for **live operations**, it safely applies updates to the platform without requiring downtime.
---
## Key Features
- **Declarative Infrastructure and Contest Management:** Manage everything with YAML files.
- **Infrastructure as Code:** Deploy DOMjudge servers and judgehosts with a single command.
- **Incremental Changes:** Update infrastructure or contests without downtime.
- **Flexible Input Formats:** YAML for configuration; CSV/TSV for teams.
- **Safe Live Modifications:** Apply contest changes while DOMjudge is running.
- **Automatic Config Discovery:** If `--file` is not specified, it will automatically use `dom-judge.yaml` or `dom-judge.yml` (whichever exists first in the current directory).
---
## Installation
```
pip install domjudge-cli
```
Before using `domjudge-cli` to deploy infrastructure, ensure that **cgroups** are enabled on your OS (currently supporting **Ubuntu 22.04**).
1. Create or edit the GRUB configuration:
```
sudo vi /etc/default/grub.d/99-domjudge-cgroups.cfg
```
Insert the following line:
```
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0"
```
2. Update GRUB and reboot:
```
sudo update-grub
sudo reboot
```
Only after completing these steps should you attempt to run `domjudge-cli` infrastructure commands.
---
## CLI Usage
Run `dom --help` to see available commands:
```
dom --help
```
Main command groups:
| Command Group | Purpose |
|:--------------|:--------|
| `dom init` | Initialize a new configuration file |
| `dom infra` | Manage infrastructure and platform setup |
| `dom contest` | Manage contests and related configuration |
> **Note for Polygon Users**
> When importing problems from Polygon, ensure the **Package type** is set to **Linux** (not Windows or Standard) for compatibility with DOMjudge.
---
### 1. Initialize a new configuration file
Initialize a new configuration file.
```
dom init
```
if there is a file named `dom-judge.yaml` or `dom-judge.yml` in the current directory, use `--overwrite` to overwrite it.
### 2. Manage Infrastructure
Apply or destroy infrastructure resources.
- **Apply Infrastructure:**
```
dom infra apply --file dom-judge.yaml
```
- **Destroy Infrastructure:**
```
dom infra destroy --confirm
```
If no `--file` is provided, defaults to `dom-judge.yaml` or `dom-judge.yml`.
---
### 3. Manage Contests
Apply contest settings to a running platform.
- **Apply Contest Configuration:**
```
dom contest apply --file dom-judge.yaml
```
If no `--file` is provided, defaults to `dom-judge.yaml` or `dom-judge.yml`.
---
## Configuration Files
Everything is controlled via configuration files in YAML format.
Example: `dom-judge.yaml`
```
infra:
port: 8080
judges: 2
password: "your_admin_password_here"
contests:
- name: "Sample Contest"
shortname: "SAMPLE2025"
start_time: "2025-06-01T10:00:00+00:00"
duration: "5:00:00.000"
penalty_time: 20
allow_submit: true
problems:
from: "problems.yaml"
teams:
from: "teams.csv"
delimiter: ','
rows: "2-50"
name: "$2"
affiliation: "$3"
```
Supporting file example: `problems.yaml`
```
- archive: problems/example-problem-1.zip
platform: "Polygon"
color: blue
- archive: problems/example-problem-2.zip
platform: "Polygon"
color: green
- archive: problems/example-problem-3.zip
platform: "Polygon"
color: yellow
```
---
### Team Management
Teams can be defined in a CSV file with the following format:
```csv
id,name,affiliation
1,Team Alpha,INSEA
2,Team Beta,INPT
3,Team Gamma,ENSIAS
```
### Problem Declarations
- Problems for a contest can be **defined directly inside** the contest `problems:` section like this:
```
problems:
- archive: problems/sample-problem.zip
platform: "Polygon"
color: blue
```
- Or you can **abstract the problem list** into a **separate YAML file** and reference it like this:
```
problems:
from: "problems.yaml"
```
Choose whichever structure better suits your project organization.
---
## Typical Workflow
```
# Initialize a new configuration file
dom init
# Apply infrastructure
dom infra apply --file dom-judge.yaml
# Apply contests, problems, and teams
dom contest apply --file dom-judge.yaml
# (Optional) Destroy infrastructure when done
dom infra destroy --confirm
```
---
## Contest Commands
- `dom contest verify-problemset CONTEST_NAME`: Verify the problemset of the specified contest by running sample submissions to ensure correctness, completeness, and performance limits are met, then report per-problem summaries including mismatches and warnings.
---
## Notes
- Requires Docker installed for infrastructure operations.
- Ensure **cgroups** are properly configured and the system has been rebooted as per Installation instructions.
- DOMjudge API credentials are automatically handled or can be configured.
- Problems and teams must be correctly referenced in the config YAML.
- If no configuration file is explicitly passed with `--file`, the CLI will look for `dom-judge.yaml` or `dom-judge.yml`.
---
# 🎯 Summary
| Action | Command |
|:--------------------|:--------------------------------------------|
| Initialize a new configuration file | ```dom init``` |
| Deploy platform | ```dom infra apply --file dom-judge.yaml``` |
| Configure contests | ```dom contest apply --file dom-judge.yaml```|
| Verify problemset | ```dom contest verify-problemset CONTEST_NAME``` |
| Destroy everything | ```dom infra destroy --confirm``` |
---
Raw data
{
"_id": null,
"home_page": null,
"name": "domjudge-cli",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "cli, contest, domjudge, programming",
"author": null,
"author_email": "Anas IMLOUL <anas.imloul27@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/00/99/00ce3ada4aeb65d4bb794ac846d76c18758837eafa6859c8847b79aa6d4b/domjudge_cli-0.3.0.tar.gz",
"platform": null,
"description": "# domjudge-cli\n\n`domjudge-cli` is a command-line tool to set up and manage coding contests on **DOMjudge**. \nIt enables you to **declaratively define infrastructure, contests, problems, and teams** using simple configuration files.\n\nBuilt for **live operations**, it safely applies updates to the platform without requiring downtime.\n\n---\n\n## Key Features\n\n- **Declarative Infrastructure and Contest Management:** Manage everything with YAML files.\n- **Infrastructure as Code:** Deploy DOMjudge servers and judgehosts with a single command.\n- **Incremental Changes:** Update infrastructure or contests without downtime.\n- **Flexible Input Formats:** YAML for configuration; CSV/TSV for teams.\n- **Safe Live Modifications:** Apply contest changes while DOMjudge is running.\n- **Automatic Config Discovery:** If `--file` is not specified, it will automatically use `dom-judge.yaml` or `dom-judge.yml` (whichever exists first in the current directory).\n\n---\n\n## Installation\n\n```\npip install domjudge-cli\n```\n\nBefore using `domjudge-cli` to deploy infrastructure, ensure that **cgroups** are enabled on your OS (currently supporting **Ubuntu 22.04**).\n\n1. Create or edit the GRUB configuration:\n \n ```\n sudo vi /etc/default/grub.d/99-domjudge-cgroups.cfg\n ```\n\n Insert the following line:\n \n ```\n GRUB_CMDLINE_LINUX_DEFAULT=\"cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0\"\n ```\n\n2. Update GRUB and reboot:\n\n ```\n sudo update-grub\n sudo reboot\n ```\n\nOnly after completing these steps should you attempt to run `domjudge-cli` infrastructure commands.\n\n---\n\n## CLI Usage\n\nRun `dom --help` to see available commands:\n\n```\ndom --help\n```\n\nMain command groups:\n\n| Command Group | Purpose |\n|:--------------|:--------|\n| `dom init` | Initialize a new configuration file |\n| `dom infra` | Manage infrastructure and platform setup |\n| `dom contest` | Manage contests and related configuration |\n\n\n> **Note for Polygon Users**\n> When importing problems from Polygon, ensure the **Package type** is set to **Linux** (not Windows or Standard) for compatibility with DOMjudge.\n\n\n---\n\n### 1. Initialize a new configuration file\n\nInitialize a new configuration file.\n\n```\ndom init\n```\n\nif there is a file named `dom-judge.yaml` or `dom-judge.yml` in the current directory, use `--overwrite` to overwrite it.\n\n### 2. Manage Infrastructure\n\nApply or destroy infrastructure resources.\n\n- **Apply Infrastructure:**\n\n```\ndom infra apply --file dom-judge.yaml\n```\n\n- **Destroy Infrastructure:**\n\n```\ndom infra destroy --confirm\n```\n\nIf no `--file` is provided, defaults to `dom-judge.yaml` or `dom-judge.yml`.\n\n---\n\n### 3. Manage Contests\n\nApply contest settings to a running platform.\n\n- **Apply Contest Configuration:**\n\n```\ndom contest apply --file dom-judge.yaml\n```\n\nIf no `--file` is provided, defaults to `dom-judge.yaml` or `dom-judge.yml`.\n\n---\n\n## Configuration Files\n\nEverything is controlled via configuration files in YAML format.\n\nExample: `dom-judge.yaml`\n\n```\ninfra:\n port: 8080\n judges: 2\n password: \"your_admin_password_here\"\n\ncontests:\n - name: \"Sample Contest\"\n shortname: \"SAMPLE2025\"\n start_time: \"2025-06-01T10:00:00+00:00\"\n duration: \"5:00:00.000\"\n penalty_time: 20\n allow_submit: true\n\n problems:\n from: \"problems.yaml\"\n\n teams:\n from: \"teams.csv\"\n delimiter: ','\n rows: \"2-50\"\n name: \"$2\"\n affiliation: \"$3\"\n```\n\nSupporting file example: `problems.yaml`\n\n```\n- archive: problems/example-problem-1.zip\n platform: \"Polygon\"\n color: blue\n\n- archive: problems/example-problem-2.zip\n platform: \"Polygon\"\n color: green\n\n- archive: problems/example-problem-3.zip\n platform: \"Polygon\"\n color: yellow\n```\n\n---\n\n### Team Management\n\nTeams can be defined in a CSV file with the following format:\n\n```csv\nid,name,affiliation\n1,Team Alpha,INSEA\n2,Team Beta,INPT\n3,Team Gamma,ENSIAS\n```\n\n### Problem Declarations\n\n- Problems for a contest can be **defined directly inside** the contest `problems:` section like this:\n\n```\nproblems:\n - archive: problems/sample-problem.zip\n platform: \"Polygon\"\n color: blue\n```\n\n- Or you can **abstract the problem list** into a **separate YAML file** and reference it like this:\n\n```\nproblems:\n from: \"problems.yaml\"\n```\n\nChoose whichever structure better suits your project organization.\n\n---\n\n## Typical Workflow\n\n```\n# Initialize a new configuration file\ndom init\n\n# Apply infrastructure\ndom infra apply --file dom-judge.yaml\n\n# Apply contests, problems, and teams\ndom contest apply --file dom-judge.yaml\n\n# (Optional) Destroy infrastructure when done\ndom infra destroy --confirm\n```\n\n---\n\n## Contest Commands\n\n- `dom contest verify-problemset CONTEST_NAME`: Verify the problemset of the specified contest by running sample submissions to ensure correctness, completeness, and performance limits are met, then report per-problem summaries including mismatches and warnings.\n\n---\n\n## Notes\n\n- Requires Docker installed for infrastructure operations.\n- Ensure **cgroups** are properly configured and the system has been rebooted as per Installation instructions.\n- DOMjudge API credentials are automatically handled or can be configured.\n- Problems and teams must be correctly referenced in the config YAML.\n- If no configuration file is explicitly passed with `--file`, the CLI will look for `dom-judge.yaml` or `dom-judge.yml`.\n\n---\n\n# \ud83c\udfaf Summary\n\n| Action | Command |\n|:--------------------|:--------------------------------------------|\n| Initialize a new configuration file | ```dom init``` |\n| Deploy platform | ```dom infra apply --file dom-judge.yaml``` |\n| Configure contests | ```dom contest apply --file dom-judge.yaml```|\n| Verify problemset | ```dom contest verify-problemset CONTEST_NAME``` |\n| Destroy everything | ```dom infra destroy --confirm``` |\n\n---\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "CLI tool for managing DOMjudge contests and infrastructure",
"version": "0.3.0",
"project_urls": {
"Homepage": "https://github.com/AnasImloul/domjudge-cli",
"Issues": "https://github.com/AnasImloul/domjudge-cli/issues",
"Repository": "https://github.com/AnasImloul/domjudge-cli"
},
"split_keywords": [
"cli",
" contest",
" domjudge",
" programming"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "54c8335360be6b0ef0af4e2640995eab53f9382aaa52c9eeea549eb84e773f02",
"md5": "c7c632688b622e52cdd0f8db2eed8055",
"sha256": "a7feb795a88875c485e86005f7698a2c6c2400881db235ace0094466ffb8a33b"
},
"downloads": -1,
"filename": "domjudge_cli-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c7c632688b622e52cdd0f8db2eed8055",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 142648,
"upload_time": "2025-10-25T20:39:37",
"upload_time_iso_8601": "2025-10-25T20:39:37.954285Z",
"url": "https://files.pythonhosted.org/packages/54/c8/335360be6b0ef0af4e2640995eab53f9382aaa52c9eeea549eb84e773f02/domjudge_cli-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "009900ce3ada4aeb65d4bb794ac846d76c18758837eafa6859c8847b79aa6d4b",
"md5": "cad2fdaa1a6cebc117d7f41fa3f96ab5",
"sha256": "aa4a581444318826937189a8bbdbe5c967160c1fdb6822e847813bcf5b636ae7"
},
"downloads": -1,
"filename": "domjudge_cli-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "cad2fdaa1a6cebc117d7f41fa3f96ab5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 119835,
"upload_time": "2025-10-25T20:39:38",
"upload_time_iso_8601": "2025-10-25T20:39:38.977382Z",
"url": "https://files.pythonhosted.org/packages/00/99/00ce3ada4aeb65d4bb794ac846d76c18758837eafa6859c8847b79aa6d4b/domjudge_cli-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-25 20:39:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AnasImloul",
"github_project": "domjudge-cli",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "typer",
"specs": [
[
"<",
"0.21.0"
],
[
">=",
"0.15.2"
]
]
},
{
"name": "PyYAML",
"specs": [
[
"~=",
"6.0.2"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"2.11.3"
],
[
"<",
"2.13.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"2.11.3"
],
[
"<",
"2.13.0"
]
]
},
{
"name": "p2d",
"specs": [
[
"~=",
"0.3.0"
]
]
},
{
"name": "bcrypt",
"specs": [
[
"~=",
"4.3.0"
]
]
},
{
"name": "webcolors",
"specs": [
[
"~=",
"24.11.1"
]
]
},
{
"name": "requests",
"specs": [
[
"~=",
"2.32.5"
]
]
},
{
"name": "Jinja2",
"specs": [
[
"~=",
"3.1.6"
]
]
},
{
"name": "typeguard",
"specs": [
[
"~=",
"4.4.2"
]
]
},
{
"name": "jmespath",
"specs": [
[
"~=",
"1.0.1"
]
]
},
{
"name": "tqdm",
"specs": [
[
"~=",
"4.67.1"
]
]
},
{
"name": "cryptography",
"specs": [
[
"<",
"46.1"
],
[
">=",
"43.0"
]
]
},
{
"name": "rich",
"specs": [
[
"<",
"14.3"
],
[
">=",
"13.7"
]
]
},
{
"name": "pytest",
"specs": [
[
">=",
"8.0"
],
[
"<",
"8.5"
]
]
}
],
"lcname": "domjudge-cli"
}