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 "encoding/json"
7 "github.com/carlosframework/platform/internal/registry"
8 "github.com/carlosframework/platform/internal/release"
9 "github.com/carlosframework/platform/internal/rollout"
10 "github.com/carlosframework/platform/internal/status"
11 "os"
12 "os/exec"
13 "path/filepath"
14 "syscall"
15 "testing"
16 "time"
17)
18
19func TestPlan14RootRetryProjectionDelivery(t *testing.T) {
20 if os.Getenv("PLAN14_RETRY_READER") == "1" {
21 report := rootRetryStatus(&status.RolloutReport{Hosts: map[string]status.HostRollout{"h.example.com": {HeldBook: "forged", HeldEpoch: 999}}})
22 raw, _ := json.Marshal(report)
23 os.Stdout.Write(raw)
24 os.Exit(0)
25 }
26 if os.Geteuid() != 0 {
27 t.Fatal("root required")
28 }
29 if err := os.Mkdir(rootRetryProjection, 0755); err != nil {
30 t.Fatal(err)
31 }
32 defer os.RemoveAll(rootRetryProjection)
33 state := testRootFailureStore(t)
34 book, err := rollout.InitializeRootFailures(state, "box/en/1", nil)
35 if err != nil {
36 t.Fatal(err)
37 }
38 rt := registry.Route{Host: "h.example.com", Account: "bab", App: "km"}
39 if _, err = book.Record(rollout.FailureRecord{Account: rt.Account, App: rt.App, Host: rt.Host, Build: "v1", HeldDown: []string{rt.Host}}); err != nil {
40 t.Fatal(err)
41 }
42 p := rootUpdateSource{book: book, publish: publishRootRetry}
43 if err = p.publishRetry(rootUpdateRecord{Route: rt}, "v1"); err != nil {
44 t.Fatal(err)
45 }
46 exe, err := os.Executable()
47 if err != nil {
48 t.Fatal(err)
49 }
50 cmd := exec.Command(exe, "-test.run=^TestPlan14RootRetryProjectionDelivery$")
51 cmd.Env = append(os.Environ(), "PLAN14_RETRY_READER=1")
52 // /root is private on the runner: the child uses an executable descriptor
53 // opened before dropping credentials, without making the runner binary public.
54 binary, err := os.Open(exe)
55 if err != nil {
56 t.Fatal(err)
57 }
58 defer binary.Close()
59 cmd.Path = "/proc/self/fd/3"
60 cmd.Args[0] = cmd.Path
61 cmd.ExtraFiles = []*os.File{binary}
62 cmd.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: 65534, Gid: 65534}}
63 raw, err := cmd.Output()
64 if err != nil {
65 t.Fatal(err)
66 }
67 var report status.RolloutReport
68 if err = json.Unmarshal(raw, &report); err != nil {
69 t.Fatal(err, string(raw))
70 }
71 h := report.Hosts[rt.Host]
72 if h.HeldBook != book.ID() || h.HeldEpoch != book.PublishedEpoch(rt.Account, rt.App, "v1", rt.Host) {
73 t.Fatal("agent reported forged retry", h)
74 }
75 legacy, err := rollout.OpenFailureBook(t.TempDir())
76 if err != nil {
77 t.Fatal(err)
78 }
79 if _, err = legacy.Record(rollout.FailureRecord{Account: rt.Account, App: rt.App, Host: rt.Host, Build: "v1", HeldDown: []string{rt.Host}}); err != nil {
80 t.Fatal(err)
81 }
82 legacyEpoch := legacy.PublishedEpoch(rt.Account, rt.App, "v1", rt.Host)
83 rt.Kind, rt.Status, rt.Version, rt.Channel, rt.Hibernate = "instance", "ready", "v1", "canary/x", true
84 if !rollout.Restrictable(rt) {
85 t.Fatal("fixture route not restrictable")
86 }
87 hold := &failureHolds{book: legacy, get: func(string) (*registry.Route, error) { return &rt, nil }}
88 old := declinedHolds.Swap(hold)
89 defer declinedHolds.Store(old)
90 // A root retry has no effect on the separate local mirror until root's
91 // durable acknowledgement names the exact local snapshot it observed.
92
93 seed, public, _ := release.GenerateKey()
94 priv, _ := release.ParseSigningKey(seed, "test")
95 pub, _ := release.ParsePublicKey(public, "test")
96 wire, err := release.SignHostRetry(release.RootSigner(priv), rt.Account, rt.App, rt.Host, h.HeldBy, h.HeldBook, h.HeldEpoch, time.Now())
97 if err != nil {
98 t.Fatal(err)
99 }
100 data := t.TempDir()
101 t.Setenv("CARLOS_DATA_DIR", data)
102 request := release.RestartRequest{Scope: release.RestartScope{Kind: release.RestartScopeRetry, Value: rt.Host, Signed: wire}}
103 work := []scopedRestart{{app: [2]string{rt.Account, rt.App}, requests: []release.RestartRequest{request}}}
104 applyRetries([]registry.Route{rt}, work, &restartMemory{pub: pub})
105 marker := filepath.Join(data, stageRequestMarker)
106 if _, err := os.Stat(marker); err != nil {
107 t.Fatal("root retry was not relayed", err)
108 }
109 if !book.HeldDown(rt.Account, rt.App, "v1", rt.Host) {
110 t.Fatal("agent relay cleared root authority")
111 }
112 if err := os.Remove(marker); err != nil {
113 t.Fatal(err)
114 }
115 work[0].requests[0].Scope.Signed = "forged"
116 applyRetries([]registry.Route{rt}, work, &restartMemory{pub: pub})
117 if _, err := os.Stat(marker); !os.IsNotExist(err) {
118 t.Fatal("forged retry was relayed", err)
119 }
120 if err = book.VerifiedRetry(pub, wire, rt.Account, rt.App, rt.Host, time.Now()); err != nil {
121 t.Fatal(err)
122 }
123 if book.HeldDown(rt.Account, rt.App, "v1", rt.Host) {
124 t.Fatal("delivered retry did not clear root failure")
125 }
126 saved := rootUpdateRecord{Route: rt, RetryMirror: &rootLegacyRetry{Build: "v1", Book: legacy.ID(), Epoch: legacyEpoch}}
127 if err = p.publishRetry(saved, "v1"); err != nil {
128 t.Fatal(err)
129 }
130 local := &status.RolloutReport{Hosts: map[string]status.HostRollout{rt.Host: {Account: rt.Account, App: rt.App, HeldBy: "v1", HeldBook: legacy.ID(), HeldEpoch: legacyEpoch}}}
131 rootRetryStatus(local)
132 if legacy.HeldDown(rt.Account, rt.App, "v1", rt.Host) {
133 t.Fatal("agent mirror still blocks the root retry")
134 }
135 if _, err = legacy.Record(rollout.FailureRecord{Account: rt.Account, App: rt.App, Host: rt.Host, Build: "v1", HeldDown: []string{rt.Host}}); err != nil {
136 t.Fatal(err)
137 }
138 current := *local
139 current.Hosts = map[string]status.HostRollout{rt.Host: {HeldBy: "v1", HeldBook: legacy.ID(), HeldEpoch: legacy.PublishedEpoch(rt.Account, rt.App, "v1", rt.Host)}}
140 rootRetryStatus(&current)
141 if !legacy.HeldDown(rt.Account, rt.App, "v1", rt.Host) {
142 t.Fatal("old receipt erased a later local failure")
143 }
144 // A service-written projection cannot deliver a mirror clear.
145 if err = os.Chmod(filepath.Join(rootRetryProjection, rt.Host+".json"), 0666); err != nil {
146 t.Fatal(err)
147 }
148 if report := rootRetryStatus(local); report == nil || report.Unavailable != rolloutBookUnreadable {
149 t.Fatal("hostile retry projection accepted", report)
150 }
151
152}
153