Skip to content

Commit 8b7606a

Browse files
committed
Make Paper jar staging transactional
1 parent 8d92426 commit 8b7606a

4 files changed

Lines changed: 767 additions & 94 deletions

File tree

‎README.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ Bash still has a place here, which is why the launcher remains a simple `papersc
4646
- Stages a newer same-version stable build only when the command is run manually.
4747
- Prompts before staging a newer or older Minecraft version family.
4848
- Supports forced re-download of the same build with `--force`.
49-
- Verifies downloads against the API-provided SHA-256.
49+
- Requires the Paper API size and SHA-256 before staging and never writes beyond the declared size.
50+
- Preflights server-root write access, durable directory sync, and enough free space for the JAR plus a safety reserve.
51+
- Verifies the exact private staging inode against the API size/SHA-256 and checks its executable manifest, Main-Class bytecode, and every ZIP entry CRC.
5052
- Stores staged-build identity and SHA-256 in `state.json` for later `verify` checks.
5153
- Caches Paper API metadata locally so repeated release checks are faster.
5254
- Publishes the verified download atomically as `Paper-<version>-<build>.jar` without replacing an existing JAR.
@@ -103,6 +105,8 @@ If you already run a live server and want to replace an older local PaperScript
103105

104106
These examples assume a central checkout. In the compact in-root layout, omit the repeated `--server-dir` option.
105107

108+
PaperScript remains a drop-in component for server roots launched through `1MB-start.sh` and `1MB-minecraft.sh`. Replacing `paperscript.sh` and the tracked program files under `paperscript/` does not require a launcher edit, config migration, new package, or new command-line option. Preserve the server-local `paperscript/config.json`, `paperscript/state.json`, and `paperscript/last-launched-jar.txt`; the file locations, marker format, numeric JAR naming contract, and manual-start behavior are unchanged.
109+
106110
For servers that use the required numeric naming pattern, such as `Paper-26.2-84.jar`, PaperScript detects the newest local build and stages the next verified build beside it. The updated `1MB-minecraft.sh` selects the greatest numeric build for its configured Minecraft version on the next manual start.
107111

108112
Keep your local `paperscript/config.json`, `paperscript/state.json`, and `paperscript/last-launched-jar.txt` when refreshing the checkout. In particular, review changes to:
@@ -161,7 +165,9 @@ Behavior:
161165
- If the launcher-selected version has a newer stable build, it stages that build.
162166
- If the newest staged build for the launcher family already matches stable, `--force update` re-downloads and verifies it without replacing the existing file.
163167
- `update` stays on the launcher-selected Minecraft version even when a newer family exists; cross-version staging requires an explicit `download --version ...` command.
164-
- The download is SHA-256 and size verified, fsynced, then atomically published under its numeric build filename.
168+
- Before network activity, PaperScript confirms that the server root can create a private file and durably sync directory entries. It also requires enough free space for the API-declared JAR size plus at least 64 MiB of remaining headroom (or 10% of the JAR size when that is larger).
169+
- The response is capped at the API-declared size. The exact on-disk inode must match that size and SHA-256, contain one executable JAR manifest and its Main-Class bytecode, and pass CRC/decompression checks for every ZIP entry.
170+
- The verified file is mode `0644`, fsynced, then atomically published under its numeric build filename without overwriting any path that appeared concurrently.
165171
- PaperScript never asks to stop the server and contains no stop/kill path.
166172
- After staging, valid launcher identity enables bounded root cleanup; missing/invalid identity defers cleanup without guessing.
167173
- If `--dry-run` is used, it reports JAR/archive actions without staging, moving, or pruning JARs; normal target-local config, logging, and metadata-cache activity may still occur.
@@ -540,7 +546,7 @@ PaperScript stores its runtime files inside the visible `paperscript/` directory
540546
- `paperscript/logs.log`
541547
Activity log
542548
- `paperscript/downloads/`
543-
Legacy/diagnostic download workspace; active staging uses a unique hidden temp file on the server filesystem
549+
Legacy/diagnostic download workspace; active staging uses one private hidden temp inode in the server root so publication stays on the same filesystem
544550
- `paperscript/cache/`
545551
Cached Paper API metadata used to speed up repeated checks
546552
- `paperscript/backups/jars/<version>/`
@@ -740,7 +746,7 @@ bash -n paperscript.sh 1MB-minecraft.sh tests/live-smoke.sh
740746
python3 -m py_compile paperscript/paperscript.py tests/test_paperscript.py tests/test_1mb_minecraft.py
741747
```
742748

743-
The unit suite verifies version ordering, stable-channel defaults, same-version build-upgrade behavior, preview selection, saved channel metadata, atomic state/config defaults, launcher marker publication and rollback, numeric latest-build selection, non-disruptive staging, per-server and active-launch locking, fail-closed marker handling, symlink/version containment, dry-run pruning previews, root retention, and archive caps. Launcher tests use a disposable fake `java` executable and never start a real server.
749+
The unit suite verifies version ordering, stable-channel defaults, same-version build-upgrade behavior, preview selection, saved channel metadata, atomic state/config defaults, launcher marker publication and rollback, numeric latest-build selection, non-disruptive staging, disk/permission/durability preflight, response size caps, private-inode continuity, executable JAR/CRC validation, per-server and active-launch locking, fail-closed marker handling, symlink/version containment, dry-run pruning previews, root retention, and archive caps. Launcher tests use a disposable fake `java` executable and never start a real server.
744750

745751
Run the opt-in live PaperMC smoke test:
746752

@@ -762,7 +768,7 @@ GitHub Actions runs the network-free unit and syntax checks on current macOS and
762768

763769
PaperScript keeps a live local todo file at [paperscript/todo.log](./paperscript/todo.log) for deferred ideas that are not implemented yet.
764770

765-
Current completed production foundations include manual non-disruptive staging, per-server locking, atomic staged publication/state, bounded JAR retention, and latest-build launcher selection with an active marker. Remaining queued ideas include:
771+
Current completed production foundations include manual non-disruptive transactional staging, per-server locking, atomic no-overwrite publication/state, bounded JAR retention, and latest-build launcher selection with an active marker. Remaining queued ideas include:
766772

767773
- metadata-cache durability and corrupt-cache diagnostics
768774
- manual review/application of the launcher diff to the canonical `1MB-minecraft.sh`

0 commit comments

Comments
 (0)