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 "log"
6 "net/http"
7 "path/filepath"
8 "time"
9
10 "github.com/carlosframework/platform/internal/hostbox"
11 "github.com/carlosframework/platform/internal/hostclaim"
12 "github.com/carlosframework/platform/internal/hostguard"
13 "github.com/carlosframework/platform/internal/hostwrite"
14 "github.com/carlosframework/platform/internal/moves"
15 "github.com/carlosframework/platform/internal/park"
16 "github.com/carlosframework/platform/internal/registry"
17 "github.com/carlosframework/platform/internal/release"
18 "github.com/carlosframework/platform/internal/rootstate"
19)
20
21// WithProductionMovesHeldRelease adds the moves held-release route (Task
22// 7b) to the claim-mode root handler WithProductionClaimLaunch returned,
23// only while CARLOS_MOVES_PHASE1 is on; otherwise the handler is returned
24// unchanged and the route refuses, exactly main's behaviour. It reuses the
25// claim root's peer authentication and the assembly's roster identity,
26// guard, policy and local authority, and builds root's held-release
27// selection from them as the assembly builds the agent's (Build's
28// WorkSource, without Prepare: participation is the agent's). A release
29// key that does not parse leaves the route unwired, so every request is
30// refused and T7 says MV-N455: fail closed, without stopping
31// instance-control.
32func WithProductionMovesHeldRelease(ctx context.Context, handler http.Handler, reg *registry.Registry, getenv func(string) string) (http.Handler, error) {
33 if !moves.Enabled(getenv) {
34 return handler, nil
35 }
36 root, ok := handler.(ClaimRootWithLaunch)
37 if !ok {
38 return nil, ErrClaimStopUnavailable
39 }
40 entry, _ := ctx.Value(claimEntryKey{}).(claimEntry)
41 a := entry.Assembly
42 if a == nil || entry.Store == nil || reg == nil || a.Guard.Root == nil || a.Guard.DataDir == "" || !filepath.IsAbs(a.ManagedRoots["opt"]) || root.Root.Stop.Authenticate == nil {
43 return nil, &ClaimDependencyError{Contracts: []string{"moves Task 7b held release: production claim assembly, registry and root peer authentication"}}
44 }
45 pub, err := release.ParsePublicKey(getenv("CARLOS_RELEASE_PUBKEY"), "CARLOS_RELEASE_PUBKEY")
46 if err != nil {
47 log.Printf("moves: held releases are refused: %v", err)
48 return root, nil
49 }
50 store := entry.Store
51 guard := a.Guard
52 guard.Claims = hostguard.StoreReader{Store: store}
53 optDir, dataDir := a.ManagedRoots["opt"], a.Guard.DataDir
54 policy, identity, local := a.Policy, a.Identity, a.Local
55 var continues func(kind, from, to string) bool
56 if a.Wake != nil {
57 continues = a.Wake.Continue
58 }
59 root.HeldRelease = &movesHeldReleaseRoot{
60 generationPins: productionRootGenerationPins(),
61 OpenRelease: func() (rootstate.Store, error) { return rootstate.Open(rootReleasePrivate, true, false) },
62 Authenticate: root.Root.Stop.Authenticate,
63 Actor: identity.Verify,
64 Store: store,
65 Claims: func(ctx context.Context, host string) (hostclaim.Observed, error) {
66 return hostclaim.Read(ctx, store, host)
67 },
68 Records: MovesRecordsFrom(store),
69 Route: reg.Get,
70 Works: func(ctx context.Context, actor hostbox.Actor, host, action string) (hostwrite.Work, error) {
71 return hostbox.WorkSource{FleetHomeRegion: actor.FleetHomeRegion, HomeRegion: actor.HomeRegion, Guard: guard, Box: actor.Box,
72 Region: park.PlacementRegion(actor.Region), Now: time.Now, Policy: policy.Check, Local: identity.Local(local), Continue: continues}.Select(ctx, host, action)
73 },
74 Selected: hostbox.Selected,
75 Pub: pub,
76 Ratchet: func() *release.DigestRatchet { return pointerRatchet(true, optDir, dataDir, getenv) },
77 Proof: func() *release.ProofGate { return release.NewRootProofGate(release.ProofPolicyPath, dataDir) },
78 OptDir: optDir,
79 DataDir: dataDir,
80 ReceiptDir: heldReleaseReceiptDir,
81 }
82 return root, nil
83}
84