package activator import ( "path/filepath" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/registry" ) // instancePaths is every per-host path the exec backend touches, resolved // once per call by layout so that no method builds a path from DataDir and // the host on its own. Flat and foreign rows keep today's flat names; a // nested row's files live in its instance directory with the same names // (design ยง3.1). type instancePaths struct { layout Layout reason string dataDir string // the directory that holds the four files runDir string // the directory that holds app.sock and the control socket dbPath string envFile string sidecarEnv string configEnv string } // Layout is ExecBackend's Classifier implementation: the same // classification pathsFor already computes, exposed so doWake can check it // before Acquire or Restore ever run. func (b *ExecBackend) Layout(rt registry.Route) (Layout, string) { return Classify(rt, b.layoutInputs()) } func (b *ExecBackend) pathsFor(rt registry.Route) instancePaths { l, reason := Classify(rt, b.layoutInputs()) p := instancePaths{layout: l, reason: reason, dataDir: b.DataDir, runDir: provision.SocketDir} if l == LayoutNested { p.dataDir = provision.InstanceDir(b.DataDir, rt.Host) if b.RunDirOverride != "" { // Test-only: a test points the nested run dir at a temp dir // rather than /run/carlos, exactly as it points DataDir at one. p.runDir = filepath.Join(b.RunDirOverride, "instances", provision.InstanceID(rt.Host)) } else { p.runDir = provision.InstanceRunDir(rt.Host) } } p.dbPath = rt.DBPath if p.dbPath == "" { p.dbPath = provision.DefaultDBPath(b.DataDir, rt.Host) } p.envFile = filepath.Join(p.dataDir, rt.Host+".env") p.sidecarEnv = filepath.Join(p.dataDir, rt.Host+"-sidecar.env") p.configEnv = filepath.Join(p.dataDir, rt.Host+".config.env") return p } // layoutInputs is the backend's LayoutInputs with DataDir filled in. A // non-empty RunDirOverride also steers the socket dir Classify tests // against, so a route built against the override dir still classifies as // nested through Task 2's sockets() helper. func (b *ExecBackend) layoutInputs() LayoutInputs { in := b.LayoutFacts in.DataDir = b.DataDir if b.RunDirOverride != "" { in.SocketDir = b.RunDirOverride } return in }