devcontainers / cli

A reference implementation for the specification that can create and configure a dev container from a devcontainer.json.
https://containers.dev
MIT License
1.61k stars 225 forks source link

Valid devcontainer.metadata can corrupt compose override file #904

Open Achllle opened 2 months ago

Achllle commented 2 months ago

dev containers version: v0.387.0 OS: Ubuntu 24.04

Description

I can't get a compose file to run through devcontainers even though it runs fine from command line. The culprit seems to be a corrupted 'Features Compose Override File' generation that I don't even know how to clear.

At one point my compose.yaml file had the following environment variable set:

ROSCONSOLE_FORMAT: "[$${severity}] [$${walltime:%Y-%m-%d %H:%M:%S}] [$${node}]: $${message}"

This works in the repro example below and has worked for me in the past with docker compose running from CLI. However, it complained while I was migrating to use compose + devcontainers. From the logs below, it seems like the dictionary was getting converted to a list, and the colon in the value field doesn't play nice:

[2024-09-24T19:43:41.966Z] Stop (354 ms): Run: docker build -f /tmp/devcontainercli-achille/updateUID.Dockerfile-0.71.0 -t vsc-dev-docker-afd93ed1eced211ffad11c8e3235c1ce630bab41c837eddba2a4841a56df1b38-uid --platform linux/amd64 --build-arg BASE_IMAGE=gmr/customer --build-arg REMOTE_USER=gmruser --build-arg NEW_UID=1000 --build-arg NEW_GID=1000 --build-arg IMAGE_USER=gmruser /home/achille/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/empty-folder
[2024-09-24T19:43:41.967Z] Docker Compose override file for creating container:
services:
  'customer':
    image: vsc-dev-docker-afd93ed1eced211ffad11c8e3235c1ce630bab41c837eddba2a4841a56df1b38-uid
    entrypoint: ["/bin/sh", "-c", "echo Container started\n
trap \"exit 0\" 15\n
\n
exec \"$$@\"\n
while sleep 1 & wait $$!; do :; done", "-", "/entrypoint.sh"]
    environment:
      - USER=achille
      - DISPLAY=:1
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility,display
      - XAUTHORITY=
      - QT_X11_NO_MITSHM=1
      - ROSCONSOLE_FORMAT='[${severity}] [${walltime:%Y-%m-%d %H:%M:%S}] [${node}]: ${message}'
    labels:
      - 'devcontainer.local_folder=/home/achille/gmr/dev-docker'
      - 'devcontainer.config_file=/home/achille/gmr/dev-docker/.devcontainer/devcontainer.json'
      - 'devcontainer.metadata=[{"postCreateCommand":"/bin/bash .devcontainer/postCreate_command.sh $${containerWorkspaceFolder}","customizations":{"vscode":{"settings":{"terminal.integrated.profiles.linux":{"bash":{"path":"bash"}},"terminal.integrated.defaultProfile.linux":"bash","remote.autoForwardPorts":false},"extensions":["dotjoshjohnson.xml","zachflower.uncrustify","ms-azuretools.vscode-docker","ms-iot.vscode-ros","ms-python.python","ms-vscode.cpptools-extension-pack","redhat.vscode-yaml","smilerobotics.urdf","streetsidesoftware.code-spell-checker","twxs.cmake","yzhang.markdown-all-in-one","github.vscode-github-actions","ms-vscode.cpptools","ms-vscode.cmake-tools"]}},"mounts":["type=bind,source=/var/log/.ros,target=/var/log/.ros","type=bind,source=$${localWorkspaceFolder}/persistent_data,target=/home/gmruser/.ss","type=bind,source=$${localWorkspaceFolder}/runtime_data,target=/home/gmruser/.ss_temp","type=bind,source=/etc/ss,target=/etc/ss","type=bind,src=$${localEnv:HOME}/.ssh,target=/home/gmruser/.ssh,readonly","type=bind,src=$${localEnv:HOME}/.ssh/known_hosts,target=/home/gmruser/.ssh/known_hosts","type=bind,src=$${localEnv:HOME}/.backport/config.json,target=/home/gmruser/.backport/config.json","type=volume,target=$${containerWorkspaceFolder}/build","type=volume,target=$${containerWorkspaceFolder}/install"],"containerEnv":{"USER":"$${localEnv:USER}","DISPLAY":"$${localEnv:DISPLAY}","NVIDIA_VISIBLE_DEVICES":"all","NVIDIA_DRIVER_CAPABILITIES":"compute,utility,display","XAUTHORITY":"$${localEnv:XAUTH}","QT_X11_NO_MITSHM":"1","ROSCONSOLE_FORMAT":"''[$${severity}] [$${walltime:%Y-%m-%d %H:%M:%S}] [$${node}]: $${message}''"},"remoteUser":"gmruser"},{"postCreateCommand":"/bin/bash .devcontainer/postCreate_command.sh $${containerWorkspaceFolder}","customizations":{"vscode":{"settings":{"terminal.integrated.profiles.linux":{"bash":{"path":"bash"}},"terminal.integrated.defaultProfile.linux":"bash","remote.autoForwardPorts":false},"extensions":["dotjoshjohnson.xml","zachflower.uncrustify","ms-azuretools.vscode-docker","ms-iot.vscode-ros","ms-python.python","ms-vscode.cpptools-extension-pack","redhat.vscode-yaml","smilerobotics.urdf","streetsidesoftware.code-spell-checker","twxs.cmake","yzhang.markdown-all-in-one","github.vscode-github-actions","ms-vscode.cpptools","ms-vscode.cmake-tools"]}},"mounts":["type=bind,source=/var/log/.ros,target=/var/log/.ros","type=bind,src=/etc/ss/,dst=/etc/ss","type=bind,src=$${localEnv:HOME}/.ssh,target=/home/gmruser/.ssh,readonly","type=bind,src=$${localEnv:HOME}/.ssh/known_hosts,target=/home/gmruser/.ssh/known_hosts","type=bind,src=$${localEnv:HOME}/.backport/config.json,target=/home/gmruser/.backport/config.json","type=volume,target=/workspaces/platform/build","type=volume,target=/workspaces/platform/install","type=volume,target=$${containerWorkspaceFolder}/build","type=volume,target=$${containerWorkspaceFolder}/install"],"containerEnv":{"USER":"$${localEnv:USER}","DISPLAY":"$${localEnv:DISPLAY}","NVIDIA_VISIBLE_DEVICES":"all","NVIDIA_DRIVER_CAPABILITIES":"compute,utility,display","XAUTHORITY":"$${localEnv:XAUTH}","QT_X11_NO_MITSHM":"1","ROSCONSOLE_FORMAT":"''[$${severity}] [$${walltime:%Y-%m-%d %H:%M:%S}] [$${node}]: $${message}''"},"remoteUser":"gmruser"},{"remoteUser":"gmruser"}]'
    volumes:
     [...]
      - vscode:/vscode
volumes:

  vscode:
    external: true

This failed with the following error:

[2024-09-24T19:43:41.967Z] Writing docker-compose.devcontainer.containerFeatures-1727207021967-6e5554e4-df63-43ad-ab82-77c2b36e0506.yml to /home/achille/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/docker-compose
[2024-09-24T19:43:41.967Z] Start: Run: docker compose --project-name dev-docker -f /home/achille/gmr/dev-docker/compose.yaml -f /home/achille/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/docker-compose/docker-compose.devcontainer.containerFeatures-1727207021967-6e5554e4-df63-43ad-ab82-77c2b36e0506.yml up -d
[2024-09-24T19:43:42.015Z] WARN[0000] The "message" variable is not set. Defaulting to a blank string. 
[2024-09-24T19:43:42.015Z] services.customer.environment.[6]: unexpected type map[string]interface {}

The first thing I did was to remove the offending ROSCONSOLE_FORMAT variable from my compose.yaml file. However, Rebuild and reopen in container will still yield the same error. I've tried reopening the window to no avail.

When I copy the command being run docker compose --project-name dev-docker -f /home/achille/gmr/dev-docker/compose.yaml -f /home/achille/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/docker-compose/docker-compose.devcontainer.containerFeatures-1727207021967-6e5554e4-df63-43ad-ab82-77c2b36e0506.yml up -d and modify the containerFeatures compose file and remove the offending line manually and then run this command from the terminal, it works fine. But this file gets regenerated every time I run 'reopen in container'.

I've tried:

EDIT: I've found that the issue stems from the devcontainer.metadata that's attached to the image being used. That image was created using devcontainers and has the ROSCONSOLE_FORMAT baked into it, which this compose override file generation seems to be using. Removing the environment variable from the original image solved the issue. I will update the repro repository accordingly.

Repro

EDIT: repro here

samruddhikhandale commented 2 months ago

@gauravsaini04 / @prathameshzarkar9 Can either of you help take a look? Thanks!

Achllle commented 2 months ago

added a reproducible example here