From e5b12da948ca08e02e5d779f76d7ecf6c47fc857 Mon Sep 17 00:00:00 2001 From: Tobias Kaupat Date: Wed, 21 Oct 2026 00:33:41 +0200 Subject: [PATCH] fix: set script modes in the image independent of the build umask (#113) COPY --chmod=755 for backup.sh, check.sh and entry.sh so the image no longer depends on the build host's umask; exact structure permission checks stay. README notes the BuildKit requirement. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 3 +++ Dockerfile | 6 +++--- README.md | 2 ++ tests/sabotage.py | 4 ---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb022ca..b98cc43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ * Test suites in `tests/` (compat, features, structure) that run the image as a real container, plus a `Test` GitHub Actions workflow running them on every pull request. The suites are written in Python (pytest) and run via `mise install` and `task test`; `task test:sabotage` proves they detect a broken backup * `.gitattributes` pinning shell scripts, the Dockerfile and YAML files to LF line endings. With a Windows checkout (`core.autocrlf=true`) the scripts were checked out with CRLF, which made the built image fail to start with `exec /entry.sh: no such file or directory` +### Changed +* The Dockerfile now sets the mode of `backup`, `check` and `entry.sh` itself (`COPY --chmod=755`), so the image no longer depends on the build host's umask or on the exec bit of the checked-out scripts. BuildKit is required as before (default since Docker 23) + ### Removed * `config-broken.yml` and `docker-compose.test.broken.yml`, replaced by `tests/structure.yml` and the test workflow diff --git a/Dockerfile b/Dockerfile index 55a4b79..a7971e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -60,9 +60,9 @@ RUN mkdir /.cache && \ # /data is the dir where you have to put the data to be backed up VOLUME /data -COPY backup.sh /bin/backup -COPY check.sh /bin/check -COPY entry.sh /entry.sh +COPY --chmod=755 backup.sh /bin/backup +COPY --chmod=755 check.sh /bin/check +COPY --chmod=755 entry.sh /entry.sh ENTRYPOINT ["/entry.sh"] CMD ["tail","-fn0","/var/log/cron.log"] diff --git a/README.md b/README.md index f985d46..35f8de0 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ Build the container (the container is named `backup-test`): ./build.sh ``` +The image needs BuildKit (default since Docker 23; on older Docker set `DOCKER_BUILDKIT=1`). + Run the container: ``` ./run.sh diff --git a/tests/sabotage.py b/tests/sabotage.py index 9d17637..3a9c272 100644 --- a/tests/sabotage.py +++ b/tests/sabotage.py @@ -54,10 +54,6 @@ def sabotage_tree(tmp: Path) -> None: if patched == lines: raise Invalid("sabotage patch did not apply, backup.sh changed shape") script.write_text("".join(patched)) - # Dockerfile COPY has no chmod: the image only works when the file is executable. - script.chmod(script.stat().st_mode | 0o111) - if not os.access(script, os.X_OK): - raise Invalid("sabotaged backup.sh is not executable") def red_tests(report: Path) -> tuple[set[str], set[str]]: