1
0
mirror of https://github.com/juanfont/headscale.git synced 2025-08-24 13:46:53 +02:00

do not use online from batcher

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby 2025-08-18 16:41:43 +02:00
parent 629098f6bf
commit 343cfd47e6
No known key found for this signature in database
3 changed files with 12 additions and 25 deletions

View File

@ -15,7 +15,6 @@ import (
"strings"
"time"
"github.com/puzpuzpuz/xsync/v4"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"google.golang.org/grpc/codes"
@ -295,10 +294,6 @@ func (api headscaleV1APIServer) GetNode(
resp := node.Proto()
// Populate the online field based on
// currently connected nodes.
resp.Online = api.h.mapBatcher.IsConnected(node.ID())
return &v1.GetNodeResponse{Node: resp}, nil
}
@ -463,8 +458,6 @@ func (api headscaleV1APIServer) ListNodes(
// the filtering of nodes by user, vs nodes as a whole can
// probably be done once.
// TODO(kradalby): This should be done in one tx.
IsConnected := api.h.mapBatcher.ConnectedMap()
if request.GetUser() != "" {
user, err := api.h.state.GetUserByName(request.GetUser())
if err != nil {
@ -473,27 +466,21 @@ func (api headscaleV1APIServer) ListNodes(
nodes := api.h.state.ListNodesByUser(types.UserID(user.ID))
response := nodesToProto(api.h.state, IsConnected, nodes)
response := nodesToProto(api.h.state, nodes)
return &v1.ListNodesResponse{Nodes: response}, nil
}
nodes := api.h.state.ListNodes()
response := nodesToProto(api.h.state, IsConnected, nodes)
response := nodesToProto(api.h.state, nodes)
return &v1.ListNodesResponse{Nodes: response}, nil
}
func nodesToProto(state *state.State, isLikelyConnected *xsync.Map[types.NodeID, bool], nodes views.Slice[types.NodeView]) []*v1.Node {
func nodesToProto(state *state.State, nodes views.Slice[types.NodeView]) []*v1.Node {
response := make([]*v1.Node, nodes.Len())
for index, node := range nodes.All() {
resp := node.Proto()
// Populate the online field based on
// currently connected nodes.
if val, ok := isLikelyConnected.Load(node.ID()); ok && val {
resp.Online = true
}
var tags []string
for _, tag := range node.RequestTags() {
if state.NodeCanHaveTag(node, tag) {
@ -501,7 +488,7 @@ func nodesToProto(state *state.State, isLikelyConnected *xsync.Map[types.NodeID,
}
}
resp.ValidTags = lo.Uniq(append(tags, node.ForcedTags().AsSlice()...))
resp.SubnetRoutes = util.PrefixesToString(append(state.GetNodePrimaryRoutes(node.ID()), node.ExitRoutes()...))
response[index] = resp
}

View File

@ -38,10 +38,10 @@ func (t *testBatcherWrapper) AddNode(id types.NodeID, c chan<- *tailcfg.MapRespo
if err != nil {
return err
}
// Then send the online notification that poll.go would normally send
t.Batcher.AddWork(change.NodeOnline(id))
t.AddWork(change.NodeOnline(id))
return nil
}
@ -51,10 +51,10 @@ func (t *testBatcherWrapper) RemoveNode(id types.NodeID, c chan<- *tailcfg.MapRe
if !removed {
return false
}
// Then send the offline notification that poll.go would normally send
t.Batcher.AddWork(change.NodeOffline(id))
t.AddWork(change.NodeOffline(id))
return true
}

View File

@ -104,7 +104,6 @@ type Node struct {
// headscale. It is best effort and not persisted.
LastSeen *time.Time `gorm:"column:last_seen"`
// ApprovedRoutes is a list of routes that the node is allowed to announce
// as a subnet router. They are not necessarily the routes that the node
// announces at the moment.
@ -357,6 +356,7 @@ func (node *Node) Proto() *v1.Node {
GivenName: node.GivenName,
User: node.User.Proto(),
ForcedTags: node.ForcedTags,
Online: *node.IsOnline,
// Only ApprovedRoutes and AvailableRoutes is set here. SubnetRoutes has
// to be populated manually with PrimaryRoute, to ensure it includes the
@ -423,7 +423,7 @@ func (node *Node) AnnouncedRoutes() []netip.Prefix {
// SubnetRoutes returns the list of routes that the node announces and are approved.
//
// IMPORTANT: This method is used for internal data structures and should NOT be used
// for the gRPC Proto conversion. For Proto, SubnetRoutes must be populated manually
// for the gRPC Proto conversion. For Proto, SubnetRoutes must be populated manually
// with PrimaryRoutes to ensure it includes only routes actively served by the node.
// See the comment in Proto() method and the implementation in grpcv1.go/nodesToProto.
func (node *Node) SubnetRoutes() []netip.Prefix {