mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
Composed first, an account a module puts in its daemon's group was put in a group the package had not made yet, and only the next apply healed it. An account that sets a shell or home still goes first (issue 213).
74 lines
3.2 KiB
Go
74 lines
3.2 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// One account, several modules: the shell's module sets its shell, the container runtime's adds it
|
|
// to a group. Groups are only ever added by the host, so they are contributed; a shell or a home is
|
|
// one value, owned by one module per node.
|
|
|
|
func userResource(fields map[string]any) map[string]any {
|
|
r := map[string]any{"id": "operator", "type": "user", "name": "op"}
|
|
for k, v := range fields {
|
|
r[k] = v
|
|
}
|
|
return r
|
|
}
|
|
|
|
func TestAShellAndAGroupOnOneAccountFromTwoModulesResolve(t *testing.T) {
|
|
zsh := Manifest{Module: "zsh", Resources: []map[string]any{userResource(map[string]any{"shell": "/usr/bin/zsh"})}}
|
|
docker := Manifest{Module: "docker", Resources: []map[string]any{userResource(map[string]any{"groups": []any{"docker"}})}}
|
|
other := Manifest{Module: "media", Resources: []map[string]any{userResource(map[string]any{"groups": []any{"video"}})}}
|
|
if problems := checkResources([]Manifest{zsh, docker, other}); len(problems) != 0 {
|
|
t.Fatalf("a shell and two modules' groups on one account were refused: %v", problems)
|
|
}
|
|
if _, err := Resolve(shelf(zsh, docker, other), []string{"zsh", "docker", "media"}, workstation(), World{}); err != nil {
|
|
t.Fatalf("the three did not resolve together: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestTwoModulesSettingOneAccountsShellOrHomeAreRefused(t *testing.T) {
|
|
for _, field := range []string{"shell", "home"} {
|
|
a := Manifest{Module: "zsh", Resources: []map[string]any{userResource(map[string]any{field: "/one"})}}
|
|
b := Manifest{Module: "fish", Resources: []map[string]any{userResource(map[string]any{field: "/two", "groups": []any{"x"}})}}
|
|
problems := checkResources([]Manifest{a, b})
|
|
want := `zsh and fish both set the ` + field + ` of the user "op"`
|
|
if len(problems) != 1 || !strings.Contains(problems[0], want) {
|
|
t.Errorf("two modules setting %s gave %v, want %q", field, problems, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// An account a module declares only to put in a group is applied where it is written, after the package
|
|
// that makes the group (novox/hq ADR 0252); one that says how it logs in still goes first (issue 213).
|
|
func TestAnAccountOnlyGivenGroupsKeepsItsWrittenPlace(t *testing.T) {
|
|
compose := func(raw string) []map[string]any {
|
|
t.Helper()
|
|
m, err := ParseManifest([]byte(raw))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
out, err := Resolution{Node: "workstation", Modules: []Manifest{m}}.Declaration(Rendering{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return out
|
|
}
|
|
out := compose(`{"module": "lights", "version": "1", "resources": [
|
|
{"id": "daemon", "type": "package", "package": "lights-daemon"},
|
|
{"id": "account", "type": "user", "name": "op", "groups": ["lights"]}
|
|
]}`)
|
|
if pkg, acct := indexOf(out, "lights.daemon"), indexOf(out, "lights.account"); pkg < 0 || acct < pkg {
|
|
t.Fatalf("the account (%d) is not after the package that makes its group (%d): %v", acct, pkg, out)
|
|
}
|
|
out = compose(`{"module": "shell", "version": "1", "resources": [
|
|
{"id": "package", "type": "package", "package": "zsh"},
|
|
{"id": "login", "type": "user", "name": "op", "shell": "/usr/bin/zsh", "groups": ["wheel"]}
|
|
]}`)
|
|
if pkg, acct := indexOf(out, "shell.package"), indexOf(out, "shell.login"); acct < 0 || acct > pkg {
|
|
t.Fatalf("an account with a shell is no longer first (%d, package %d): %v", acct, pkg, out)
|
|
}
|
|
}
|