max / alloy
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+38 insertions,
-6 deletions
| @@ -495,7 +495,23 @@ | |||
| 495 | 495 | /// | |
| 496 | 496 | /// So the sequence is mount, configure, finalize, unmount, and this is the | |
| 497 | 497 | /// mountpoint used throughout. | |
| 498 | - | const TARGET_MOUNT: &str = "/mnt/alloy-target"; | |
| 498 | + | /// | |
| 499 | + | /// **Under `/run` and not `/mnt`, and the difference is load-bearing.** On the | |
| 500 | + | /// live medium `/mnt` is a symlink to `var/mnt`, which is ostree's own layout. | |
| 501 | + | /// `systemctl --root=/mnt/alloy-target/...` then resolves a drop-in to a path | |
| 502 | + | /// under `/var/mnt/...`, decides it has escaped the root it was given, refuses | |
| 503 | + | /// to read it, and reports the unit it could not finish loading as `bad`. The | |
| 504 | + | /// acceptance check in [`acceptance_checks`] reads that as a greeter that would | |
| 505 | + | /// not start and fails an install that was fine, so every client-profile | |
| 506 | + | /// install died at the last step and wiped the disk it had just written. | |
| 507 | + | /// Measured in a VM 2026-08-09: the same check against the same deployment | |
| 508 | + | /// reads `enabled` when the mount is at `/run/alloy-target`. | |
| 509 | + | /// | |
| 510 | + | /// `/run` because it is a real directory on every Linux, tmpfs, never a | |
| 511 | + | /// symlink. `/var/mnt` would work on this image and is what `/mnt` points at, | |
| 512 | + | /// but it hardcodes ostree's layout into a path that has no other reason to | |
| 513 | + | /// know it. | |
| 514 | + | const TARGET_MOUNT: &str = "/run/alloy-target"; | |
| 499 | 515 | ||
| 500 | 516 | /// The activity light's lit and dim glyphs. | |
| 501 | 517 | /// | |
| @@ -5557,10 +5573,26 @@ | |||
| 5557 | 5573 | ), | |
| 5558 | 5574 | ); | |
| 5559 | 5575 | assert_eq!(shown[1], "udevadm settle"); | |
| 5560 | - | assert_eq!(shown[2], "mkdir -p /mnt/alloy-target"); | |
| 5576 | + | assert_eq!(shown[2], "mkdir -p /run/alloy-target"); | |
| 5561 | 5577 | assert!(shown[3].starts_with("lsblk"), "{}", shown[3]); | |
| 5562 | 5578 | } | |
| 5563 | 5579 | ||
| 5580 | + | // Where the target is mounted decides whether the acceptance checks can | |
| 5581 | + | // read it. `systemctl --root=X` refuses any path whose resolution leaves X, | |
| 5582 | + | // and on this image `/mnt` is a symlink to `var/mnt`, so a mountpoint there | |
| 5583 | + | // made systemd report a unit it could not finish loading as `bad` and | |
| 5584 | + | // failed every client-profile install at the last step. The constant's doc | |
| 5585 | + | // comment carries the measurement; this is the part a future edit trips | |
| 5586 | + | // over. | |
| 5587 | + | #[test] | |
| 5588 | + | fn the_target_is_mounted_somewhere_that_is_not_a_symlink() { | |
| 5589 | + | assert!( | |
| 5590 | + | TARGET_MOUNT.starts_with("/run/"), | |
| 5591 | + | "{TARGET_MOUNT} is not under /run; a mountpoint under /mnt resolves \ | |
| 5592 | + | through ostree's var/mnt symlink and breaks `systemctl --root`", | |
| 5593 | + | ); | |
| 5594 | + | } | |
| 5595 | + | ||
| 5564 | 5596 | // The summary can only show what is known before anything runs. Everything | |
| 5565 | 5597 | // past the first discovery depends on values that do not exist yet, and | |
| 5566 | 5598 | // inventing lines for them would be the summary claiming to know more than | |
| @@ -5609,7 +5641,7 @@ | |||
| 5609 | 5641 | } | |
| 5610 | 5642 | ||
| 5611 | 5643 | /// A deployment directory shaped the way ostree names them. | |
| 5612 | - | const DEPLOYMENT: &str = "/mnt/alloy-target/ostree/deploy/default/deploy/abc123.0"; | |
| 5644 | + | const DEPLOYMENT: &str = "/run/alloy-target/ostree/deploy/default/deploy/abc123.0"; | |
| 5613 | 5645 | ||
| 5614 | 5646 | /// The configure half, against a deployment directory as discovered. | |
| 5615 | 5647 | /// | |
| @@ -5803,7 +5835,7 @@ | |||
| 5803 | 5835 | assert!(useradd.contains("--home-dir /var/home/max"), "{useradd}"); | |
| 5804 | 5836 | assert_eq!( | |
| 5805 | 5837 | mkdir, | |
| 5806 | - | "mkdir -p /mnt/alloy-target/ostree/deploy/default/var/home/max" | |
| 5838 | + | "mkdir -p /run/alloy-target/ostree/deploy/default/var/home/max" | |
| 5807 | 5839 | ); | |
| 5808 | 5840 | } | |
| 5809 | 5841 | ||
| @@ -5887,7 +5919,7 @@ | |||
| 5887 | 5919 | fn the_stateroot_var_is_two_levels_above_the_deployment() { | |
| 5888 | 5920 | assert_eq!( | |
| 5889 | 5921 | stateroot_var(DEPLOYMENT).unwrap(), | |
| 5890 | - | "/mnt/alloy-target/ostree/deploy/default/var" | |
| 5922 | + | "/run/alloy-target/ostree/deploy/default/var" | |
| 5891 | 5923 | ); | |
| 5892 | 5924 | } | |
| 5893 | 5925 | ||
| @@ -5896,7 +5928,7 @@ | |||
| 5896 | 5928 | // var directory from. | |
| 5897 | 5929 | #[test] | |
| 5898 | 5930 | fn a_path_that_is_not_a_deployment_is_a_named_failure() { | |
| 5899 | - | let error = stateroot_var("/mnt/alloy-target").unwrap_err(); | |
| 5931 | + | let error = stateroot_var("/run/alloy-target").unwrap_err(); | |
| 5900 | 5932 | assert!(error.contains("not an ostree deployment"), "{error}"); | |
| 5901 | 5933 | } | |
| 5902 | 5934 |