agent v0.35.1: shared-parent unit runs before pve-guests on host boot
The shared-parent oneshot never ran before pve-guests (WantedBy=multi-user wasn't pulled into the boot transaction), so on a host reboot the guest bound a not-yet-shared parent -> private -> propagation broken. Now WantedBy=pve-guests (pve-guests pulls it in + Before= orders it first); EnsureSharedParent reinstalls the unit when content differs so the fix deploys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,14 @@
|
||||
All notable changes to **felhom-agent** are recorded here. Update on every code
|
||||
change that gets pushed.
|
||||
|
||||
## v0.35.1 — shared-parent unit: run before pve-guests on host boot (2026-06-15)
|
||||
|
||||
Fix for the host-reboot ordering (the shared-parent oneshot never ran before pve-guests on the live
|
||||
host, so the guest bound a not-yet-shared parent → private bind → propagation broken). The unit now uses
|
||||
`WantedBy=pve-guests.service` (pve-guests PULLS IT IN + Before= orders it first) instead of the
|
||||
unreliable `WantedBy=multi-user.target`, and drops `DefaultDependencies=no`. `EnsureSharedParent`
|
||||
reinstalls the unit when its content differs (so the fix deploys on the next agent start/reconcile).
|
||||
|
||||
## v0.35.0 — intermediary mount: guest-reboot re-propagation (load-bearing) (2026-06-15)
|
||||
|
||||
Fix for the guest-reboot gap (caught in the live demo migration). A guest's parent bind is
|
||||
|
||||
@@ -44,7 +44,7 @@ import (
|
||||
|
||||
// version is the agent version. Overridable at build time with
|
||||
// -ldflags "-X main.version=<v>"; defaults to the in-repo CHANGELOG version.
|
||||
var version = "0.35.0"
|
||||
var version = "0.35.1"
|
||||
|
||||
// runGuestHook is the PVE pre-start hook body (`felhom-agent guest-hook <vmid> <phase>`). On the
|
||||
// pre-start phase it creates placeholder dirs for any absent bind-mount source so the guest always boots
|
||||
|
||||
@@ -37,9 +37,13 @@ mount --make-shared ` + StableParentDir + `
|
||||
`
|
||||
|
||||
const sharedParentUnitPath = "/etc/systemd/system/felhom-shared-parent.service"
|
||||
|
||||
// sharedParentUnit MUST run before pve-guests so the guest's parent bind inherits the shared peer group.
|
||||
// WantedBy=pve-guests.service makes pve-guests itself PULL IT IN (and Before= orders it first) — a plain
|
||||
// WantedBy=multi-user.target proved unreliable (the unit wasn't pulled into the boot transaction; it
|
||||
// never ran before pve-guests). local-fs.target ordering ensures /mnt is available.
|
||||
const sharedParentUnit = `[Unit]
|
||||
Description=Felhom stable drive parent (shared bind for live drive hot-swap)
|
||||
DefaultDependencies=no
|
||||
After=local-fs.target
|
||||
Before=pve-guests.service
|
||||
ConditionPathExists=` + sharedParentScriptPath + `
|
||||
@@ -50,7 +54,7 @@ RemainAfterExit=yes
|
||||
ExecStart=` + sharedParentScriptPath + `
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=pve-guests.service multi-user.target
|
||||
`
|
||||
|
||||
// StablePathForRaw maps a drive's RAW host mount (/mnt/<name>) to its stable in-guest path
|
||||
@@ -94,9 +98,10 @@ func (b *GuestBinder) EnsureSharedParent(ctx context.Context) error {
|
||||
if err := b.run(ctx, "mount", "--make-shared", StableParentDir); err != nil {
|
||||
return fmt.Errorf("shared-parent: make-shared: %w", err)
|
||||
}
|
||||
// Install the boot-persistence unit only if it's not already there — EnsureSharedParent runs on a
|
||||
// periodic reconcile, and re-writing files + daemon-reload every tick would be wasteful.
|
||||
if _, err := os.Stat(sharedParentUnitPath); err != nil {
|
||||
// Install the boot-persistence unit only when missing OR its content differs from what we ship (so a
|
||||
// unit-template fix deploys) — EnsureSharedParent runs on a periodic reconcile, and re-writing files +
|
||||
// daemon-reload every tick would be wasteful, so the common case (unchanged) is a cheap read.
|
||||
if cur, err := os.ReadFile(sharedParentUnitPath); err != nil || string(cur) != sharedParentUnit {
|
||||
if ierr := b.installSharedParentUnit(ctx); ierr != nil {
|
||||
b.logger.Warn("shared-parent: boot-persistence unit install failed (live setup OK; survives until host reboot)", "err", ierr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user