Giter Club home page Giter Club logo

cli's People

Contributors

aledbf avatar alexander-smolyakov avatar alexdima avatar bamurtaugh avatar chrmarti avatar chuxel avatar codeman99 avatar davidwallacejackson avatar dependabot[bot] avatar dhhyi avatar edgonmsft avatar eljog avatar hellodword avatar imphil avatar jarrodcolburn avatar jkeech avatar joshaber avatar joshspicer avatar juzuluag avatar kmpf avatar natescherer avatar robjackstewart avatar rzhao271 avatar samruddhikhandale avatar shauryaag avatar stewartfrancis avatar stuartleeks avatar toddlerer avatar trxcllnt avatar yokonao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cli's Issues

Why Is `--workspace-folder` Required. Can we default to $PWD?

I found it odd that this parameter was required when using devcontainer up and was wondering why and if that was intentional. Not sure if it is also required in other commands ( just learning here ) but did want to share it felt odd to do this.

$ devcontainer up --workspace-folder .

Support specifying user via "exec"

Currently the dev container CLI exec command runs as the remoteUser specified in the dev container metadata. While this makes sense as a default, implementers will also need to perform certain actions as root like installing dependencies for injected tools.

I would propose a --user flag to allow you to temporarily set this.

`devcontainer exec` tries to use different container than the response of `devcontainer up` in WSL

devcontainer exec tries to use different container than the response of devcontainer up.

$ devcontainer up --workspace-folder .
[14 ms] @devcontainers/cli 0.12.1.
{"outcome":"success","containerId":"66d0453b1f8340282242c2efeff1e79af03734b45d56cfc7630b5b92b108880e","composeProjectName":"masked","remoteUser":"vscode","remoteWorkspaceFolder":"/workspace"}
$ devcontainer exec --workspace-folder . pwd
Shell server terminated (code: 1, signal: null)

Error response from daemon: Container 7a07354654d1bc329e8ba1ba2721582171fe483c541e5ee65f042c9dc6d7fe4f is not running

{"outcome":"error","message":"An error occurred running a command in the container.","description":"An error occurred running a command in the container."}

Version info: [email protected] /home/sarisia/.asdf/installs/nodejs/18.5.0/.npm/lib/node_modules/@devcontainers/cli

`devcontainer build` returns 0 even after failure

Building a Dockerfile that includes an error - e.g. "forget" \ at the end of a continuation line - fails but devcontainer returns the success code (0).

$ devcontainer build --image-name sagebionetworks/challenge-devcontainer:test
[497 ms] Start: Run in Host: /home/tschaffter/.vscode-remote-containers/bin/b3318bc0524af3d74034b8bb8a64df0ccf35549a/node /home/tschaffter/.vscode-remote-containers/dist/dev-containers-cli-0.245.2/dist/spec-node/devContainersSpecCLI.js build --workspace-folder /home/tschaffter/dev2/tschaffter/challenge-registry/tools/devcontainers/challenge-devcontainer --log-level info --log-format json --image-name sagebionetworks/challenge-devcontainer:test
[581 ms] remote-containers 0.245.2.
[712 ms] Start: Run: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/vsch-tschaffter/container-features/0.245.2-1661698018485/Dockerfile-with-features -t sagebionetworks/challenge-devcontainer:test --target dev_containers_target_stage --build-arg imageVersion=bullseye-20211220-slim --build-arg devcontainerVersion= --build-context dev_containers_feature_content_source=/tmp/vsch-tschaffter/container-features/0.245.2-1661698018485 --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp /home/tschaffter/dev2/tschaffter/challenge-registry/tools/devcontainers/challenge-devcontainer/.devcontainer
[+] Building 1.1s (6/6) FINISHED                                                
 => [internal] load build definition from Dockerfile-with-features         0.0s
 => => transferring dockerfile: 3.44kB                                     0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => resolve image config for docker.io/docker/dockerfile:1.4               0.8s
 => CACHED docker-image://docker.io/docker/dockerfile:1.4@sha256:443aab4c  0.0s
 => [internal] load build definition from Dockerfile-with-features         0.0s
 => [internal] load .dockerignore                                          0.0s
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 = dockerfile parse error on line 58: unknown instruction: &&
[2169 ms] Error: Command failed: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/vsch-tschaffter/container-features/0.245.2-1661698018485/Dockerfile-with-features -t sagebionetworks/challenge-devcontainer:test --target dev_containers_target_stage --build-arg imageVersion=bullseye-20211220-slim --build-arg devcontainerVersion= --build-context dev_containers_feature_content_source=/tmp/vsch-tschaffter/container-features/0.245.2-1661698018485 --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp /home/tschaffter/dev2/tschaffter/challenge-registry/tools/devcontainers/challenge-devcontainer/.devcontainer
[2169 ms]     at HS (/home/tschaffter/.vscode-remote-containers/dist/dev-containers-cli-0.245.2/dist/spec-node/devContainersSpecCLI.js:256:1490)
[2169 ms]     at processTicksAndRejections (internal/process/task_queues.js:93:5)
[2169 ms]     at async Cu (/home/tschaffter/.vscode-remote-containers/dist/dev-containers-cli-0.245.2/dist/spec-node/devContainersSpecCLI.js:255:2801)
[2170 ms]     at async $P (/home/tschaffter/.vscode-remote-containers/dist/dev-containers-cli-0.245.2/dist/spec-node/devContainersSpecCLI.js:360:12358)
[2170 ms]     at async jP (/home/tschaffter/.vscode-remote-containers/dist/dev-containers-cli-0.245.2/dist/spec-node/devContainersSpecCLI.js:360:10865)
[2173 ms] Exit code 1

$ echo $?
0

I initially spotted the issue in our CI workflow, which was not stopping after devcontainer build had failed.

[Tracking] `devcontainer features test` improvements

An issue collecting various improvements that can be made for the features test... command. The command is still experimental and under active development.

  • remoteUser, containerUser, or a container with a default non-root user are failing with a permissions issue when included in a scenario
  • Scenario tests appear to run as root even when -u specified in command line
  • Feature values specified in scenario.json do not appear to be space escaped ("a b" ends up as "a")
  • -f prevents other parameters after it from being used since it treats them all as part of the array. Makes it impossible to pass in the require parameters.
  • Document all command functionality (ie: devcontainers/spec#113 (comment)) (#219)
  • If there is a scenario.json file and no test.sh, the test will not run unless --skip-autogenerated is set. We should be smarter about this
  • The one positional argument (path to collection) is required and doesn't use the default value (cwd)
  • Support build.dockerfile - Currently errors since Dockerfile referenced is not copied to temp location
  • Allow specifying a specific scenario to test via the CLI (helps if only one of several is failing)
  • #438
  • Output results to stdout so you can pipe to a log file w/o getting the entire build output (appears to go to stderr right now)
  • Be able to override a certain base image <-> feature combos in the autogenerated tests (devcontainers/features#116 (review))
  • #163 / #217
  • devcontainers/spec#114 (reply in thread)
  • #334
  • #409
  • #448

"customizations" (and legacy extension, settings properties) not processed in features

Running devcontainer read-configuration --include-features-configuration on a workspace with a devcontainer.json with features does not return customizations or the legacy extensions or settings properties (whether original or converted).

In the latest Remote - Containers release extensions are not installed and settings are not applied either.

They seem to be missing in several spots along with other properties from the spec (https://github.com/devcontainers/spec/blob/main/proposals/devcontainer-features.md#devcontainer-featurejson-properties).

Possible places where the issue could be coming from (if not all of them):

  • feature.containerEnv = featureJson.containerEnv;
    feature.buildArg = featureJson.buildArg;
    feature.options = featureJson.options;
    feature.installAfter = featureJson.installAfter;
    feature.init = featureJson.init;
    feature.privileged = featureJson.privileged;
    feature.capAdd = featureJson.capAdd;
    feature.securityOpt = featureJson.securityOpt;
    feature.mounts = featureJson.mounts;
    feature.entrypoint = featureJson.entrypoint;
  • feature.buildArg = seekedFeature?.buildArg;
    feature.options = seekedFeature?.options;
    feature.init = seekedFeature?.init;
    feature.privileged = seekedFeature?.privileged;
    feature.capAdd = seekedFeature?.capAdd;
    feature.securityOpt = seekedFeature?.securityOpt;
    feature.mounts = seekedFeature?.mounts;
    feature.entrypoint = seekedFeature?.entrypoint;
  • export interface Feature {
    id: string;
    version?: string;
    name: string;
    description?: string;
    cachePath?: string;
    internalVersion?: string; // set programmatically
    consecutiveId?: string;
    documentationURL?: string;
    licenseURL?: string;
    options?: Record<string, FeatureOption>;
    buildArg?: string; // old properties for temporary compatibility
    containerEnv?: Record<string, string>;
    mounts?: Mount[];
    init?: boolean;
    privileged?: boolean;
    capAdd?: string[];
    securityOpt?: string[];
    entrypoint?: string;
    installAfter?: string[];
    include?: string[];
    exclude?: string[];
    value: boolean | string | Record<string, boolean | string | undefined>; // set programmatically
    included: boolean; // set programmatically
    }

Issues following "Try out the CLI" instructions

Windows 11, Powershell Core 7.2.5, node v16.15.1
Note: node installed using nvm for windows version 1.1.9, if that matters

Following instructions in https://code.visualstudio.com/blogs/2022/05/18/dev-container-cli quite literally, I ran into some issues following the instructions referring to https://github.com/microsoft/vscode-remote-try-rust. The instructions say:

git clone https://github.com/microsoft/vscode-remote-try-rust
devcontainer up --workspace-folder <path-to-vscode-remote-try-rust>

Expected: these commands should execute without error.

Actual: The first problem was the <path-to-vscode-remote-try-rust>, which isn't proper for any shell. I replaced it with a relative path, so now I have:

git clone https://github.com/microsoft/vscode-remote-try-rust
devcontainer up --workspace-folder ./vscode-remote-try-rust

So now I get an error I really don't understand:

Error: Command failed: docker ps -q -a --filter label=devcontainer.local_folder=C:\Users\burt_\vscode-remote-try-rust
    at createSetupError (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\singleContainer.js:59:84)
    at openDockerfileDevContainer (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\singleContainer.js:54:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async resolveWithLocalFolder (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\configContainer.js:74:18)
    at async launch (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\devContainers.js:42:20)
    at async doProvision (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\devContainersSpecCLI.js:185:24)
    at async provision (C:\Users\burt_\AppData\Roaming\nvm\v16.15.1\node_modules\@devcontainers\cli\dist\spec-node\devContainersSpecCLI.js:170:20)
{"outcome":"error","message":"Command failed: docker ps -q -a --filter label=devcontainer.local_folder=C:\\Users\\burt_\\vscode-remote-try-rust","description":"An error occurred setting up the container."}

Would like to be able to execute interactive command

In my env, developer will likely want to run devcontainer exec bash and then be able to navigate the container and do stuff within using command-line interface.

As such, I think the option to exec the command in interactive mode is important.

devcontainer build doesn't go well with multi-CPU architecture support enabled

If multi-CPU architecture support is enabled, devcontainer build action fails if features are specified in devcontainers.json:

...
[999 ms] local container features stored at: /Users/romanzhuzha/.vscode/extensions/ms-vscode-remote.remote-containers-0.241.3/dist/node_modules/vscode-dev-containers/container-features
[1000 ms] Start: Run: tar --no-same-owner -x -f -
[1021 ms] Start: Run: docker build -t dev_container_feature_content_temp -f /var/folders/f5/rlxvlqks455c6n8y863jcd1c0000gn/T/vsch/container-features/0.241.3-1657892458442/Dockerfile.buildContent /var/folders/f5/rlxvlqks455c6n8y863jcd1c0000gn/T/vsch/container-features/0.241.3-1657892458442
WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load 
[+] Building 0.2s (4/4) FINISHED
...

As you can see, there is even a warning which mentions that the image will reside in build cache only.

The fix is to add argument --load to this build command. This argument also doesn't harm while docker driver is being used.

`--help` should show version number and install location

We currently distribute two competing commands named devcontainer:

  1. there is this one (i.e. @devcontainer/cli)
  2. there is the one shipped with the Remote Containers extension since around 1 year

We have heard through numerous feedback channels (e.g. #108) that when executing devcontainer on the command line oftentimes the wrong one is picked up (possibly due to previous actions users have taken or due to how the PATH env variable is set up).

Normally, when running a command with --help, it is atypical to present version or install location information, but I have found a few which do so, e.g:

npm --help
npm <command>

Usage:

npm install        install all the dependencies in your project
npm install <foo>  add the <foo> dependency to your project
npm test           run this project's tests
npm run <foo>      run the script named <foo>
npm <command> -h   quick help on <command>
npm -l             display usage info for all commands
npm help <term>    search for help on <term>
npm help npm       more involved overview

All commands:

    access, adduser, audit, bin, bugs, cache, ci, completion,
    config, dedupe, deprecate, diff, dist-tag, docs, doctor,
    edit, exec, explain, explore, find-dupes, fund, get, help,
    hook, init, install, install-ci-test, install-test, link,
    ll, login, logout, ls, org, outdated, owner, pack, ping,
    pkg, prefix, profile, prune, publish, rebuild, repo,
    restart, root, run-script, search, set, set-script,
    shrinkwrap, star, stars, start, stop, team, test, token,
    uninstall, unpublish, unstar, update, version, view, whoami

Specify configs in the ini-formatted file:
    /Users/alex/.npmrc
or on the command line via: npm <command> --key=value

More configuration info: npm help config
Configuration fields: npm help 7 config

[email protected] /usr/local/lib/node_modules/npm
vim --help
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jun 17 2022 21:26:11)

Usage: vim [arguments] [file ..]       edit specified file(s)
   or: vim [arguments] -               read text from stdin
   or: vim [arguments] -t tag          edit file where tag is defined
   or: vim [arguments] -q [errorfile]  edit file with first error

Arguments:
   --			Only file names after this
   -v			Vi mode (like "vi")
   -e			Ex mode (like "ex")
   -E			Improved Ex mode
   -s			Silent (batch) mode (only for "ex")
   -d			Diff mode (like "vimdiff")
   -y			Easy mode (like "evim", modeless)
   -R			Readonly mode (like "view")
   -Z			Restricted mode (like "rvim")
   -m			Modifications (writing files) not allowed
   -M			Modifications in text not allowed
   -b			Binary mode
   -l			Lisp mode
   -C			Compatible with Vi: 'compatible'
   -N			Not fully Vi compatible: 'nocompatible'
   -V[N][fname]		Be verbose [level N] [log messages to fname]
   -D			Debugging mode
   -n			No swap file, use memory only
   -r			List swap files and exit
   -r (with file name)	Recover crashed session
   -L			Same as -r
   -T <terminal>	Set terminal type to <terminal>
   --not-a-term		Skip warning for input/output not being a terminal
   --ttyfail		Exit if input or output is not a terminal
   -u <vimrc>		Use <vimrc> instead of any .vimrc
   --noplugin		Don't load plugin scripts
   -p[N]		Open N tab pages (default: one for each file)
   -o[N]		Open N windows (default: one for each file)
   -O[N]		Like -o but split vertically
   +			Start at end of file
   +<lnum>		Start at line <lnum>
   --cmd <command>	Execute <command> before loading any vimrc file
   -c <command>		Execute <command> after loading the first file
   -S <session>		Source file <session> after loading the first file
   -s <scriptin>	Read Normal mode commands from file <scriptin>
   -w <scriptout>	Append all typed commands to file <scriptout>
   -W <scriptout>	Write all typed commands to file <scriptout>
   -x			Edit encrypted files
   --startuptime <file>	Write startup timing messages to <file>
   --log <file>	Start logging to <file> early
   -i <viminfo>		Use <viminfo> instead of .viminfo
   --clean		'nocompatible', Vim defaults, no plugins, no viminfo
   -h  or  --help	Print Help (this message) and exit
   --version		Print version information and exit
tar --help
tar(bsdtar): manipulate archive files
First option must be a mode specifier:
  -c Create  -r Add/Replace  -t List  -u Update  -x Extract
Common Options:
  -b #  Use # 512-byte records per I/O block
  -f <filename>  Location of archive
  -v    Verbose
  -w    Interactive
Create: tar -c [options] [<file> | <dir> | @<archive> | -C <dir> ]
  <file>, <dir>  add these items to archive
  -z, -j, -J, --lzma  Compress archive with gzip/bzip2/xz/lzma
  --format {ustar|pax|cpio|shar}  Select archive format
  --exclude <pattern>  Skip files that match pattern
  -C <dir>  Change to <dir> before processing remaining files
  @<archive>  Add entries from <archive> to output
List: tar -t [options] [<patterns>]
  <patterns>  If specified, list only entries that match
Extract: tar -x [options] [<patterns>]
  <patterns>  If specified, extract only entries that match
  -k    Keep (don't overwrite) existing files
  -m    Don't restore modification times
  -O    Write entries to stdout, don't restore to disk
  -p    Restore permissions (including ACLs, owner, file flags)
bsdtar 3.5.1 - libarchive 3.5.1 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.8

In an attempt to reduce confusion, I suggest that we print the version information and install location at the end of devcontainer --help

Will there be a `devcontainer open` command?

I was getting kind of tired of opening a new VS Code window and using the "Remote-Containers: Open Folder in Container..." command and was wondering if there was an easy way to do the same via the CLI. Eventually I stumbled on this thread which I've participated on as well.

microsoft/vscode-remote-release#2133 (comment)

Not sure if this project would have a simple open command or not or where that would land?

Build command mentions positional path argument

Should there not be [path] in the help page? Looks like --workspace-folder is required, not a positional argument known as path

@joshspicer โžœ /workspaces/features (test โœ—) $ npx dev-containers-cli-0.1.0.tgz build /tmp/vsch/container-features-test/165219861073
dev-containers-cli build [path]

Build a dev container image

Options:
  --help                 Show help                                                                             [boolean]
  --version              Show version number                                                                   [boolean]
  --user-data-folder     Host path to a directory that is intended to be persisted and share state between sessions.
                                                                                                                [string]
  --docker-path          Docker CLI path.                                                                       [string]
  --docker-compose-path  Docker Compose CLI path.                                                               [string]
  --workspace-folder     Workspace folder path. The devcontainer.json will be looked up relative to this path.
                                                                                                     [string] [required]
  --log-level            Log level.                                [choices: "info", "debug", "trace"] [default: "info"]
  --log-format           Log format.                                         [choices: "text", "json"] [default: "text"]
  --no-cache             Builds the image with `--no-cache`.                                  [boolean] [default: false]
  --image-name           Image name.                                                                            [string]
  --cache-from           Additional image to use as potential layer cache                                       [string]

Missing required argument: workspace-folder

Originally posted by @joshspicer in #4 (comment)

Spaces not properly escaped in Feature option values

Having a space in a Feature option value can cause a build to fail or only the part before the space to be picked up.

Repro:

  1. Create a repo from https://github.com/devcontainers/feature-template
  2. Add the following .devcontainer.json:
    {
        "image": "mcr.microsoft.com/devcontainers/base:ubnutu",
        "features": {
            "./src/hello": {
               "greeting": "Hello there"
           }
        }
    }
    
  3. Reopen in container
  4. Go to a terminal and type hello.

Expected: Command outputs "Hello there, vscode!"
Actual: Command outputs "Hello, vscode!"

I can repro this in more complex features (e.g. this one) as well - it seems to be across the board.

[Feature Request] Read devcontainer.json from a docker volume

I'm always cloning repositories into named docker volumes, since mounting workspaces folders into docker machines introduces performance impacts, and for keeping my host clean. This is done via the Clone Repository in Named Container Volume-option provided by your remote containers extension.

It would be pretty cool if I could do the same using the CLI, for building, starting and running commands, like devcontainer up @myproject or similar.

Regression: "entrypoint", "privileged" dev container feature settings no longer work

This will break both docker-in-docker and docker-from-docker.

Repro:

  1. Put the following devcontainer.json on disk:
    {
         "image": "debian",
         "features": {
             "docker-in-docker": "latest"
         }
     }
  2. Install dev container CLI v0.8.0
  3. devcontainer up --workspace-folder .
  4. devcontainer exec --workspace-folder . docker ps

Expected: No error
Actual: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

There's an underlying permissions denied error here because --privileged isn't set like it is supposed to per the feature setup. To see it, type: devcontainer exec --workspace-folder . /usr/local/share/docker-init.sh

You will see:

mount: /sys/kernel/security: permission denied.
Could not mount /sys/kernel/security.
AppArmor detection and --privileged mode might break.
mount: /tmp: permission denied.

This repros in the latest preview Remote - Containers and in the dev container Action and AzDO tasks that pulled in version 0.8.0.

Add an option to show the version of the CLI

I wanted to report the version of the CLI installed in my environment in another ticket, then realized that the option --version is not implemented.

$ devcontainer --version
Specify a command
devcontainer <command>

Commands:
  devcontainer open [path]   Open a dev container in VS Code
  devcontainer build [path]  Build a dev container image

Options:
  -h, --help               Show help  [boolean]
      --disable-telemetry  Disable telemetry  [boolean] [default: false]

Mirror CI tests on Windows hosts

We've run into some issues during development of features when running on Windows machines (pathing, etc..). I think there are some code conventions this project followed to ensure compatibility across platforms, but perhaps as a final safety net, we enable unit tests to run on windows as well as linux?

Wrap lifecycle hooks and other operations in `start`/`stop` log messages

Recently Codespaces has gotten several reports where the root cause was difficult to debug. It would be useful if the logs emitted from the CLI clearly mark the start and end of a lifecycle script - perhaps like the following:

---  starting to execute 'postCreateCommand' script 'foo'

... foo output...

--- 'postCreateCommand' script 'foo' exited code 0

This would be particularly helpful in cases where foo does not emit any logs.

Hidden files excluded from devcontainer Docker build context

Repro steps

  1. Create a VS Code workspace and add development container configuration files (exact features don't matter).
  2. Add a hidden file to the .devcontainer folder (any file whose name starts with .)
  3. Add this command to the Dockerfile:
    COPY . /tmp/buildcontext
  4. Rebuild the devcontainer and open the workspace in it.
  5. In the Terminal, run ls /tmp/buildcontext

Expected behavior

Upon copying the entire .devcontainer folder into my devcontainer, I would see all of its files under /tmp/buildcontext within the container.

Actual behavior

All files are copied to /tmp/buildcontext in the devcontainer except hidden files.

Notes

For context, I am working with the CDK (Cloud Development Kit) to provision AWS resources via code. One powerful feature of the CDK is that I can set context variables (config values, essentially) in a number of places, including the ~/.cdk.json file. By adding context variables to that file, the values will be kept secret from version control, much like user secrets in Visual Studio. The project that I'm working on is using a devcontainer, so I was planning to add a "template" .cdk.json file in my .devcontainer folder with placeholder values, COPY it into my devcontainer from the Dockerfile, and then modify it in the running devcontainer to have the correct secret values.

Based on the above repro steps, it looks like something about the devcontainer build process is ignoring hidden files. I could just name the file without a starting period in the name and COPY that, but I feel like that shouldn't be necessary. I do not have a .dockerignore file present in the .devcontainer folder. However, if I rebuild the devcontainer and click the "Starting Dev Container (show log)" notification in VS Code, I see the following log statements in a couple places:

 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 32B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s

So I'm wondering if VS Code is adding some default .dockerignore file that ignores hidden files. I don't see anything in the docker build or .dockerignore docs to suggest that this caused by the Docker engine itself.

Now that this repo exists, I figured maybe VS Code is using this CLI under the hood, but let me know if there's a more appropriate repo at which to raise the Issue. Either way, if this issue is caused by VS Code or the devcontainer CLI, then I request a way to override this in devcontainer.json so that we can include hidden files in our containers. ๐Ÿ™

EDIT: Apparently the following Dockerfile command also works, so for some reason hidden files are only excluded when copying the whole build context:

COPY .cdk.json /root/.cdk.json`

Move to multi-stage build for container-features

This issue proposes moving the container-features build over to using a multi-stage docker build.

Prior to container-features, it was possible to build the dev container image with an inline cache manifest, push it to a registry and then reference that image in the cacheFrom in devcontainer.json (or in cache_from in docker-compose.yml) to have the registry image used as a layer cache.
When using container-features, there are now two images built, so you would need to push two images to the registry and reference two images in the cacheFrom.

Making this change will result in a single image build step for the container which will allow for pushing the resulting image to a registry complete with an inline cache manifest, making it possible to get back to the single dev container image that works for image caching.

Anticipated steps:

  • Combine extendImage into build function for Dockerfile #9
  • Update Dockerfile build to use multi-stage build with container-features #13
  • Combine extendImage into build function for docker-compose and update docker-compose build to use multi-stage build with container-features (#38)

Having issue building the tool locally

I believe to have all the requirements, running CentOS7, but I am getting this error:

$ npm install -g @vscode/dev-container-cli
npm ERR! code 1
npm ERR! path /home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty
npm ERR! command failed
npm ERR! command sh -c node scripts/install.js
npm ERR! make: Entering directory `/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty/build'
npm ERR!   CXX(target) Release/obj.target/pty/src/unix/pty.o
npm ERR! make: Leaving directory `/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty/build'
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using [email protected]
npm ERR! gyp info using [email protected] | linux | x64
npm ERR! gyp info find Python using Python version 3.6.8 found at "/usr/bin/python3"
npm ERR! gyp info spawn /usr/bin/python3
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args   '/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args   'binding.gyp',
npm ERR! gyp info spawn args   '-f',
npm ERR! gyp info spawn args   'make',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty/build/config.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/ykoehler/.cache/node-gyp/16.1.0/include/node/common.gypi',
npm ERR! gyp info spawn args   '-Dlibrary=shared_library',
npm ERR! gyp info spawn args   '-Dvisibility=default',
npm ERR! gyp info spawn args   '-Dnode_root_dir=/home/ykoehler/.cache/node-gyp/16.1.0',
npm ERR! gyp info spawn args   '-Dnode_gyp_dir=/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/npm/node_modules/node-gyp',
npm ERR! gyp info spawn args   '-Dnode_lib_file=/home/ykoehler/.cache/node-gyp/16.1.0/<(target_arch)/node.lib',
npm ERR! gyp info spawn args   '-Dmodule_root_dir=/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty',
npm ERR! gyp info spawn args   '-Dnode_engine=v8',
npm ERR! gyp info spawn args   '--depth=.',
npm ERR! gyp info spawn args   '--no-parallel',
npm ERR! gyp info spawn args   '--generator-output',
npm ERR! gyp info spawn args   'build',
npm ERR! gyp info spawn args   '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! In file included from /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:30:0,
npm ERR!                  from /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h:63,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/unix/pty.cc:20:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-internal.h: In function โ€˜void v8::internal::PerformCastCheck(T*)โ€™:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-internal.h:452:33: error: โ€˜remove_cv_tโ€™ is not a member of โ€˜stdโ€™
npm ERR!              !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
npm ERR!                                  ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-internal.h:452:33: error: โ€˜remove_cv_tโ€™ is not a member of โ€˜stdโ€™
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-internal.h:452:50: error: template argument 2 is invalid
npm ERR!              !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
npm ERR!                                                   ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-internal.h:452:61: error: โ€˜::Performโ€™ has not been declared
npm ERR!              !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
npm ERR!                                                              ^
npm ERR! In file included from /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h:63:0,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/unix/pty.cc:20:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h: At global scope:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1465:49: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    V8_INLINE Local<Integer> ResourceLineOffset() const;
npm ERR!                                                  ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1467:51: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    V8_INLINE Local<Integer> ResourceColumnOffset() const;
npm ERR!                                                    ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1469:39: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    V8_INLINE Local<Integer> ScriptID() const;
npm ERR!                                        ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1621:33: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    int GetModuleRequestsLength() const;
npm ERR!                                  ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1629:41: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Local<String> GetModuleRequest(int i) const;
npm ERR!                                          ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1638:44: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Location GetModuleRequestLocation(int i) const;
npm ERR!                                             ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1674:79: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!                                                        ResolveCallback callback);
npm ERR!                                                                                ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:1765:58: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!                                  Local<Value> export_value);
npm ERR!                                                           ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:2057:49: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        CompileOptions options = kNoCompileOptions);
npm ERR!                                                  ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:3619:23: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Local<Value> Name() const { return Description(); }
npm ERR!                        ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:4281:34: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Local<Context> CreationContext();
npm ERR!                                   ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:4288:77: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    static Local<Context> CreationContext(const PersistentBase<Object>& object);
npm ERR!                                                                              ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:4769:33: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Local<Value> GetDisplayName() const;
npm ERR!                                  ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5478:76: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
npm ERR!                                                                             ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5525:21: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    bool IsExternal() const;
npm ERR!                      ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5551:24: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Contents Externalize();
npm ERR!                         ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5561:70: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    void Externalize(const std::shared_ptr<BackingStore>& backing_store);
npm ERR!                                                                       ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5572:24: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Contents GetContents();
npm ERR!                         ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:5960:76: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
npm ERR!                                                                             ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:6009:76: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
npm ERR!                                                                             ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:6018:21: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    bool IsExternal() const;
npm ERR!                      ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:6033:24: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Contents Externalize();
npm ERR!                         ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:6043:70: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    void Externalize(const std::shared_ptr<BackingStore>& backing_store);
npm ERR!                                                                       ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:6058:24: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    Contents GetContents();
npm ERR!                         ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:8537:30: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!      std::vector<std::string> supported_import_assertions;
npm ERR!                               ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:8871:51: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        HostImportModuleDynamicallyCallback callback);
npm ERR!                                                    ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:9035:59: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!                                      MeasureMemoryMode mode);
npm ERR!                                                            ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:9692:55: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!        ModifyCodeGenerationFromStringsCallback callback);
npm ERR!                                                        ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8.h:10051:75: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    static bool TryHandleSignal(int signal_number, void* info, void* context);
npm ERR!                                                                            ^
npm ERR! In file included from /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h:65:0,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/unix/pty.cc:20:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-platform.h:234:28: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    virtual bool IsCompleted() { return !IsActive(); }
npm ERR!                             ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-platform.h:245:26: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    virtual bool IsRunning() { return IsValid(); }
npm ERR!                           ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/v8-platform.h:278:38: warning: โ€˜deprecatedโ€™ attribute directive ignored [-Wattributes]
npm ERR!    virtual size_t GetMaxConcurrency() const { return 0; }
npm ERR!                                       ^
npm ERR! In file included from ../../nan/nan.h:60:0,
npm ERR!                  from ../src/unix/pty.cc:20:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h: In lambda function:
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h:581:43: error: parameter packs not expanded with โ€˜...โ€™:
npm ERR!              std::forward<EnvironmentArgs>(env_args)...);
npm ERR!                                            ^
npm ERR! /home/ykoehler/.cache/node-gyp/16.1.0/include/node/node.h:581:43: note:         โ€˜env_argsโ€™
npm ERR! make: *** [Release/obj.target/pty/src/unix/pty.o] Error 1
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack     at ChildProcess.onExit (/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:365:28)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Linux 3.10.0-1160.53.1.el7.x86_64
npm ERR! gyp ERR! command "/home/ykoehler/.nvm/versions/node/v16.1.0/bin/node" "/home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd /home/ykoehler/.nvm/versions/node/v16.1.0/lib/node_modules/@vscode/dev-container-cli/node_modules/node-pty
npm ERR! gyp ERR! node -v v16.1.0
npm ERR! gyp ERR! node-gyp -v v9.0.0
npm ERR! gyp ERR! not ok

Any help apprecited here.

[Announcement] Dev Container CLI Feedback

Hi everyone ๐Ÿ‘‹! We'd love to hear your feedback as you review and try out the dev container CLI. This can include:

We'll also share issues or topics we'd like your feedback on. For instance, we'd greatly appreciate your thoughts on publishing the devcontainer.json schema.

There is an FAQ for the specification here.

Weโ€™re incredibly excited for the future of container-based development and canโ€™t wait to hear your feedback. Thank you!

"ENV" randomly added to environment variables that originate from features can prevent container from starting

Currently if you add both the node and python features, the container will fail to start properly in Remote - Containers stable.

In CLI 0.10.1, try building using this devcontainer.json...

{
    "image": "mcr.microsoft.com/vscode/devcontainers/base:0-bullseye",
    "features": {
       "node": "latest",
       "python": "os-provided"
    } 
}

Now, start the container using the image that was built but specify /bin/bash as the entrypoint:

docker run -it --rm <image-id> /bin/bash -c 'echo ${PATH}'

You will get...

/usr/local/python/bin:/usr/local/share/nvm/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binENV:/usr/local/py-utils/bin:/root/.local/bin

The ENV is smashed up against /bin (becoming /binENV) which prevents anything under the /bin folder, including bash, from being found.

With 0.11.1 or using the new dev container features via OCI, you will instead see a hang after the installation of Python followed eventually by lots of errors about chown... possibly caused by the same type of thing.

{
    "image": "mcr.microsoft.com/vscode/devcontainers/base:0-bullseye",
    "features": {
       "ghcr.io/devcontainers/features/node": "latest",
       "ghcr.io/devcontainers/features/python": "os-provided"
    } 
}

Build result:

...
#0 46.35 Updating /etc/bash.bashrc and /etc/zsh/zshrc...
#0 141.7 chmod: cannot access '/usr/local/share/nvm/test/fast/Listing': No such
file or directory
#0 141.7 chmod: cannot access 'versions': No such file or directory
#0 141.7 chmod: cannot access '/usr/local/share/nvm/test/fast/Listing': No such
file or directory
...

.gitconfig file copy function not working when git settings are part of the postCreateCommand

VSCode Version: 1.69.1
Local OS Version: Windows 11 Pro, OS Build 22000.795
Local chip architecture: x86
Reproduces in: Remote - Containers
Name of Dev Container Definition with Issue: Custom Container Image

When using the build in function in devcontainers that copies the host systems .gitconfig file into the container, it is not possible to also edit the .gitconfig file under the postCreateCommand part of the container build process, which could be needed to change things such as the safe.directory settings.

For example, as part of the container build, I want to add the workspace folder to the copied .gitconfigs safe directory settings by having the follow in my postCreateCommand:
git config --global --add safe.directory ${containerWorkspaceFolder}

However since the file at this point has not been copied into the container yet, using any git config command will create a .gitconfig file inside the container. Later in the build, a check runs that looks for an existing .gitconfig file and if it find ones, it does not copy.

Steps to Reproduce:

  1. Set Remote โ€บ Containers: Copy Git Config setting to true
  2. Set in devcontainer.json git config --global --add safe.directory ${containerWorkspaceFolder}

Suggested solutions:

  1. Run the copy of gitconfig from host before postCreateCommand.
  2. Add a setting natively in devcontainer.json or the vscode plugin to add add safe.directory at the appropriate timing after copy from host.

Devcontainers cli issue resuming docker-compose codespaces

There were reports of failure in resuming docker-compose codespaces, with the following error.

2022-06-29 19:30:32.390Z: ERROR: build path /tmp/devcontainers_cli_empty either does not exist, is not accessible, or is not a valid URL.

context: /tmp/devcontainers_cli_empty

Codespaces are resumed on a new VM each time and the tmp directory contents of the VM on which the container was originally built is not available on the VMs where it is subsequently resumed.
As mentioned on the original issue, we have applied a temporary fix in Codespaces agent, that will pre-create the /tmp/devcontainers_cli_empty on the Codespaces VM before calling the devcontainers-cli for starting the containers.

  • We might need a more permanent fix implemented in devcontainers-cli to ensure this directory is present on the machine before attempting to build/start containers
  • Question? Is it safe to put the conents to /tmp directory, as different OS' may have different settings as to how it cleans/claims space in tmp

updateUID fails if user home directory was not created

As best practice, non-root users are created as system users without a home folder. updateUID.Dockerfile will fail when used with such images, because it tries to chown the non-existing home folder.

We could either skip chowning or create the home folder. The latter would be useful since vscode seems to use the remote user home folder for its own setup.

Simplify install process

Currently this CLI has a native module dependency which drives the need for node-gyp dependencies like Python and C++. This makes installing the CLI far more difficult than intended.

To solve this issue, I'd propose we have a "distro" that is already compiled, and could even bundle Node.js. Installation can then just be an unzip/untar to keep things easy to begin with. We could then keep the npm option around for those that prefer to deal with the dependenceis.

The alternative would be to look into ways to remove the native dependency so that only Node.js is required.

//cc: @chrmarti @bamurtaugh

Regression: Feature entrypoints run as remoteUser

From microsoft/vscode-dev-containers#1517. It appears that feature entrypoints are run as remoteUser instead of the containerUser as expected. In the repro below, commenting out remoteUser causes things to function - the only reason sudo would get tripped is if the script is not being run as root.

//cc @joshspicer @edgonmsft @jkeech @chrmarti @bamurtaugh @harrywithers


  • VSCode Version: 1.68.1
  • Local OS Version: macOS Monterey 12.3.1
  • Local chip architecture: Intel Core i7
  • Reproduces in: Remote - Containers
  • Name of Dev Container Definition with Issue: docker-in-docker

Steps to Reproduce:

  1. Create a devcontainer file and docker file with the following configuration
{
    "name": "name",
    "build": {
        "dockerfile": "./Dockerfile"
    },
    "remoteUser": "node",
    "features": {
        "docker-in-docker": "latest",
    }
}
FROM node:16.14.0
  1. Reopen in dev container
  2. Run docker ps in the dev container

Result:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

But expected docker to be up and running in the container.

Docker container log:

Container started
/usr/local/share/docker-init.sh: 65: /usr/local/share/docker-init.sh: sudo: not found

Docker version output in dev container:

Client:
 Version:           20.10.17+azure-1
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c70180fde3601def79a59cc3e996aa553c9b9
 Built:             Mon Jun  6 21:36:39 UTC 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Docker version output locally

Client:
 Cloud integration: v1.0.25
 Version:           20.10.16
 API version:       1.41
 Go version:        go1.17.10
 Git commit:        aa7e414
 Built:             Thu May 12 09:20:34 2022
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Server: Docker Desktop 4.9.1 (81317)
 Engine:
  Version:          20.10.16
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.10
  Git commit:       f756502
  Built:            Thu May 12 09:15:42 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.4
  GitCommit:        212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
 runc:
  Version:          1.1.1
  GitCommit:        v1.1.1-0-g52de29d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Example repository:
https://github.com/harrywithers/broken-dind

Seemed to be working fine a week or so ago, I've got a few projects using this setup and all of them now fail to start docker.

Anyone know how to fix this? Thanks in advance!

devcontainer build fails with authentication error

Hi everyone,

I've been using the build feature of the devcontainer CLI before and didn't have any issues until recently.

Now when I try to build my devcontainer configuration I receive the following error:

Building app
[+] Building 1.4s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile-with-features         0.0s
 => => transferring dockerfile: 3.85kB                                     0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => ERROR [internal] load metadata for docker.io/library/dev_container_fe  1.3s
 => [internal] load metadata for mcr.microsoft.com/vscode/devcontainers/b  0.3s
 => [auth] library/dev_container_feature_content_temp:pull token for regi  0.0s
------
 > [internal] load metadata for docker.io/library/dev_container_feature_content_temp:latest:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
ERROR: Service 'app' failed to build : Build failed
[4407 ms] Error: Command failed: docker-compose --project-name workspace_devcontainer -f /workspace/.devcontainer/docker-compose.yml -f /tmp/docker-compose/docker-compose.devcontainer.build-1655998380158.yml build --no-cache --pull app
[4407 ms]     at buildAndExtendDockerCompose (/usr/local/share/nvm/versions/node/v16.15.1/lib/node_modules/@vscode/dev-container-cli/dist/spec-node/devContainersSpecCLI.js:19967:51)
[4407 ms]     at processTicksAndRejections (node:internal/process/task_queues:96:5)
[4407 ms]     at async doBuild (/usr/local/share/nvm/versions/node/v16.15.1/lib/node_modules/@vscode/dev-container-cli/dist/spec-node/devContainersSpecCLI.js:21358:7)
[4407 ms]     at async build (/usr/local/share/nvm/versions/node/v16.15.1/lib/node_modules/@vscode/dev-container-cli/dist/spec-node/devContainersSpecCLI.js:21269:18)
[4415 ms] Exit code 1

I'm logged into Docker hub and can pull other images with no problem. Any ideas what could be the issue here?

Run onCreateCommand and updateContentCommand in prebuilt images (not pre-built Codespaces)

Codespaces has an option to bake onCreateCommand and updateContentCommand steps into the image in case they are time-consuming.

If a user installs dependencies into a dev container via new features spec, they won't be able to reference those in the image's Dockerfile because features are applied after the initial build process. So the only way to customize the image becomes those aforementioned steps.

Providing a way to create an analog of Codespaces prebuilds would allow the publication of organization-wide fully ready-made images for local use.

Local feature not working in Remote-Containers

Remote-Containers 0.244.0

Using:

{
	"context": ".",
	"dockerFile": "Dockerfile",
	"features": {
		"./local-features/foo": "latest"
	}
}

fails with:

ENOENT: no such file or directory, lstat '/Users/chrmarti/.vscode-insiders/extensions/ms-vscode-remote.remote-containers-0.244.0/local-features/foo'

@devcontainer/[email protected] unable to run devcontainer up

I'm using Windows 10. I've just checked Development container CLI page and installed dev container CLI using the following command:

npm install -g @devcontainers/cli

After been installed, I realized that it's a bit different than docs said:

I only have two commands:

devcontainer <command>

Commands:
  devcontainer open [path]   Open a dev container in VS Code
  devcontainer build [path]  Build a dev container image

Options:
  -h, --help               Show help  [boolean]
      --disable-telemetry  Disable telemetry  [boolean] [default: false]

What am I missing?

devcontainer executable permissions.

Hey folks.

Thanks for this - it's awesome!

I followed the instructions and enabled the devcontainer cli both on my Mac and on my Pop_OS linux machine. On both of these the devcontainer script was correctly symlinked into place, however calling devcontainer from a shell caused a permission denied error. Upon further inspection the ms-vscode-remote.remote-containers/cli-bin/devcontainer script was installed with 644 file permissions. I had to change them to 755 to be able to run it. Sadly, this means that I am getting an error about a corrupt vscode installation.

`features` and Dockerfile `ARG` values should be able to share arguments through the config

@samruddhikhandale has run into a problem where she wants to be able to share configuration arguments in both the build's Dockerfile, and inside of a feature's install script.

One idea I have for this, is that we automatically expose the build.arg arguments in the devcontainer.json to all feature script.

Eg:

{
   "build": {
      {
        "dockerfile": "./Dockerfile"
        "args": {
           "MY_USERNAME": "josh"
         }
   },
    "features": {
       "/features/go": "latest",
       "/features/java": "latest"
     }
}

/features/go/install.sh

#!/bin/bash
...
echo $MY_USERNAME
...

/features/java/install.sh

#!/bin/bash
...
echo $MY_USERNAME
...

./Dockerfile

ARG MY_USERNAME=adam
RUN echo ${MY_USERNAME}

Another idea is moving the "args" property to the top-level, to indicate they arguments should be shared with other customizations, etc that come along.

Allow for Default Environment Variable Value in `${localEnv:...}` and `${containerEnv:...}`

@celestialorb microsoft/vscode-remote-release#1108 at 08/06/2019 11:25:45:

I wasn't able to find anything suggesting this was possible, nor did it seem to work when I tried it myself.

I'd like to see the ability to specify a default value for local environment variable values in the runArgs property of the devcontainer.json file. I'm trying to use the value of a local env var to determine the filesystem source of a bind mount into the remote environment container, or default to a named volume if the variable does not exist.

I propose the ability to use the standard way of defining a default value for a shell/environment variable, with the <variable-name>:-<default-value>. I have tried this and it does not seem to work. An example is shown below for the runArgs property of the devcontainer.json file.

runArgs: [
    -v, ${env:DOES_NOT_EXIST:-name-of-volume-or-default-path}:/path/in/container/filesystem,
],

Target not overwritten when using features

Reported by @sajaysurya in microsoft/vscode-dev-containers#1519:

Currently the docker-from-docker feature doesn't support multistage Dockerfiles

Relates to: Remote - Containers

It works well with the following Dockerfile

FROM python:3.10.5 
RUN apt-get update -q \
    && apt-get install -q -y --no-install-recommends \
        sudo
# add non-root user with sudo access (sudo required by docker-from-docker feature)
RUN adduser vscode
RUN echo vscode ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/vscode \
    && chmod 0440 /etc/sudoers.d/$USERNAME
USER vscode

and the following .devcontainer.json file

        "dockerFile": "Dockerfile",
        "containerUser": "vscode",
	"features": {
		"docker-from-docker": {
			"version": "latest"
		}
	}

It actually works with a named stage in the Dockerfile like

FROM python:3.10.5 AS vscode_dev
RUN apt-get update -q \
    && apt-get install -q -y --no-install-recommends \
        sudo
# add non-root user with sudo access (sudo required by docker-from-docker feature)
RUN adduser vscode
RUN echo vscode ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/vscode \
    && chmod 0440 /etc/sudoers.d/$USERNAME
USER vscode

as long as the build target in not explicitly mentioned in the .devcontainer.json file

        "dockerFile": "Dockerfile",
	"build": { "target": "vscode_dev" }, <--- NOTE: works without this line!
        "containerUser": "vscode",
	"features": {
		"docker-from-docker": {
			"version": "latest"
		}
	}

Provide an "effective" merged devcontainer.json inclusive of Features from read-configuration command

Currently the devcontainers read-configuration command has two modes. One that shows the contents of devcontainer.json and one that also shows the feature configuration for any features referenced (via the --include-features-configuration).

However, what would be most useful would be a way to get a merged configuration inclusive of both out of the CLI. For example, adding a --effective-configuration flag:

$ devcontainer read-configuration --effective-configuration true --workspace-folder .

This would be extremely useful for tool or service implementors that need to any pre-processing steps prior to starting a dev container, or need to inject contents based on the configuration.

As a concrete example, we could use this to modify the tools-vscode-server example under example-usage in this repository to adapt to customizations.vscode.settings and customizations.vscode.extensions through the use of jq and some shell scripts. Right now you'd have to manually parse each feature and do a merge yourself - which could deviate from the standard logic.

cliHost.ts: connectLocal function and cygwin/mingw unix socket files

Hi,

I'm wondering what this code is supposed to to, is it supposed to be able to connect to cygwin unix-domain sockets files ?

const socket = new net.Socket();
(async () => {
const buf = await readLocalFile(socketPath);
const i = buf.indexOf(0xa);
const port = parseInt(buf.slice(0, i).toString(), 10);
const guid = buf.slice(i + 1);
socket.connect(port, '127.0.0.1', () => {
socket.write(guid, err => {
if (err) {
console.error(err);
socket.destroy();
}
});
});
})()

In microsoft/vscode-remote-release#6719 , I've found that a modification to this function can allow VSCode to forward Git Bash's ssh-agent socket file (which use the cygwin unix domain sockets format).

Would a PR be welcome to change this function to handle cygwin unix-domain sockets files ?

--platform and --push flags force the use of a Dockerfile even if features are referenced

The --platform and --push flags are important enablers for pre-building images - particularly those that take advantage of Dev Container Features (devcontainers/spec#61).

Unfortunately, right now there's an error if only an image is referenced along with a set of features in devcontainer.json. Given just being able to just start from an image is one of the primary goals of Dev Container Features, this seems to be pretty clearly a bug.

This occurred in version 0.9.1 of the CLI.

Error: --platform or --push require dockerfilePath.
    at doBuild (/usr/local/share/npm-global/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:342:23)
    at async build (/usr/local/share/npm-global/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:233:20)
{"outcome":"error","message":"--platform or --push require dockerfilePath.","description":"--platform or --push require dockerfilePath."}

//cc @chrmarti @joshspicer @alexdima @bamurtaugh

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.