mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-21 21:02:16 -05:00
app_startup.sh runs whatever it finds under that name in the package it just decrypted. That is the entire contract -- plus the exit code, where 0 means "flashed, power-cycle me" and non-zero means "carry on booting" -- so owning the name is all it takes to own the install. We were not using it. We shipped FlashForge's copy verbatim and reached the printer through the one exec hook their file offers: the software component's run.sh, into which bin/patch.sh spliced two marked blocks with 40 lines of regex. installer/runFirmwareExe.sh is that file now. run-pre.sh and run-append.sh are folded into it unchanged in substance -- the manifest delete, the HelixScreen settings rescue, the s6 scandir sweep, the config merge, the password dance are all the same code -- and the two orderings that mattered are kept explicitly rather than by where a regex put them: the backups run BEFORE any component is installed, because the software component ships /usr/prog's shadow and passwd and its run.sh copies them over the live ones. The four component installers become one function. Their semantics are kept exactly, including that a component failing md5sum.list is discarded rather than half-installed, and that every previous version directory is wiped before the new one lands. What is NOT kept is the third of that file which never ran: create_key(), defined and never called, and built its paths without a slash so it would have written /usr/progprivate.pem; SSID_NAME/SSID_PASS, assigned and never read; the commented-out kernel version gate; the screwflag factory bypass of the model check, which we ship no screwflag for. bin/pack.sh stages it, rewriting MACHINE=, PID= and MOD_PW_AUTO= and then GREPPING for all three -- a package whose gate still said Creator5Pro because a sed missed would install on the wrong machine. MOD_PW_AUTO is 0 in the checkout, which is the safe default and not an arbitrary one: test_upgrade.py runs the unsubstituted file, and 1 would have it reroll the replica's root password and drop a password file on /mnt every run. The software component still ships, unchanged, and its run.sh is left exactly as FlashForge wrote it. Dropping it is the next commit; this one moves the vehicle without changing what reaches /usr/prog. Gates: qa/static/test_shell_syntax.py already covered installer/*.sh under both bash -n and the printer's ash plus shellcheck, so the new file was checked the day it landed -- 91 pass. test_upgrade.py runs the real installer over two synthetic payloads and is repointed at it. Two doc claims corrected while their sections were open, both false before this change rather than because of it: how-it-works.md said app_startup.sh's firmwareExe recovery "still works" -- it cannot, because it copies out of the version directory and ours has had firmwareExe deleted from it -- and it described a Moonraker preflight-and-rollback that went with the /usr/prog copy; moonraker-preflight.py exists nowhere in the tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CH7Yb4wuPhnppHAB25UX7e