devcontainers / spec

Development Containers: Use a container as a full-featured development environment.
https://containers.dev
Creative Commons Attribution 4.0 International
3.62k stars 234 forks source link

containerEnv and remoteEnv issues in devcontainer and devcontainer-feature #434

Open hellodword opened 9 months ago

hellodword commented 9 months ago

related issues:

docs:

First test a devcontainer.json:

{
    "image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04",
    "containerEnv": {
        "WHATEVER1": "WHATEVER1",
        "WHATEVER2": "$WHATEVER1",
        "WHATEVER3": "${containerEnv:WHATEVER1}",
        "WHATEVER4": "${remoteEnv:R_WHATEVER1}",
        "WHATEVER5": "${containerEnv:HOME}",
        "WHATEVER6": "${remoteEnv:HOME}",
        "WHATEVER7": "$HOME",
        "WHATEVER8": "${localEnv:HOME}"
    },
    "remoteEnv": {
        "R_WHATEVER1": "WHATEVER1",
        "R_WHATEVER2": "$WHATEVER1",
        "R_WHATEVER3": "${containerEnv:WHATEVER1}",
        "R_WHATEVER4": "${remoteEnv:R_WHATEVER1}",
        "R_WHATEVER5": "${containerEnv:HOME}",
        "R_WHATEVER6": "${remoteEnv:HOME}",
        "R_WHATEVER7": "$HOME",
        "R_WHATEVER8": "${localEnv:HOME}",
        "PATH": "${containerEnv:PATH}:WHATEVER/bin"
    }
}

build and check the env:

$ env | sort | grep WHATEVER
PATH=/vscode/vscode-server/bin/linux-x64/<...>/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:WHATEVER/bin:/home/vscode/.local/bin
R_WHATEVER1=WHATEVER1
R_WHATEVER2=$WHATEVER1
R_WHATEVER3=WHATEVER1
R_WHATEVER4=${remoteEnv:R_WHATEVER1}
R_WHATEVER5=
R_WHATEVER6=${remoteEnv:HOME}
R_WHATEVER7=$HOME
R_WHATEVER8=/home/ubuntu
WHATEVER1=WHATEVER1
WHATEVER2=$WHATEVER1
WHATEVER3=${containerEnv:WHATEVER1}
WHATEVER4=${remoteEnv:R_WHATEVER1}
WHATEVER5=${containerEnv:HOME}
WHATEVER6=${remoteEnv:HOME}
WHATEVER7=$HOME
WHATEVER8=/home/ubuntu

Then the devcontainer-feature.json, remoteEnv is not allowed, and all the ${*:*} pattern will throw an error:

{
    "name": "containerenv",
    "id": "containerenv",
    "version": "1.0.0",
    "description": "",
    "containerEnv": {
        "WHATEVER1": "WHATEVER1",
        "WHATEVER2": "$WHATEVER1",
        "WHATEVER7": "$HOME"
    },
    "installsAfter": [
        "ghcr.io/devcontainers/features/common-utils"
    ]
}

build and check the env:

$ env | sort | grep WHATEVER
WHATEVER1=WHATEVER1
WHATEVER2=WHATEVER1
WHATEVER7=

I have some questions:

  1. Is it possible that the devcontainer-feature.json keep the same logic of containerEnv & remoteEnv with devcontainer.json in the future? Or at least support the ${localEnv:*}?

  2. Check the outputs, have you considered about evaluating these as empty string? Similar with the behavior of shell.

    $ env | sort | grep WHATEVER
    R_WHATEVER4=${remoteEnv:R_WHATEVER1}
    R_WHATEVER6=${remoteEnv:HOME}
    WHATEVER3=${containerEnv:WHATEVER1}
    WHATEVER4=${remoteEnv:R_WHATEVER1}
    WHATEVER5=${containerEnv:HOME}
    WHATEVER6=${remoteEnv:HOME}
alexanderilyin commented 9 months ago

Yeah, I need to access some credentials in install.sh and for now I had to try to fall back to mounting some kind of file instead of using env vars.

P. S.

devcontainer-feature.json

    "containerEnv": {
        "ARTIFACTORY_USERNAME": "${localEnv:ARTIFACTORY_USERNAME}",
        "ARTIFACTORY_PASSWORD": "${localEnv:ARTIFACTORY_PASSWORD}"
    }

remoteContainers-….log

[2024-02-20T20:47:34.686Z] ERROR: failed to solve: rpc error: 
    code = Unknown 
    desc = failed to solve with frontend dockerfile.v0: failed to solve with frontend gateway.v0: 
        rpc error: code = Unknown 
        desc = failed to process "\"${localEnv:ARTIFACTORY_USERNAME}\"": unsupported modifier (A) in substitution

/tmp/devcontainercli-USERNAME/container-features/0.56.0-1708462050881/Dockerfile.extended

ENV ARTIFACTORY_USERNAME="${localEnv:ARTIFACTORY_USERNAME}"
ENV ARTIFACTORY_PASSWORD="${localEnv:ARTIFACTORY_PASSWORD}"
RUN --mount=type=bind,from=dev_containers_feature_content_source,source=MY_FEATURE_NAME_0,target=/tmp/build-features-src/MY_FEATURE_NAME_0 \
    cp -ar /tmp/build-features-src/MY_FEATURE_NAME_0 /tmp/dev-container-features \
 && chmod -R 0755 /tmp/dev-container-features/MY_FEATURE_NAME_0 \
 && cd /tmp/dev-container-features/MY_FEATURE_NAME_0 \
 && chmod +x ./devcontainer-features-install.sh \
 && ./devcontainer-features-install.sh \
 && rm -rf /tmp/dev-container-features/MY_FEATURE_NAME_0
alexanderilyin commented 9 months ago

Can't use devcontainer-feature.json:.mounts

    "mounts": [
        {
            "source": "$HOME/.netrc",
            "target": "/root/.netrc",
            "type": "bind"
        }
    ]

Because it's not mounted when install.sh is executed:

 > [dev_containers_target_stage 5/6] \
RUN --mount=type=bind,from=dev_containers_feature_content_source,source=MY_FEATURE_NAME_0,target=/tmp/build-features-src/MY_FEATURE_NAME_0     \
cp -ar /tmp/build-features-src/MY_FEATURE_NAME_0 /tmp/dev-container-features  \
&& chmod -R 0755 /tmp/dev-container-features/MY_FEATURE_NAME_0  \
&& cd /tmp/dev-container-features/MY_FEATURE_NAME_0  \
&& chmod +x ./devcontainer-features-install.sh  \
&& ./devcontainer-features-install.sh  \
&& rm -rf /tmp/dev-container-features/MY_FEATURE_NAME_0:
samruddhikhandale commented 9 months ago

Hello!

Thanks for providing a detailed description of the issue, very helpful.

Is it possible that the devcontainer-feature.json keep the same logic of containerEnv & remoteEnv with devcontainer.json in the future? Or at least support the ${localEnv:*}?

This request makes sense, moving this issue to the spec repo.