//go:build linux && rootrunner package host import ( "context" "errors" "fmt" "os" "os/exec" "path/filepath" "strings" "syscall" "testing" "time" "github.com/carlosframework/platform/internal/activator" "github.com/carlosframework/platform/internal/registry" "github.com/carlosframework/platform/internal/release" ) func TestPlan14GenerationBackendInstalledRootRunner(t *testing.T) { dir := generationRootRunnerDir(t) pid1, err := os.ReadFile("/proc/1/comm") if err != nil || strings.TrimSpace(string(pid1)) != "systemd" { t.Fatal("designated runner requires systemd as PID 1") } for _, name := range []string{"data", "run", "opt/live", "opt/versions/v1"} { if err := os.MkdirAll(filepath.Join(dir, name), 0755); err != nil { t.Fatal(err) } } for _, name := range []string{"data", "run"} { if err := os.Chown(filepath.Join(dir, name), 65534, 65534); err != nil { t.Fatal(err) } } probe := filepath.Join(dir, "opt/write-probe") if err := os.WriteFile(probe, nil, 0600); err != nil { t.Fatal(err) } if err := os.Chown(probe, 65534, 65534); err != nil { t.Fatal(err) } binary, err := os.Executable() if err != nil { t.Fatal(err) } raw, err := os.ReadFile(binary) if err != nil { t.Fatal(err) } installed := filepath.Join(dir, "runner.test") if err := os.WriteFile(installed, raw, 0755); err != nil { t.Fatal(err) } artifact := filepath.Join(dir, "opt/versions/v1/app") script := fmt.Sprintf("#!/bin/sh\nprintf 'executed' > '%s'\n", filepath.Join(dir, "data/executed")) if err := os.WriteFile(artifact, []byte(script), 0755); err != nil { t.Fatal(err) } if err := os.Symlink(artifact, filepath.Join(dir, "opt/live/worker.example")); err != nil { t.Fatal(err) } raw, err = unitsFS.ReadFile("units/carlos-edge.service") if err != nil { t.Fatal(err) } ctl := func(ctx context.Context, args ...string) (string, error) { ctx, cancel := context.WithTimeout(ctx, 45*time.Second) defer cancel() out, err := exec.CommandContext(ctx, "systemctl", args...).CombinedOutput() return strings.TrimSpace(string(out)), err } for _, mode := range []string{"off", "on"} { t.Run(mode, func(t *testing.T) { unit := filepath.Base(dir) + "-backend-" + mode + ".service" var lines []string for _, line := range strings.Split(string(raw), "\n") { key, _, _ := strings.Cut(line, "=") switch key { case "Requires", "After", "Wants", "ExecStart", "ExecReload", "EnvironmentFile", "User", "Group", "Restart", "Slice": continue case "ReadWritePaths": line = "ReadWritePaths=" + filepath.Join(dir, "data") + " " + filepath.Join(dir, "run") } lines = append(lines, line) } // Test plumbing replaces identity, dependencies and entrypoint only. // The generated agent's hardening and delegation remain in force. content := strings.Join(lines, "\n") + fmt.Sprintf("\n[Service]\nUser=65534\nGroup=65534\nType=oneshot\nRestart=no\nTimeoutStartSec=45s\nExecStart=%s -test.run=^TestPlan14GenerationBackendUnitPayload$ -test.v -test.timeout=30s\nEnvironment=PLAN14_E40_UNIT=%s PLAN14_E40_MODE=%s\nIPAddressDeny=any\n", installed, dir, mode) path := filepath.Join("/run/systemd/system", unit) file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) if err != nil { t.Fatal(err) } t.Cleanup(func() { if out, err := ctl(context.Background(), "stop", unit); err != nil { t.Errorf("stop: %v %s", err, out) } _, _ = ctl(context.Background(), "reset-failed", unit) if err := os.Remove(path); err != nil { t.Error(err) } if out, err := ctl(context.Background(), "daemon-reload"); err != nil { t.Errorf("reload: %v %s", err, out) } }) _, writeErr := file.WriteString(content) if err := errors.Join(writeErr, file.Close()); err != nil { t.Fatal(err) } for _, args := range [][]string{{"daemon-reload"}, {"start", unit}} { if out, err := ctl(t.Context(), args...); err != nil { logs, _ := exec.CommandContext(t.Context(), "journalctl", "-u", unit, "--no-pager", "-n", "60").CombinedOutput() t.Fatalf("systemctl %v: %v %s\n%s", args, err, out, logs) } } for prop, want := range map[string]string{"Result": "success", "ExecMainStatus": "0"} { if got, err := ctl(t.Context(), "show", unit, "--property="+prop, "--value"); err != nil || got != want { t.Fatalf("%s: %q %v", prop, got, err) } } }) } } func TestPlan14GenerationBackendUnitPayload(t *testing.T) { dir, mode := os.Getenv("PLAN14_E40_UNIT"), os.Getenv("PLAN14_E40_MODE") if dir == "" || (mode != "on" && mode != "off") || os.Geteuid() != 65534 { t.Fatal("invoke through TestPlan14GenerationBackendInstalledRootRunner") } opt := filepath.Join(dir, "opt") if err := os.WriteFile(filepath.Join(opt, "write-probe"), nil, 0600); !errors.Is(err, syscall.EROFS) { t.Fatalf("installed agent version namespace is writable: %v", err) } b := &activator.ExecBackend{OptDir: opt, DataDir: filepath.Join(dir, "data")} b.Cfg.HostWrites.Enabled = mode == "on" rt := registry.Route{Host: "worker.example", Kind: "worker", Args: `["run"]`} id, err := release.ResolveLive(opt, rt.Host) if err != nil { t.Fatal(err) } marker := filepath.Join(dir, "data/executed") for _, pinned := range []bool{false, true} { if err := os.Remove(marker); err != nil && !errors.Is(err, os.ErrNotExist) { t.Fatal(err) } var onto *release.StagedIdentity if pinned { onto = &id } p, _, err := b.StartWorkerStaged(t.Context(), rt, nil, onto) if p != nil { t.Cleanup(func() { if err := p.Stop(context.Background()); err != nil { t.Error(err) } }) deadline := time.Now().Add(5 * time.Second) for !p.Exited() && time.Now().Before(deadline) { time.Sleep(10 * time.Millisecond) } if !p.Exited() { t.Fatal("fixture worker did not exit") } } if mode == "on" { if !errors.Is(err, activator.ErrClaimIsolationUnavailable) || p != nil { t.Fatalf("claimed raw worker: %v %v", p, err) } if _, err := os.Stat(marker); !errors.Is(err, os.ErrNotExist) { t.Fatalf("claimed worker executed: %v", err) } } else { if err != nil || p == nil { t.Fatalf("legacy raw worker: %v %v", p, err) } if raw, err := os.ReadFile(marker); err != nil || string(raw) != "executed" { t.Fatalf("legacy execution marker: %q %v", raw, err) } } } }