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 "context"
5 "os"
6 "path/filepath"
7 "strings"
8)
9
10func (g Guard) PendingFences(ctx context.Context) ([]FenceTarget, error) {
11 return g.pendingFences(ctx, true)
12}
13
14func (g Guard) PendingStopFences(ctx context.Context) ([]FenceTarget, error) {
15 return g.pendingFences(ctx, false)
16}
17
18func (g Guard) pendingFences(ctx context.Context, handovers bool) ([]FenceTarget, error) {
19 if g.FenceView != nil {
20 return nil, ErrUnsupported
21 }
22 names, err := g.recordNames()
23 if err != nil {
24 return nil, err
25 }
26 var out []FenceTarget
27 for _, name := range names {
28 if !strings.HasSuffix(name, ".json") {
29 continue
30 }
31 host := strings.TrimSuffix(name, ".json")
32 err := g.readLocked(ctx, host, func(d *recordDir) error {
33 r, err := d.read(host)
34 if err != nil {
35 return err
36 }
37 if r.ActiveFence == nil || (!handovers && r.root && r.barrier != nil && *r.barrier == *r.ActiveFence) {
38 return nil
39 }
40 for _, receipt := range r.FenceJournal {
41 if receipt.Target == *r.ActiveFence {
42 return nil
43 }
44 }
45 out = append(out, *r.ActiveFence)
46 return nil
47 })
48 if err != nil {
49 return nil, err
50 }
51 }
52 return out, nil
53}
54func (g Guard) ResumeFence(ctx context.Context, target FenceTarget) error {
55 return g.fenceLocked(ctx, target.Host, Captured{Incarnation: target.Incarnation, Stamp: target.Stamp}, func(d *recordDir) error {
56 r, err := d.read(target.Host)
57 if err != nil {
58 return err
59 }
60 if r.ActiveFence == nil || *r.ActiveFence != target {
61 return ErrFenceTarget
62 }
63 return nil
64 })
65}
66
67func (g Guard) ExistingFence(ctx context.Context, want FenceTarget) (FenceTarget, error) {
68 var found FenceTarget
69 err := g.fenceLocked(ctx, want.Host, Captured{Incarnation: want.Incarnation, Stamp: want.Stamp}, func(d *recordDir) error {
70 r, err := d.read(want.Host)
71 if err != nil {
72 return err
73 }
74 if r.ActiveFence == nil || !r.ActiveFence.sameAuthority(want) {
75 return ErrFenceTarget
76 }
77 found = *r.ActiveFence
78 return nil
79 })
80 return found, err
81}
82
83func (g Guard) recordNames() ([]string, error) {
84 if g.Root != nil {
85 return g.Root.store.Names()
86 }
87 entries, err := os.ReadDir(filepath.Join(g.DataDir, "hostguard"))
88 if err != nil {
89 return nil, err
90 }
91 var names []string
92 for _, entry := range entries {
93 if !entry.IsDir() {
94 names = append(names, entry.Name())
95 }
96 }
97 return names, nil
98}
99