A module's containers ran as whatever their image chose and shared folders were made writable by putting accounts in the folder's group (ADR 0312), which ADR 0325 supersedes. The engine now makes each declared module identity as a system account with the controller's numbers, runs a container declaring `identity` as it, and keeps each placed shared folder usable through one POSIX ACL entry per user, set through the kernel's xattrs on descriptors it opened itself. A folder holding data is kept only after the operator's warrant (the take act); a missing folder is made where its data lives and waits where its disk is not; root's data is never kept. A watch and a bounded sweep put back what an app narrows. The group grant is removed, and what it put an account in is taken back. Reuses the descriptor walks, the create act, the missing-path wait and the warrant- backed act message from the paused issue 567 branch.
62 lines
3.3 KiB
Go
62 lines
3.3 KiB
Go
package declaration
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
const anImage = "docker.io/library/x@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
// The fields ADR 0325 adds, read as the controller sends them (novox/hq ADR 0325 §2, §3, §5, issue 567).
|
|
func TestIdentitiesUsersAndARunAsAreReadAsSent(t *testing.T) {
|
|
d, err := Parse([]byte(`{"declaration":1,
|
|
"identities":[{"module":"radarr","name":"mesh-radarr","uid":61001,"gid":61001}],
|
|
"resources":[
|
|
{"id":"radarr.app","type":"container","name":"radarr","image":"` + anImage + `",
|
|
"identity":{"mode":"env","user_env":"PUID","group_env":"PGID","uid":61001,"gid":61001}},
|
|
{"id":"plex.app","type":"container","name":"plex","image":"` + anImage + `","identity":{"mode":"run","uid":61002,"gid":61002}},
|
|
{"id":"radarr.movies","type":"access","path":"/srv/media/movies","mode":"read-write","taken":true,
|
|
"users":[{"identity":"mesh-radarr","uid":61001,"use":"read-write","from":"container"},
|
|
{"identity":"nox","uid":61003,"use":"read","from":"tool-runner"}]},
|
|
{"id":"old.movies","type":"access","path":"/srv/media/movies","mode":"read-write","grant":{"account":"nox"}}]}`))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(d.Identities) != 1 || d.Identities[0].UID != 61001 {
|
|
t.Fatalf("identities: %+v", d.Identities)
|
|
}
|
|
if c := d.Resources[0].(*Container); c.RunAs == nil || c.RunAs.UserEnv != "PUID" {
|
|
t.Fatalf("a container's identity: %+v", c.RunAs)
|
|
}
|
|
if a := d.Resources[2].(*Access); !a.Taken || len(a.Users) != 2 || a.Users[1].From != FromToolRunner {
|
|
t.Fatalf("an access's users: %+v", a)
|
|
}
|
|
}
|
|
|
|
// What the engine refuses on arrival: a root number, an identity not named for its module, a field it does not
|
|
// know, a user that writes a read access, a variable set twice.
|
|
func TestWhatADeclarationMayNotSayOfAnIdentity(t *testing.T) {
|
|
for want, raw := range map[string]string{
|
|
"never root": `"identities":[{"module":"m","name":"mesh-m","uid":0,"gid":61001}],"resources":[]`,
|
|
"named mesh-<module>": `"identities":[{"module":"m","name":"m","uid":61001,"gid":61001}],` +
|
|
`"resources":[]`,
|
|
"is mesh-a's too": `"identities":[{"module":"a","name":"mesh-a","uid":61001,"gid":61001},` +
|
|
`{"module":"b","name":"mesh-b","uid":61001,"gid":61002}],"resources":[]`,
|
|
"unknown field": `"identities":[{"module":"m","name":"mesh-m","uid":61001,"gid":61001,"home":"/"}],` +
|
|
`"resources":[]`,
|
|
"writes an access declared read": `"resources":[{"id":"m.a","type":"access","path":"/srv/x","mode":"read",` +
|
|
`"users":[{"identity":"mesh-m","uid":61001,"use":"read-write","from":"container"}]}]`,
|
|
"uid 0": `"resources":[{"id":"m.a","type":"access","path":"/srv/x","users":[{"identity":"root","uid":0,` +
|
|
`"use":"read","from":"container"}]}]`,
|
|
"one value": `"resources":[{"id":"m.c","type":"container","name":"c","image":"` + anImage + `",` +
|
|
`"env":{"PUID":"1000"},"identity":{"mode":"env","user_env":"PUID","uid":61001,"gid":61001}}]`,
|
|
`"env" or "run"`: `"resources":[{"id":"m.c","type":"container","name":"c","image":"` + anImage + `",` +
|
|
`"identity":{"mode":"sudo","uid":61001,"gid":61001}}]`,
|
|
} {
|
|
_, err := Parse([]byte(`{"declaration":1,` + raw + `}`))
|
|
if err == nil || !strings.Contains(err.Error(), want) {
|
|
t.Errorf("want a refusal saying %q, got %v", want, err)
|
|
}
|
|
}
|
|
}
|