diff --git a/.dockerignore b/.dockerignore index 2d60bbff0f..d2d5085324 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,3 +3,4 @@ Dockerfile .vagrant/ codecov/ .dev/ +.venv/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ed93b499e..1699261dbc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,10 @@ jobs: test: runs-on: ubuntu-24.04 + strategy: + matrix: + base_image: ["ubuntu:noble", "debian:bookworm"] + steps: - uses: actions/checkout@v2 @@ -17,7 +21,8 @@ jobs: - name: Build docker image run: | - docker compose -p cms -f docker/docker-compose.test.yml build testcms + docker compose -p cms -f docker/docker-compose.test.yml build \ + --build-arg BASE_IMAGE=${{ matrix.base_image }} testcms - name: Run tests run: | diff --git a/Dockerfile b/Dockerfile index 6927b9e593..c9874470d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,53 +1,75 @@ # syntax=docker/dockerfile:1 -FROM ubuntu:24.04 +# Supported combinations: ubuntu:noble, debian:bookworm. +ARG BASE_IMAGE=ubuntu:noble +FROM ${BASE_IMAGE} -RUN \ - export DEBIAN_FRONTEND=noninteractive ; \ - apt update && \ - apt upgrade -y && \ - apt install -y \ - build-essential \ - cgroup-lite \ - cppreference-doc-en-html \ - curl \ - fp-compiler \ - git \ - ghc \ - libcap-dev \ - libcups2-dev \ - libffi-dev \ - libpq-dev \ - libyaml-dev \ - mono-mcs \ - openjdk-8-jdk-headless \ - php-cli \ - postgresql-client \ - pypy3 \ - python3-pip \ - python3-venv \ - python3.12 \ - python3.12-dev \ - rustc \ - shared-mime-info \ - sudo \ - wait-for-it \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked </etc/apt/sources.list.d/isolate.list && \ - curl https://www.ucw.cz/isolate/debian/signing-key.asc >/etc/apt/keyrings/isolate.asc && \ - apt update && \ - apt install -y isolate && \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked </etc/apt/sources.list.d/isolate.list + curl https://www.ucw.cz/isolate/debian/signing-key.asc \ + >/etc/apt/keyrings/isolate.asc + apt-get update + apt-get install -y isolate sed -i 's@^cg_root .*@cg_root = /sys/fs/cgroup@' /etc/isolate +EOF # Create cmsuser user with sudo privileges and access to isolate -RUN \ - useradd -ms /bin/bash cmsuser && \ - usermod -aG sudo cmsuser && \ - usermod -aG isolate cmsuser && \ - # Disable sudo password \ +RUN <> /etc/sudoers +EOF # Set cmsuser as default user USER cmsuser @@ -58,15 +80,21 @@ COPY --chown=cmsuser:cmsuser install.py constraints.txt /home/cmsuser/src/ WORKDIR /home/cmsuser/src -RUN ./install.py venv +RUN --mount=type=cache,target=/home/cmsuser/.cache/pip,uid=1001 ./install.py venv ENV PATH="/home/cmsuser/cms/bin:$PATH" COPY --chown=cmsuser:cmsuser . /home/cmsuser/src -RUN ./install.py cms --devel +RUN --mount=type=cache,target=/home/cmsuser/.cache/pip,uid=1001 ./install.py cms --devel -RUN sed 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@testdb:5432/cmsdbfortesting"|' ./config/cms.sample.toml >../cms/etc/cms-testdb.toml -RUN sed -e 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@devdb:5432/cmsdb"|' -e 's/127.0.0.1/0.0.0.0/' ./config/cms.sample.toml >../cms/etc/cms-devdb.toml -RUN sed -i 's/127.0.0.1/0.0.0.0/' ../cms/etc/cms_ranking.toml +RUN <../cms/etc/cms-testdb.toml + sed -e 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@devdb:5432/cmsdb"|' \ + -e 's/127.0.0.1/0.0.0.0/' \ + ./config/cms.sample.toml >../cms/etc/cms-devdb.toml + sed -i 's/127.0.0.1/0.0.0.0/' ../cms/etc/cms_ranking.toml +EOF CMD ["/bin/bash"] diff --git a/cmstestsuite/unit_tests/server/contest/submission/file_retrieval_test.py b/cmstestsuite/unit_tests/server/contest/submission/file_retrieval_test.py index 10df9e5e6e..34556635ab 100755 --- a/cmstestsuite/unit_tests/server/contest/submission/file_retrieval_test.py +++ b/cmstestsuite/unit_tests/server/contest/submission/file_retrieval_test.py @@ -19,6 +19,7 @@ import base64 import io +import sys import tarfile import unittest import zipfile @@ -94,6 +95,7 @@ def test_filename_with_null(self): extract_files_from_archive(archive_data.getvalue()), [ReceivedFile(None, "foo", b"some content")]) + @unittest.skipIf(sys.version_info < (3, 12), "this archive crashes zipfile before py3.12") def test_empty_filename(self): archive_data = io.BytesIO() with zipfile.ZipFile(archive_data, "w") as f: