@@ -456,7 +456,7 @@ func (t *trySingleflight) Do(key string, fn func()) {
456
456
fn ()
457
457
}
458
458
459
- func (a * agent )reportMetadata (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
459
+ func (a * agent )reportMetadata (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
460
460
tickerDone := make (chan struct {})
461
461
collectDone := make (chan struct {})
462
462
ctx ,cancel := context .WithCancel (ctx )
@@ -672,7 +672,7 @@ func (a *agent) reportMetadata(ctx context.Context, aAPI proto.DRPCAgentClient24
672
672
673
673
// reportLifecycle reports the current lifecycle state once. All state
674
674
// changes are reported in order.
675
- func (a * agent )reportLifecycle (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
675
+ func (a * agent )reportLifecycle (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
676
676
for {
677
677
select {
678
678
case <- a .lifecycleUpdate :
@@ -752,7 +752,7 @@ func (a *agent) setLifecycle(state codersdk.WorkspaceAgentLifecycle) {
752
752
}
753
753
754
754
// reportConnectionsLoop reports connections to the agent for auditing.
755
- func (a * agent )reportConnectionsLoop (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
755
+ func (a * agent )reportConnectionsLoop (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
756
756
for {
757
757
select {
758
758
case <- a .reportConnectionsUpdate :
@@ -872,7 +872,7 @@ func (a *agent) reportConnection(id uuid.UUID, connectionType proto.Connection_T
872
872
// fetchServiceBannerLoop fetches the service banner on an interval. It will
873
873
// not be fetched immediately; the expectation is that it is primed elsewhere
874
874
// (and must be done before the session actually starts).
875
- func (a * agent )fetchServiceBannerLoop (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
875
+ func (a * agent )fetchServiceBannerLoop (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
876
876
ticker := time .NewTicker (a .announcementBannersRefreshInterval )
877
877
defer ticker .Stop ()
878
878
for {
@@ -925,7 +925,7 @@ func (a *agent) run() (retErr error) {
925
925
connMan := newAPIConnRoutineManager (a .gracefulCtx ,a .hardCtx ,a .logger ,aAPI ,tAPI )
926
926
927
927
connMan .startAgentAPI ("init notification banners" ,gracefulShutdownBehaviorStop ,
928
- func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
928
+ func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
929
929
bannersProto ,err := aAPI .GetAnnouncementBanners (ctx ,& proto.GetAnnouncementBannersRequest {})
930
930
if err != nil {
931
931
return xerrors .Errorf ("fetch service banner: %w" ,err )
@@ -942,7 +942,7 @@ func (a *agent) run() (retErr error) {
942
942
// sending logs gets gracefulShutdownBehaviorRemain because we want to send logs generated by
943
943
// shutdown scripts.
944
944
connMan .startAgentAPI ("send logs" ,gracefulShutdownBehaviorRemain ,
945
- func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
945
+ func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
946
946
err := a .logSender .SendLoop (ctx ,aAPI )
947
947
if xerrors .Is (err ,agentsdk .ErrLogLimitExceeded ) {
948
948
// we don't want this error to tear down the API connection and propagate to the
@@ -961,7 +961,7 @@ func (a *agent) run() (retErr error) {
961
961
connMan .startAgentAPI ("report metadata" ,gracefulShutdownBehaviorStop ,a .reportMetadata )
962
962
963
963
// resources monitor can cease as soon as we start gracefully shutting down.
964
- connMan .startAgentAPI ("resources monitor" ,gracefulShutdownBehaviorStop ,func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
964
+ connMan .startAgentAPI ("resources monitor" ,gracefulShutdownBehaviorStop ,func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
965
965
logger := a .logger .Named ("resources_monitor" )
966
966
clk := quartz .NewReal ()
967
967
config ,err := aAPI .GetResourcesMonitoringConfiguration (ctx ,& proto.GetResourcesMonitoringConfigurationRequest {})
@@ -1008,7 +1008,7 @@ func (a *agent) run() (retErr error) {
1008
1008
connMan .startAgentAPI ("handle manifest" ,gracefulShutdownBehaviorStop ,a .handleManifest (manifestOK ))
1009
1009
1010
1010
connMan .startAgentAPI ("app health reporter" ,gracefulShutdownBehaviorStop ,
1011
- func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
1011
+ func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
1012
1012
if err := manifestOK .wait (ctx );err != nil {
1013
1013
return xerrors .Errorf ("no manifest: %w" ,err )
1014
1014
}
@@ -1041,7 +1041,7 @@ func (a *agent) run() (retErr error) {
1041
1041
1042
1042
connMan .startAgentAPI ("fetch service banner loop" ,gracefulShutdownBehaviorStop ,a .fetchServiceBannerLoop )
1043
1043
1044
- connMan .startAgentAPI ("stats report loop" ,gracefulShutdownBehaviorStop ,func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
1044
+ connMan .startAgentAPI ("stats report loop" ,gracefulShutdownBehaviorStop ,func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
1045
1045
if err := networkOK .wait (ctx );err != nil {
1046
1046
return xerrors .Errorf ("no network: %w" ,err )
1047
1047
}
@@ -1056,8 +1056,8 @@ func (a *agent) run() (retErr error) {
1056
1056
}
1057
1057
1058
1058
// handleManifest returns a function that fetches and processes the manifest
1059
- func (a * agent )handleManifest (manifestOK * checkpoint )func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
1060
- return func (ctx context.Context ,aAPI proto.DRPCAgentClient24 )error {
1059
+ func (a * agent )handleManifest (manifestOK * checkpoint )func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
1060
+ return func (ctx context.Context ,aAPI proto.DRPCAgentClient26 )error {
1061
1061
var (
1062
1062
sentResult = false
1063
1063
err error
@@ -1080,6 +1080,18 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
1080
1080
if manifest .AgentID == uuid .Nil {
1081
1081
return xerrors .New ("nil agentID returned by manifest" )
1082
1082
}
1083
+ if manifest .ParentID != uuid .Nil {
1084
+ // This is a sub agent, disable all the features that should not
1085
+ // be used by sub agents.
1086
+ a .logger .Debug (ctx ,"sub agent detected, disabling features" ,
1087
+ slog .F ("parent_id" ,manifest .ParentID ),
1088
+ slog .F ("agent_id" ,manifest .AgentID ),
1089
+ )
1090
+ if a .experimentalDevcontainersEnabled {
1091
+ a .logger .Info (ctx ,"devcontainers are not supported on sub agents, disabling feature" )
1092
+ a .experimentalDevcontainersEnabled = false
1093
+ }
1094
+ }
1083
1095
a .client .RewriteDERPMap (manifest .DERPMap )
1084
1096
1085
1097
// Expand the directory and send it back to coderd so external
@@ -1187,8 +1199,8 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
1187
1199
1188
1200
// createOrUpdateNetwork waits for the manifest to be set using manifestOK, then creates or updates
1189
1201
// the tailnet using the information in the manifest
1190
- func (a * agent )createOrUpdateNetwork (manifestOK ,networkOK * checkpoint )func (context.Context , proto.DRPCAgentClient24 )error {
1191
- return func (ctx context.Context ,_ proto.DRPCAgentClient24 ) (retErr error ) {
1202
+ func (a * agent )createOrUpdateNetwork (manifestOK ,networkOK * checkpoint )func (context.Context , proto.DRPCAgentClient26 )error {
1203
+ return func (ctx context.Context ,aAPI proto.DRPCAgentClient26 ) (retErr error ) {
1192
1204
if err := manifestOK .wait (ctx );err != nil {
1193
1205
return xerrors .Errorf ("no manifest: %w" ,err )
1194
1206
}
@@ -1200,14 +1212,15 @@ func (a *agent) createOrUpdateNetwork(manifestOK, networkOK *checkpoint) func(co
1200
1212
network := a .network
1201
1213
a .closeMutex .Unlock ()
1202
1214
if network == nil {
1203
- keySeed ,err := SSHKeySeed (manifest .OwnerUsername ,manifest .WorkspaceName ,manifest .AgentName )
1215
+ keySeed ,err := SSHKeySeed (manifest .OwnerName ,manifest .WorkspaceName ,manifest .AgentName )
1204
1216
if err != nil {
1205
1217
return xerrors .Errorf ("generate SSH key seed: %w" ,err )
1206
1218
}
1207
1219
// use the graceful context here, because creating the tailnet is not itself tied to the
1208
1220
// agent API.
1209
1221
network ,err = a .createTailnet (
1210
1222
a .gracefulCtx ,
1223
+ aAPI ,
1211
1224
manifest .AgentID ,
1212
1225
manifest .DERPMap ,
1213
1226
manifest .DERPForceWebSockets ,
@@ -1355,6 +1368,7 @@ func (a *agent) trackGoroutine(fn func()) error {
1355
1368
1356
1369
func (a * agent )createTailnet (
1357
1370
ctx context.Context ,
1371
+ aAPI proto.DRPCAgentClient26 ,
1358
1372
agentID uuid.UUID ,
1359
1373
derpMap * tailcfg.DERPMap ,
1360
1374
derpForceWebSockets ,disableDirectConnections bool ,
@@ -1487,7 +1501,7 @@ func (a *agent) createTailnet(
1487
1501
}()
1488
1502
if err = a .trackGoroutine (func () {
1489
1503
defer apiListener .Close ()
1490
- apiHandler ,closeAPIHAndler := a .apiHandler ()
1504
+ apiHandler ,closeAPIHAndler := a .apiHandler (aAPI )
1491
1505
defer func () {
1492
1506
_ = closeAPIHAndler ()
1493
1507
}()
@@ -1960,7 +1974,7 @@ const (
1960
1974
1961
1975
type apiConnRoutineManager struct {
1962
1976
logger slog.Logger
1963
- aAPI proto.DRPCAgentClient24
1977
+ aAPI proto.DRPCAgentClient26
1964
1978
tAPI tailnetproto.DRPCTailnetClient24
1965
1979
eg * errgroup.Group
1966
1980
stopCtx context.Context
@@ -1969,7 +1983,7 @@ type apiConnRoutineManager struct {
1969
1983
1970
1984
func newAPIConnRoutineManager (
1971
1985
gracefulCtx ,hardCtx context.Context ,logger slog.Logger ,
1972
- aAPI proto.DRPCAgentClient24 ,tAPI tailnetproto.DRPCTailnetClient24 ,
1986
+ aAPI proto.DRPCAgentClient26 ,tAPI tailnetproto.DRPCTailnetClient24 ,
1973
1987
)* apiConnRoutineManager {
1974
1988
// routines that remain in operation during graceful shutdown use the remainCtx. They'll still
1975
1989
// exit if the errgroup hits an error, which usually means a problem with the conn.
@@ -2002,7 +2016,7 @@ func newAPIConnRoutineManager(
2002
2016
// but for Tailnet.
2003
2017
func (a * apiConnRoutineManager )startAgentAPI (
2004
2018
name string ,behavior gracefulShutdownBehavior ,
2005
- f func (context.Context , proto.DRPCAgentClient24 )error ,
2019
+ f func (context.Context , proto.DRPCAgentClient26 )error ,
2006
2020
) {
2007
2021
logger := a .logger .With (slog .F ("name" ,name ))
2008
2022
var ctx context.Context