Skip to content

Commit

Permalink
Merge branch 'main' into feature_table_cell_stretched
Browse files Browse the repository at this point in the history
  • Loading branch information
thijskh authored Oct 14, 2023
2 parents 01983f1 + 74535eb commit 3ae6fd6
Show file tree
Hide file tree
Showing 42 changed files with 662 additions and 109 deletions.
4 changes: 2 additions & 2 deletions doc/manual/config-advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ DOMjudge can optionally present country flags, affiliation logos,
team pictures and a page-wide banner on the public interface.

You can place the images under the path `public/images/` (see
the Config checker in the admin interfae for the full filesystem
the Config checker in the admin interface for the full filesystem
path of your installation) as follows:

- *Country flags* are shown when the ``show_flags`` configuration option
Expand Down Expand Up @@ -405,7 +405,7 @@ Clearing the PHP/Symfony cache
------------------------------

Some operations require you to clear the PHP/Symfony cache. To do this, execute
the `webapp/bin/console` (see the Config checker in the admin interfae for the
the `webapp/bin/console` (see the Config checker in the admin interface for the
full filesystem path of your installation) binary with the `cache:clear` subcommand::

webapp/bin/console cache:clear
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Note: this docker compose stack should only be used for development purposes.
# Do not use it for production deployments. If you want to deploy DOMjudge in
# production with Docker, see https://hub.docker.com/r/domjudge/domserver.
# It is recommended to use `docker compose up` to start this stack. Note, don't
# use sudo or the legacy docker-compose.

version: '3'

Expand Down
9 changes: 9 additions & 0 deletions etc/db-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,15 @@
default_value: false
public: true
description: Show canonical compiler and runner version on the team pages.
- name: show_teams_on_scoreboard
type: int
default_value: 0
public: true
description: Show teams on the scoreboard?
options:
0: Always
1: After login
2: After first submission
- category: Authentication
description: Options related to authentication.
items:
Expand Down
10 changes: 4 additions & 6 deletions judge/create_cgroups.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
JUDGEHOSTUSER=@DOMJUDGE_USER@
CGROUPBASE=@judgehost_cgroupdir@

print_cgroup_instruction () {
echo ""
cgroup_error_and_usage () {
echo "$1" >&2
echo "To fix this, please make the following changes:
1. In /etc/default/grub, add 'cgroup_enable=memory swapaccount=1' to GRUB_CMDLINE_LINUX_DEFAULT.
On modern distros (e.g. Debian bullseye and Ubuntu Jammy Jellyfish) which have cgroup v2 enabled by default,
Expand All @@ -24,16 +24,14 @@ for i in cpuset memory; do
mkdir -p $CGROUPBASE/$i
if [ ! -d $CGROUPBASE/$i/ ]; then
if ! mount -t cgroup -o$i $i $CGROUPBASE/$i/; then
echo "Error: Can not mount $i cgroup. Probably cgroup support is missing from running kernel. Unable to continue."
print_cgroup_instruction
cgroup_error_and_usage "Error: Can not mount $i cgroup. Probably cgroup support is missing from running kernel. Unable to continue."
fi
fi
mkdir -p $CGROUPBASE/$i/domjudge
done

if [ ! -f $CGROUPBASE/memory/memory.limit_in_bytes ] || [ ! -f $CGROUPBASE/memory/memory.memsw.limit_in_bytes ]; then
echo "Error: cgroup support missing memory features in running kernel. Unable to continue."
print_cgroup_instruction
cgroup_error_and_usage "Error: cgroup support missing memory features in running kernel. Unable to continue."
fi

chown -R $JUDGEHOSTUSER $CGROUPBASE/*/domjudge
Expand Down
38 changes: 27 additions & 11 deletions judge/judgedaemon.main.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ function fetch_executable_internal(
$execid,
$hash
]);
global $langexts;
$execdeploypath = $execdir . '/.deployed';
$execbuilddir = $execdir . '/build';
$execbuildpath = $execbuilddir . '/build';
Expand Down Expand Up @@ -379,12 +380,6 @@ function fetch_executable_internal(
$do_compile = false;
} else {
// detect lang and write build file
$langexts = [
'c' => ['c'],
'cpp' => ['cpp', 'C', 'cc'],
'java' => ['java'],
'py' => ['py'],
];
$buildscript = "#!/bin/sh\n\n";
$execlang = false;
$source = "";
Expand Down Expand Up @@ -642,6 +637,21 @@ function fetch_executable_internal(
// Populate the DOMjudge configuration initially
djconfig_refresh();

// Prepopulate default language extensions, afterwards update based on domserver config
$langexts = [
'c' => ['c'],
'cpp' => ['cpp', 'C', 'cc'],
'java' => ['java'],
'py' => ['py'],
];
$domserver_languages = dj_json_decode(request('languages', 'GET'));
foreach ($domserver_languages as $language) {
$id = $language['id'];
if (key_exists($id, $langexts)) {
$langexts[$id] = $language['extensions'];
}
}

// Constantly check API for unjudged submissions
$endpointIDs = array_keys($endpoints);
$currentEndpoint = 0;
Expand Down Expand Up @@ -1069,7 +1079,7 @@ function compile(
): bool {
global $myhost, $EXITCODES;

// Re-use compilation if it already exists.
// Reuse compilation if it already exists.
if (file_exists("$workdir/compile.success")) {
return true;
}
Expand Down Expand Up @@ -1340,10 +1350,6 @@ function judge(array $judgeTask): bool
}

// do the actual test-run
$hardtimelimit = $run_config['time_limit'] +
overshoot_time($run_config['time_limit'], $overshoot);


$combined_run_compare = $compare_config['combined_run_compare'];
[$run_runpath, $error] = fetch_executable(
$workdirpath,
Expand Down Expand Up @@ -1373,6 +1379,16 @@ function judge(array $judgeTask): bool
}
}

$hardtimelimit = $run_config['time_limit'] +
overshoot_time($run_config['time_limit'], $overshoot);
if ($combined_run_compare) {
// This accounts for wall time spent in the validator. We may likely
// want to make this configurable in the future. The current factor is
// under the assumption that the validator has to do approximately the
// same amount of work wall-time wise as the submission.
$hardtimelimit *= 2;
}

// While we already set those above to likely the same values from the
// compile config, we do set them again from the compare config here.
putenv('SCRIPTTIMELIMIT=' . $compare_config['script_timelimit']);
Expand Down
19 changes: 17 additions & 2 deletions judge/runguard.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ void setrestrictions()
setlim(STACK);

if ( filesize!=RLIM_INFINITY ) {
verbose("setting filesize limit to %d bytes",(int)filesize);
verbose("setting filesize limit to %lu bytes",filesize);
lim.rlim_cur = lim.rlim_max = filesize;
setlim(FSIZE);
}
Expand Down Expand Up @@ -1428,8 +1428,23 @@ int main(int argc, char **argv)
} else {
exitcode = WEXITSTATUS(status);
}
verbose("child exited with exit code %d", exitcode);

check_remaining_procs();
if ( use_walltime ) {
/* Disarm timer we set previously so if any of the
* clean-up steps below are slow we are not mistaking
* this for a wall-time timeout. */
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_usec = 0;
itimer.it_value.tv_sec = 0;
itimer.it_value.tv_usec = 0;

if ( setitimer(ITIMER_REAL,&itimer,NULL)!=0 ) {
error(errno,"disarming timer");
}
}

check_remaining_procs();

double cputime = -1;
output_cgroup_stats(&cputime);
Expand Down
35 changes: 24 additions & 11 deletions misc-tools/configure-domjudge.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import json
import os.path
import requests
import requests.utils
import shutil
import sys
from typing import List, Set

Expand Down Expand Up @@ -98,16 +99,6 @@ else:
print('Need a "config.json" to update general DOMjudge configuration.')


if os.path.exists('executables'):
executables = []
for file in os.listdir('executables'):
if file.endswith(".zip"):
executables.append(file[:-4])
if executables and dj_utils.confirm('Upload language executables (found: ' + ','.join(executables) + ')?', False):
for langid in executables:
dj_utils.upload_file(f'languages/{langid}/executable', 'executable', f'executables/{langid}.zip')


if os.path.exists('languages.json'):
print('Comparing DOMjudge\'s language configuration:')
with open('languages.json') as langConfigFile:
Expand All @@ -126,7 +117,29 @@ if os.path.exists('languages.json'):
if missing_keys:
print(f' - missing keys from expected config = {missing_keys}')
if diffs or new_keys or missing_keys:
print(' - We cannot update the configuration yet, but you might want to change it via the UI.')
if os.path.exists('executables'):
executables = []
for file in os.listdir('executables'):
if os.path.isdir(f'executables/{file}'):
executables.append(file)
shutil.make_archive(f'executables/{file}', 'zip', f'executables/{file}')

if executables:
if dj_utils.confirm('Upload language executables (found: ' + ','.join(executables) + ')?', False):
for langid in executables:
dj_utils.upload_file(f'languages/{langid}/executable', 'executable', f'executables/{langid}.zip')
for langid in executables:
os.remove(f'executables/{langid}.zip')
if dj_utils.confirm(' - Upload configuration changes?', True):
actual_config = _keyify_list(dj_utils.upload_file(f'languages', 'json', f'languages.json'))
diffs, new_keys, missing_keys = compare_configs(
actual_config=actual_config,
expected_config=expected_config
)
if diffs:
print(' - There are still configuration differences after uploading:')
for d in diffs:
print(d)
else:
print(' - Language configuration is already up-to-date, nothing to update.')
else:
Expand Down
10 changes: 7 additions & 3 deletions misc-tools/import-contest.in
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ def import_images(entity: str, property: str, filename_regexes: List[str]):
if not os.path.isdir(entity):
return
images_per_entity = {}
for entity_id in listdir(entity):
with open(f'{entity}.json') as entityFile:
entities = json.load(entityFile)
entity_ids = [entity['id'] for entity in entities]
for entity_id in entity_ids:
entity_dir = f'{entity}/{entity_id}'
if not os.path.isdir(entity_dir):
continue
Expand Down Expand Up @@ -154,9 +157,10 @@ if cid is not None:
# Problem import is also special: we need to upload each individual problem and detect what they are
if os.path.exists('problems.yaml') or os.path.exists('problems.json') or os.path.exists('problemset.yaml'):
if dj_utils.confirm('Import problems?', True):
# Check if our user is linked to a team
# Check if our user is linked to a team.
user_data = dj_utils.do_api_request('user')
if not 'team' in user_data and not dj_utils.confirm('No team associated with your account. Jury submissions won\'t be imported. Really continue?', False):
has_team_linked = 'team' in user_data and user_data['team'] and 'roles' in user_data and 'team' in user_data['roles']
if not has_team_linked and not dj_utils.confirm('No team associated with your account. Jury submissions won\'t be imported. Really continue?', False):
exit(2)

print('Importing problems.')
Expand Down
2 changes: 1 addition & 1 deletion sql/files/defaultdata/kt/run
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ COMPILESCRIPTDIR="$(dirname "$0")"
# Note that you then also might want to fix this in the compiler and runner version commands.
# For example
# KOTLIN_DIR=/usr/lib/kotlinc/bin
KOTLIN_DIR="$(dirname "$(command -v kotlinc)")"
KOTLIN_DIR="$(dirname "$(realpath "$(command -v kotlinc)")")"

# Stack size in the JVM in KB. Note that this will be deducted from
# the total memory made available for the heap.
Expand Down
34 changes: 34 additions & 0 deletions webapp/migrations/Version20231006185028.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231006185028 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add the last received HTTP code for the external contest source.';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE external_contest_source ADD last_httpcode SMALLINT UNSIGNED DEFAULT NULL COMMENT \'Last HTTP code received by event feed reader\'');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE external_contest_source DROP last_httpcode');
}

public function isTransactional(): bool
{
return false;
}
}
14 changes: 9 additions & 5 deletions webapp/public/js/domjudge.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function sendNotification(title, options = {})
if ( getCookie('domjudge_notify')==1 ) {
var not = new Notification(title, options);
if ( link!==null ) {
not.onclick = function() {
not.onclick = function() {
window.location.href = link;
};
}
Expand Down Expand Up @@ -435,10 +435,14 @@ function processAjaxResponse(jqXHR, data) {
window.location = jqXHR.getResponseHeader('X-Login-Page');
} else {
var newCurrentContest = jqXHR.getResponseHeader('X-Current-Contest');
var dataCurrentContest = $('[data-current-contest]').data('current-contest').toString();

// If the contest ID changed from another tab, reload or whole page
if (dataCurrentContest !== undefined && newCurrentContest !== dataCurrentContest) {
var dataCurrentContest = $('[data-current-contest]').data('current-contest');
var refreshStop = $('[data-ajax-refresh-stop]').data('ajax-refresh-stop');

// Reload the whole page if
// - we were signaled to stop refreshing, or
// - if the contest ID changed from another tab.
if ((refreshStop !== undefined && refreshStop.toString() === "1")
|| (dataCurrentContest !== undefined && newCurrentContest !== dataCurrentContest.toString())) {
window.location.reload();
return;
}
Expand Down
5 changes: 5 additions & 0 deletions webapp/public/style_domjudge.css
Original file line number Diff line number Diff line change
Expand Up @@ -630,3 +630,8 @@ blockquote {
padding-left: .5em;
color: darkgrey;
}

.category-best {
margin-right: 2em;
font-weight: normal;
}
4 changes: 4 additions & 0 deletions webapp/public/style_jury.css
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,7 @@ table.table-full-clickable-cell thead.thead-light tr th.table-button-head-left {
table.table-full-clickable-cell tr .table-button-head-right-right{
padding-left: 0.5rem;
}

.execid {
font-family: monospace;
}
Loading

0 comments on commit 3ae6fd6

Please sign in to comment.