Skip to content

Commit 5d714b5

Browse files
chore(agent/agentcontainers): disable project autostart by default
We disable the logic that allows autostarting discovered devcontainers by default. We want this behavior to be opt-in rather than opt-out.
1 parent 8b43503 commit 5d714b5

File tree

4 files changed

+119
-24
lines changed

4 files changed

+119
-24
lines changed

agent/agentcontainers/api.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ type API struct {
7777
subAgentURL string
7878
subAgentEnv []string
7979

80-
projectDiscovery bool // If we should perform project discovery or not.
80+
projectDiscovery bool // If we should perform project discovery or not.
81+
discoveryAutostart bool // If we should autostart discovered projects.
8182

8283
ownerName string
8384
workspaceName string
@@ -144,7 +145,8 @@ func WithCommandEnv(ce CommandEnv) Option {
144145
strings.HasPrefix(s, "CODER_AGENT_TOKEN=") ||
145146
strings.HasPrefix(s, "CODER_AGENT_AUTH=") ||
146147
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_ENABLE=") ||
147-
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE=")
148+
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE=") ||
149+
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE=")
148150
})
149151
return shell, dir, env, nil
150152
}
@@ -287,6 +289,14 @@ func WithProjectDiscovery(projectDiscovery bool) Option {
287289
}
288290
}
289291

292+
// WithProjectDiscovery sets if the API should attempt to autostart
293+
// projects that have been discovered
294+
func WithDiscoveryAutostart(discoveryAutostart bool) Option {
295+
return func(api *API) {
296+
api.discoveryAutostart = discoveryAutostart
297+
}
298+
}
299+
290300
// ScriptLogger is an interface for sending devcontainer logs to the
291301
// controlplane.
292302
type ScriptLogger interface {
@@ -542,11 +552,13 @@ func (api *API) discoverDevcontainersInProject(projectPath string) error {
542552
Container: nil,
543553
}
544554

545-
config, err := api.dccli.ReadConfig(api.ctx, workspaceFolder, path, []string{})
546-
if err != nil {
547-
logger.Error(api.ctx, "read project configuration", slog.Error(err))
548-
} else if config.Configuration.Customizations.Coder.AutoStart {
549-
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStarting
555+
if api.discoveryAutostart {
556+
config, err := api.dccli.ReadConfig(api.ctx, workspaceFolder, path, []string{})
557+
if err != nil {
558+
logger.Error(api.ctx, "read project configuration", slog.Error(err))
559+
} else if config.Configuration.Customizations.Coder.AutoStart {
560+
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStarting
561+
}
550562
}
551563

552564
api.knownDevcontainers[workspaceFolder] = dc

agent/agentcontainers/api_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,6 +3792,7 @@ func TestDevcontainerDiscovery(t *testing.T) {
37923792
agentcontainers.WithContainerCLI(&fakeContainerCLI{}),
37933793
agentcontainers.WithDevcontainerCLI(mDCCLI),
37943794
agentcontainers.WithProjectDiscovery(true),
3795+
agentcontainers.WithDiscoveryAutostart(true),
37953796
)
37963797
api.Start()
37973798
defer api.Close()
@@ -3813,6 +3814,75 @@ func TestDevcontainerDiscovery(t *testing.T) {
38133814
// Then: We expect the mock infra to not fail.
38143815
})
38153816
}
3817+
3818+
t.Run("Disabled", func(t *testing.T) {
3819+
t.Parallel()
3820+
var (
3821+
ctx = testutil.Context(t, testutil.WaitShort)
3822+
logger = testutil.Logger(t)
3823+
mClock = quartz.NewMock(t)
3824+
mDCCLI = acmock.NewMockDevcontainerCLI(gomock.NewController(t))
3825+
3826+
fs = map[string]string{
3827+
"/home/coder/.git/HEAD": "",
3828+
"/home/coder/.devcontainer/devcontainer.json": "",
3829+
}
3830+
3831+
r = chi.NewRouter()
3832+
)
3833+
3834+
// We expect that neither `ReadConfig`, nor `Up` are called as we
3835+
// have explicitly disabled the agentcontainers API from attempting
3836+
// to autostart devcontainers that it discovers.
3837+
mDCCLI.EXPECT().ReadConfig(gomock.Any(),
3838+
"/home/coder",
3839+
"/home/coder/.devcontainer/devcontainer.json",
3840+
[]string{},
3841+
).Return(agentcontainers.DevcontainerConfig{
3842+
Configuration: agentcontainers.DevcontainerConfiguration{
3843+
Customizations: agentcontainers.DevcontainerCustomizations{
3844+
Coder: agentcontainers.CoderCustomization{
3845+
AutoStart: true,
3846+
},
3847+
},
3848+
},
3849+
}, nil).Times(0)
3850+
3851+
mDCCLI.EXPECT().Up(gomock.Any(),
3852+
"/home/coder",
3853+
"/home/coder/.devcontainer/devcontainer.json",
3854+
gomock.Any(),
3855+
).Return("", nil).Times(0)
3856+
3857+
api := agentcontainers.NewAPI(logger,
3858+
agentcontainers.WithClock(mClock),
3859+
agentcontainers.WithWatcher(watcher.NewNoop()),
3860+
agentcontainers.WithFileSystem(initFS(t, fs)),
3861+
agentcontainers.WithManifestInfo("owner", "workspace", "parent-agent", "/home/coder"),
3862+
agentcontainers.WithContainerCLI(&fakeContainerCLI{}),
3863+
agentcontainers.WithDevcontainerCLI(mDCCLI),
3864+
agentcontainers.WithProjectDiscovery(true),
3865+
agentcontainers.WithDiscoveryAutostart(false),
3866+
)
3867+
api.Start()
3868+
defer api.Close()
3869+
r.Mount("/", api.Routes())
3870+
3871+
// When: All expected dev containers have been found.
3872+
require.Eventuallyf(t, func() bool {
3873+
req := httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx)
3874+
rec := httptest.NewRecorder()
3875+
r.ServeHTTP(rec, req)
3876+
3877+
got := codersdk.WorkspaceAgentListContainersResponse{}
3878+
err := json.NewDecoder(rec.Body).Decode(&got)
3879+
require.NoError(t, err)
3880+
3881+
return len(got.Devcontainers) >= 1
3882+
}, testutil.WaitShort, testutil.IntervalFast, "dev containers never found")
3883+
3884+
// Then: We expect the mock infra to not fail.
3885+
})
38163886
})
38173887
}
38183888

cli/agent.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,24 @@ import (
4040

4141
func (r *RootCmd) workspaceAgent() *serpent.Command {
4242
var (
43-
auth string
44-
logDir string
45-
scriptDataDir string
46-
pprofAddress string
47-
noReap bool
48-
sshMaxTimeout time.Duration
49-
tailnetListenPort int64
50-
prometheusAddress string
51-
debugAddress string
52-
slogHumanPath string
53-
slogJSONPath string
54-
slogStackdriverPath string
55-
blockFileTransfer bool
56-
agentHeaderCommand string
57-
agentHeader []string
58-
devcontainers bool
59-
devcontainerProjectDiscovery bool
43+
auth string
44+
logDir string
45+
scriptDataDir string
46+
pprofAddress string
47+
noReap bool
48+
sshMaxTimeout time.Duration
49+
tailnetListenPort int64
50+
prometheusAddress string
51+
debugAddress string
52+
slogHumanPath string
53+
slogJSONPath string
54+
slogStackdriverPath string
55+
blockFileTransfer bool
56+
agentHeaderCommand string
57+
agentHeader []string
58+
devcontainers bool
59+
devcontainerProjectDiscovery bool
60+
devcontainerDiscoveryAutostart bool
6061
)
6162
cmd := &serpent.Command{
6263
Use: "agent",
@@ -366,6 +367,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
366367
DevcontainerAPIOptions: []agentcontainers.Option{
367368
agentcontainers.WithSubAgentURL(r.agentURL.String()),
368369
agentcontainers.WithProjectDiscovery(devcontainerProjectDiscovery),
370+
agentcontainers.WithDiscoveryAutostart(devcontainerDiscoveryAutostart),
369371
},
370372
})
371373

@@ -519,6 +521,13 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
519521
Description: "Allow the agent to search the filesystem for devcontainer projects.",
520522
Value: serpent.BoolOf(&devcontainerProjectDiscovery),
521523
},
524+
{
525+
Flag: "devcontainers-discovery-autostart-enable",
526+
Default: "false",
527+
Env: "CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE",
528+
Description: "Allow the agent to autostart devcontainer projects it discovers based on their configuration.",
529+
Value: serpent.BoolOf(&devcontainerDiscoveryAutostart),
530+
},
522531
}
523532

524533
return cmd

cli/testdata/coder_agent_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ OPTIONS:
3333
--debug-address string, $CODER_AGENT_DEBUG_ADDRESS (default: 127.0.0.1:2113)
3434
The bind address to serve a debug HTTP server.
3535

36+
--devcontainers-discovery-autostart-enable bool, $CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE (default: false)
37+
Allow the agent to autostart devcontainer projects it discovers based
38+
on their configuration.
39+
3640
--devcontainers-enable bool, $CODER_AGENT_DEVCONTAINERS_ENABLE (default: true)
3741
Allow the agent to automatically detect running devcontainers.
3842

0 commit comments

Comments
 (0)