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 "sync"
6
7 "github.com/carlosframework/platform/internal/hostbox"
8 "github.com/carlosframework/platform/internal/hostwrite"
9 "github.com/carlosframework/platform/internal/lease"
10 "github.com/carlosframework/platform/internal/release"
11)
12
13// ClaimProductionRelocationSource is region HA's production owner source
14// (claim Plan 11 R1, R8). Open returns the typed relocation owner set for
15// the verified box actor, plus any append-only policy refusals. It grants no
16// local process, roster or policy authority beyond those: the owners see
17// only what the claim's dispatcher and policy gate hand them, and a refusal
18// can only refuse.
19type ClaimProductionRelocationSource interface {
20 Open(context.Context, release.Store, lease.VersionedStore, hostbox.Actor) (ClaimRelocationOwners, []hostbox.PolicyRefusal, error)
21 Close(context.Context) error
22}
23
24var claimRelocationSources struct {
25 sync.Mutex
26 Source ClaimProductionRelocationSource
27}
28
29// RegisterProductionClaimRelocationSource registers region HA's source once
30// at process startup. A second registration, or a nil one, is refused: it
31// can neither replace an owner set nor add a permissive fallback.
32func RegisterProductionClaimRelocationSource(s ClaimProductionRelocationSource) error {
33 claimRelocationSources.Lock()
34 defer claimRelocationSources.Unlock()
35 if s == nil || claimRelocationSources.Source != nil {
36 return hostwrite.ErrUnavailable
37 }
38 claimRelocationSources.Source = s
39 return nil
40}
41
42func productionClaimRelocationSource() ClaimProductionRelocationSource {
43 claimRelocationSources.Lock()
44 defer claimRelocationSources.Unlock()
45 return claimRelocationSources.Source
46}
47
48// openClaimRelocationOwners binds the registered source into out with
49// CARLOS_REGION_HA on. With it off, or nothing registered, out is unchanged
50// and relocating stays refused exactly as before Plan 11. The returned close
51// is the source's, or nil when nothing was opened.
52func openClaimRelocationOwners(ctx context.Context, getenv func(string) string, source ClaimProductionRelocationSource, store release.Store, data lease.VersionedStore, actor hostbox.Actor, out *ClaimOwnerBindings) (func(context.Context) error, error) {
53 if source == nil || getenv == nil || !regionHAEnabled(getenv) {
54 return nil, nil
55 }
56 // N5: region HA's source gets main's own serving launch, markers and
57 // C8 provider, inside the region HA gate, before it opens. Its
58 // Identity is main's serving owners' identity check (carry 5): the
59 // owners' own IdentityProvider.Verify, as claimconstruction.go binds
60 // it before every data-bucket request main's serving owners make.
61 if s, ok := source.(*RelocationSource); ok {
62 serving := out.Serving
63 identity := out.Identity
64 serving.Identity = func(ctx context.Context) error { _, err := identity.Verify(ctx); return err }
65 s.SetServingSources(serving)
66 }
67 owners, refusals, err := source.Open(ctx, store, data, actor)
68 if err != nil {
69 return nil, err
70 }
71 out.Relocation = owners
72 out.PolicyRefusals = append(append([]hostbox.PolicyRefusal(nil), out.PolicyRefusals...), refusals...)
73 return source.Close, nil
74}
75