mesh/delivery-group group feat/sdk1 rejected: composed together: the checker's verdict at the members' heads (428d048dd50a): unit: git.novox.be/novox/mesh-sdk/…
mesh/delivery closed: a newer head of the same pull request
mesh/check failed: unit: git.novox.be/novox/mesh-sdk/go/process.TestStatePutWritesAKeyWhole: a Put through a short blackout: 0, mesh-mail's state send…
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
62 lines
2.8 KiB
Go
62 lines
2.8 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A bind mount the module never declared is refused where it is written (novox/hq 04-ISSUES/026,
|
|
// ADR 0091). The container runtime creates a missing bind source itself, as root, with a mode it
|
|
// picks, so the module's own owner and mode never reach the directory holding its data, and the
|
|
// rule that keeps data when a module goes away (ADR 0030) does not cover it.
|
|
|
|
const aContainerMounting = `{"id":"server","type":"container","name":"store","image":"x@sha256:` +
|
|
`0000000000000000000000000000000000000000000000000000000000000000","volumes":["%s:/inside"]}`
|
|
|
|
func manifestMounting(from string, beside string) []byte {
|
|
res := aContainerMounting
|
|
if beside != "" {
|
|
res = beside + "," + res
|
|
}
|
|
return []byte(`{"module":"store","resources":[` + strings.Replace(res, "%s", from, 1) + `]}`)
|
|
}
|
|
|
|
// Declaring it is enough — including declaring the directory above it.
|
|
func TestAMountUnderADeclaredDirectoryIsAccepted(t *testing.T) {
|
|
_, err := decodeForTest(manifestMounting("/services/store/data",
|
|
`{"id":"state","type":"directory","path":"/services/store","mode":"0700"}`))
|
|
if err != nil {
|
|
t.Fatalf("a module that said where its data lives was refused anyway: %v", err)
|
|
}
|
|
}
|
|
|
|
// The operator's path, granted for use (ADR 0051), is declared by `accesses`, not by a directory the
|
|
// module would then own.
|
|
func TestAMountOfAnAccessedPathIsAccepted(t *testing.T) {
|
|
_, err := decodeForTest([]byte(`{"module":"store","accesses":[{"path":"/services/media/movies","mode":"read"}],` +
|
|
`"resources":[` + strings.Replace(aContainerMounting, "%s", "/services/media/movies", 1) + `]}`))
|
|
if err != nil {
|
|
t.Fatalf("a mount of a path the module declares it accesses was refused: %v", err)
|
|
}
|
|
}
|
|
|
|
// Where a bound fact lands is the mesh's file too, and a container may mount it directly.
|
|
func TestAMountOfABoundFactIsAccepted(t *testing.T) {
|
|
_, err := decodeForTest([]byte(`{"module":"store","requires":["model-access"],` +
|
|
`"binds":{"model-access":"/var/lib/store/model.json"},"resources":[` +
|
|
strings.Replace(aContainerMounting, "%s", "/var/lib/store/model.json", 1) + `]}`))
|
|
if err != nil {
|
|
t.Fatalf("a mount of the file the mesh writes a binding to was refused: %v", err)
|
|
}
|
|
}
|
|
|
|
// The file a filter module's rule set is written to is declared by `filtering.into` (novox/hq ADR
|
|
// 0169): the module's runtime mounts it to reload the mesh's own table, and nothing else declares it.
|
|
func TestAMountOfTheFilterFileIsDeclaredByFilteringInto(t *testing.T) {
|
|
_, err := decodeForTest([]byte(`{"module":"nftables","filtering":{"into":"/etc/nftables.conf"},` +
|
|
`"resources":[` + strings.Replace(aContainerMounting, "%s", "/etc/nftables.conf", 1) + `]}`))
|
|
if err != nil {
|
|
t.Fatalf("a filter module mounting its own filter file was refused: %v", err)
|
|
}
|
|
}
|