fix(tailnet): Skip nodes without DERP, avoid use of RemoveAllPeers (#6320)

* fix(tailnet): Skip nodes without DERP, avoid use of RemoveAllPeers
This commit is contained in:
Mathias Fredriksson
2023-02-24 18:16:29 +02:00
committed by GitHub
parent a414de9e81
commit 677721e4a1
10 changed files with 90 additions and 45 deletions

View File

@ -80,16 +80,16 @@ func TestDERP(t *testing.T) {
})
require.NoError(t, err)
w2Ready := make(chan struct{}, 1)
w2Ready := make(chan struct{})
w2ReadyOnce := sync.Once{}
w1.SetNodeCallback(func(node *tailnet.Node) {
w2.UpdateNodes([]*tailnet.Node{node})
w2.UpdateNodes([]*tailnet.Node{node}, false)
w2ReadyOnce.Do(func() {
close(w2Ready)
})
})
w2.SetNodeCallback(func(node *tailnet.Node) {
w1.UpdateNodes([]*tailnet.Node{node})
w1.UpdateNodes([]*tailnet.Node{node}, false)
})
conn := make(chan struct{})

View File

@ -404,6 +404,7 @@ func (api *API) workspaceAgentListeningPorts(rw http.ResponseWriter, r *http.Req
}
func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (*codersdk.WorkspaceAgentConn, error) {
ctx := r.Context()
clientConn, serverConn := net.Pipe()
derpMap := api.DERPMap.Clone()
@ -453,32 +454,32 @@ func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (*
}
sendNodes, _ := tailnet.ServeCoordinator(clientConn, func(node []*tailnet.Node) error {
err := conn.RemoveAllPeers()
if err != nil {
return xerrors.Errorf("remove all peers: %w", err)
}
err = conn.UpdateNodes(node)
err = conn.UpdateNodes(node, true)
if err != nil {
return xerrors.Errorf("update nodes: %w", err)
}
return nil
})
conn.SetNodeCallback(sendNodes)
go func() {
err := (*api.TailnetCoordinator.Load()).ServeClient(serverConn, uuid.New(), agentID)
if err != nil {
api.Logger.Warn(r.Context(), "tailnet coordinator client error", slog.Error(err))
_ = conn.Close()
}
}()
return &codersdk.WorkspaceAgentConn{
agentConn := &codersdk.WorkspaceAgentConn{
Conn: conn,
CloseFunc: func() {
_ = clientConn.Close()
_ = serverConn.Close()
},
}, nil
}
go func() {
err := (*api.TailnetCoordinator.Load()).ServeClient(serverConn, uuid.New(), agentID)
if err != nil {
api.Logger.Warn(r.Context(), "tailnet coordinator client error", slog.Error(err))
_ = agentConn.Close()
}
}()
if !agentConn.AwaitReachable(ctx) {
_ = agentConn.Close()
return nil, xerrors.Errorf("agent not reachable")
}
return agentConn, nil
}
// @Summary Get connection info for workspace agent

View File

@ -191,12 +191,21 @@ func setupAgent(t *testing.T, metadata agentsdk.Metadata, ptyTimeout time.Durati
})
go coordinator.ServeClient(serverConn, uuid.New(), agentID)
sendNode, _ := tailnet.ServeCoordinator(clientConn, func(node []*tailnet.Node) error {
return conn.UpdateNodes(node)
return conn.UpdateNodes(node, false)
})
conn.SetNodeCallback(sendNode)
return &codersdk.WorkspaceAgentConn{
agentConn := &codersdk.WorkspaceAgentConn{
Conn: conn,
}
t.Cleanup(func() {
_ = agentConn.Close()
})
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
defer cancel()
if !agentConn.AwaitReachable(ctx) {
t.Fatal("agent not reachable")
}
return agentConn
}
type client struct {