Skip to content

Commit d61353f

Browse files
fix(agent/agentcontainers): read WorkspaceFolder from config (#18467)
Instead of exec'ing `pwd` inside of the container, we instead read `WorkspaceFolder` from the outcome of `read-configuration`.
1 parent 9c1feff commit d61353f

File tree

3 files changed

+20
-51
lines changed

3 files changed

+20
-51
lines changed

agent/agentcontainers/api.go

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package agentcontainers
22

33
import (
4-
"bytes"
54
"context"
65
"errors"
76
"fmt"
8-
"io"
97
"net/http"
108
"os"
119
"path"
@@ -1114,27 +1112,6 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
11141112
if proc.agent.ID == uuid.Nil || maybeRecreateSubAgent {
11151113
subAgentConfig.Architecture = arch
11161114

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-
var pwdBuf 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-
if err != nil {
1127-
return xerrors.Errorf("check workspace folder in container: %w", err)
1128-
}
1129-
directory := strings.TrimSpace(pwdBuf.String())
1130-
if directory == "" {
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-
11381115
displayAppsMap := map[codersdk.DisplayApp]bool{
11391116
// NOTE(DanielleMaywood):
11401117
// We use the same defaults here as set in terraform-provider-coder.
@@ -1146,7 +1123,10 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
11461123
codersdk.DisplayAppPortForward: true,
11471124
}
11481125

1149-
var appsWithPossibleDuplicates []SubAgentApp
1126+
var (
1127+
appsWithPossibleDuplicates []SubAgentApp
1128+
workspaceFolder = DevcontainerDefaultContainerWorkspaceFolder
1129+
)
11501130

11511131
if err := func() error {
11521132
var (
@@ -1167,6 +1147,8 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
11671147
return err
11681148
}
11691149

1150+
workspaceFolder = config.Workspace.WorkspaceFolder
1151+
11701152
// NOTE(DanielleMaywood):
11711153
// We only want to take an agent name specified in the root customization layer.
11721154
// This restricts the ability for a feature to specify the agent name. We may revisit
@@ -1241,6 +1223,7 @@ func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc c
12411223

12421224
subAgentConfig.DisplayApps = displayApps
12431225
subAgentConfig.Apps = apps
1226+
subAgentConfig.Directory = workspaceFolder
12441227
}
12451228

12461229
deleteSubAgent := proc.agent.ID != uuid.Nil && maybeRecreateSubAgent && !proc.agent.EqualConfig(subAgentConfig)

agent/agentcontainers/api_test.go

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,11 @@ func TestAPI(t *testing.T) {
12621262
deleteErrC: make(chan error, 1),
12631263
}
12641264
fakeDCCLI = &fakeDevcontainerCLI{
1265+
readConfig: agentcontainers.DevcontainerConfig{
1266+
Workspace: agentcontainers.DevcontainerWorkspace{
1267+
WorkspaceFolder: "/workspaces/coder",
1268+
},
1269+
},
12651270
execErrC: make(chan func(cmd string, args ...string) error, 1),
12661271
readConfigErrC: make(chan func(envs []string) error, 1),
12671272
}
@@ -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: "/home/coder/coder",
1282+
agentcontainers.DevcontainerConfigFileLabel: "/home/coder/coder/.devcontainer/devcontainer.json",
12781283
},
12791284
}
12801285
)
@@ -1320,11 +1325,6 @@ 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(cmd string, args ...string) error {
1324-
assert.Equal(t, "pwd", cmd)
1325-
assert.Empty(t, args)
1326-
return nil
1327-
}) // Exec pwd.
13281328
testutil.RequireSend(ctx, t, fakeDCCLI.readConfigErrC, func(envs []string) error {
13291329
assert.Contains(t, envs, "CODER_WORKSPACE_AGENT_NAME=test-container")
13301330
assert.Contains(t, envs, "CODER_WORKSPACE_NAME=test-workspace")
@@ -1350,7 +1350,7 @@ func TestAPI(t *testing.T) {
13501350
// Verify agent was created.
13511351
require.Len(t, fakeSAC.created, 1)
13521352
assert.Equal(t, "test-container", fakeSAC.created[0].Name)
1353-
assert.Equal(t, "/workspaces", fakeSAC.created[0].Directory)
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...")
@@ -1467,11 +1467,6 @@ 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(cmd string, args ...string) error {
1471-
assert.Equal(t, "pwd", cmd)
1472-
assert.Empty(t, args)
1473-
return nil
1474-
}) // Exec pwd.
14751470
testutil.RequireSend(ctx, t, fakeDCCLI.readConfigErrC, func(envs []string) error {
14761471
assert.Contains(t, envs, "CODER_WORKSPACE_AGENT_NAME=test-container")
14771472
assert.Contains(t, envs, "CODER_WORKSPACE_NAME=test-workspace")
@@ -1814,7 +1809,6 @@ func TestAPI(t *testing.T) {
18141809
},
18151810
},
18161811
},
1817-
execErrC: make(chan func(cmd string, 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
defer close(fSAC.createErrC)
1864-
defer close(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(cmd string, args ...string) error {
1869-
assert.Equal(t, "pwd", cmd)
1870-
assert.Empty(t, args)
1871-
return nil
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(chan func(envs []string) error, 2),
1916-
execErrC: make(chan func(cmd string, args ...string) error, 1),
19171904
}
19181905

19191906
testContainer = codersdk.WorkspaceAgentContainer{
@@ -1960,16 +1947,10 @@ func TestAPI(t *testing.T) {
19601947

19611948
// Close before api.Close() defer to avoid deadlock after test.
19621949
defer close(fSAC.createErrC)
1963-
defer close(fDCCLI.execErrC)
19641950
defer close(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(cmd string, args ...string) error {
1969-
assert.Equal(t, "pwd", cmd)
1970-
assert.Empty(t, args)
1971-
return nil
1972-
})
19731954
testutil.RequireSend(ctx, t, fDCCLI.readConfigErrC, func(env []string) error {
19741955
// We expect the wrong workspace agent name passed in first.
19751956
assert.Contains(t, env, "CODER_WORKSPACE_AGENT_NAME=test-container")

agent/agentcontainers/devcontainercli.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
type DevcontainerConfig struct {
2323
MergedConfiguration DevcontainerMergedConfiguration `json:"mergedConfiguration"`
2424
Configuration DevcontainerConfiguration `json:"configuration"`
25+
Workspace DevcontainerWorkspace `json:"workspace"`
2526
}
2627

2728
type DevcontainerMergedConfiguration struct {
@@ -46,6 +47,10 @@ type CoderCustomization struct {
4647
Name string `json:"name,omitempty"`
4748
}
4849

50+
type DevcontainerWorkspace struct {
51+
WorkspaceFolder string `json:"workspaceFolder"`
52+
}
53+
4954
// DevcontainerCLI is an interface for the devcontainer CLI.
5055
type DevcontainerCLI interface {
5156
Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIUpOptions) (id string, err error)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy