carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package hostguard
2
3import (
4 "bytes"
5 "context"
6 "github.com/carlosframework/platform/internal/hostclaim"
7)
8
9func (g Guard) RebindRootInventory(ctx context.Context, prior Captured, revision uint64, next RootInstallation, intent []byte, check func(*hostclaim.Claim) error, commit func() error) error {
10 if g.Root == nil || check == nil || commit == nil || len(intent) == 0 || prior.Incarnation != next.Incarnation || prior.Stamp == 0 || next.Stamp <= prior.Stamp || revision == 0 || next.InventoryRevision == 0 {
11 return ErrInvalidInput
12 }
13 return g.locked(ctx, next.Host, func(d *recordDir) error {
14 c, err := g.fresh(ctx, next.Host)
15 if err != nil {
16 return err
17 }
18 if err = check(c); err != nil {
19 return err
20 }
21 if c.Holder.Incarnation != next.Incarnation || c.Holder.Stamp != next.Stamp || c.Holder.Account != next.Account || c.Holder.App != next.App {
22 return ErrClaimIncarnation
23 }
24 r, err := d.read(next.Host)
25 if err != nil {
26 return err
27 }
28 if r.barrier != nil {
29 return ErrFenced
30 }
31 want := Captured{Incarnation: next.Incarnation, Stamp: next.Stamp}
32 for _, denied := range r.rootRetired {
33 if denied == want {
34 return ErrRetiredStamp
35 }
36 }
37 if r.ActiveFence != nil && r.ActiveFence.matchesSession(c, want) {
38 return ErrFenced
39 }
40 for _, receipt := range r.FenceJournal {
41 if receipt.Target.matchesSession(c, want) {
42 return ErrFenced
43 }
44 }
45 next.Artifacts = r.installation.Artifacts
46 if r.installation == next && r.pendingInstallation == nil && bytes.Equal(r.rebindCommit, intent) {
47 return d.sync(next.Host)
48 }
49 old := r.installation
50 if r.Incarnation != prior.Incarnation || r.ActiveStamp != prior.Stamp || old.InventoryRevision != revision || old.Empty || old.Account != next.Account || old.App != next.App || old.Record != next.Record || old.Box != next.Box || old.Enrollment != next.Enrollment || old.Migration != next.Migration {
51 return ErrRecordIncarnation
52 }
53 if r.pendingInstallation != nil && (*r.pendingInstallation != next || !bytes.Equal(r.pendingInventory, intent)) {
54 return ErrFenced
55 }
56 r.pendingInventory = append([]byte(nil), intent...)
57 r.pendingInstallation = &next
58 if err = d.write(r); err != nil {
59 return err
60 }
61 c, err = g.fresh(ctx, next.Host)
62 if err != nil {
63 return err
64 }
65 if err = check(c); err != nil {
66 return err
67 }
68 if err = commit(); err != nil {
69 return err
70 }
71 r.retire()
72 r.Incarnation, r.ActiveStamp, r.installation = next.Incarnation, next.Stamp, next
73 r.pendingInventory, r.pendingInstallation = nil, nil
74 r.quarantined, r.settled = false, false
75 r.rebindCommit = append([]byte(nil), intent...)
76 return d.write(r)
77 })
78}
79