7
7
"maps"
8
8
"math"
9
9
"net/netip"
10
+ "slices"
10
11
"strings"
11
12
"sync"
12
13
"time"
@@ -19,6 +20,7 @@ import (
19
20
"tailscale.com/util/dnsname"
20
21
21
22
"cdr.dev/slog"
23
+ "github.com/coder/coder/v2/coderd/util/ptr"
22
24
"github.com/coder/coder/v2/codersdk"
23
25
"github.com/coder/coder/v2/tailnet/proto"
24
26
"github.com/coder/quartz"
@@ -918,6 +920,19 @@ type Agent struct {
918
920
Hosts map [dnsname.FQDN ][]netip.Addr
919
921
}
920
922
923
+ func (a * Agent ) Clone () Agent {
924
+ hosts := make (map [dnsname.FQDN ][]netip.Addr , len (a .Hosts ))
925
+ for k , v := range a .Hosts {
926
+ hosts [k ] = slices .Clone (v )
927
+ }
928
+ return Agent {
929
+ ID : a .ID ,
930
+ Name : a .Name ,
931
+ WorkspaceID : a .WorkspaceID ,
932
+ Hosts : hosts ,
933
+ }
934
+ }
935
+
921
936
func (t * TunnelAllWorkspaceUpdatesController ) New (client WorkspaceUpdatesClient ) CloserWaiter {
922
937
t .mu .Lock ()
923
938
defer t .mu .Unlock ()
@@ -958,12 +973,7 @@ func (t *TunnelAllWorkspaceUpdatesController) CurrentState() (WorkspaceUpdate, e
958
973
Status : w .Status ,
959
974
})
960
975
for _ , a := range w .agents {
961
- out .UpsertedAgents = append (out .UpsertedAgents , & Agent {
962
- ID : a .ID ,
963
- Name : a .Name ,
964
- WorkspaceID : a .WorkspaceID ,
965
- Hosts : maps .Clone (a .Hosts ),
966
- })
976
+ out .UpsertedAgents = append (out .UpsertedAgents , ptr .Ref (a .Clone ()))
967
977
}
968
978
}
969
979
return out , nil
@@ -1064,12 +1074,7 @@ func (w *WorkspaceUpdate) Clone() WorkspaceUpdate {
1064
1074
}
1065
1075
}
1066
1076
for i , a := range w .UpsertedAgents {
1067
- clone .UpsertedAgents [i ] = & Agent {
1068
- ID : a .ID ,
1069
- Name : a .Name ,
1070
- WorkspaceID : a .WorkspaceID ,
1071
- Hosts : maps .Clone (a .Hosts ),
1072
- }
1077
+ clone .UpsertedAgents [i ] = ptr .Ref (a .Clone ())
1073
1078
}
1074
1079
for i , ws := range w .DeletedWorkspaces {
1075
1080
clone .DeletedWorkspaces [i ] = & Workspace {
@@ -1079,12 +1084,7 @@ func (w *WorkspaceUpdate) Clone() WorkspaceUpdate {
1079
1084
}
1080
1085
}
1081
1086
for i , a := range w .DeletedAgents {
1082
- clone .DeletedAgents [i ] = & Agent {
1083
- ID : a .ID ,
1084
- Name : a .Name ,
1085
- WorkspaceID : a .WorkspaceID ,
1086
- Hosts : maps .Clone (a .Hosts ),
1087
- }
1087
+ clone .DeletedAgents [i ] = ptr .Ref (a .Clone ())
1088
1088
}
1089
1089
return clone
1090
1090
}
@@ -1112,7 +1112,7 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
1112
1112
ownerUsername : t .ownerUsername ,
1113
1113
agents : make (map [uuid.UUID ]* Agent ),
1114
1114
}
1115
- t .upsertWorkspace (w )
1115
+ t .upsertWorkspaceLocked (w )
1116
1116
currentUpdate .UpsertedWorkspaces = append (currentUpdate .UpsertedWorkspaces , w )
1117
1117
}
1118
1118
@@ -1126,7 +1126,7 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
1126
1126
if err != nil {
1127
1127
return xerrors .Errorf ("failed to parse workspace ID: %w" , err )
1128
1128
}
1129
- deletedAgent , err := t .deleteAgent (workspaceID , agentID )
1129
+ deletedAgent , err := t .deleteAgentLocked (workspaceID , agentID )
1130
1130
if err != nil {
1131
1131
return xerrors .Errorf ("failed to delete agent: %w" , err )
1132
1132
}
@@ -1137,7 +1137,7 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
1137
1137
if err != nil {
1138
1138
return xerrors .Errorf ("failed to parse workspace ID: %w" , err )
1139
1139
}
1140
- deletedWorkspace , err := t .deleteWorkspace (workspaceID )
1140
+ deletedWorkspace , err := t .deleteWorkspaceLocked (workspaceID )
1141
1141
if err != nil {
1142
1142
return xerrors .Errorf ("failed to delete workspace: %w" , err )
1143
1143
}
@@ -1156,15 +1156,15 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
1156
1156
return xerrors .Errorf ("failed to parse workspace ID: %w" , err )
1157
1157
}
1158
1158
a := & Agent {Name : ua .Name , ID : agentID , WorkspaceID : workspaceID }
1159
- err = t .upsertAgent (workspaceID , a )
1159
+ err = t .upsertAgentLocked (workspaceID , a )
1160
1160
if err != nil {
1161
1161
return xerrors .Errorf ("failed to upsert agent: %w" , err )
1162
1162
}
1163
1163
currentUpdate .UpsertedAgents = append (currentUpdate .UpsertedAgents , a )
1164
1164
}
1165
- allAgents := t .allAgentIDs ()
1165
+ allAgents := t .allAgentIDsLocked ()
1166
1166
t .coordCtrl .SyncDestinations (allAgents )
1167
- dnsNames := t .updateDNSNames ()
1167
+ dnsNames := t .updateDNSNamesLocked ()
1168
1168
if t .dnsHostsSetter != nil {
1169
1169
t .logger .Debug (context .Background (), "updating dns hosts" )
1170
1170
err := t .dnsHostsSetter .SetDNSHosts (dnsNames )
@@ -1184,7 +1184,7 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
1184
1184
return nil
1185
1185
}
1186
1186
1187
- func (t * tunnelUpdater ) upsertWorkspace (w * Workspace ) * Workspace {
1187
+ func (t * tunnelUpdater ) upsertWorkspaceLocked (w * Workspace ) * Workspace {
1188
1188
old , ok := t .workspaces [w .ID ]
1189
1189
if ! ok {
1190
1190
t .workspaces [w .ID ] = w
@@ -1196,7 +1196,7 @@ func (t *tunnelUpdater) upsertWorkspace(w *Workspace) *Workspace {
1196
1196
return w
1197
1197
}
1198
1198
1199
- func (t * tunnelUpdater ) deleteWorkspace (id uuid.UUID ) (* Workspace , error ) {
1199
+ func (t * tunnelUpdater ) deleteWorkspaceLocked (id uuid.UUID ) (* Workspace , error ) {
1200
1200
w , ok := t .workspaces [id ]
1201
1201
if ! ok {
1202
1202
return nil , xerrors .Errorf ("workspace %s not found" , id )
@@ -1205,7 +1205,7 @@ func (t *tunnelUpdater) deleteWorkspace(id uuid.UUID) (*Workspace, error) {
1205
1205
return w , nil
1206
1206
}
1207
1207
1208
- func (t * tunnelUpdater ) upsertAgent (workspaceID uuid.UUID , a * Agent ) error {
1208
+ func (t * tunnelUpdater ) upsertAgentLocked (workspaceID uuid.UUID , a * Agent ) error {
1209
1209
w , ok := t .workspaces [workspaceID ]
1210
1210
if ! ok {
1211
1211
return xerrors .Errorf ("workspace %s not found" , workspaceID )
@@ -1214,7 +1214,7 @@ func (t *tunnelUpdater) upsertAgent(workspaceID uuid.UUID, a *Agent) error {
1214
1214
return nil
1215
1215
}
1216
1216
1217
- func (t * tunnelUpdater ) deleteAgent (workspaceID , id uuid.UUID ) (* Agent , error ) {
1217
+ func (t * tunnelUpdater ) deleteAgentLocked (workspaceID , id uuid.UUID ) (* Agent , error ) {
1218
1218
w , ok := t .workspaces [workspaceID ]
1219
1219
if ! ok {
1220
1220
return nil , xerrors .Errorf ("workspace %s not found" , workspaceID )
@@ -1227,7 +1227,7 @@ func (t *tunnelUpdater) deleteAgent(workspaceID, id uuid.UUID) (*Agent, error) {
1227
1227
return a , nil
1228
1228
}
1229
1229
1230
- func (t * tunnelUpdater ) allAgentIDs () []uuid.UUID {
1230
+ func (t * tunnelUpdater ) allAgentIDsLocked () []uuid.UUID {
1231
1231
out := make ([]uuid.UUID , 0 , len (t .workspaces ))
1232
1232
for _ , w := range t .workspaces {
1233
1233
for id := range w .agents {
@@ -1237,8 +1237,9 @@ func (t *tunnelUpdater) allAgentIDs() []uuid.UUID {
1237
1237
return out
1238
1238
}
1239
1239
1240
- // updateDNSNames updates the DNS names for all workspaces in the tunnelUpdater.
1241
- func (t * tunnelUpdater ) updateDNSNames () map [dnsname.FQDN ][]netip.Addr {
1240
+ // updateDNSNamesLocked updates the DNS names for all workspaces in the tunnelUpdater.
1241
+ // t.Mutex must be held.
1242
+ func (t * tunnelUpdater ) updateDNSNamesLocked () map [dnsname.FQDN ][]netip.Addr {
1242
1243
names := make (map [dnsname.FQDN ][]netip.Addr )
1243
1244
for _ , w := range t .workspaces {
1244
1245
err := w .updateDNSNames ()
0 commit comments