Repository navigation
Ask once for the password in a quieter, renamed Recovery step - #39
Conversation
|
Thanks, all fair. Fixed in 4c56647, and checked on the M3 from its own Recovery:
Two more from testing:
|
|
Follow-up in baaa687: I dropped the password-less |
|
@scottjones thanks, this round is solid. Re-reviewed at One thing before merge:
Nits, fine as follow-ups:
Merge order: I'd like #27 to land first. Its catalog generator refuses an engine at |
|
Thanks. Fixed in 38509de; checks pass on macOS and in an Ubuntu 24.04 container as CI runs them.
Merge order: understood. I'll rebase after #27, set the templates' minimum to 2.1.0 and rebuild one engine with both overlays. The plan is in the description. |
|
CI fix in 6b97334: the Ctrl-C test for a hidden |
0ee4b81 to
76d23d1
Compare
|
Rebased onto |
The stub's Recovery setup is now Omarchy's own step2.sh, titled with the app's name. It asks for the password once and asks one "Are you sure?", then answers bputil, bless and kmutil with the known owner and that password. kmutil reads its user name and password from its terminal and discards type-ahead, so it runs on a hidden terminal and gets each answer when its prompt appears; if it fails or stalls for a minute, the owner answers it directly. A spinner shows bputil and kmutil working, a wrong password is named plainly, and every line fits an 80-column Terminal. Engine v0.9.2-omarchy.26 carries it, and the release inputs move to it. The app passes DISTRO "Omarchy" and OMARCHY_INSTALLER_NAME. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review: bputil lowered the stub's security before the owner was asked, so declining left it lowered. "Are you sure?" now comes first, and "n" changes nothing. bputil and kmutil now run in the foreground, where Ctrl-C reaches them, with the spinner in the background. On any exit a handler stops the spinner and any hidden kmutil, restores echo, clears the password and deletes the /tmp logs. kmutil runs under script through a wrapper that records its own process ID, so the one-minute watchdog stops kmutil itself and the fallback never runs two at once. After three bputil failures, bputil asks the owner itself, as upstream did, instead of looping. Passwords keep leading and trailing spaces (IFS= read). A rejected password replaces the "Updating" line with the reason. On the wrong Recovery, bless --setBoot exits 0 and ignores the credentials it asks for, so step 2 checks the startup disk (bless --getBoot against Omarchy's volume group) instead, asks nothing when Omarchy already is the startup disk, and tries bless without a password before asking for one. OMARCHY_INSTALLER_NAME is optional again, so released apps keep working with this engine; the title then falls back to DISTRO. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit tried bless with an empty password first, because recoveryOS's bless ignores the credentials it asks for. It needs a non-empty one, and sending a made-up password to work around Apple's check isn't something to rely on. On the wrong Recovery, step 2 now asks for the password once, as before, and still checks bless --getBoot rather than bless's exit status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI runs on Linux, where /bin/sh is dash, and failed: a bare `read` is a
bash extension that dash rejects ("read: arg count"). macOS runs step2.sh's
reads become `read -r _`. The SystemVersion rename inherited from upstream
used brace expansion, which a POSIX sh leaves unexpanded, so it now names
both paths.
The step 2 tests now run the script with `bash --posix`, as macOS and its
recoveryOS do, and again under dash when it is installed (on CI, and as
/bin/dash on macOS), so neither shell is tested by accident.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nits From review: after three rejected passwords, bputil asks the owner itself, but PASSWORD still held the third rejected one; the hidden kmutil typed it, failed, and the owner waited a minute for a fourth failed login. The password is now cleared once bputil asks for itself, and without one step 2 goes straight to kmutil's own prompts. Also from review: the volume group check matches only diskutil's "APFS Volume Group" line; cleanup signals the recorded PID only while it is still kmutil configure-boot, never a process that has reused the ID; the trap comment says how kmutil is stopped; and the volume group and Preboot volume group must be UUIDs before they go into the script, like the owner and the title. New tests cover Ctrl-C at the password prompt (echo is restored) and during a hidden kmutil that ignores it (it is stopped). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ests CI hung in the Ctrl-C test for a hidden kmutil: the fake script ran kmutil in the foreground of the same process group, so with a kmutil that ignores SIGINT the shells waited on it and step 2's cleanup never ran. The real script gives kmutil its own session on a pseudo-terminal, where Ctrl-C ends script but never reaches kmutil. The fake now does the same: kmutil runs in the background, where SIGINT is ignored, and script exits on SIGINT. Step 2 also closes the gap the test exposed: once script returns, any kmutil still running under the recorded ID is stopped before the ID is forgotten, so none can outlive its script. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dash CI failed on Linux in the three tests that answer kmutil through the fake script: it ran kmutil in the background with <&0, but dash still replaces a background job's stdin with /dev/null, so the fake kmutil read empty answers. Its input now comes through descriptor 3. The dash test class also runs the fake recoveryOS tools under dash, so this fails locally as it did on CI; the step 2 script itself is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catalog's installation engine now carries #40's stub-probe fix and this branch's Recovery step: installer-v0.9.2-omarchy.28.tar.gz, 17,843,348 bytes, SHA-256 0cf1aa87..., reproduced twice with macOS /usr/bin/python3 3.9.6. Compared with .27 only omarchy_asahi.py, omarchy_runtime.py and version.tag change. The app keeps bundling .27 for inspection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76d23d1 to
a398080
Compare
|
@scottjones re-reviewed the rebase at One thing before merge:
Nit: |
cutover-wizard and assemble-candidate-v8.sh take the catalog engine from Packaging/build-app.sh, so with the app still pinned to .27 they would upload .27 while the templates name .28, and the catalog generator would stop on a missing asset. The packager, the Swift artifact pin and its test now select .28, whose inspection code matches .27. The docs no longer say the templates select .27. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
maralcbr
left a comment
There was a problem hiding this comment.
Approved at 5b75651. The bundled inspection pin, packager and templates now all select .28 (0cf1aa87…, 17,843,348 bytes, reproduced twice with /usr/bin/python3 3.9.6), so the cutover wizard and assemble-candidate publish the engine the catalog names. The Recovery step itself is unchanged from the version reviewed at 0ee4b81. Publishing .28 and the signed catalog, and the pending hardware checks, remain before release.
Make the Recovery step short and quiet. On an existing install the screen is now:
Before, it was titled "Omarchy MX Mac installer (second step)", asked for the user name and password up to three times, showed
kmutil's raw prompts and Apple's warning, and printedbputil's "Use at your own risk!" banner on a wrong password.What changes
step2.sh: the stub installer writes it over asahi-installer's afterinstall_files, titled with the app's name (OMARCHY_INSTALLER_NAME), for the owner the app already knows (OMARCHY_MACHINE_OWNER).yexits with "Nothing was changed".bputil -nctakes the owner and the password as arguments. After three failures,bputil -nc -vasks the owner itself, as upstream does; the rejected password is then cleared, andkmutilasks the owner directly instead of being typed it. A rejected password replaces the "Updating" line with "That password didn't work for . Try again." The password is read withIFS= read -r, so leading and trailing spaces survive.kmutil configure-boothas no credential options. It reads "are you sure" from stdin but the user name and password from its terminal, and discards anything typed ahead (piping all three stalls). So it runs underscripton a hidden terminal, and the script types each answer once its prompt appears in the log. The password is sent with echo off, so the log never holds it.kmutilfails, or is still running after a minute, it's stopped and the owner answers it directly. A one-line wrapper recordskmutil's own process ID, so the watchdog stopskmutilitself, not onlyscript, and the fallback never overlaps it.bputilandkmutilrun in the foreground, so Ctrl-C reaches them. The spinner runs in the background.kmutil, restores echo, clears the password and deletes every/tmplog.bless --setBootasks for a user name and password but accepts any values and exits 0 (tested on macOS 26.6.2 with a made-up user name). So step 2 checks the result withbless --getBootagainst Omarchy's volume group, notbless's exit status.sh:step2.shis#!/bin/sh, which macOS runs as bash in POSIX mode. It no longer uses barereador the brace expansion upstream'sSystemVersionrename relied on, so it also runs underdash.DISTROis now "Omarchy" (was "Omarchy MX Mac"), and the app passesOMARCHY_INSTALLER_NAME.DISTRO + " installer".v0.9.2-omarchy.28: one engine with Allow a minimum Omarchy install when the doubled size does not fit #27's planner, Fix #27's zip link, stub probe and divider margin; pin engine .27 #40's stub-probe fix and this step: 17,843,348 bytes, SHA-2560cf1aa87760f90a545298b7cef737c9b497f2cad421d79ac59f557a81f2eb146. Compared with Fix #27's zip link, stub probe and divider margin; pin engine .27 #40's.27, onlyomarchy_asahi.py,omarchy_runtime.pyandversion.tagchange; compared with the earlier.26, only Fix #27's zip link, stub probe and divider margin; pin engine .27 #40'somarchy_runtime.pyfix andversion.tag. It reproduces byte for byte with macOS/usr/bin/python33.9.6, the interpreter Allow a minimum Omarchy install when the doubled size does not fit #27 records indocs/extraction.md; other Python versions encode the tar headers differently. It includes #166's planner change, which.17never shipped. The release inputs templates move to.28, keeping Allow a minimum Omarchy install when the doubled size does not fit #27's installer minimum of 2.1.0 and Fix #27's zip link, stub probe and divider margin; pin engine .27 #40's zip link. The app bundles.28too (Packaging/build-app.sh,ValidationEngineArtifact.swift), because the release scripts take the catalog engine from that pin.Validation
Candidate
41544a2, stacked on #40 (9787a83), on Xcode 27.0, macOS 26.6.2, M4 Pro:./test/allpasses (Bash 5.3).swift-format lint --strictis clean.swift testpasses in debug and release (519 tests, 1 skipped).step2.shitself against fakebputil,bless,diskutil,kmutilandscript, underbash --posix(as macOS runs it) and again underdash(CI's/bin/sh). They cover:.28builds byte-identically twice, andverify-archive-modes.pyandverify-source-lock.pypass.bash test/allpasses in an Ubuntu 24.04 container (dashas/bin/sh, bash 5.2, Python 3.12). The Ctrl-C and stall tests passed 10 repeated rounds each on x86_64 and arm64 Ubuntu, and 15 on macOS.scriptbehaviour on macOS: the exactkmutilblock ran under/bin/shwith the realscript(1)against stand-ins.kmutildoes: it finishes, and the password is not in the log./tmp.j613, 512 GB, macOS 26.6.2), owner-run: a developer test build of this branch on Allow a minimum Omarchy install when the doubled size does not fit #27 before Fix #27's zip link, stub probe and divider margin; pin engine .27 #40 (engine.26,dde21d63…, from a dev-key catalog and locally staged assets) removed the previous Omarchy, installed, ran this Recovery step from the Mac's own recoveryOS and booted Omarchy.j613, macOS 26.6.2, 25G83), owner-run: step 2 from this branch was placed on an existing install and run from its own Recovery.nstops before the password.bputil, and duringkmutileach stop cleanly: nobputil,kmutilorscriptleft, and no/tmpfiles.38509de's step 2):bputilasked for itself, thenkmutilasked straight away, with no wait and no reuse of the rejected password./dev/disk4s1): one password prompt, then Omarchy became the startup disk (/dev/disk2s2) and the--getBootcheck recognized it.bless --setBootin Recovery switched the startup disk with a made-up user name and any password.j700, macOS 26.6, 25G72): the first version of this step (single password, hiddenkmutilanswers) ran end to end on an existing install.The
.28artifact still has to be published where the release inputs expect it before a catalog can name it.Merge order
Stacked on #40, which fixes #27's post-merge findings (zip link, stub probe, divider margin). Merge #40 first; this PR's base then becomes
main. The templates carry #27's 2.1.0 minimum and #40's zip link, and one.28engine carries both overlays.Not in this PR
mac/neo-j700), which will be rebased onto this.🤖 Generated with Claude Code