Files
mesh-host/internal/apply/found_is_said_test.go
T
jochen ae1293e73e
mesh/merge-gate pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-host@7c046a8a1d84 (merged as d28ca959 into main, walk plan-17915049347305…
Read every runtime's data root, keep when a directory was found, and key a hand-over to its resource
The review of #64 asked for containerd's tree, dockerd's --data-root from its
unit and drop-ins, and podman's graphroot to be refused like docker's own
(hq issue 339); and the controller now tells a directory a send found from
one found before it, which needs the time it was first found kept across
applies instead of the time of the last apply. A hand-over now names the
resource it was for, so it lapses if another declaration points at the path.
2026-10-09 00:55:21 +02:00

139 lines
5.5 KiB
Go

package apply
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/novox/mesh-host/internal/store"
)
// A directory used as found is never quiet, and a person at the machine can hand it over (novox/hq issue 339).
func TestAFoundDirectoryIsSaidAndCanBeHandedOver(t *testing.T) {
dir := t.TempDir()
found := filepath.Join(dir, "found")
if err := os.Mkdir(found, 0o700); err != nil {
t.Fatal(err)
}
decl := `{"id":"notes.data","type":"directory","path":"` + found + `","mode":"0755"}`
var said []string
log := func(line string) { said = append(said, line) }
_, state, err := Apply(context.Background(), archHost(t), declare(t, decl), store.State{}, store.OriginDeclared,
noServices, log, nil)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(strings.Join(said, "\n"), "WARNING notes.data") {
t.Fatalf("the apply did not warn of a directory used as found: %q", said)
}
if a, _ := state.Find("notes.data"); !a.AsFound || !strings.Contains(a.Declared, "755") {
t.Fatalf("the record does not say what was declared: %+v", a)
}
// Said again at the next apply: a warning once is a warning missed.
said = nil
if _, state, err = Apply(context.Background(), archHost(t), declare(t, decl), state, store.OriginDeclared,
noServices, log, nil); err != nil {
t.Fatal(err)
}
if !strings.Contains(strings.Join(said, "\n"), "WARNING notes.data") {
t.Fatalf("the next apply did not warn again: %q", said)
}
// Handed over: the next apply gives it the declared mode and it is the mesh's.
before := HandedOver
HandedOver = func() map[string]bool { return map[string]bool{handOverKey("notes.data", found): true} }
t.Cleanup(func() { HandedOver = before })
if _, state, err = Apply(context.Background(), archHost(t), declare(t, decl), state, store.OriginDeclared,
noServices, nil, nil); err != nil {
t.Fatal(err)
}
if info, _ := os.Stat(found); info.Mode().Perm() != 0o755 {
t.Fatalf("a directory handed over was not given its declared mode: %o", info.Mode().Perm())
}
if a, _ := state.Find("notes.data"); a.AsFound {
t.Fatal("a directory handed over is still recorded as found")
}
}
// The review's additions to the guard: the spool, /opt, the container runtimes' data wherever the runtime keeps
// it, and an account's .ssh as an access or a mount, or as a directory anywhere but its own home.
func TestTheRuntimesDataAndAnySSHAreRefused(t *testing.T) {
cfg := filepath.Join(t.TempDir(), "daemon.json")
if err := os.WriteFile(cfg, []byte(`{"data-root":"/storage/docker"}`), 0o644); err != nil {
t.Fatal(err)
}
before := runtimeConfigs
runtimeConfigs = runtimeFiles{daemonJSON: cfg}
t.Cleanup(func() { runtimeConfigs = before })
for _, kind := range []placing{placingDirectory, placingAccess, placingMount} {
for _, path := range []string{"/var/spool/cron", "/opt/app", "/var/lib/docker/volumes/x",
"/var/lib/containers/storage", "/storage/docker", "/storage/docker/overlay2"} {
if err := refusePath(path, kind, "notes", ""); err == nil {
t.Errorf("%v at %s was taken", kind, path)
}
}
}
for _, path := range []string{"/srv/backup/.ssh", "/srv/backup/.ssh/keys"} {
for _, kind := range []placing{placingDirectory, placingAccess, placingMount} {
if err := refusePath(path, kind, "notes", ""); err == nil {
t.Errorf("%v at %s was taken", kind, path)
}
}
}
if err := refusePath("/storage/dockerish", placingAccess, "notes", ""); err != nil {
t.Errorf("a path beside the data root: %v", err)
}
}
// When a directory was found is kept from the first apply that found it (novox/hq issue 339): the controller
// tells a directory a send found from one found before it by that time, so it must not move with every apply.
func TestWhenADirectoryWasFoundIsKept(t *testing.T) {
dir := t.TempDir()
found := filepath.Join(dir, "found")
if err := os.Mkdir(found, 0o700); err != nil {
t.Fatal(err)
}
decl := `{"id":"notes.data","type":"directory","path":"` + found + `","mode":"0755"}`
_, state, err := Apply(context.Background(), archHost(t), declare(t, decl), store.State{}, store.OriginDeclared,
noServices, nil, nil)
if err != nil {
t.Fatal(err)
}
first, _ := state.Find("notes.data")
if first.FoundAt.IsZero() {
t.Fatal("no time the directory was found")
}
time.Sleep(10 * time.Millisecond)
_, state, err = Apply(context.Background(), archHost(t), declare(t, decl), state, store.OriginDeclared, noServices, nil, nil)
if err != nil {
t.Fatal(err)
}
if again, _ := state.Find("notes.data"); !again.FoundAt.Equal(first.FoundAt) {
t.Fatalf("found at %v, then %v: the time moved with the apply", first.FoundAt, again.FoundAt)
}
}
// A hand-over is for the resource that was used as found there: another declaration that later points another
// resource at the same path is not handed anything (novox/hq issue 339).
func TestAHandOverIsForTheResourceThatAskedForIt(t *testing.T) {
dir := t.TempDir()
found := filepath.Join(dir, "found")
if err := os.Mkdir(found, 0o700); err != nil {
t.Fatal(err)
}
before := HandedOver
HandedOver = func() map[string]bool { return map[string]bool{handOverKey("notes.data", found): true} }
t.Cleanup(func() { HandedOver = before })
other := `{"id":"other.data","type":"directory","path":"` + found + `","mode":"0755"}`
if _, _, err := Apply(context.Background(), archHost(t), declare(t, other), store.State{}, store.OriginDeclared,
noServices, nil, nil); err != nil {
t.Fatal(err)
}
if info, _ := os.Stat(found); info.Mode().Perm() != 0o700 {
t.Fatalf("a hand-over for notes.data gave other.data the directory: mode %o", info.Mode().Perm())
}
}