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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 11 additions & 6 deletions
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

Lines changed: 11 additions & 3 deletions
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

Lines changed: 1 addition & 3 deletions
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)
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