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 "errors"
6 "log"
7 "path/filepath"
8 "time"
9
10 execlease "github.com/carlosframework/platform/internal/hostexec"
11 "github.com/carlosframework/platform/internal/rootparticipation"
12)
13
14// Recovery constructs only root's local readers and settlement machinery.
15// It never starts the monitor, contacts instance-control, or calls Execute.
16func recoverRootExecution(ctx context.Context, dataDir, guardDir string) (result error) {
17 ledger, required, err := rootparticipation.OpenForUpdate()
18 if err != nil {
19 return err
20 }
21 if !required {
22 if ledger.State != nil {
23 ledger.State.Close()
24 }
25 return execlease.RecoverPending(ctx, dataDir, guardDir)
26 }
27 ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
28 defer cancel()
29 census, err := ledger.RecoveryCensus()
30 ledger.State.Close()
31 if err != nil {
32 return err
33 }
34 if census.NeverEnrolled {
35 return nil
36 }
37 store, err := openDeployStore(ctx)
38 if err != nil {
39 return err
40 }
41 reg, err := openServiceRegistry(filepath.Join(dataDir, "registry.db"))
42 if err != nil {
43 return err
44 }
45 defer reg.Close()
46 // FS-R4: an enrolled census keeps retained root state under maintenance
47 // even if claims are now off; the no-census branch above stays separate.
48 ctx = context.WithValue(ctx, claimEntryKey{}, claimEntry{FlagRead: true, Enabled: true, Store: store})
49 ctx = withClaimRuntimeResources(ctx, ClaimRuntimeResources{Mode: "instance-control", Registry: reg, DataDir: dataDir, OptDir: filepath.Dir(filepath.Dir(guardDir)), UnitsDir: "/etc/systemd/system"})
50 ctx, err = ensureProductionClaimAssembly(ctx)
51 if err != nil {
52 return err
53 }
54 entry, _ := ctx.Value(claimEntryKey{}).(claimEntry)
55 defer func() {
56 cleanup, cancel := context.WithTimeout(context.Background(), 30*time.Second)
57 defer cancel()
58 result = errors.Join(result, entry.Assembly.Close(cleanup))
59 }()
60 handler, err := NewProductionRootClaimStop(ctx)
61 if err != nil {
62 return err
63 }
64 runtime := handler.(ClaimRootHTTP).executionRuntime
65 defer func() {
66 cleanup, cancel := context.WithTimeout(context.Background(), 30*time.Second)
67 defer cancel()
68 result = errors.Join(result, runtime.Close(cleanup))
69 }()
70 handler, err = WithProductionClaimLaunch(ctx, handler)
71 if err != nil {
72 return err
73 }
74 root := handler.(ClaimRootWithLaunch).Root
75 return recoverRootExecutionBeforeUpdate(ctx, runtime.broker, root)
76}
77
78func recoverRootExecutionBeforeUpdate(ctx context.Context, broker *execlease.RootBroker, root ClaimRootHTTP) error {
79 if err := broker.Recover(ctx); err != nil {
80 return err
81 }
82 if err := root.RecoverPending(ctx); err != nil {
83 log.Print(err)
84 }
85 return nil
86}
87