Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0660cba

Browse files
feat(agent/agentcontainers): fall back to workspace folder name
This PR changes the logic for how we decide on an agent name.Previously it followed these steps:1. Use a name from `customizations.coder.name`2. Use a name from the terraform resource `coder_devcontainer`3. Use the dev container's friendly nameWith this change it now does:1. Use a name from `customizations.coder.name`2. Use a name from the terraform resource `coder_devcontainer`3. Use a name from the workspace folder4. Use the dev container's friendly nameWe now attempt to construct a valid agent name from the workspacefolder. Should we fail to construct a valid agent name from theworkspace folder, we will fall back to the dev container's friendlyname.
1 parent32239b2 commit0660cba

File tree

4 files changed

+69
-71
lines changed

4 files changed

+69
-71
lines changed

‎agent/agentcontainers/api.go

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
package agentcontainers
22

33
import (
4-
"bytes"
54
"context"
65
"errors"
76
"fmt"
8-
"io"
97
"net/http"
108
"os"
119
"path"
1210
"path/filepath"
11+
"regexp"
1312
"runtime"
1413
"slices"
1514
"strings"
1615
"sync"
1716
"sync/atomic"
1817
"time"
18+
"unicode"
1919

2020
"github.com/fsnotify/fsnotify"
2121
"github.com/go-chi/chi/v5"
@@ -585,10 +585,10 @@ func (api *API) processUpdatedContainersLocked(ctx context.Context, updated code
585585
ifdc.Container!=nil {
586586
if!api.devcontainerNames[dc.Name] {
587587
// If the devcontainer name wasn't set via terraform, we
588-
//use the containers friendlynameas a fallback which
589-
//will keep changing as the devcontainer is recreated.
590-
//TODO(mafredri): Parse the container label (i.e. devcontainer.json) for customization.
591-
dc.Name=safeFriendlyName(dc.Container.FriendlyName)
588+
//will attempt to create an agentnamebased on the workspace
589+
//folder's name. If that is not possible, we will fall back
590+
//to using the container's friendly name.
591+
dc.Name=safeAgentName(filepath.Base(dc.WorkspaceFolder),dc.Container.FriendlyName)
592592
}
593593
}
594594

@@ -633,6 +633,39 @@ func (api *API) processUpdatedContainersLocked(ctx context.Context, updated code
633633
api.containersErr=nil
634634
}
635635

636+
varconsecutiveHyphenRegex=regexp.MustCompile("-+")
637+
638+
// safeAgentName returns an agent name safe version
639+
// of a folder name, falling back to a safe version
640+
// of the container name if unable to create a name.
641+
funcsafeAgentName(namestring,friendlyNamestring)string {
642+
// Keep only letters and digits, replacing everything
643+
// else with a hyphen.
644+
varsb strings.Builder
645+
for_,r:=rangestrings.ToLower(name) {
646+
ifunicode.IsLetter(r)||unicode.IsDigit(r) {
647+
sb.WriteRune(r)
648+
}else {
649+
sb.WriteRune('-')
650+
}
651+
}
652+
653+
// Remove any consecutive hyphens, and then trim and leading
654+
// and trailing hyphens.
655+
name=consecutiveHyphenRegex.ReplaceAllString(sb.String(),"-")
656+
name=strings.Trim(name,"-")
657+
658+
name=strings.ToLower(name)
659+
name=strings.ReplaceAll(name," ","-")
660+
name=strings.ReplaceAll(name,"_","-")
661+
662+
ifname=="" {
663+
returnsafeFriendlyName(name)
664+
}
665+
666+
returnname
667+
}
668+
636669
// safeFriendlyName returns a API safe version of the container's
637670
// friendly name.
638671
//
@@ -1114,27 +1147,6 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
11141147
ifproc.agent.ID==uuid.Nil||maybeRecreateSubAgent {
11151148
subAgentConfig.Architecture=arch
11161149

1117-
// Detect workspace folder by executing `pwd` in the container.
1118-
// NOTE(mafredri): This is a quick and dirty way to detect the
1119-
// workspace folder inside the container. In the future we will
1120-
// rely more on `devcontainer read-configuration`.
1121-
varpwdBuf bytes.Buffer
1122-
err=api.dccli.Exec(ctx,dc.WorkspaceFolder,dc.ConfigPath,"pwd", []string{},
1123-
WithExecOutput(&pwdBuf,io.Discard),
1124-
WithExecContainerID(container.ID),
1125-
)
1126-
iferr!=nil {
1127-
returnxerrors.Errorf("check workspace folder in container: %w",err)
1128-
}
1129-
directory:=strings.TrimSpace(pwdBuf.String())
1130-
ifdirectory=="" {
1131-
logger.Warn(ctx,"detected workspace folder is empty, using default workspace folder",
1132-
slog.F("default_workspace_folder",DevcontainerDefaultContainerWorkspaceFolder),
1133-
)
1134-
directory=DevcontainerDefaultContainerWorkspaceFolder
1135-
}
1136-
subAgentConfig.Directory=directory
1137-
11381150
displayAppsMap:=map[codersdk.DisplayApp]bool{
11391151
// NOTE(DanielleMaywood):
11401152
// We use the same defaults here as set in terraform-provider-coder.
@@ -1207,6 +1219,8 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
12071219
appsWithPossibleDuplicates=append(appsWithPossibleDuplicates,customization.Apps...)
12081220
}
12091221

1222+
subAgentConfig.Directory=config.Workspace.WorkspaceFolder
1223+
12101224
returnnil
12111225
}();err!=nil {
12121226
api.logger.Error(ctx,"unable to read devcontainer config",slog.Error(err))

‎agent/agentcontainers/api_test.go

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -897,26 +897,26 @@ func TestAPI(t *testing.T) {
897897
FriendlyName:"project1-container",
898898
Running:true,
899899
Labels:map[string]string{
900-
agentcontainers.DevcontainerLocalFolderLabel:"/workspace/project",
901-
agentcontainers.DevcontainerConfigFileLabel:"/workspace/project/.devcontainer/devcontainer.json",
900+
agentcontainers.DevcontainerLocalFolderLabel:"/workspace/project1",
901+
agentcontainers.DevcontainerConfigFileLabel:"/workspace/project1/.devcontainer/devcontainer.json",
902902
},
903903
},
904904
{
905905
ID:"project2-container",
906906
FriendlyName:"project2-container",
907907
Running:true,
908908
Labels:map[string]string{
909-
agentcontainers.DevcontainerLocalFolderLabel:"/home/user/project",
910-
agentcontainers.DevcontainerConfigFileLabel:"/home/user/project/.devcontainer/devcontainer.json",
909+
agentcontainers.DevcontainerLocalFolderLabel:"/home/user/project2",
910+
agentcontainers.DevcontainerConfigFileLabel:"/home/user/project2/.devcontainer/devcontainer.json",
911911
},
912912
},
913913
{
914914
ID:"project3-container",
915915
FriendlyName:"project3-container",
916916
Running:true,
917917
Labels:map[string]string{
918-
agentcontainers.DevcontainerLocalFolderLabel:"/var/lib/project",
919-
agentcontainers.DevcontainerConfigFileLabel:"/var/lib/project/.devcontainer/devcontainer.json",
918+
agentcontainers.DevcontainerLocalFolderLabel:"/var/lib/project3",
919+
agentcontainers.DevcontainerConfigFileLabel:"/var/lib/project3/.devcontainer/devcontainer.json",
920920
},
921921
},
922922
},
@@ -1262,7 +1262,12 @@ func TestAPI(t *testing.T) {
12621262
deleteErrC:make(chanerror,1),
12631263
}
12641264
fakeDCCLI=&fakeDevcontainerCLI{
1265-
execErrC:make(chanfunc(cmdstring,args...string)error,1),
1265+
execErrC:make(chanfunc(cmdstring,args...string)error,1),
1266+
readConfig: agentcontainers.DevcontainerConfig{
1267+
Workspace: agentcontainers.DevcontainerWorkspace{
1268+
WorkspaceFolder:"/workspaces/coder",
1269+
},
1270+
},
12661271
readConfigErrC:make(chanfunc(envs []string)error,1),
12671272
}
12681273

@@ -1273,8 +1278,8 @@ func TestAPI(t *testing.T) {
12731278
Running:true,
12741279
CreatedAt:time.Now(),
12751280
Labels:map[string]string{
1276-
agentcontainers.DevcontainerLocalFolderLabel:"/workspaces",
1277-
agentcontainers.DevcontainerConfigFileLabel:"/workspace/.devcontainer/devcontainer.json",
1281+
agentcontainers.DevcontainerLocalFolderLabel:"/workspaces/coder",
1282+
agentcontainers.DevcontainerConfigFileLabel:"/workspaces/coder/.devcontainer/devcontainer.json",
12781283
},
12791284
}
12801285
)
@@ -1320,13 +1325,8 @@ func TestAPI(t *testing.T) {
13201325

13211326
// Allow initial agent creation and injection to succeed.
13221327
testutil.RequireSend(ctx,t,fakeSAC.createErrC,nil)
1323-
testutil.RequireSend(ctx,t,fakeDCCLI.execErrC,func(cmdstring,args...string)error {
1324-
assert.Equal(t,"pwd",cmd)
1325-
assert.Empty(t,args)
1326-
returnnil
1327-
})// Exec pwd.
13281328
testutil.RequireSend(ctx,t,fakeDCCLI.readConfigErrC,func(envs []string)error {
1329-
assert.Contains(t,envs,"CODER_WORKSPACE_AGENT_NAME=test-container")
1329+
assert.Contains(t,envs,"CODER_WORKSPACE_AGENT_NAME=coder")
13301330
assert.Contains(t,envs,"CODER_WORKSPACE_NAME=test-workspace")
13311331
assert.Contains(t,envs,"CODER_WORKSPACE_OWNER_NAME=test-user")
13321332
assert.Contains(t,envs,"CODER_URL=test-subagent-url")
@@ -1349,8 +1349,8 @@ func TestAPI(t *testing.T) {
13491349

13501350
// Verify agent was created.
13511351
require.Len(t,fakeSAC.created,1)
1352-
assert.Equal(t,"test-container",fakeSAC.created[0].Name)
1353-
assert.Equal(t,"/workspaces",fakeSAC.created[0].Directory)
1352+
assert.Equal(t,"coder",fakeSAC.created[0].Name)
1353+
assert.Equal(t,"/workspaces/coder",fakeSAC.created[0].Directory)
13541354
assert.Len(t,fakeSAC.deleted,0)
13551355

13561356
t.Log("Agent injected successfully, now testing reinjection into the same container...")
@@ -1405,7 +1405,7 @@ func TestAPI(t *testing.T) {
14051405
WaitStartLoop:
14061406
for {
14071407
// Agent reinjection will succeed and we will not re-create the
1408-
// agent, nor re-probe pwd.
1408+
// agent.
14091409
mCCLI.EXPECT().List(gomock.Any()).Return(codersdk.WorkspaceAgentListContainersResponse{
14101410
Containers: []codersdk.WorkspaceAgentContainer{testContainer},
14111411
},nil).Times(1)// 1 update.
@@ -1467,13 +1467,8 @@ func TestAPI(t *testing.T) {
14671467
testutil.RequireSend(ctx,t,fakeSAC.deleteErrC,nil)
14681468
// Expect the agent to be recreated.
14691469
testutil.RequireSend(ctx,t,fakeSAC.createErrC,nil)
1470-
testutil.RequireSend(ctx,t,fakeDCCLI.execErrC,func(cmdstring,args...string)error {
1471-
assert.Equal(t,"pwd",cmd)
1472-
assert.Empty(t,args)
1473-
returnnil
1474-
})// Exec pwd.
14751470
testutil.RequireSend(ctx,t,fakeDCCLI.readConfigErrC,func(envs []string)error {
1476-
assert.Contains(t,envs,"CODER_WORKSPACE_AGENT_NAME=test-container")
1471+
assert.Contains(t,envs,"CODER_WORKSPACE_AGENT_NAME=coder")
14771472
assert.Contains(t,envs,"CODER_WORKSPACE_NAME=test-workspace")
14781473
assert.Contains(t,envs,"CODER_WORKSPACE_OWNER_NAME=test-user")
14791474
assert.Contains(t,envs,"CODER_URL=test-subagent-url")
@@ -1814,7 +1809,6 @@ func TestAPI(t *testing.T) {
18141809
},
18151810
},
18161811
},
1817-
execErrC:make(chanfunc(cmdstring,args...string)error,1),
18181812
}
18191813

18201814
testContainer= codersdk.WorkspaceAgentContainer{
@@ -1861,15 +1855,9 @@ func TestAPI(t *testing.T) {
18611855

18621856
// Close before api.Close() defer to avoid deadlock after test.
18631857
deferclose(fSAC.createErrC)
1864-
deferclose(fDCCLI.execErrC)
18651858

18661859
// Given: We allow agent creation and injection to succeed.
18671860
testutil.RequireSend(ctx,t,fSAC.createErrC,nil)
1868-
testutil.RequireSend(ctx,t,fDCCLI.execErrC,func(cmdstring,args...string)error {
1869-
assert.Equal(t,"pwd",cmd)
1870-
assert.Empty(t,args)
1871-
returnnil
1872-
})
18731861

18741862
// Wait until the ticker has been registered.
18751863
tickerTrap.MustWait(ctx).MustRelease(ctx)
@@ -1913,7 +1901,6 @@ func TestAPI(t *testing.T) {
19131901
},
19141902
},
19151903
readConfigErrC:make(chanfunc(envs []string)error,2),
1916-
execErrC:make(chanfunc(cmdstring,args...string)error,1),
19171904
}
19181905

19191906
testContainer= codersdk.WorkspaceAgentContainer{
@@ -1923,8 +1910,8 @@ func TestAPI(t *testing.T) {
19231910
Running:true,
19241911
CreatedAt:time.Now(),
19251912
Labels:map[string]string{
1926-
agentcontainers.DevcontainerLocalFolderLabel:"/workspaces",
1927-
agentcontainers.DevcontainerConfigFileLabel:"/workspace/.devcontainer/devcontainer.json",
1913+
agentcontainers.DevcontainerLocalFolderLabel:"/workspaces/coder",
1914+
agentcontainers.DevcontainerConfigFileLabel:"/workspaces/coder/.devcontainer/devcontainer.json",
19281915
},
19291916
}
19301917
)
@@ -1960,25 +1947,19 @@ func TestAPI(t *testing.T) {
19601947

19611948
// Close before api.Close() defer to avoid deadlock after test.
19621949
deferclose(fSAC.createErrC)
1963-
deferclose(fDCCLI.execErrC)
19641950
deferclose(fDCCLI.readConfigErrC)
19651951

19661952
// Given: We allow agent creation and injection to succeed.
19671953
testutil.RequireSend(ctx,t,fSAC.createErrC,nil)
1968-
testutil.RequireSend(ctx,t,fDCCLI.execErrC,func(cmdstring,args...string)error {
1969-
assert.Equal(t,"pwd",cmd)
1970-
assert.Empty(t,args)
1971-
returnnil
1972-
})
19731954
testutil.RequireSend(ctx,t,fDCCLI.readConfigErrC,func(env []string)error {
19741955
// We expect the wrong workspace agent name passed in first.
1975-
assert.Contains(t,env,"CODER_WORKSPACE_AGENT_NAME=test-container")
1956+
assert.Contains(t,env,"CODER_WORKSPACE_AGENT_NAME=coder")
19761957
returnnil
19771958
})
19781959
testutil.RequireSend(ctx,t,fDCCLI.readConfigErrC,func(env []string)error {
19791960
// We then expect the agent name passed here to have been read from the config.
19801961
assert.Contains(t,env,"CODER_WORKSPACE_AGENT_NAME=custom-name")
1981-
assert.NotContains(t,env,"CODER_WORKSPACE_AGENT_NAME=test-container")
1962+
assert.NotContains(t,env,"CODER_WORKSPACE_AGENT_NAME=coder")
19821963
returnnil
19831964
})
19841965

‎agent/agentcontainers/devcontainer.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ const (
1818
// DevcontainerConfigFileLabel is the label that contains the path to
1919
// the devcontainer.json configuration file.
2020
DevcontainerConfigFileLabel="devcontainer.config_file"
21-
// The default workspace folder inside the devcontainer.
22-
DevcontainerDefaultContainerWorkspaceFolder="/workspaces"
2321
)
2422

2523
constdevcontainerUpScriptTemplate=`

‎agent/agentcontainers/devcontainercli.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ import (
2222
typeDevcontainerConfigstruct {
2323
MergedConfigurationDevcontainerMergedConfiguration`json:"mergedConfiguration"`
2424
ConfigurationDevcontainerConfiguration`json:"configuration"`
25+
WorkspaceDevcontainerWorkspace`json:"workspace"`
26+
}
27+
28+
typeDevcontainerWorkspacestruct {
29+
WorkspaceFolderstring`json:"workspaceFolder"`
2530
}
2631

2732
typeDevcontainerMergedConfigurationstruct {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp