Skip to content

Commit e75fb3b

Browse files
committed
Merge branch 'main' into callum-cors
Signed-off-by: Callum Styan <callumstyan@gmail.com>
2 parents 432aff6 + 1319ae2 commit e75fb3b

File tree

91 files changed

+3751
-1182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3751
-1182
lines changed

.github/workflows/release.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ jobs:
693693
gsutil -h "Cache-Control:no-cache,max-age=0" cp build/helm/provisioner_helm_${version}.tgz gs://helm.coder.com/v2
694694
gsutil -h "Cache-Control:no-cache,max-age=0" cp build/helm/index.yaml gs://helm.coder.com/v2
695695
gsutil -h "Cache-Control:no-cache,max-age=0" cp helm/artifacthub-repo.yml gs://helm.coder.com/v2
696+
helm push build/coder_helm_${version}.tgz oci://ghcr.io/coder/chart
697+
helm push build/provisioner_helm_${version}.tgz oci://ghcr.io/coder/chart
696698
697699
- name: Upload artifacts to actions (if dry-run)
698700
if: ${{ inputs.dry_run }}

agent/agent.go

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -336,18 +336,16 @@ func (a *agent) init() {
336336
// will not report anywhere.
337337
a.scriptRunner.RegisterMetrics(a.prometheusRegistry)
338338

339-
if a.devcontainers {
340-
containerAPIOpts := []agentcontainers.Option{
341-
agentcontainers.WithExecer(a.execer),
342-
agentcontainers.WithCommandEnv(a.sshServer.CommandEnv),
343-
agentcontainers.WithScriptLogger(func(logSourceID uuid.UUID) agentcontainers.ScriptLogger {
344-
return a.logSender.GetScriptLogger(logSourceID)
345-
}),
346-
}
347-
containerAPIOpts = append(containerAPIOpts, a.containerAPIOptions...)
348-
349-
a.containerAPI = agentcontainers.NewAPI(a.logger.Named("containers"), containerAPIOpts...)
339+
containerAPIOpts := []agentcontainers.Option{
340+
agentcontainers.WithExecer(a.execer),
341+
agentcontainers.WithCommandEnv(a.sshServer.CommandEnv),
342+
agentcontainers.WithScriptLogger(func(logSourceID uuid.UUID) agentcontainers.ScriptLogger {
343+
return a.logSender.GetScriptLogger(logSourceID)
344+
}),
350345
}
346+
containerAPIOpts = append(containerAPIOpts, a.containerAPIOptions...)
347+
348+
a.containerAPI = agentcontainers.NewAPI(a.logger.Named("containers"), containerAPIOpts...)
351349

352350
a.reconnectingPTYServer = reconnectingpty.NewServer(
353351
a.logger.Named("reconnecting-pty"),
@@ -1162,7 +1160,7 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
11621160
scripts = manifest.Scripts
11631161
devcontainerScripts map[uuid.UUID]codersdk.WorkspaceAgentScript
11641162
)
1165-
if a.containerAPI != nil {
1163+
if a.devcontainers {
11661164
// Init the container API with the manifest and client so that
11671165
// we can start accepting requests. The final start of the API
11681166
// happens after the startup scripts have been executed to
@@ -1197,7 +1195,7 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
11971195
// autostarted devcontainer will be included in this time.
11981196
err := a.scriptRunner.Execute(a.gracefulCtx, agentscripts.ExecuteStartScripts)
11991197

1200-
if a.containerAPI != nil {
1198+
if a.devcontainers {
12011199
// Start the container API after the startup scripts have
12021200
// been executed to ensure that the required tools can be
12031201
// installed.
@@ -1928,10 +1926,8 @@ func (a *agent) Close() error {
19281926
a.logger.Error(a.hardCtx, "script runner close", slog.Error(err))
19291927
}
19301928

1931-
if a.containerAPI != nil {
1932-
if err := a.containerAPI.Close(); err != nil {
1933-
a.logger.Error(a.hardCtx, "container API close", slog.Error(err))
1934-
}
1929+
if err := a.containerAPI.Close(); err != nil {
1930+
a.logger.Error(a.hardCtx, "container API close", slog.Error(err))
19351931
}
19361932

19371933
// Wait for the graceful shutdown to complete, but don't wait forever so

agent/agent_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,7 +2441,8 @@ func TestAgent_DevcontainersDisabledForSubAgent(t *testing.T) {
24412441

24422442
// Setup the agent with devcontainers enabled initially.
24432443
//nolint:dogsled
2444-
conn, _, _, _, _ := setupAgent(t, manifest, 0, func(*agenttest.Client, *agent.Options) {
2444+
conn, _, _, _, _ := setupAgent(t, manifest, 0, func(_ *agenttest.Client, o *agent.Options) {
2445+
o.Devcontainers = true
24452446
})
24462447

24472448
// Query the containers API endpoint. This should fail because
@@ -2453,8 +2454,8 @@ func TestAgent_DevcontainersDisabledForSubAgent(t *testing.T) {
24532454
require.Error(t, err)
24542455

24552456
// Verify the error message contains the expected text.
2456-
require.Contains(t, err.Error(), "The agent dev containers feature is experimental and not enabled by default.")
2457-
require.Contains(t, err.Error(), "To enable this feature, set CODER_AGENT_DEVCONTAINERS_ENABLE=true in your template.")
2457+
require.Contains(t, err.Error(), "Dev Container feature not supported.")
2458+
require.Contains(t, err.Error(), "Dev Container integration inside other Dev Containers is explicitly not supported.")
24582459
}
24592460

24602461
func TestAgent_Dial(t *testing.T) {

agent/agentcontainers/devcontainercli.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -106,63 +106,63 @@ type DevcontainerCLI interface {
106106

107107
// DevcontainerCLIUpOptions are options for the devcontainer CLI Up
108108
// command.
109-
type DevcontainerCLIUpOptions func(*devcontainerCLIUpConfig)
109+
type DevcontainerCLIUpOptions func(*DevcontainerCLIUpConfig)
110110

111-
type devcontainerCLIUpConfig struct {
112-
args []string // Additional arguments for the Up command.
113-
stdout io.Writer
114-
stderr io.Writer
111+
type DevcontainerCLIUpConfig struct {
112+
Args []string // Additional arguments for the Up command.
113+
Stdout io.Writer
114+
Stderr io.Writer
115115
}
116116

117117
// WithRemoveExistingContainer is an option to remove the existing
118118
// container.
119119
func WithRemoveExistingContainer() DevcontainerCLIUpOptions {
120-
return func(o *devcontainerCLIUpConfig) {
121-
o.args = append(o.args, "--remove-existing-container")
120+
return func(o *DevcontainerCLIUpConfig) {
121+
o.Args = append(o.Args, "--remove-existing-container")
122122
}
123123
}
124124

125125
// WithUpOutput sets additional stdout and stderr writers for logs
126126
// during Up operations.
127127
func WithUpOutput(stdout, stderr io.Writer) DevcontainerCLIUpOptions {
128-
return func(o *devcontainerCLIUpConfig) {
129-
o.stdout = stdout
130-
o.stderr = stderr
128+
return func(o *DevcontainerCLIUpConfig) {
129+
o.Stdout = stdout
130+
o.Stderr = stderr
131131
}
132132
}
133133

134134
// DevcontainerCLIExecOptions are options for the devcontainer CLI Exec
135135
// command.
136-
type DevcontainerCLIExecOptions func(*devcontainerCLIExecConfig)
136+
type DevcontainerCLIExecOptions func(*DevcontainerCLIExecConfig)
137137

138-
type devcontainerCLIExecConfig struct {
139-
args []string // Additional arguments for the Exec command.
140-
stdout io.Writer
141-
stderr io.Writer
138+
type DevcontainerCLIExecConfig struct {
139+
Args []string // Additional arguments for the Exec command.
140+
Stdout io.Writer
141+
Stderr io.Writer
142142
}
143143

144144
// WithExecOutput sets additional stdout and stderr writers for logs
145145
// during Exec operations.
146146
func WithExecOutput(stdout, stderr io.Writer) DevcontainerCLIExecOptions {
147-
return func(o *devcontainerCLIExecConfig) {
148-
o.stdout = stdout
149-
o.stderr = stderr
147+
return func(o *DevcontainerCLIExecConfig) {
148+
o.Stdout = stdout
149+
o.Stderr = stderr
150150
}
151151
}
152152

153153
// WithExecContainerID sets the container ID to target a specific
154154
// container.
155155
func WithExecContainerID(id string) DevcontainerCLIExecOptions {
156-
return func(o *devcontainerCLIExecConfig) {
157-
o.args = append(o.args, "--container-id", id)
156+
return func(o *DevcontainerCLIExecConfig) {
157+
o.Args = append(o.Args, "--container-id", id)
158158
}
159159
}
160160

161161
// WithRemoteEnv sets environment variables for the Exec command.
162162
func WithRemoteEnv(env ...string) DevcontainerCLIExecOptions {
163-
return func(o *devcontainerCLIExecConfig) {
163+
return func(o *DevcontainerCLIExecConfig) {
164164
for _, e := range env {
165-
o.args = append(o.args, "--remote-env", e)
165+
o.Args = append(o.Args, "--remote-env", e)
166166
}
167167
}
168168
}
@@ -185,8 +185,8 @@ func WithReadConfigOutput(stdout, stderr io.Writer) DevcontainerCLIReadConfigOpt
185185
}
186186
}
187187

188-
func applyDevcontainerCLIUpOptions(opts []DevcontainerCLIUpOptions) devcontainerCLIUpConfig {
189-
conf := devcontainerCLIUpConfig{stdout: io.Discard, stderr: io.Discard}
188+
func applyDevcontainerCLIUpOptions(opts []DevcontainerCLIUpOptions) DevcontainerCLIUpConfig {
189+
conf := DevcontainerCLIUpConfig{Stdout: io.Discard, Stderr: io.Discard}
190190
for _, opt := range opts {
191191
if opt != nil {
192192
opt(&conf)
@@ -195,8 +195,8 @@ func applyDevcontainerCLIUpOptions(opts []DevcontainerCLIUpOptions) devcontainer
195195
return conf
196196
}
197197

198-
func applyDevcontainerCLIExecOptions(opts []DevcontainerCLIExecOptions) devcontainerCLIExecConfig {
199-
conf := devcontainerCLIExecConfig{stdout: io.Discard, stderr: io.Discard}
198+
func applyDevcontainerCLIExecOptions(opts []DevcontainerCLIExecOptions) DevcontainerCLIExecConfig {
199+
conf := DevcontainerCLIExecConfig{Stdout: io.Discard, Stderr: io.Discard}
200200
for _, opt := range opts {
201201
if opt != nil {
202202
opt(&conf)
@@ -241,7 +241,7 @@ func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath st
241241
if configPath != "" {
242242
args = append(args, "--config", configPath)
243243
}
244-
args = append(args, conf.args...)
244+
args = append(args, conf.Args...)
245245
cmd := d.execer.CommandContext(ctx, "devcontainer", args...)
246246

247247
// Capture stdout for parsing and stream logs for both default and provided writers.
@@ -251,14 +251,14 @@ func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath st
251251
&devcontainerCLILogWriter{
252252
ctx: ctx,
253253
logger: logger.With(slog.F("stdout", true)),
254-
writer: conf.stdout,
254+
writer: conf.Stdout,
255255
},
256256
)
257257
// Stream stderr logs and provided writer if any.
258258
cmd.Stderr = &devcontainerCLILogWriter{
259259
ctx: ctx,
260260
logger: logger.With(slog.F("stderr", true)),
261-
writer: conf.stderr,
261+
writer: conf.Stderr,
262262
}
263263

264264
if err := cmd.Run(); err != nil {
@@ -293,17 +293,17 @@ func (d *devcontainerCLI) Exec(ctx context.Context, workspaceFolder, configPath
293293
if configPath != "" {
294294
args = append(args, "--config", configPath)
295295
}
296-
args = append(args, conf.args...)
296+
args = append(args, conf.Args...)
297297
args = append(args, cmd)
298298
args = append(args, cmdArgs...)
299299
c := d.execer.CommandContext(ctx, "devcontainer", args...)
300300

301-
c.Stdout = io.MultiWriter(conf.stdout, &devcontainerCLILogWriter{
301+
c.Stdout = io.MultiWriter(conf.Stdout, &devcontainerCLILogWriter{
302302
ctx: ctx,
303303
logger: logger.With(slog.F("stdout", true)),
304304
writer: io.Discard,
305305
})
306-
c.Stderr = io.MultiWriter(conf.stderr, &devcontainerCLILogWriter{
306+
c.Stderr = io.MultiWriter(conf.Stderr, &devcontainerCLILogWriter{
307307
ctx: ctx,
308308
logger: logger.With(slog.F("stderr", true)),
309309
writer: io.Discard,

agent/api.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"github.com/go-chi/chi/v5"
9+
"github.com/google/uuid"
910

1011
"github.com/coder/coder/v2/coderd/httpapi"
1112
"github.com/coder/coder/v2/codersdk"
@@ -36,12 +37,19 @@ func (a *agent) apiHandler() http.Handler {
3637
cacheDuration: cacheDuration,
3738
}
3839

39-
if a.containerAPI != nil {
40+
if a.devcontainers {
4041
r.Mount("/api/v0/containers", a.containerAPI.Routes())
42+
} else if manifest := a.manifest.Load(); manifest != nil && manifest.ParentID != uuid.Nil {
43+
r.HandleFunc("/api/v0/containers", func(w http.ResponseWriter, r *http.Request) {
44+
httpapi.Write(r.Context(), w, http.StatusForbidden, codersdk.Response{
45+
Message: "Dev Container feature not supported.",
46+
Detail: "Dev Container integration inside other Dev Containers is explicitly not supported.",
47+
})
48+
})
4149
} else {
4250
r.HandleFunc("/api/v0/containers", func(w http.ResponseWriter, r *http.Request) {
4351
httpapi.Write(r.Context(), w, http.StatusForbidden, codersdk.Response{
44-
Message: "The agent dev containers feature is experimental and not enabled by default.",
52+
Message: "Dev Container feature not enabled.",
4553
Detail: "To enable this feature, set CODER_AGENT_DEVCONTAINERS_ENABLE=true in your template.",
4654
})
4755
})

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