A process runs its own bundle's binary, written ./name (hq ADR 0193)

A bundle compiled to a binary runs itself, but only the host knows where it unpacked it, and the
service manager takes no path relative to the working directory. A command written ./name is that
file in the process's own unpacked bundle, made absolute in the unit.
This commit is contained in:
jochen
2026-10-03 21:13:55 +02:00
parent 195fc63f6a
commit b7ede83c8c
2 changed files with 26 additions and 1 deletions
+13 -1
View File
@@ -214,7 +214,7 @@ func unitFor(r *declaration.Process) string {
if r.User != "" {
fmt.Fprintf(&b, "User=%s\n", r.User)
}
fmt.Fprintf(&b, "ExecStart=%s\n", strings.Join(r.Run, " "))
fmt.Fprintf(&b, "ExecStart=%s\n", strings.Join(runFrom(r), " "))
if r.Schedule != "" {
// Started by its timer and expected to finish. Restarting it would have it run
// continuously between fires, which is the opposite of a schedule.
@@ -346,3 +346,15 @@ func removeProcess(ctx context.Context, a store.Applied, run Runner) (string, st
}
return "removed", "stopped; its unit and its bundle removed — the mesh's own code", nil
}
// runFrom is the command as the unit runs it. **A command written `./name` is that file in the
// process's own unpacked bundle** (novox/hq ADR 0193): a bundle compiled to a binary runs itself,
// and only the host knows where it unpacked it, while the service manager takes an absolute path or
// a name it finds on its own search path — never one relative to the working directory.
func runFrom(r *declaration.Process) []string {
run := append([]string(nil), r.Run...)
if len(run) > 0 && strings.HasPrefix(run[0], "./") {
run[0] = filepath.Join(daemonRoot, r.Name, strings.TrimPrefix(run[0], "./"))
}
return run
}