carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux && rootrunner
2
3package host
4
5import (
6 "flag"
7 "fmt"
8 "github.com/carlosframework/platform/internal/instanceexec"
9 "github.com/carlosframework/platform/internal/version"
10 "os"
11 "os/exec"
12 "os/user"
13 "strconv"
14 "testing"
15)
16
17// The test binary must take the same private registry entrypoint as carlos.
18func TestMain(m *testing.M) {
19 // The installed carlos-dbread@ unit runs this binary as
20 // /opt/carlos/carlos system db-worker (dbreads_rootrunner_linux_test.go).
21 if len(os.Args) == 3 && os.Args[1] == "system" && os.Args[2] == "db-worker" {
22 dbreadsTestWorker()
23 return
24 }
25 // A tenant inside the installed tenant unit, reaching for the worker.
26 if len(os.Args) == 2 && os.Args[1] == "dbread-tenant-witness" {
27 dbreadsTenantWitness()
28 return
29 }
30 // The agent half of the db-read root-runner tests, run as carlos.
31 if os.Getenv("DBREAD_RUNNER_PAYLOAD") != "" {
32 flag.Set("test.run", "^TestRootDBReadPayload$")
33 flag.Set("test.v", "false")
34 flag.Set("test.timeout", "5m")
35 os.Exit(m.Run())
36 }
37 if os.Getenv("PLAN14_LIFECYCLE_GUARD") == "1" && len(os.Args) > 1 {
38 if os.Args[1] == "system" && len(os.Args) > 2 {
39 switch os.Args[2] {
40 case "guard-arm":
41 version.Build = "v2.0.0"
42 RunSystemGuardArm(os.Args[3:])
43 return
44 case "guard-exec":
45 RunSystemGuardExec(os.Args[3:])
46 return
47 case "apply":
48 RunSystemApply(os.Args[3:])
49 return
50 }
51 }
52 if len(os.Args) == 2 && os.Args[1] == "agent" && os.Getenv("PLAN14_LIFECYCLE_AGENT") == "1" {
53 os.Setenv("CARLOS_S3_ENDPOINT", os.Getenv("PLAN14_LIFECYCLE_DATA_ENDPOINT"))
54 flag.Set("test.run", "^TestPlan14LifecycleEndToEndRootRunnerPayload$")
55 flag.Set("test.v", "true")
56 flag.Set("test.timeout", "4m")
57 os.Exit(m.Run())
58 }
59 }
60
61 if os.Getenv("PLAN14_CONSOLE") == "1" {
62 plan14ConsolePayload()
63 return
64 }
65 if os.Getenv("PLAN14_TENANT_SOCKET") != "" {
66 plan14InstalledTenant()
67 return
68 }
69 if len(os.Args) > 1 {
70 switch os.Args[1] {
71 case "instance-exec":
72 instanceexec.RunExec(os.Args[2:])
73 return
74 case "instance-exit":
75 instanceexec.RunExit(os.Args[2:])
76 return
77 case "plan14-tenant":
78 plan14InstalledTenant()
79 return
80 }
81 }
82 if len(os.Args) > 1 && os.Args[1] == registryChildCommand {
83 if err := RunRegistryChild(os.Args[2:]); err != nil {
84 fmt.Fprintln(os.Stderr, err)
85 os.Exit(1)
86 }
87 os.Exit(0)
88 }
89 os.Exit(m.Run())
90}
91
92func generationRunnerRegistryUser(t *testing.T) (int, int) {
93 t.Helper()
94 if os.Geteuid() != 0 {
95 t.Fatal("designated runner must execute as root")
96 }
97 service, err := user.Lookup(serviceUser)
98 if err != nil {
99 if _, ok := err.(user.UnknownUserError); !ok {
100 t.Fatal(err)
101 }
102 if _, err := user.LookupGroup(serviceUser); err == nil {
103 t.Fatal("service group exists without its user")
104 } else if _, ok := err.(user.UnknownGroupError); !ok {
105 t.Fatal(err)
106 }
107 if out, err := exec.Command("useradd", "--system", "--user-group", "--no-create-home", "--shell", "/usr/sbin/nologin", serviceUser).CombinedOutput(); err != nil {
108 t.Fatalf("create runner service user: %v %s", err, out)
109 }
110 t.Cleanup(func() {
111 if out, err := exec.Command("userdel", serviceUser).CombinedOutput(); err != nil {
112 t.Errorf("remove runner service user: %v %s", err, out)
113 return
114 }
115 if _, err := user.LookupGroup(serviceUser); err == nil {
116 if out, err := exec.Command("groupdel", serviceUser).CombinedOutput(); err != nil {
117 t.Errorf("remove runner service group: %v %s", err, out)
118 }
119 }
120 })
121 service, err = user.Lookup(serviceUser)
122 if err != nil {
123 t.Fatal(err)
124 }
125 }
126 uid, err := strconv.Atoi(service.Uid)
127 if err != nil || uid <= 0 {
128 t.Fatal("runner service UID must be non-root", err)
129 }
130 gid, err := strconv.Atoi(service.Gid)
131 if err != nil || gid < 0 {
132 t.Fatal("invalid runner service GID", err)
133 }
134 return uid, gid
135}
136