fix(agent/agentcontainers): correct definition of remoteEnv (#16845)

`devcontainer.metadata` is apparently an array, not an object. Missed
this first time round!

```
    error= get container env info:
               github.com/coder/coder/v2/agent/reconnectingpty.(*Server).handleConn
                   /home/runner/work/coder/coder/agent/reconnectingpty/server.go:193
             - read devcontainer remoteEnv:
               github.com/coder/coder/v2/agent/agentcontainers.EnvInfo
                   /home/runner/work/coder/coder/agent/agentcontainers/containers_dockercli.go:119
             - unmarshal devcontainer.metadata:
               github.com/coder/coder/v2/agent/agentcontainers.devcontainerEnv
                   /home/runner/work/coder/coder/agent/agentcontainers/containers_dockercli.go:189
             - json: cannot unmarshal array into Go value of type struct { RemoteEnv map[string]string "json:\"remoteEnv\"" }
```
This commit is contained in:
Cian Johnston
2025-03-07 15:59:37 +00:00
committed by GitHub
parent 32c36d5336
commit 61246bc48e
3 changed files with 26 additions and 12 deletions
@@ -182,17 +182,18 @@ func devcontainerEnv(ctx context.Context, execer agentexec.Execer, container str
if !ok {
return nil, nil
}
meta := struct {
RemoteEnv map[string]string `json:"remoteEnv"`
}{}
meta := make([]DevContainerMeta, 0)
if err := json.Unmarshal([]byte(rawMeta), &meta); err != nil {
return nil, xerrors.Errorf("unmarshal devcontainer.metadata: %w", err)
}
// The environment variables are stored in the `remoteEnv` key.
env := make([]string, 0, len(meta.RemoteEnv))
for k, v := range meta.RemoteEnv {
env = append(env, fmt.Sprintf("%s=%s", k, v))
env := make([]string, 0)
for _, m := range meta {
for k, v := range m.RemoteEnv {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
}
slices.Sort(env)
return env, nil
@@ -53,7 +53,7 @@ func TestIntegrationDocker(t *testing.T) {
Cmd: []string{"sleep", "infnity"},
Labels: map[string]string{
"com.coder.test": testLabelValue,
"devcontainer.metadata": `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`,
"devcontainer.metadata": `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`,
},
Mounts: []string{testTempDir + ":" + testTempDir},
ExposedPorts: []string{fmt.Sprintf("%d/tcp", testRandPort)},
@@ -437,7 +437,7 @@ func TestDockerEnvInfoer(t *testing.T) {
}{
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "root",
@@ -445,7 +445,7 @@ func TestDockerEnvInfoer(t *testing.T) {
},
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
@@ -453,14 +453,14 @@ func TestDockerEnvInfoer(t *testing.T) {
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "coder",
expectedUserShell: "/bin/bash",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "coder",
expectedUsername: "coder",
@@ -468,7 +468,15 @@ func TestDockerEnvInfoer(t *testing.T) {
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/bash",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar"}},{"remoteEnv": {"MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
@@ -0,0 +1,5 @@
package agentcontainers
type DevContainerMeta struct {
RemoteEnv map[string]string `json:"remoteEnv,omitempty"`
}