agent v0.86.0: DR-tier-by-default — capability inactive state (GatedBy/GateActive, pbsdr gate via DRConfigured) + F-3 root-run provision parent ownership
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
This commit is contained in:
@@ -52,6 +52,9 @@ type BackHalf struct {
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// geteuid is the effective-uid seam (F-3): tests fake a root run without being root.
|
||||
var geteuid = os.Geteuid
|
||||
|
||||
// NewBackHalf builds the back-half. stateDir defaults to /var/lib/felhom-agent when empty.
|
||||
func NewBackHalf(tokens TokenMinter, runner proxmox.Runner, stateDir string, logger *slog.Logger) *BackHalf {
|
||||
if stateDir == "" {
|
||||
@@ -135,6 +138,23 @@ func (b *BackHalf) Provision(ctx context.Context, in Input) (Result, error) {
|
||||
if err := os.MkdirAll(hostDir, 0o700); err != nil {
|
||||
return Result{}, fmt.Errorf("provision: config dir: %w", err)
|
||||
}
|
||||
|
||||
// 3b. F-3 (DRILL-day0-vm-2026-07-12): a ROOT-run provision (the Day-0 one-shot) leaves the
|
||||
// just-created guests/ + guests/<vmid>/ parents root:root 0700 inside the agent-owned
|
||||
// state dir — the non-root daemon's lanresolver then can't traverse them ("permission
|
||||
// denied"). Own the two PARENTS to whatever owns the state dir (chown --reference; the
|
||||
// installer made that the agent user). NON-recursive on purpose: only the bootstrap leaf
|
||||
// below belongs to the mapped guest-root. A daemon-run provision creates them as the
|
||||
// agent user already — euid≠0 skips (and needs no sudoers vector for this shape).
|
||||
if geteuid() == 0 {
|
||||
guestsDir := filepath.Join(b.stateDir, "guests")
|
||||
vmidDir := filepath.Join(guestsDir, strconv.Itoa(in.VMID))
|
||||
if err := b.run(ctx, "chown", "--reference="+b.stateDir, guestsDir, vmidDir); err != nil {
|
||||
// Warn-only: the drill's manual fix is a one-liner and lanresolver degrades visibly.
|
||||
b.logger.Warn("provision: could not own guests parent dirs to the state-dir owner (F-3)",
|
||||
"err", err)
|
||||
}
|
||||
}
|
||||
bootPath := filepath.Join(hostDir, bootstrapFile)
|
||||
if err := os.WriteFile(bootPath, rendered, 0o600); err != nil {
|
||||
return Result{}, fmt.Errorf("provision: write bootstrap: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user