mesh/check failed: unit: clipmenu/cmd/clipmenu-tools.TestTheLauncherWaitsQuietlyWhileAnotherClipmenudHoldsTheLock: manifest_test.go:199: the launcher …
mesh/merge-gate head 098c6d3ec70f merged into trunk 2f05e70734cd — pass: builds pacman → ace, g14, novox, shanks; no bus step; every machine composes with …
mesh/repo-check head 098c6d3ec70f merged into trunk 2f05e70734cd — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
pacman's state directory said place ".", which resolves to /var/lib/pacman: the
package manager's database directory. The node-engine used it as found and
reported it unhealthy on every machine, and wrote keeper.json into it. It is now
the mesh's directory for the module (place "mesh", /var/lib/mesh/pacman), as
docker's is; keeper.json, the keeper's bus secret and the root helper's socket
follow through ${dir:state}.
checks/owned rule 5 refuses a directory that is, lies in or holds a /var/lib
directory a system package owns (checks/owned/system, read from shanks through
pacman_owns and tmpfiles.d), and any resource inside one. systemd and postgres
collide today and are listed in checks/owned/system-known under issue 1873; that
list only shrinks.
249 lines
9.9 KiB
Go
249 lines
9.9 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func manifest(t *testing.T, root, module, body string) {
|
|
t.Helper()
|
|
dir := filepath.Join(root, "modules", module)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(body), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func check(t *testing.T, root string) []Finding {
|
|
t.Helper()
|
|
if _, err := os.Stat(filepath.Join(root, SystemList)); os.IsNotExist(err) {
|
|
lists(t, root, "/var/lib/pacman pacman: pacman -Qo\n", "")
|
|
}
|
|
found, err := Check(root, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return found
|
|
}
|
|
|
|
// only asserts exactly one finding, of the rule, naming the module and the resource (issue 1024).
|
|
func only(t *testing.T, found []Finding, rule int, module, id string) {
|
|
t.Helper()
|
|
if len(found) != 1 || found[0].Rule != rule || found[0].Module != module || found[0].ID != id || found[0].Why == "" {
|
|
t.Fatalf("found %+v; want one finding of rule %d for %s/%s with a reason", found, rule, module, id)
|
|
}
|
|
}
|
|
|
|
// lists writes the catalogue's list of system directories and its known exceptions.
|
|
func lists(t *testing.T, root, system, known string) {
|
|
t.Helper()
|
|
if err := os.MkdirAll(filepath.Join(root, "checks", "owned"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, SystemList), []byte(system), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, SystemKnown), []byte(known), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func dir(id, path, rest string) string {
|
|
return `{"id":"` + id + `","type":"directory","path":"` + path + `"` + rest + `}`
|
|
}
|
|
|
|
func mod(name string, resources ...string) string {
|
|
return `{"module":"` + name + `","resources":[` + strings.Join(resources, ",") + `]}`
|
|
}
|
|
|
|
func TestMissingOrUnknownValueIsRefused(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a", dir("d", "/var/lib/a", "")))
|
|
only(t, check(t, root), 1, "a", "d")
|
|
|
|
root = t.TempDir()
|
|
manifest(t, root, "a", mod("a", `{"id":"z","type":"archive","path":"/opt/a","unknown":"delete"}`))
|
|
only(t, check(t, root), 1, "a", "z")
|
|
}
|
|
|
|
func TestMoveOutOutsideAHomeIsRefused(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a", dir("d", "/etc/a.d", `,"unknown":"move-out"`)))
|
|
only(t, check(t, root), 2, "a", "d")
|
|
}
|
|
|
|
func TestMoveOutUnderAHomeIsAllowed(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a",
|
|
dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out"`),
|
|
dir("e", "${dir:d}/sub", `,"unknown":"move-out"`),
|
|
dir("f", "${machine:agent-home}/x", `,"unknown":"move-out"`),
|
|
dir("g", "/var/lib/a", `,"unknown":"program"`),
|
|
dir("h", "${machine:account-home}/.ssh", `,"unknown":"module"`)))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("refused %+v", found)
|
|
}
|
|
}
|
|
|
|
func TestBadKnowsIsRefused(t *testing.T) {
|
|
for _, knows := range []string{`[""]`, `["/abs"]`, `["a/../b"]`, `["./a"]`, `["a//b"]`, `["a","a"]`, `["a","a/"]`} {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":`+knows)))
|
|
only(t, check(t, root), 3, "a", "d")
|
|
}
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":["forge.credentials","kept/"]`)))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("refused %+v", found)
|
|
}
|
|
}
|
|
|
|
func TestAnotherModulesPathInsideADirectoryIsRefused(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "owner", mod("owner", dir("ssh", "${machine:account-home}/.ssh", `,"unknown":"module"`)))
|
|
manifest(t, root, "intruder", mod("intruder", `{"id":"f","type":"file","path":"${machine:account-home}/.ssh/config.d/20"}`))
|
|
manifest(t, root, "viahome", mod("viahome", `{"id":"g","type":"file","path":"${machine:agent-home}/.ssh/x"}`))
|
|
manifest(t, root, "facty", `{"module":"facty","facts":{"hosts":{"path":".ssh/config.d/00","home":true}}}`)
|
|
manifest(t, root, "outside", mod("outside", `{"id":"o","type":"file","path":"${machine:account-home}/.sshrc"}`))
|
|
got := map[string]int{}
|
|
for _, f := range check(t, root) {
|
|
if f.Rule != 4 || f.Why == "" {
|
|
t.Fatalf("finding %+v", f)
|
|
}
|
|
got[f.Module]++
|
|
}
|
|
if len(got) != 3 || got["intruder"] != 1 || got["viahome"] != 1 || got["facty"] != 1 {
|
|
t.Fatalf("refused %v; want intruder, viahome, facty", got)
|
|
}
|
|
}
|
|
|
|
func TestDirReferencesAreResolvedPerModule(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "owner", mod("owner", dir("base", "${machine:account-home}/.config/o", `,"unknown":"move-out"`)))
|
|
manifest(t, root, "other", mod("other",
|
|
dir("base", "${machine:account-home}/.config/p", `,"unknown":"move-out"`),
|
|
`{"id":"f","type":"file","path":"${dir:base}/x"}`))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("refused %+v", found)
|
|
}
|
|
manifest(t, root, "third", mod("third",
|
|
dir("d", "${machine:account-home}/.config/t", `,"unknown":"move-out"`),
|
|
`{"id":"f","type":"file","path":"${dir:d}/../o/x"}`))
|
|
only(t, check(t, root), 4, "third", "f")
|
|
}
|
|
|
|
func TestAnArchiveIsNotAContainerAndSameModuleIsFine(t *testing.T) {
|
|
root := t.TempDir()
|
|
manifest(t, root, "a", mod("a",
|
|
`{"id":"arc","type":"archive","path":"/opt/a","unknown":"program"}`,
|
|
dir("d", "/opt/a2", `,"unknown":"program"`),
|
|
`{"id":"f","type":"file","path":"/opt/a2/x"}`))
|
|
manifest(t, root, "b", mod("b", `{"id":"f","type":"file","path":"/opt/a/x"}`))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("refused %+v", found)
|
|
}
|
|
}
|
|
|
|
// Issue 1484: a directory the mesh places for a module (no path, `place`) is that module's own: another module's
|
|
// directory of the same id, and a path under it, are not inside it.
|
|
func TestPlacedDirectoriesOfTwoModulesAreTheirOwn(t *testing.T) {
|
|
root := t.TempDir()
|
|
for _, name := range []string{"first", "second"} {
|
|
manifest(t, root, name, mod(name,
|
|
`{"id":"state","type":"directory","place":".","unknown":"program"}`,
|
|
dir("ssh", "${dir:state}/.ssh", `,"unknown":"program"`),
|
|
`{"id":"conf","type":"file","path":"${dir:ssh}/config"}`))
|
|
}
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("refused %+v", found)
|
|
}
|
|
}
|
|
|
|
// 1841/AC18: a module's directory that resolves to a /var/lib directory a system package owns, lies inside one or
|
|
// holds one, is refused, whether placed (place ".", or by default beneath the module's own) or stated; a placed
|
|
// directory saying place "mesh" lies under /var/lib/mesh and passes (issue 1841: pacman's state was /var/lib/pacman).
|
|
func TestADirectoryOfASystemPackageIsRefused(t *testing.T) {
|
|
system := "/var/lib/pacman pacman: pacman -Qo\n/var/lib/systemd/coredump systemd: tmpfiles.d/systemd.conf\n"
|
|
for name, resources := range map[string][]string{
|
|
"placed-own": {`{"id":"state","type":"directory","place":".","unknown":"program"}`},
|
|
"placed-beneath": {`{"id":"coredump","type":"directory","unknown":"program"}`},
|
|
"stated-inside": {dir("d", "/var/lib/pacman/keeper", `,"unknown":"program"`)},
|
|
"stated-holding": {dir("d", "/var/lib/systemd", `,"unknown":"program"`)},
|
|
"file-inside": {`{"id":"state","type":"directory","place":"mesh","unknown":"program"}`,
|
|
`{"id":"f","type":"file","path":"/var/lib/pacman/keeper.json"}`},
|
|
} {
|
|
module := map[string]string{"placed-own": "pacman", "placed-beneath": "systemd"}[name]
|
|
if module == "" {
|
|
module = "keeper"
|
|
}
|
|
root := t.TempDir()
|
|
lists(t, root, system, "")
|
|
manifest(t, root, module, mod(module, resources...))
|
|
found := check(t, root)
|
|
if len(found) != 1 || found[0].Rule != 5 || found[0].Module != module ||
|
|
!strings.Contains(found[0].Why, "/var/lib/") || !strings.Contains(found[0].Why, "package") {
|
|
t.Errorf("%s: found %+v; want one finding of rule 5 for %s naming the path and the package", name, found, module)
|
|
}
|
|
}
|
|
root := t.TempDir()
|
|
lists(t, root, system, "")
|
|
manifest(t, root, "pacman", mod("pacman",
|
|
`{"id":"state","type":"directory","place":"mesh","unknown":"program"}`,
|
|
`{"id":"f","type":"file","path":"${dir:state}/keeper.json"}`,
|
|
dir("other", "/var/lib/pacman-other", `,"unknown":"program"`)))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("a directory under /var/lib/mesh/pacman was refused: %+v", found)
|
|
}
|
|
}
|
|
|
|
// 1841/AC18: a known exception passes; one that no longer collides is refused, so the list only shrinks; one the trunk's
|
|
// copy does not hold is refused; and an absent list of system directories fails the check rather than passing it.
|
|
func TestKnownSystemExceptionsOnlyShrink(t *testing.T) {
|
|
system := "/var/lib/systemd systemd: tmpfiles.d/systemd.conf\n"
|
|
known := "# comment\nsystemd state issue 1873\n"
|
|
root := t.TempDir()
|
|
lists(t, root, system, known)
|
|
manifest(t, root, "systemd", mod("systemd", `{"id":"state","type":"directory","place":".","unknown":"program"}`))
|
|
if found := check(t, root); len(found) != 0 {
|
|
t.Fatalf("a known exception was refused: %+v", found)
|
|
}
|
|
if found, err := Check(root, []string{"systemd state issue 1873"}); err != nil || len(found) != 0 {
|
|
t.Fatalf("a known exception held by the trunk was refused: %+v %v", found, err)
|
|
}
|
|
if found, err := Check(root, []string{}); err != nil || len(found) != 1 || found[0].Rule != 5 {
|
|
t.Fatalf("an exception the trunk does not hold passed: %+v %v", found, err)
|
|
}
|
|
|
|
manifest(t, root, "systemd", mod("systemd", `{"id":"state","type":"directory","place":"mesh","unknown":"program"}`))
|
|
only(t, check(t, root), 5, "systemd", "state")
|
|
|
|
root = t.TempDir()
|
|
manifest(t, root, "a", mod("a"))
|
|
if err := os.MkdirAll(filepath.Join(root, "checks", "owned"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, SystemList), []byte("# nothing\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := Check(root, nil); err == nil {
|
|
t.Fatal("an empty list of system directories passed")
|
|
}
|
|
}
|
|
|
|
// 1841/AC18: the catalogue as it stands passes rule 5 with its own lists.
|
|
func TestTheCatalogueKeepsOutOfSystemDirectories(t *testing.T) {
|
|
found, err := Check("../..", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, f := range found {
|
|
if f.Rule == 5 {
|
|
t.Errorf("%s: %s: %s", f.Module, f.ID, f.Why)
|
|
}
|
|
}
|
|
}
|