carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostactors
2
3import (
4 "crypto/sha256"
5 "encoding/hex"
6 "encoding/json"
7)
8
9// BoxBinding is the digest installed claim state on one box binds to: the
10// deployment's binding facts and that box's row identity and state, read from
11// one verified roster. It changes only when one of those facts changes. Holds,
12// activations, enrollment attempts, consoles, regions, other boxes' rows, this
13// box's role, label, group, loss ids and enrollment time, and the roster's
14// write counter (Revision) never change it, so the console's per-operation
15// roster writes no longer strand installed instances.
16//
17// The second result is false when ref names no row.
18func BoxBinding(r Roster, ref string) (string, bool) {
19 b, ok := r.Boxes[ref]
20 if !ok {
21 return "", false
22 }
23 sum := sha256.Sum256(boxBindingV1(r, b))
24 return hex.EncodeToString(sum[:]), true
25}
26
27// ValidBinding reports whether s has BoxBinding's form: 64 lower-case hex
28// digits. It says nothing about which roster or box it was computed from.
29func ValidBinding(s string) bool {
30 if len(s) != 2*sha256.Size {
31 return false
32 }
33 for i := 0; i < len(s); i++ {
34 if c := s[i]; (c < '0' || c > '9') && (c < 'a' || c > 'f') {
35 return false
36 }
37 }
38 return true
39}
40
41// boxBindingV1 freezes the binding facts in an ordered v1 tuple, encoded like
42// the journal's request tuple (hostbox/journalservice.go). Never extend this
43// tuple when Roster or Box grows: a new bound fact requires a new version tag
44// and a separate encoder, and every installed stamp changes with it.
45func boxBindingV1(r Roster, b Box) []byte {
46 raw, _ := json.Marshal([]any{
47 "carlos-box-binding-v1",
48 r.DeploymentBucket, r.HomeRegion, r.RequestLimitNS, r.Publication, r.FloorSHA256,
49 b.Enrollment, b.Namespace, b.BoxID, b.Region, b.Pool,
50 []any{b.Cloud.Provider, b.Cloud.Account, b.Cloud.Region, b.Cloud.InstanceID},
51 b.EvidenceSHA256, b.State, b.QuarantineRevision, hex.EncodeToString(b.CensusPublicKey),
52 })
53 return raw
54}
55