Skip to content

docs: Saruman's arrays are measured and alexander boots from the SSD pool (#527) - #556

Merged
Gerrrt merged 1 commit into
mainfrom
gerrrt/saruman-ssds-logical-drive-4a8edc
Sep 20, 2026
Merged

Gerrrt merged 1 commit into
mainfrom
gerrrt/saruman-ssds-logical-drive-4a8edc

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Sep 20, 2026

Copy link
Copy Markdown
Owner

What changed

The Saruman half of #527 ran from the Mac between 22:50 UTC on 2026-09-19 and 03:03 UTC on 2026-09-20, and this PR records it and flips every document the fit made stale.

What was measured (4 KiB random write, direct=1, an 8 GiB thin volume in each pool):

Run Target IOPS clat mean clat p99
M3, idle HDD mirror, QD1 741 1.30 ms 12.5 ms
M1, guest live HDD mirror, QD1 734 1.32 ms 12.6 ms
ceiling HDD mirror, QD32 × 4 712 179 ms 300 ms
M2 SSD mirror, QD1 7,952 102 µs 198 µs
ceiling SSD mirror, QD32 × 4 51,600 2.45 ms 6.3 ms

What was read. ssacli 6.60 installed from HPE's trixie suite (path 1, one apt-get) and read the P440ar for the first time from the host: Cache Ratio: 10% Read / 90% Write, 1.8 GB battery-backed, LD 1 Caching: Enabled, LD 2 on SSD Smart Path with caching refused for that reason. So #76's answer is branch (a): the iLO does not populate its cache columns on this hardware, and the 741 on a 7.2K mirror is that cache at work. Both spinners are Interface Type: SATA, not SAS.

What moved. alexander's 100 GiB disk mirrored across to large_data online in 7 min 28 s, unused0 was removed once the guest answered, ssd=1 set, and the guest rebooted; lsblk inside reads ROTA 0. No silence created; none needed.

The flip, in the runbook's order: hardware.md (numbers; SAS → SATA), ADR-0029 / ADR-0007 / ADR-0017 (dated notes, text unchanged per ADR-0001), the roadmap (#414 paragraph replaced, #418/#527 entry closed, a Done entry, a dated paragraph in the buy section, the Done #76 entry extended), the iLO rules header (the fit that needed no silence; the columns no rule may read), both lab build runbooks (disk-cache paragraph flipped to the (a) reason; the guest one gains the qemu-guest-agent install the fit found missing, and notes alexander is on large_data at 100 GiB; the domain one points its six disks at large_data for #414 to change), stacks/lab/compose.yaml (the volume no longer shares the spindles), and the runbook itself (status, steps 2/3/6/8/9/10, step 11's Observed column, items 1, 6, 7, 8, 9, 10, 12, 15).

Why

#527's done condition: step 8's two numbers in hardware.md, alexander booting from the SSD pool, and the roadmap's "holds until step 8 measures both arrays" sentence replaced by what it measured. All three hold, verified from Prometheus at 03:05 UTC: sdb carrying the guest's writes, homelab_guest_running 1, cpqDaAccelBadData 2, cpqDaLogDrvCondition{1} 2, walk 12.0 s, nothing on Saruman or shiva firing.

Blast radius

  • No change to network segmentation or firewall rules
  • No new port published to a VLAN that could not already reach the service
  • No credential added outside secrets/*.sops.yaml

Verification

  • make lint, make check-docs pass locally; promtool check rules and promtool test rules pass on the edited rules file through the pinned image
  • Deployed to the lab and confirmed working — this PR is the record of that
  • Docs updated

Closes #527. Refs #76, refs #414, refs #529, refs #538.

🤖 Generated with Claude Code

…pool (#527)

Steps 2, 3, 6, 8, 9, 10 and 11 of the fit runbook ran from the Mac
between 22:50 UTC on 2026-09-19 and 03:03 UTC on 2026-09-20, and every
document the fit made stale is flipped.

ssacli 6.60 installed from HPE's trixie suite through path 1 and finds
the P440ar through hpsa 3.4.20. The controller, read from the host for
the first time: Cache Ratio 10% Read / 90% Write, 1.8 GB battery-backed,
LD 1 Caching Enabled, LD 2 on SSD Smart Path with caching refused for
that reason. That is #76's branch (a): the iLO does not populate its
cache columns on this hardware, the ratio was set all along, and the
change #76 would have owned does not exist. Both spinners read
Interface Type SATA, so hardware.md loses the word SAS and ADR-0007
gets a note for it.

fio, 4 KiB random write at queue depth 1 on a thin volume in each pool:
the 7.2K mirror 741 IOPS idle and 734 with the guest live (712 at queue
depth 32), against the 83 ADR-0029 derived assuming no write cache;
the SSD mirror 7,952 (51,600 at queue depth 32). alexander's 100 GiB
disk moved online in 7 min 28 s, unused0 was removed after the guest
answered, ssd=1 set, and the guest rebooted: lsblk inside reads ROTA 0.
No silence was created and none was needed.

Flipped: hardware.md carries the numbers; ADR-0029, ADR-0007 and
ADR-0017 carry dated notes; the roadmap's #414 paragraph says what the
number is now and its #418/#527 entry and Done list record the run; the
iLO rules header records the fit that needed no silence and the columns
no rule may read; both lab build runbooks flip their disk-cache
paragraph to the (a) reason, the guest one gains the qemu-guest-agent
install the fit found missing, and the domain one points its six disks
at large_data for #414 to change; the lab compose comment stops saying
its volume shares the spindles. The runbook's status block, steps 2, 3,
6, 8, 9 and 10, step 11's Observed column, "Flipping the documents" and
items 1, 6, 7, 8, 9, 10, 12 and 15 of "What this runbook does not know"
record all of it.

Closes #527. Refs #76, refs #414, refs #529, refs #538.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Gerrrt
Gerrrt merged commit 6a2148a into main Sep 20, 2026
3 checks passed
@Gerrrt
Gerrrt deleted the gerrrt/saruman-ssds-logical-drive-4a8edc branch September 20, 2026 03:47
Gerrrt added a commit that referenced this pull request Oct 21, 2026
…0101) (#1241)

* feat(home-assistant): patch ring_doorbell's push parser locally (ADR-0101)

ring_doorbell 0.9.14's RingEventListener._get_ring_event raises KeyError
on Ring pushes with no ding.id, and firebase_messaging shuts the push
receiver down after three in a row. After that no Ring motion or doorbell
event reaches Home Assistant. On trinity that happened at 13:12 and
again seconds after the 14:09 restart (python-ring-doorbell/python-ring-doorbell#537. Upstream PRs
python-ring-doorbell/python-ring-doorbell#540 and #556 are open, with
no release since February.)

custom_components/ring_push_guard, mounted read-only and loaded by
packages/ring_push_guard.yaml, replaces that one method for 0.9.14 only.
The id falls back to eventito.timestamp, then created_at in ms, and
anything unparseable is skipped instead of raised. Any other version is
left alone, with a warning. If Ring set up first, its entry is reloaded
once so the listener restarts patched.

Tested in the pinned image: the original raises on an id-less push. The
patch handles normal, id-less (both fallbacks), malformed and non-Ring
pushes. Three id-less pushes and a malformed one through the real
_on_notification raise nothing, and repeat detection still works. ruff
0.17.0 (the pinned version) and check_config pass.

Refs #1240

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(home-assistant): reload a Ring entry that is still setting up

Ring starts its push receiver during platform setup, while its entry
reads SETUP_IN_PROGRESS. A replayed bad push can stop the receiver in
that window, and the LOADED-only check then skipped the reload for good.
The guard now also reloads entries in SETUP_IN_PROGRESS and
SETUP_RETRY. async_reload takes the entry's setup lock, so a reload
asked for mid-setup waits for setup to finish. Tested across every
ConfigEntryState. ADR-0101 says the same.

Refs #1240

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Saruman's SSDs are fitted and in no logical drive: steps 5–11 of the fit runbook, and the IOPS number ADR-0029 is sized on

1 participant