Say a layer whole where the mesh reports it, and give tests their placement (issue 651)
The facts snapshot, the take preview and the settings history read a layer as it was set; tests that place give the layer through LayerOf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -424,8 +424,9 @@ func comparisonOf(module string, c comparison, opts takeOptions) (preview string
|
||||
}
|
||||
// And its settings on this machine, composed against its definition (rule 1, rule 6).
|
||||
for _, layer := range c.layers {
|
||||
keys := make([]string, 0, len(layer.Values))
|
||||
for k := range layer.Values {
|
||||
said := layer.Whole()
|
||||
keys := make([]string, 0, len(said))
|
||||
for k := range said {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
@@ -348,11 +348,11 @@ func gatherFacts(ctx context.Context, open *stores, busVersion string) (snapshot
|
||||
if layer.From == catalogue.MeshWideLayer {
|
||||
if !meshWide[module] {
|
||||
meshWide[module] = true
|
||||
f.Settings = append(f.Settings, snapshot.Settings{Module: module, Values: scrub.Values(layer.Values)})
|
||||
f.Settings = append(f.Settings, snapshot.Settings{Module: module, Values: scrub.Values(layer.Whole())})
|
||||
}
|
||||
continue
|
||||
}
|
||||
m.Settings = append(m.Settings, snapshot.Settings{Module: module, Values: scrub.Values(layer.Values)})
|
||||
m.Settings = append(m.Settings, snapshot.Settings{Module: module, Values: scrub.Values(layer.Whole())})
|
||||
}
|
||||
}
|
||||
m.Declaration = declarationFacts(ctx, open, n.Name, gens, gensErr, scrub)
|
||||
|
||||
@@ -33,7 +33,21 @@ import (
|
||||
func aMesh(t *testing.T) *stores {
|
||||
t.Helper()
|
||||
inventory.ForTest(t) // raises the store, migrates it, and points the environment at it
|
||||
licences.ForTest(t) // planning reaches this one too, by name and never by connection
|
||||
return aMeshOnTheStore(t)
|
||||
}
|
||||
|
||||
// aMeshBefore is aMesh on a store migrated only below migration `number`, with the function that runs the
|
||||
// rest: for a test of what a migration that moves data does to what the mesh composes (novox/hq issue 651).
|
||||
func aMeshBefore(t *testing.T, number int) (*stores, func()) {
|
||||
t.Helper()
|
||||
_, migrate := inventory.ForTestBefore(t, number)
|
||||
return aMeshOnTheStore(t), migrate
|
||||
}
|
||||
|
||||
// aMeshOnTheStore is the mesh aMesh makes, on the store the environment points at.
|
||||
func aMeshOnTheStore(t *testing.T) *stores {
|
||||
t.Helper()
|
||||
licences.ForTest(t) // planning reaches this one too, by name and never by connection
|
||||
|
||||
open, err := openStores(t.Context())
|
||||
if err != nil {
|
||||
|
||||
@@ -537,6 +537,10 @@ func settingsCommand(ctx context.Context, args []string) error {
|
||||
if p.SetBy != "" {
|
||||
by = "; " + p.SetBy
|
||||
}
|
||||
if p.Why != "" {
|
||||
// A layer whose placement moved out of it (migration 0097): still the layer, as it stands.
|
||||
by += "; " + p.Why
|
||||
}
|
||||
fmt.Printf("%s on %s, until %s (%s%s):\n %s\n", positionals[0], where,
|
||||
p.ReplacedAt.Local().Format("2006-01-02 15:04:05"), p.ReplacedBy, by, shown)
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestTheBackupHoldersLinesAreDerivedFromTheData(t *testing.T) {
|
||||
{"id":"meta","path":"${dir:meta}","class":"rebuildable"}]},
|
||||
"resources":[{"id":"meta","type":"directory","mode":"0700"}]}`)
|
||||
facts := map[string]string{"account-home": "/home/op"}
|
||||
with := Rendering{Settings: SettingsBy{"media": {{From: "node", Values: map[string]any{AccessesSetting: map[string]any{"films": "/tank/films"}}}}}}
|
||||
with := Rendering{Settings: SettingsBy{"media": {LayerOf("node", map[string]any{AccessesSetting: map[string]any{"films": "/tank/films"}})}}}
|
||||
backup, _, err := seatContributions([]Manifest{pg, agent, media}, Manifest{}, BackupSeat+":"+BackupKindBackup, with, facts, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -427,7 +427,7 @@ func TestALeftOutModulesUnplaceableBackupLineCostsOnlyThatLine(t *testing.T) {
|
||||
r := anAdoptedAnchor()
|
||||
r.Modules = append(r.Modules, holder, media, placedBadly)
|
||||
with := anchorRendering(false)
|
||||
with.Settings["notes"] = []Layer{{From: "anchor", Values: map[string]any{PlacesSetting: "not a map"}}}
|
||||
with.Settings["notes"] = []Layer{LayerOf("anchor", map[string]any{PlacesSetting: "not a map"})}
|
||||
composed, err := r.Compose(with)
|
||||
if err != nil {
|
||||
t.Fatalf("an unplaceable line of a left-out module failed the machine: %v", err)
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestASettingThatCannotComposeIsRefusedByNameAndLeavesOnlyItsModuleOut(t *te
|
||||
if c.name == "a mesh-wide port" {
|
||||
from = MeshWideLayer
|
||||
}
|
||||
err := JudgeSettings(web, []Layer{{From: from, Values: c.layer}}, true)
|
||||
err := JudgeSettings(web, []Layer{LayerOf(from, c.layer)}, true)
|
||||
if err == nil || !strings.Contains(err.Error(), c.refuse) {
|
||||
t.Errorf("%s: judged %v, want %q", c.name, err, c.refuse)
|
||||
}
|
||||
@@ -69,8 +69,8 @@ func TestASettingThatCannotComposeIsRefusedByNameAndLeavesOnlyItsModuleOut(t *te
|
||||
// declaration as the networks it also joins.
|
||||
func TestAKeptNetworkReachesTheContainerOnAnAdoptedMachineOnly(t *testing.T) {
|
||||
r := anAdoptedAnchor()
|
||||
keep := SettingsBy{"hello-web": {{From: "anchor",
|
||||
Values: map[string]any{NetworksSetting: map[string]any{"server": []any{"predecessor_default"}}}}}}
|
||||
keep := SettingsBy{"hello-web": {LayerOf("anchor",
|
||||
map[string]any{NetworksSetting: map[string]any{"server": []any{"predecessor_default"}}})}}
|
||||
|
||||
with := anchorRendering(true)
|
||||
with.Settings = keep
|
||||
@@ -107,13 +107,13 @@ func TestAKeptNetworkReachesTheContainerOnAnAdoptedMachineOnly(t *testing.T) {
|
||||
layer Layer
|
||||
want string
|
||||
}{
|
||||
{"mesh-wide", Layer{From: MeshWideLayer, Values: map[string]any{NetworksSetting: map[string]any{"server": []any{"x"}}}},
|
||||
{"mesh-wide", LayerOf(MeshWideLayer, map[string]any{NetworksSetting: map[string]any{"server": []any{"x"}}}),
|
||||
"a found network is a fact about one machine"},
|
||||
{"an unknown container", Layer{From: "anchor", Values: map[string]any{NetworksSetting: map[string]any{"db": []any{"x"}}}},
|
||||
{"an unknown container", LayerOf("anchor", map[string]any{NetworksSetting: map[string]any{"db": []any{"x"}}}),
|
||||
`names the container "db", which it does not declare`},
|
||||
{"not a list", Layer{From: "anchor", Values: map[string]any{NetworksSetting: map[string]any{"server": "x"}}},
|
||||
{"not a list", LayerOf("anchor", map[string]any{NetworksSetting: map[string]any{"server": "x"}}),
|
||||
"is a list of network names"},
|
||||
{"not a network name", Layer{From: "anchor", Values: map[string]any{NetworksSetting: map[string]any{"server": []any{"a/b"}}}},
|
||||
{"not a network name", LayerOf("anchor", map[string]any{NetworksSetting: map[string]any{"server": []any{"a/b"}}}),
|
||||
"which is not a network name"},
|
||||
} {
|
||||
_, err := KeptNetworks(web, []Layer{c.layer}, true)
|
||||
|
||||
@@ -13,22 +13,22 @@ func TestAPlacementOrAnAccessAtTheMachinesOwnIsRefused(t *testing.T) {
|
||||
for _, path := range []string{"/", "/etc", "/etc/", "/etc/sudoers.d", "/usr/bin", "/root", "/var", "/var/lib",
|
||||
"/home", "/home/", "/run", "/run/user/1000", "/var/lib/mesh/x", "/var/lib/mesh-host", "/var/lib/mesh-host/identity",
|
||||
"/srv/../etc", "//etc", "/proc/1", "/sys", "/dev", "/boot/efi", "/bin", "/sbin", "/lib", "/lib64"} {
|
||||
layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}}
|
||||
layers := []Layer{LayerOf("laptop", map[string]any{PlacesSetting: map[string]any{"data": path}})}
|
||||
if _, err := Places(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") {
|
||||
t.Errorf("a place at %s: %v", path, err)
|
||||
}
|
||||
layers = []Layer{{From: "laptop", Values: map[string]any{AccessesSetting: map[string]any{"media": path}}}}
|
||||
layers = []Layer{LayerOf("laptop", map[string]any{AccessesSetting: map[string]any{"media": path}})}
|
||||
if _, err := AccessPlaces(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") {
|
||||
t.Errorf("an access at %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
for _, path := range []string{"/srv/notes", "/mnt/plex/data", "/storage/media", "/services/media/movies",
|
||||
"/var/lib/notes/data", "/home/restic/repo", "/var/lib/mesh-store"} {
|
||||
layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}}
|
||||
layers := []Layer{LayerOf("laptop", map[string]any{PlacesSetting: map[string]any{"data": path}})}
|
||||
if got, err := Places(m, layers); err != nil || got["data"].Path != path {
|
||||
t.Errorf("a place at %s: %v %v", path, got, err)
|
||||
}
|
||||
layers = []Layer{{From: "laptop", Values: map[string]any{AccessesSetting: map[string]any{"media": path}}}}
|
||||
layers = []Layer{LayerOf("laptop", map[string]any{AccessesSetting: map[string]any{"media": path}})}
|
||||
if got, err := AccessPlaces(m, layers); err != nil || got["media"] != path {
|
||||
t.Errorf("an access at %s: %v %v", path, got, err)
|
||||
}
|
||||
@@ -111,17 +111,17 @@ func TestTheRuntimesDataAndAnyHomesSSHAreTheMachinesOwn(t *testing.T) {
|
||||
for _, path := range []string{"/var/spool", "/var/spool/cron", "/var/lib/docker", "/var/lib/docker/volumes",
|
||||
"/var/lib/containers/storage", "/var/lib/containerd", "/var/lib/containerd/io.containerd.snapshotter.v1", "/opt", "/opt/app", "/home/alice/.ssh", "/home/alice/.ssh/keys",
|
||||
"/srv/backup/.ssh", "/root/.ssh"} {
|
||||
layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}}
|
||||
layers := []Layer{LayerOf("laptop", map[string]any{PlacesSetting: map[string]any{"data": path}})}
|
||||
if _, err := Places(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") {
|
||||
t.Errorf("a place at %s: %v", path, err)
|
||||
}
|
||||
layers = []Layer{{From: "laptop", Values: map[string]any{AccessesSetting: map[string]any{"media": path}}}}
|
||||
layers = []Layer{LayerOf("laptop", map[string]any{AccessesSetting: map[string]any{"media": path}})}
|
||||
if _, err := AccessPlaces(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") {
|
||||
t.Errorf("an access at %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
for _, path := range []string{"/var/lib/dockerish", "/home/alice/ssh", "/home/alice/.sshd-notes", "/storage/media"} {
|
||||
layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}}
|
||||
layers := []Layer{LayerOf("laptop", map[string]any{PlacesSetting: map[string]any{"data": path}})}
|
||||
if _, err := Places(m, layers); err != nil {
|
||||
t.Errorf("a place at %s: %v", path, err)
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -61,3 +61,6 @@
|
||||
./cmd/mesh-controller TestAProviderElsewhereServesItsOwnComposedName
|
||||
./cmd/mesh-controller TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne
|
||||
./internal/inventory TestAReportOfABusyContainerIsKeptAndReadBack
|
||||
./internal/inventory TestPlacementMovesOutOfTheSettingsLayers
|
||||
./internal/inventory TestASettingRoutesPlacementBesideTheLayer
|
||||
./cmd/mesh-controller TestADeclarationIsTheSameAfterPlacementMoves
|
||||
|
||||
Reference in New Issue
Block a user