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 "os"
6 "path/filepath"
7 "strings"
8
9 "github.com/carlosframework/platform/internal/registry"
10)
11
12// Registry rows can contradict retained obligations, but cannot remove them.
13// Read them through the service-user parser, including on the final recheck.
14func productionGenerationRegistryInventory(ctx context.Context, snapshot generationInventory) (generationInventory, error) {
15 reg, err := openServiceRegistryReadOnly(filepath.Join(dataDir(), "registry.db"))
16 if err != nil {
17 return generationInventory{}, err
18 }
19 defer reg.Close()
20 return generationRegistryInventory(ctx, reg, snapshot)
21}
22
23func generationRegistryInventory(ctx context.Context, reg *registry.Registry, snapshot generationInventory) (generationInventory, error) {
24 var zero generationInventory
25 if reg == nil {
26 return zero, os.ErrPermission
27 }
28 if err := generationRetainedTimers(snapshot); err != nil {
29 return zero, err
30 }
31 retired, err := generationRetirements(ctx, snapshot)
32 if err != nil {
33 return zero, err
34 }
35 transferred, err := generationTransfers(ctx, snapshot)
36 if err != nil {
37 return zero, err
38 }
39 type key struct{ kind, host, name string }
40 expected := map[key]registry.ClaimOwnership{}
41 hosts := map[string]bool{}
42 for index, p := range snapshot.Payloads {
43 in := p.Inventory
44 hosts[in.Host] = true
45 if _, ok := transferred[index]; ok {
46 continue
47 }
48 if retired[index] != "" {
49 continue
50 }
51 for _, entry := range in.Entries {
52 if entry.Kind != "route" && entry.Kind != "timer" {
53 continue
54 }
55 name := ""
56 if entry.Kind == "timer" {
57 name = strings.TrimPrefix(entry.RelativePath, in.Host+"/")
58 if name == "" || name == "." || name == ".." || strings.ContainsAny(name, "/\\") || entry.RelativePath != in.Host+"/"+name {
59 return zero, os.ErrPermission
60 }
61 } else if entry.RelativePath != in.Host {
62 return zero, os.ErrPermission
63 }
64 own := registry.ClaimOwnership{ClaimIncarnation: in.Incarnation, ClaimStamp: in.InstallationStamp, ClaimOwner: entry.Ownership, ClaimRowID: entry.RowIdentity}
65 k := key{entry.Kind, in.Host, name}
66 if !own.Valid() || entry.ManagedRoot != "registry" || entry.Materialization != "materialized" {
67 return zero, os.ErrPermission
68 }
69 if _, exists := expected[k]; exists {
70 return zero, os.ErrPermission
71 }
72 if entry.TimerRetired {
73 continue
74 }
75 expected[k] = own
76 if len(expected) > 8192 {
77 return zero, os.ErrPermission
78 }
79 }
80 }
81 candidates, err := reg.ArtifactHosts()
82 if err != nil {
83 return zero, err
84 }
85 if len(candidates) > 8192 {
86 return zero, os.ErrPermission
87 }
88 for _, host := range candidates {
89 if !hosts[host] {
90 return zero, os.ErrPermission
91 }
92 }
93 for host := range hosts {
94 if err := ctx.Err(); err != nil {
95 return zero, err
96 }
97 route, err := reg.Get(host)
98 if err != nil {
99 return zero, err
100 }
101 k := key{"route", host, ""}
102 own, exists := expected[k]
103 if (route != nil) != exists {
104 return zero, os.ErrPermission
105 }
106 if exists {
107 if route.Host != host || route.ClaimOwnership != own {
108 return zero, os.ErrPermission
109 }
110 delete(expected, k)
111 }
112 timers, err := reg.TimersFor(host)
113 if err != nil {
114 return zero, err
115 }
116 if len(timers) > 8192 {
117 return zero, os.ErrPermission
118 }
119 for _, timer := range timers {
120 k := key{"timer", host, timer.Name}
121 own, exists := expected[k]
122 if !exists || timer.Host != host || timer.ClaimOwnership != own || timer.Registration != own.ClaimRowID {
123 return zero, os.ErrPermission
124 }
125 delete(expected, k)
126 }
127 }
128 if len(expected) != 0 {
129 return zero, os.ErrPermission
130 }
131 return snapshot, ctx.Err()
132}
133