Skip to content

Commit 7af188b

Browse files
authored
fix(agent): fix unexpanded devcontainer paths for agentcontainers (#17736)
Devcontainers were duplicated in the API because paths weren't absolute, we now normalize them early on to keep it simple. Updates #16424
1 parent bd65914 commit 7af188b

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

agent/agent.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,8 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
10851085
if err != nil {
10861086
return xerrors.Errorf("expand directory: %w", err)
10871087
}
1088+
// Normalize all devcontainer paths by making them absolute.
1089+
manifest.Devcontainers = agentcontainers.ExpandAllDevcontainerPaths(a.logger, expandPathToAbs, manifest.Devcontainers)
10881090
subsys, err := agentsdk.ProtoFromSubsystems(a.subsystems)
10891091
if err != nil {
10901092
a.logger.Critical(ctx, "failed to convert subsystems", slog.Error(err))
@@ -1127,7 +1129,7 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
11271129
)
11281130
if a.experimentalDevcontainersEnabled {
11291131
var dcScripts []codersdk.WorkspaceAgentScript
1130-
scripts, dcScripts = agentcontainers.ExtractAndInitializeDevcontainerScripts(a.logger, expandPathToAbs, manifest.Devcontainers, scripts)
1132+
scripts, dcScripts = agentcontainers.ExtractAndInitializeDevcontainerScripts(manifest.Devcontainers, scripts)
11311133
// See ExtractAndInitializeDevcontainerScripts for motivation
11321134
// behind running dcScripts as post start scripts.
11331135
scriptRunnerOpts = append(scriptRunnerOpts, agentscripts.WithPostStartScripts(dcScripts...))

agent/agent_test.go

+11-6
Original file line numberDiff line numberDiff line change
@@ -1998,8 +1998,9 @@ func TestAgent_ReconnectingPTYContainer(t *testing.T) {
19981998
// You can run it manually as follows:
19991999
//
20002000
// CODER_TEST_USE_DOCKER=1 go test -count=1 ./agent -run TestAgent_DevcontainerAutostart
2001+
//
2002+
//nolint:paralleltest // This test sets an environment variable.
20012003
func TestAgent_DevcontainerAutostart(t *testing.T) {
2002-
t.Parallel()
20032004
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
20042005
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
20052006
}
@@ -2012,9 +2013,12 @@ func TestAgent_DevcontainerAutostart(t *testing.T) {
20122013

20132014
// Prepare temporary devcontainer for test (mywork).
20142015
devcontainerID := uuid.New()
2015-
tempWorkspaceFolder := t.TempDir()
2016-
tempWorkspaceFolder = filepath.Join(tempWorkspaceFolder, "mywork")
2016+
tmpdir := t.TempDir()
2017+
t.Setenv("HOME", tmpdir)
2018+
tempWorkspaceFolder := filepath.Join(tmpdir, "mywork")
2019+
unexpandedWorkspaceFolder := filepath.Join("~", "mywork")
20172020
t.Logf("Workspace folder: %s", tempWorkspaceFolder)
2021+
t.Logf("Unexpanded workspace folder: %s", unexpandedWorkspaceFolder)
20182022
devcontainerPath := filepath.Join(tempWorkspaceFolder, ".devcontainer")
20192023
err = os.MkdirAll(devcontainerPath, 0o755)
20202024
require.NoError(t, err, "create devcontainer directory")
@@ -2031,9 +2035,10 @@ func TestAgent_DevcontainerAutostart(t *testing.T) {
20312035
// is expected to be prepared by the provisioner normally.
20322036
Devcontainers: []codersdk.WorkspaceAgentDevcontainer{
20332037
{
2034-
ID: devcontainerID,
2035-
Name: "test",
2036-
WorkspaceFolder: tempWorkspaceFolder,
2038+
ID: devcontainerID,
2039+
Name: "test",
2040+
// Use an unexpanded path to test the expansion.
2041+
WorkspaceFolder: unexpandedWorkspaceFolder,
20372042
},
20382043
},
20392044
Scripts: []codersdk.WorkspaceAgentScript{

agent/agentcontainers/devcontainer.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ devcontainer up %s
3636
// initialize the workspace (e.g. git clone, npm install, etc). This is
3737
// important if e.g. a Coder module to install @devcontainer/cli is used.
3838
func ExtractAndInitializeDevcontainerScripts(
39-
logger slog.Logger,
40-
expandPath func(string) (string, error),
4139
devcontainers []codersdk.WorkspaceAgentDevcontainer,
4240
scripts []codersdk.WorkspaceAgentScript,
4341
) (filteredScripts []codersdk.WorkspaceAgentScript, devcontainerScripts []codersdk.WorkspaceAgentScript) {
@@ -47,7 +45,6 @@ ScriptLoop:
4745
// The devcontainer scripts match the devcontainer ID for
4846
// identification.
4947
if script.ID == dc.ID {
50-
dc = expandDevcontainerPaths(logger, expandPath, dc)
5148
devcontainerScripts = append(devcontainerScripts, devcontainerStartupScript(dc, script))
5249
continue ScriptLoop
5350
}
@@ -75,6 +72,17 @@ func devcontainerStartupScript(dc codersdk.WorkspaceAgentDevcontainer, script co
7572
return script
7673
}
7774

75+
// ExpandAllDevcontainerPaths expands all devcontainer paths in the given
76+
// devcontainers. This is required by the devcontainer CLI, which requires
77+
// absolute paths for the workspace folder and config path.
78+
func ExpandAllDevcontainerPaths(logger slog.Logger, expandPath func(string) (string, error), devcontainers []codersdk.WorkspaceAgentDevcontainer) []codersdk.WorkspaceAgentDevcontainer {
79+
expanded := make([]codersdk.WorkspaceAgentDevcontainer, 0, len(devcontainers))
80+
for _, dc := range devcontainers {
81+
expanded = append(expanded, expandDevcontainerPaths(logger, expandPath, dc))
82+
}
83+
return expanded
84+
}
85+
7886
func expandDevcontainerPaths(logger slog.Logger, expandPath func(string) (string, error), dc codersdk.WorkspaceAgentDevcontainer) codersdk.WorkspaceAgentDevcontainer {
7987
logger = logger.With(slog.F("devcontainer", dc.Name), slog.F("workspace_folder", dc.WorkspaceFolder), slog.F("config_path", dc.ConfigPath))
8088

agent/agentcontainers/devcontainer_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,7 @@ func TestExtractAndInitializeDevcontainerScripts(t *testing.T) {
242242
}
243243
}
244244
gotFilteredScripts, gotDevcontainerScripts := agentcontainers.ExtractAndInitializeDevcontainerScripts(
245-
logger,
246-
tt.args.expandPath,
247-
tt.args.devcontainers,
245+
agentcontainers.ExpandAllDevcontainerPaths(logger, tt.args.expandPath, tt.args.devcontainers),
248246
tt.args.scripts,
249247
)
250248

0 commit comments

Comments
 (0)