//go:build linux package apply import ( "context" "fmt" "path/filepath" "strings" "testing" "github.com/novox/mesh-host/internal/declaration" "github.com/novox/mesh-host/internal/store" ) // A container that reads a filled file and mounts a library whose disk is not there is held by the write verb as a // full apply holds it (novox/hq ADR 0328 ยง9, issue 668): never created or recreated over the missing disk. func TestAWriteDoesNotRecreateAContainerHeldForItsLibrary(t *testing.T) { // No folder is given the group: the library's root is absent, and nothing is made. gid := 61000 libraries(t, nil, nil) base := t.TempDir() root := filepath.Join(base, "gone", "media") env := filepath.Join(base, "radarr.env") raw := fmt.Sprintf(`{"declaration":1,"provisioner_account":"mesh-node-provisioner","filled_files":[%q], "groups":[{"name":"mesh-media","gid":%d}],"libraries":[%s],"resources":[ {"id":"radarr.env","type":"file","path":%q,"content":"","mode":"0600","owner-at-runtime":"owned"}, {"id":"radarr.app","type":"container","name":"radarr","image":%q,"env-file":[%q],"volumes":[%q]}]}`, env, gid, libJSON("media", root, gid, true, false, "movies"), env, pinned, env, filepath.Join(root, "movies")+":/movies") d, err := declaration.Parse([]byte(raw)) if err != nil { t.Fatal(err) } var ran []string run := func(_ context.Context, name string, args ...string) (string, error) { ran = append(ran, name+" "+strings.Join(args, " ")) return "", nil } var state store.State for _, content := range []string{"PORT=1\n", "PORT=2\n"} { var report Report report, state, err = WriteFilled(context.Background(), archHost(t), d, state, env, []byte(content), run, nil, nil, nil) if err != nil { t.Fatal(err) } if o := outcomeOf(report, "radarr.app"); o.Action != "waiting" { t.Errorf("after writing %q the container is %+v, not held for its library", content, o) } } for _, line := range ran { if strings.HasPrefix(line, "docker run") || strings.HasPrefix(line, "docker rm") { t.Errorf("the container was created or removed over a missing disk: %v", ran) } } }