carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "os"
8
9 "github.com/carlosframework/platform/internal/moves"
10 "github.com/carlosframework/platform/internal/rootparticipation"
11)
12
13type rootFloorHealthy struct {
14 Identity rootFloorIdentity
15 Binary rootFloorBinary
16}
17
18// Only a successful root health gate supplies this observation. A signed file
19// alone proves identity, not that the box ever accepted it as healthy.
20func (f rootMovesFloors) acceptHealthy(ctx context.Context, b rootFloorBinary) error {
21 if !b.supports(nil) {
22 return errRootFloorHistory
23 }
24 unlock, err := f.private.Lock(ctx, "floor.lock")
25 if err != nil {
26 return err
27 }
28 defer unlock()
29 old, err := f.healthy()
30 if err != nil {
31 return err
32 }
33 if old != nil {
34 if at, _ := moves.ReleaseAtOrAbove(old.Version, b.Version); at {
35 b = *old
36 }
37 }
38 raw, _ := json.Marshal(rootFloorHealthy{Identity: f.identity, Binary: b})
39 if err := f.private.Write("healthy.json", raw); err != nil {
40 return err
41 }
42 bound, err := f.localBound()
43 if err != nil {
44 return err
45 }
46 // A healthy observation never acknowledges a bound the observed build cannot meet.
47 if !b.supports(bound) {
48 return nil
49 }
50 generation := uint64(1)
51 if r, err := f.record(rootFloorAccepted); err == nil {
52 generation = r.Generation + 1
53 }
54 r := rootFloorRecord{Schema: 1, Identity: f.identity, Generation: generation, Floor: bound, NeverArmed: bound == nil,
55 Provenance: rootFloorReconstruction{Identity: f.identity, Source: "root health gate", Digest: b.Digest, Floor: bound, NeverArmed: bound == nil}}
56 return f.persist(r, bound, true)
57}
58func (f rootMovesFloors) healthy() (*rootFloorBinary, error) {
59 raw, err := f.private.Read("healthy.json")
60 if errors.Is(err, os.ErrNotExist) {
61 return nil, nil
62 }
63 if err != nil {
64 return nil, err
65 }
66 var h rootFloorHealthy
67 if rootparticipation.Decode(raw, &h) != nil || h.Identity != f.identity || !h.Binary.supports(nil) {
68 return nil, nil
69 }
70 return &h.Binary, nil
71}
72func (f rootMovesFloors) capLegacy(legacy []*moves.Floor) ([]*moves.Floor, error) {
73 h, err := f.healthy()
74 if err != nil || h == nil {
75 return nil, err
76 }
77 out := make([]*moves.Floor, 0, len(legacy))
78 for _, fl := range legacy {
79 if !validRootFloor(fl) {
80 continue
81 }
82 c := *fl
83 if c.Min > h.Protocol {
84 c.Min = h.Protocol
85 }
86 if at, _ := moves.ReleaseAtOrAbove(c.MinRelease, h.Version); at {
87 c.MinRelease = h.Version
88 }
89 if validRootFloor(&c) {
90 out = append(out, &c)
91 }
92 }
93 return out, nil
94}
95func (a *systemApplier) acceptRootFloorHealthy(ctx context.Context) error {
96 id, required, err := a.rootMoves.read()
97 if err != nil || !required {
98 return err
99 }
100 b, err := readRootFloorBinary(a.optDir, systemBinaryPath(a.optDir))
101 if err != nil {
102 return err
103 }
104 f, err := openRootMovesFloors(a.optDir, id, true)
105 if err != nil {
106 return err
107 }
108 defer f.close()
109 if err := f.acceptHealthy(ctx, b); err != nil {
110 return err
111 }
112 bound, err := readRootSeedsBound(a.optDir, id)
113 if err != nil || bound == nil {
114 return err
115 }
116 seeds, err := openRootProtocolFloors(rootSeedsFloorDir(a.optDir), id, true)
117 if err != nil {
118 return err
119 }
120 defer seeds.close()
121 return seeds.acceptHealthy(ctx, b.forSeeds())
122}
123