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 "bytes"
5 "context"
6 "os"
7
8 "github.com/carlosframework/platform/internal/rootstate"
9)
10
11// The caller holds the binding lock and has resolved the successor from the
12// current root installation. A route edit never reaches this transition.
13func (m claimUnitMaterializer) handover(ctx context.Context, old, next claimUnitBinding) error {
14 if m.state == nil || m.read == nil || m.replace == nil || m.idle == nil || !old.valid() || !next.valid() || !old.Retired || next.Retiring || next.Retired || old.Shape != next.Shape || old.Owner == next.Owner {
15 return os.ErrPermission
16 }
17 unlock, err := m.state.Lock(ctx, "materialize")
18 if err != nil {
19 return err
20 }
21 defer unlock()
22 r, err := m.load(old.Owner.Host)
23 if err != nil {
24 return err
25 }
26 want, err := claimOwnedUnitDefinition(next)
27 if err != nil {
28 return err
29 }
30 previous := old
31 previous.Retiring, previous.Retired = false, false
32 if r.Binding == previous {
33 if !r.Retired || r.Identity == (rootstate.FileIdentity{}) {
34 return os.ErrPermission
35 }
36 raw, id, err := m.read(old.Shape.Unit)
37 if err != nil {
38 return err
39 }
40 if !id.Same(r.Identity) || !bytes.Equal(raw, claimRetiredUnitDefinition(old)) {
41 return os.ErrPermission
42 }
43 r = claimUnitMaterialization{Binding: next, Digest: claimUnitDigest(want), Prior: old, PriorIdentity: r.Identity}
44 }
45 if r.Binding != next || r.Prior != old || r.Digest != claimUnitDigest(want) || r.Retiring || r.Retired {
46 return os.ErrPermission
47 }
48 if err = m.save(r); err != nil {
49 return err
50 }
51 raw, id, err := m.read(next.Shape.Unit)
52 if err != nil {
53 return err
54 }
55 if r.Identity == (rootstate.FileIdentity{}) && id.Same(r.PriorIdentity) && bytes.Equal(raw, claimRetiredUnitDefinition(old)) {
56 if err = m.idle(next.Shape.Host); err != nil {
57 return err
58 }
59 if err = m.replace(next.Shape.Unit, r.PriorIdentity, want); err != nil {
60 return err
61 }
62 raw, id, err = m.read(next.Shape.Unit)
63 if err != nil {
64 return err
65 }
66 }
67 if !bytes.Equal(raw, want) || id == (rootstate.FileIdentity{}) || (r.Identity != (rootstate.FileIdentity{}) && !r.Identity.Same(id)) {
68 return os.ErrPermission
69 }
70 r.Identity = id
71 return m.save(r)
72}
73