feat: machine Reset endpoint with asynchronous resource and data cleanup

This commit is contained in:
Pasha Sviderski
2025-07-24 19:50:25 +10:00
parent 2acfafe218
commit 7a6c5bf6d7
9 changed files with 217 additions and 35 deletions
@@ -24,3 +24,7 @@ func (n *WireGuardNetwork) Run(ctx context.Context) error {
func (n *WireGuardNetwork) WatchEndpoints() <-chan EndpointChangeEvent {
return nil
}
func (n *WireGuardNetwork) Cleanup() error {
return errors.New("not implemented on darwin")
}
@@ -27,6 +27,8 @@ type WireGuardNetwork struct {
peers map[string]*peer
// watchers is a list of channels that are notified when the endpoints of the peers change.
watchers []chan EndpointChangeEvent
// running indicates whether the network control loop (Run) is currently running.
running bool
// mu synchronises concurrent network configuration changes.
mu sync.Mutex
}
@@ -273,6 +275,14 @@ func (n *WireGuardNetwork) Run(ctx context.Context) error {
}
defer wg.Close()
n.mu.Lock()
if n.running {
n.mu.Unlock()
return errors.New("network is already running")
}
n.running = true
n.mu.Unlock()
ticker := time.NewTicker(1 * time.Second)
for {
select {
@@ -291,6 +301,11 @@ func (n *WireGuardNetwork) Run(ctx context.Context) error {
for _, ch := range n.watchers {
close(ch)
}
n.mu.Lock()
n.running = false
n.mu.Unlock()
return nil
}
}
@@ -428,3 +443,23 @@ func (n *WireGuardNetwork) notifyWatchers(ctx context.Context, events []Endpoint
}
return nil
}
// Cleanup deletes the WireGuard link. The network must not be running when this method is called.
func (n *WireGuardNetwork) Cleanup() error {
n.mu.Lock()
defer n.mu.Unlock()
if n.running {
return errors.New("network is still running, stop it before cleanup")
}
// Delete the WireGuard link.
name := n.link.Attrs().Name
if err := netlink.LinkDel(n.link); err != nil {
return fmt.Errorf("delete WireGuard link %q: %w", name, err)
}
n.link = nil
slog.Info("Deleted WireGuard interface.", "name", name)
return nil
}