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:
@@ -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