A macOS runner installs each version as SakRunner.app, signed on the host with the identity its configuration names #142
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "task/3797-each-sak-runner-update-drops-the-macos-p"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tracker: #3797
macOS keys a privacy grant to a bare executable by its path and its code requirement. Each sak-runner version was its own file,
~/.sak-runner/bin/<version>/sak-runner, linker-signed ad hoc, so its designated requirement was its own cdhash, and every Update all dropped what Agra had granted the runner. A bundled app's grants are keyed by its bundle identifier, so this PR installs every macOS version as one app bundle,com.swipelab.sak-runner, which the host signs.What it delivers
~/.sak-runner/bin/<version>/SakRunner.app:Contents/MacOS/sak-runneris the checked build, andContents/Info.plistcarriesCFBundleIdentifiercom.swipelab.sak-runner,CFBundleExecutablesak-runnerand the version. The version file the link, the gates and the slots use is the bundle's executable, so~/.local/bin/sak-runnerlinks it and the launchd agent of either slot runs…/SakRunner.app/Contents/MacOS/sak-runner --slot <a|b>.codesign-identity=<identity>, names the code-signing identity (on m5,Apple Development: Alexandru Agrapine (DC8VVHJ9W4)). The install and each update make the bundle beside its place (~/.sak-runner/bin/.SakRunner.app), sign it withcodesign --force --sign <identity> --identifier com.swipelab.sak-runner, verify it withcodesign --verify --strict, and only then move it into place. A signing or verification that fails reports the update failed with the reason, and the running version stays in place: no bundle of the update, no link moved, nonext. A host whose configuration names no identity installs the bundle as it comes, unsigned. A join keeps the line, as it keepsslotandservice.codesign-identityfrom the configuration file each time it installs a bundle (update.installtakes the configuration file's path), not once when its process starts. So a line added or changed while a slot runs signs the next update, with no restart. A configuration file that cannot be read at that moment fails the update ("the configuration file cannot be read for the codesign-identity…") rather than installing the bundle unsigned.sak-runner --installinstalls the executable it runs from as its version, the way an update installs a checked download, and moves the link to it. install.sh now runs it after the sha256 and--versionchecks, in place of its ownmvandln. So the install signs when the configuration already names an identity. On a fresh host the join writes the configuration only after the install, so the first install there is unsigned and the next update signs./runner/<platform>/sak-runner,sha256,version) are unchanged. sak still serves the bare macOS build, and the bundle is made on the host around it, for two reasons. The deploy job cross-builds the macOS runner on Linux, where no bundle can be signed. And a 0.3.6 runner's Update all can only install a bare file, so it can still take the release this PR goes into.Rollout
codesign-identity=line: its configuration parser rejects any key it does not know, so a 0.3.6 process that starts while the line is there fails. Add the line on m5 only once no 0.3.6 process can start, that is once the 0.3.7 hand-over has ended (the old slot unloaded and its plist gone):codesign-identity=Apple Development: Alexandru Agrapine (DC8VVHJ9W4)in~/.config/sak-runner/config. No restart is needed.The first signing from the runner's launchd agent may show macOS's key-access prompt once on m5's screen. s32 has no Apple Development identity, so it installs unsigned bundles until one is added.
Evidence
codesign -d -r-gives each version file its own requirement:bin/0.3.5/sak-runneriscdhash H"3b6b44dd…"andbin/0.3.6/sak-runneriscdhash H"adf69948…". The agent'sProgramArgumentsis["/Users/agra/.sak-runner/bin/0.3.6/sak-runner","--slot","a"].SakRunner.appwas signed withcodesign --force --sign "Apple Development: Alexandru Agrapine (DC8VVHJ9W4)" --identifier com.swipelab.sak-runner. No keychain prompt appeared.codesign -d -r-printeddesignated => identifier "com.swipelab.sak-runner" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Alexandru Agrapine (DC8VVHJ9W4)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */, andcodesign --verify --strictpassed. The tests sign ad hoc (codesign-identity=-), so they raise no keychain prompt and run on s32 too.tests/runner_launchd.sx(real launchd, a scratch service label) pins:ProgramArguments, asplutilreads them, is the bundle executable;check_unsignedchanges the line from-to an identity no keychain holds while slot a runs, with no restart, and the next update fails with "cannot be signed", leaving slot a's version in place, with no bundle of the update and nonext.tests/runner_install.sxpins the macOS install as the bundle, and that install.sh run again signs it with the configuration's identity.tests/step9_release.sxpins the bundle executable for install.sh on this Mac.uname -son the runner's PATH: on Darwin the slots run under launchd and each version is a bundle. That is the same answer that picks the service manager, so a test that stubsunameas Linux gets bare files.git archivearms with the gate cache's sx, undertaskpolicy -b).6f3b4f5(identity read once, at process start) with this head'stests/runner_launchd.sx:RUNNER LAUNCHD FAIL (2 checks), "the card shows the update failed: its bundle cannot be signed" and "slot a keeps its version: the link, its agent and its registration, with no next and no bundle of the update". The running process still signed with-, so the update went through.0422ff9:RUNNER LAUNCHD OK, 42 ok.0422ff9(m5, same arms).runner_handover(75 ok),runner_install(65 ok) andrunner_view(30 ok) pass. These are the tests whose shared install helper now writes the configuration before it installs, soupdate.installreads it.0422ff9).update.installwithbundleand a configuration file holding a line it cannot parse answers "the configuration file cannot be read for the codesign-identity that signs sak-runner 9.9.9's bundle" and installs no bundle. With the line fixed, the same call installs a bundle thatcodesign -dvshows asIdentifier=com.swipelab.sak-runner.Master merged in
5daee6bmerges master05a68a2into the branch, with no conflict. Both sides touchedrunner/config.sx(master'smin-freekey beside this PR'scodesign-identity) andrunner/README.md, in different hunks.diff <(git diff 8cda22f 0422ff9) <(git diff origin/master 5daee6b)differs only in index lines, hunk offsets and theFILE_KEYScontext line, andgit diff-tree --ccshows no line that differs from both parents. The merge was needed for the gate: 0422ff9'sfullfailed only tworunner_coretiming checks that #3629 (on master sincead26ff3) made signal-driven, "the waiting run's stream says it waits" and the gate idle-timeout check. This PR touches neitherrunner/run.sx,runner/gate.sxnortests/runner_core.sx.Gates (m5)
fullat0422ff9: tracker gate run 440 (this run's #1), failed only ontests/runner_core.sx, the two #3629 checks above. Every othertests/*.sxfile passed.fullat5daee6b: tracker gate run 443 (this run's #2), passed. That covers everytests/*.sxfile, release withstep9_release, the deploy contract, the main Playwright config (740 passed, 1 skipped, 3.5 min) and the runner Playwright config (10 passed).6f3b4f5, before this round:fastgate run 380 andfullgate run 382 passed.Left for the rollout
The acceptance "a grant Agra gives the runner on m5 keeps working after an update" needs the rollout above on the live runner, so this PR cannot show it. Verify it there with
codesign -d -r- ~/.sak-runner/bin/<version>/SakRunner.appafter each update.