Own directories of a joining module carry setgid, to an engine that takes it (hq ADR 0334 v4)

This commit is contained in:
2026-10-13 00:31:54 +02:00
parent 96e15f8693
commit 1de9bbc448
4 changed files with 29 additions and 11 deletions
+13 -5
View File
@@ -424,8 +424,8 @@ func toolsDirectoryProblems(m Manifest) []string {
}
if n&0o050 != 0o050 {
problems = append(problems, fmt.Sprintf("%s's tools name its directory %s, whose mode %s closes it to its "+
"own group: the tool runner reads it through that group, so it needs group read and enter (0750) "+
"(novox/hq ADR 0334 §3)", m.Module, id, mode))
"own group: the tool runner reads it through that group, so it needs group read and enter (0750; "+
"the mesh adds setgid, 2750) (novox/hq ADR 0334 §3)", m.Module, id, mode))
}
}
}
@@ -619,7 +619,7 @@ func identityFill(s string, j Joined) string {
// joinedInto composes one resource of a joining module (§4, §5, §10): ${identity:…} filled everywhere, a container's
// ${library:<id>} volume sources filled with the host path and a read entry mounted read-only, and a directory owned by
// the module's user and primary group.
func joinedInto(resource map[string]any, m Manifest, j Joined, paths map[string]string) error {
func joinedInto(resource map[string]any, m Manifest, j Joined, paths map[string]string, setgid bool) error {
for k, v := range resource {
if k == "id" || k == "type" {
continue
@@ -630,10 +630,18 @@ func joinedInto(resource map[string]any, m Manifest, j Joined, paths map[string]
}
resource[k] = filled
}
// Its own directories belong to its user and its own group (ADR 0334 §1): the library's group is its processes'
// primary, so what they make in a library keeps that group, and its own data stays its own.
// Its own directories belong to its user and its own group, with setgid (ADR 0334 §1, v4): the library's group is
// its processes' primary, so what they make in a library keeps that group — and what they make in their own
// directories keeps mesh-<module> by the setgid bit. The bit only to an engine that takes a mode with it
// (Rendering.RunnerJoinsOwnGroups, link.OwnGroupContract): the one pinned refuses a mode not starting with 0.
if fmt.Sprint(resource["type"]) == "directory" {
resource["owner"] = fmt.Sprintf("%d:%d", j.UID, j.UID)
if mode, ok := resource["mode"].(string); ok && setgid {
var n uint64
if _, err := fmt.Sscanf(mode, "%o", &n); err == nil && mode != "" {
resource["mode"] = fmt.Sprintf("%04o", n|0o2000)
}
}
}
if fmt.Sprint(resource["type"]) != "container" {
return nil