package host import ( "context" "sync" "time" "github.com/carlosframework/platform/internal/release" "github.com/carlosframework/platform/internal/rootparticipation" "github.com/carlosframework/platform/internal/rootstate" ) type rootLaunchVerifier struct { exclude *release.ReleaseExclusion open func() (rootstate.Store, error) reconcile generationReconciler } type launchRecoveryCensusKey struct{} func (v rootLaunchVerifier) verify(ctx context.Context, revision uint64) error { if v.exclude.Check(ctx) != nil || v.open == nil || v.reconcile.read == nil || revision == 0 { return rootparticipation.ErrUnavailable } store, err := v.open() if err != nil { return err } if store == nil { return rootparticipation.ErrUnavailable } defer store.Close() ledger := &release.RootGenerations{Store: store} records, err := ledger.Reservations(ctx) if err != nil { return err } verifier := v.reconcile read := verifier.read verifier.read = func(ctx context.Context) (generationInventory, error) { snapshot, err := read(ctx) if err == nil && snapshot.Census.LaunchRevision != revision { return generationInventory{}, rootparticipation.ErrUnavailable } return snapshot, err } if rootparticipation.IsAcquisitionRecovery(ctx) { ctx = context.WithValue(ctx, launchRecoveryCensusKey{}, true) } _, err = ledger.Certify(ctx, records, verifier.reconcile) return err } var rootLaunchStartup struct { sync.Once err error } var participationRelease = &release.ReleaseExclusion{Wait: 5 * time.Second, Open: func() (rootstate.Store, error) { return rootstate.Open(rootReleasePrivate, true, false) }} func registerProductionLaunchVerifier() error { rootLaunchStartup.Do(func() { v := rootLaunchVerifier{exclude: participationRelease, open: func() (rootstate.Store, error) { return rootstate.Open(release.RootGenerationsDir, false, false) }, reconcile: generationReconciler{read: productionLocalGenerationInventory, kernel: productionGenerationKernelCensus}, } rootLaunchStartup.err = rootparticipation.RegisterLaunchVerifier(v.verify, participationRelease.With) }) return rootLaunchStartup.err }