Fill a preference's ${setting:} from its manifest default (hq ADR 0262)

Without a default, a running module could never gain a setting: the file asking for it
failed to compose until set, and the key was refused as stray until a file asked for it.
Defaults sit under the mesh's and the node's settings, never merge into a JSON file, are
refused for the operator's own values, and settings shows each value's source.
This commit is contained in:
jochen
2026-10-08 17:24:32 +02:00
parent 3f68a495f1
commit e41b78cd77
11 changed files with 470 additions and 13 deletions
+45 -3
View File
@@ -502,13 +502,38 @@ func settingsCommand(ctx context.Context, args []string) error {
}
if !has {
fmt.Printf("%s on %s: no layer — the module's definition says\n", positionals[0], where)
return nil
} else {
shown, err := json.MarshalIndent(values, "", " ")
if err != nil {
return err
}
fmt.Println(string(shown))
}
shown, err := json.MarshalIndent(values, "", " ")
// Every value the module gives a default or a layer sets, and where it came from (novox/hq
// ADR 0262): the default, the mesh's layer, or this node's. Said after the layer, which stays
// the first thing printed because a caller reads it before replacing it (ADR 0217).
known, err := inv.Catalogue(ctx)
if err != nil {
return err
}
fmt.Println(string(shown))
m, ok := known[positionals[0]]
if !ok || len(m.Settings) == 0 {
return nil
}
var layers []catalogue.Layer
if *node != "" {
if mesh, has, err := inv.Layer(ctx, "", positionals[0]); err != nil {
return err
} else if has {
layers = append(layers, catalogue.Layer{From: catalogue.MeshWideLayer, Values: mesh})
}
if has {
layers = append(layers, catalogue.Layer{From: *node, Values: values})
}
} else if has {
layers = append(layers, catalogue.Layer{From: catalogue.MeshWideLayer, Values: values})
}
fmt.Print(describeEffective(positionals[0], where, catalogue.Effective(m, layers)))
return nil
case "clear":
@@ -526,6 +551,23 @@ func settingsCommand(ctx context.Context, args []string) error {
}
}
// describeEffective says each setting's value on a machine or the whole mesh, where it came from, and
// the module's default when a layer overrides it.
func describeEffective(module, where string, values []catalogue.SettingSource) string {
var b strings.Builder
fmt.Fprintf(&b, "%s on %s, every value and where it comes from:\n", module, where)
for _, v := range values {
value, _ := json.Marshal(v.Value)
fmt.Fprintf(&b, " %s = %s (%s", v.Key, value, v.From)
if v.HasDefault && v.From != catalogue.DefaultLayer {
d, _ := json.Marshal(v.Default)
fmt.Fprintf(&b, "; the default is %s", d)
}
b.WriteString(")\n")
}
return b.String()
}
// nodeFlag is ` --node <node>` for a machine's layer, nothing for the whole mesh's.
func nodeFlag(node string) string {
if node == "" {
+1 -1
View File
@@ -1425,7 +1425,7 @@ func servedOnNode(ctx context.Context, inv *inventory.Inventory, node string,
}
serves := catalogue.ServedOn(m, provision, ports)
if len(serves) > 0 {
serves, err = catalogue.Settle(serves, layers)
serves, err = catalogue.Settle(serves, catalogue.WithDefaults(m, layers))
if err != nil {
return nil, err
}
@@ -0,0 +1,21 @@
package main
import (
"testing"
"github.com/novox/mesh-controller/internal/catalogue"
)
// `settings` says each value and where it came from, and the default a layer overrides (novox/hq ADR 0262).
func TestSettingsSayWhereEachValueComesFrom(t *testing.T) {
got := describeEffective("dunst", "laptop", []catalogue.SettingSource{
{Key: "font-size", Value: float64(13), From: "laptop", Default: float64(10), HasDefault: true},
{Key: "width", Value: float64(250), From: catalogue.DefaultLayer, Default: float64(250), HasDefault: true},
})
want := "dunst on laptop, every value and where it comes from:\n" +
" font-size = 13 (laptop; the default is 10)\n" +
" width = 250 (default)\n"
if got != want {
t.Fatalf("said\n%s\nwant\n%s", got, want)
}
}