coder / coder/envbuilder

Add `read-configuration` subcommand to output a merged devcontainer configuration

Đang mở
#210 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Go
Star
300
Fork
64
Merge trung bình
20 phút
Pull request đã merge (30 ngày)
1

Mô tả

**Note:** If we implement option 1 from https://github.com/coder/envbuilder/issues/211, we could punt this feature for the time being.

This feature is a pre-requisite for generating a computed `devcontainer.json` for use by e.g. coder modules. This can help resolve issues like https://github.com/coder/envbuilder/issues/68 where a list of extensions needs to be available during installation of `vscode`, `code-server`, etc.

This commands main purpose is to output a merged configuration based on the projects `devcontainer.json` as well as configuration introduced by features.

A logical approach would be to mimic `@devcontainer/cli` output. Doing so would make `envbuilder` a versatile tool for interpreting devcontainer features, and potentially a drop-in single binary alternative.

Here's an example output from `@devcontainer/cli` when run against the `microsoft/vscode` repo.

devcontainer read-configuration --include-merged-configuration --log-format json --workspace-folder /tmp/envbuilder/vscode

```json
{
"configuration": {
"name": "Code - OSS",
"build": {"dockerfile": "Dockerfile"},
"features": {"ghcr.io/devcontainers/features/desktop-lite:1": {}},
"containerEnv": {"DISPLAY": ""},
"overrideCommand": false,
"privileged": true,
"mounts": [
{"source": "vscode-dev", "target": "/vscode-dev", "type": "volume"}
],
"postCreateCommand": "./.devcontainer/post-create.sh",
"customizations": {
"vscode": {
"settings": {
"resmon.show.battery": false,
"resmon.show.cpufreq": false
},
"extensions": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"GitHub.vscode-pull-request-github",
"ms-vscode.vscode-github-issue-notebooks",
"ms-vscode.vscode-selfhost-test-provider",
"mutantdino.resourcemonitor"
]
}
},
"forwardPorts": [6080, 5901],
"portsAttributes": {
"5901": {"label": "VNC TCP port", "onAutoForward": "silent"},
"6080": {"label": "VNC web client (noVNC)", "onAutoForward": "silent"}
},
"hostRequirements": {"memory": "9gb"},
"configFilePath": {
"$mid": 1,
"fsPath": "/tmp/envbuilder/vscode/.devcontainer/devcontainer.json",
"path": "/tmp/envbuilder/vscode/.devcontainer/devcontainer.json",
"scheme": "vscode-fileHost"
}
},
"workspace": {
"workspaceFolder": "/workspaces/vscode",
"workspaceMount": "type=bind,source=/tmp/envbuilder/vscode,target=/workspaces/vscode"
},
"featuresConfiguration": {
"featureSets": [
{
"sourceInformation": {
"type": "oci",
"manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.devcontainers",
"digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"size": 0
},
"layers": [
{
"mediaType": "application/vnd.devcontainers.layer.v1+tar",
"digest": "sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad",
"size": 28160,
"annotations": {
"org.opencontainers.image.title": "devcontainer-feature-desktop-lite.tgz"
}
}
],
"annotations": {"com.github.package.type": "devcontainer_feature"}
},
"manifestDigest": "sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7",
"featureRef": {
"id": "desktop-lite",
"owner": "devcontainers",
"namespace": "devcontainers/features",
"registry": "ghcr.io",
"resource": "ghcr.io/devcontainers/features/desktop-lite",
"path": "devcontainers/features/desktop-lite",
"version": "1",
"tag": "1"
},
"userFeatureId": "ghcr.io/devcontainers/features/desktop-lite:1",
"userFeatureIdWithoutVersion": "ghcr.io/devcontainers/features/desktop-lite"
},
"features": [
{
"id": "desktop-lite",
"version": "1.0.8",
"name": "Light-weight Desktop",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/desktop-lite",
"description": "Adds a lightweight Fluxbox based desktop to the container that can be accessed using a VNC viewer or the web. GUI-based commands executed from the built-in VS code terminal will open on the desktop automatically.",
"options": {
"version": {
"type": "string",
"proposals": ["latest"],
"default": "latest",
"description": "Currently Unused!"
},
"noVncVersion": {
"type": "string",
"proposals": ["1.2.0"],
"default": "1.2.0",
"description": "NoVnc Version"
},
"password": {
"type": "string",
"proposals": ["vscode", "codespaces", "password"],
"default": "vscode",
"description": "Enter a password for desktop connections"
},
"webPort": {
"type": "string",
"proposals": ["6080"],
"default": "6080",
"description": "Enter a port for the VNC web client"
},
"vncPort": {
"type": "string",
"proposals": ["5901"],
"default": "5901",
"description": "Enter a port for the desktop VNC server"
}
},
"init": true,
"entrypoint": "/usr/local/share/desktop-init.sh",
"containerEnv": {"DISPLAY": ":1"},
"installsAfter": ["ghcr.io/devcontainers/features/common-utils"],
"included": true,
"value": {},
"cachePath": "/tmp/devcontainercli-coder/container-features/0.60.0-1716804265094/desktop-lite_0",
"consecutiveId": "desktop-lite_0"
}
],
"internalVersion": "2",
"computedDigest": "sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7"
}
],
"dstFolder": "/tmp/devcontainercli-coder/container-features/0.60.0-1716804265094"
},
"mergedConfiguration": {
"name": "Code - OSS",
"build": {"dockerfile": "Dockerfile"},
"features": {"ghcr.io/devcontainers/features/desktop-lite:1": {}},
"containerEnv": {"DISPLAY": ""},
"overrideCommand": false,
"privileged": true,
"mounts": [
{"source": "vscode-dev", "target": "/vscode-dev", "type": "volume"}
],
"forwardPorts": [6080, 5901],
"portsAttributes": {
"5901": {"label": "VNC TCP port", "onAutoForward": "silent"},
"6080": {"label": "VNC web client (noVNC)", "onAutoForward": "silent"}
},
"hostRequirements": {"cpus": 0, "memory": "9663676416"},
"configFilePath": {
"$mid": 1,
"fsPath": "/tmp/envbuilder/vscode/.devcontainer/devcontainer.json",
"path": "/tmp/envbuilder/vscode/.devcontainer/devcontainer.json",
"scheme": "vscode-fileHost"
},
"init": true,
"entrypoints": ["/usr/local/share/desktop-init.sh"],
"customizations": {
"vscode": [
{"extensions": ["dbaeumer.vscode-eslint"]},
{"extensions": ["dbaeumer.vscode-eslint"]},
{"extensions": ["dbaeumer.vscode-eslint"]},
{
"settings": {
"resmon.show.battery": false,
"resmon.show.cpufreq": false
},
"extensions": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"GitHub.vscode-pull-request-github",
"ms-vscode.vscode-github-issue-notebooks",
"ms-vscode.vscode-selfhost-test-provider",
"mutantdino.resourcemonitor"
]
}
]
},
"onCreateCommands": [],
"updateContentCommands": [],
"postCreateCommands": ["./.devcontainer/post-create.sh"],
"postStartCommands": [],
"postAttachCommands": [],
"remoteUser": "node",
"remoteEnv": {}
}
}
```

Under `.configuration` the only new field is `.configuration.configFilePath`. Otherwise this is the project `devcontainer.json` as-is. The rest: `.workspace`, `.featuresConfiguration` and `.mergedConfiguration` are all added by `read-configuration` (and the merged config flag).

For this issue, we're mainly interested in implementing `.mergedConfiguration`.

Reference:

- https://github.com/devcontainers/cli/blob/be1f2034e10395f42843ebf26600a42e11e66531/example-usage/tool-vscode-server/start.sh#L11-L11
- https://github.com/devcontainers/cli/blob/be1f2034e10395f42843ebf26600a42e11e66531/example-usage/tool-vscode-server/server/init-vscode-server.sh#L38-L42

Logs (for reference)

```json
{"type":"text","level":3,"timestamp":1716804265041,"text":"@devcontainers/cli 0.60.0. Node.js v18.20.2. linux 5.19.17-051917-generic x64."}
{"type":"start","level":2,"timestamp":1716804265041,"text":"Run: git rev-parse --show-cdup"}
{"type":"stop","level":2,"timestamp":1716804265049,"text":"Run: git rev-parse --show-cdup","startTimestamp":1716804265041}
{"type":"start","level":2,"timestamp":1716804265050,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/tmp/envbuilder/vscode --filter label=devcontainer.config_file=/tmp/envbuilder/vscode/.devcontainer/devcontainer.json"}
{"type":"stop","level":2,"timestamp":1716804265072,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/tmp/envbuilder/vscode --filter label=devcontainer.config_file=/tmp/envbuilder/vscode/.devcontainer/devcontainer.json","startTimestamp":1716804265050}
{"type":"start","level":2,"timestamp":1716804265072,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/tmp/envbuilder/vscode"}
{"type":"stop","level":2,"timestamp":1716804265094,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/tmp/envbuilder/vscode","startTimestamp":1716804265072}
{"type":"text","level":1,"timestamp":1716804265095,"text":"workspace root: /tmp/envbuilder/vscode"}
{"type":"text","level":1,"timestamp":1716804265095,"text":"configPath: /tmp/envbuilder/vscode/.devcontainer/devcontainer.json"}
{"type":"text","level":1,"timestamp":1716804265096,"text":"--- Processing User Features ----"}
{"type":"text","level":1,"timestamp":1716804265096,"text":"[* user-provided] ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":3,"timestamp":1716804265096,"text":"Resolving Feature dependencies for 'ghcr.io/devcontainers/features/desktop-lite:1'..."}
{"type":"text","level":2,"timestamp":1716804265097,"text":"* Processing feature: ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> input: ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804265097,"text":">"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> resource: ghcr.io/devcontainers/features/desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> id: desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> owner: devcontainers"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> namespace: devcontainers/features"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> registry: ghcr.io"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> path: devcontainers/features/desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265097,"text":">"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> version: 1"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> tag?: 1"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"> digest?: undefined"}
{"type":"text","level":1,"timestamp":1716804265097,"text":"manifest url: https://ghcr.io/v2/devcontainers/features/desktop-lite/manifests/sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7"}
{"type":"text","level":1,"timestamp":1716804265322,"text":"[httpOci] Attempting to authenticate via 'Bearer' auth."}
{"type":"text","level":1,"timestamp":1716804265324,"text":"[httpOci] No authentication credentials found for registry 'ghcr.io' via docker config or credential helper."}
{"type":"text","level":1,"timestamp":1716804265324,"text":"[httpOci] No authentication credentials found for registry 'ghcr.io'. Accessing anonymously."}
{"type":"text","level":1,"timestamp":1716804265324,"text":"[httpOci] Attempting to fetch bearer token from: https://ghcr.io/token?service=ghcr.io&scope=repository:devcontainers/features/desktop-lite:pull"}
{"type":"text","level":1,"timestamp":1716804265766,"text":"[httpOci] 200 on reattempt after auth: https://ghcr.io/v2/devcontainers/features/desktop-lite/manifests/sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> input: ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804265767,"text":">"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> resource: ghcr.io/devcontainers/features/desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> id: desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> owner: devcontainers"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> namespace: devcontainers/features"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> registry: ghcr.io"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> path: devcontainers/features/desktop-lite"}
{"type":"text","level":1,"timestamp":1716804265767,"text":">"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> version: 1"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> tag?: 1"}
{"type":"text","level":1,"timestamp":1716804265767,"text":"> digest?: undefined"}
{"type":"text","level":1,"timestamp":1716804265768,"text":"blob url: https://ghcr.io/v2/devcontainers/features/desktop-lite/blobs/sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad"}
{"type":"text","level":1,"timestamp":1716804265769,"text":"[httpOci] Applying cachedAuthHeader for registry ghcr.io..."}
{"type":"text","level":1,"timestamp":1716804266117,"text":"[httpOci] 200 (Cached): https://ghcr.io/v2/devcontainers/features/desktop-lite/blobs/sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad"}
{"type":"text","level":1,"timestamp":1716804266125,"text":"./ : Directory"}
{"type":"text","level":1,"timestamp":1716804266128,"text":"./NOTES.md : File"}
{"type":"text","level":1,"timestamp":1716804266129,"text":"./README.md : File"}
{"type":"text","level":1,"timestamp":1716804266129,"text":"./devcontainer-feature.json : File"}
{"type":"text","level":1,"timestamp":1716804266129,"text":"./install.sh : File"}
{"type":"text","level":1,"timestamp":1716804266135,"text":"Files extracted from blob: ./NOTES.md, ./README.md, ./devcontainer-feature.json, ./install.sh"}
{"type":"text","level":1,"timestamp":1716804266138,"text":"Found metadata file 'devcontainer-feature.json' in blob"}
{"type":"text","level":2,"timestamp":1716804266139,"text":"* Processing feature: ghcr.io/devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> input: ghcr.io/devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266139,"text":">"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> resource: ghcr.io/devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> id: common-utils"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> owner: devcontainers"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> namespace: devcontainers/features"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> registry: ghcr.io"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> path: devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266139,"text":">"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> version: latest"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> tag?: latest"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"> digest?: undefined"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"manifest url: https://ghcr.io/v2/devcontainers/features/common-utils/manifests/latest"}
{"type":"text","level":1,"timestamp":1716804266139,"text":"[httpOci] Applying cachedAuthHeader for registry ghcr.io..."}
{"type":"text","level":1,"timestamp":1716804266380,"text":"[httpOci] 200 (Cached): https://ghcr.io/v2/devcontainers/features/common-utils/manifests/latest"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> input: ghcr.io/devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266380,"text":">"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> resource: ghcr.io/devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> id: common-utils"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> owner: devcontainers"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> namespace: devcontainers/features"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> registry: ghcr.io"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> path: devcontainers/features/common-utils"}
{"type":"text","level":1,"timestamp":1716804266380,"text":">"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> version: latest"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> tag?: latest"}
{"type":"text","level":1,"timestamp":1716804266380,"text":"> digest?: undefined"}
{"type":"text","level":1,"timestamp":1716804266381,"text":"[* resolved worklist] ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804266381,"text":"[\n {\n \"type\": \"user-provided\",\n \"userFeatureId\": \"ghcr.io/devcontainers/features/desktop-lite:1\",\n \"options\": {},\n \"dependsOn\": [],\n \"installsAfter\": [\n {\n \"type\": \"resolved\",\n \"userFeatureId\": \"ghcr.io/devcontainers/features/common-utils\",\n \"options\": {},\n \"featureSet\": {\n \"sourceInformation\": {\n \"type\": \"oci\",\n \"manifest\": {\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.devcontainers\",\n \"digest\": \"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n \"size\": 0\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.devcontainers.layer.v1+tar\",\n \"digest\": \"sha256:d846c58d563c29194c84f0af63fcfdef7b9c27982e9c974e0eff94c48fb89c4b\",\n \"size\": 47104,\n \"annotations\": {\n \"org.opencontainers.image.title\": \"devcontainer-feature-common-utils.tgz\"\n }\n }\n ],\n \"annotations\": {\n \"dev.containers.metadata\": \"{\\\"id\\\":\\\"common-utils\\\",\\\"version\\\":\\\"2.4.3\\\",\\\"name\\\":\\\"Common Utilities\\\",\\\"documentationURL\\\":\\\"https://github.com/devcontainers/features/tree/main/src/common-utils\\\",\\\"description\\\":\\\"Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user.\\\",\\\"options\\\":{\\\"installZsh\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":true,\\\"description\\\":\\\"Install ZSH?\\\"},\\\"configureZshAsDefaultShell\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":false,\\\"description\\\":\\\"Change default shell to ZSH?\\\"},\\\"installOhMyZsh\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":true,\\\"description\\\":\\\"Install Oh My Zsh!?\\\"},\\\"installOhMyZshConfig\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":true,\\\"description\\\":\\\"Allow installing the default dev container .zshrc templates?\\\"},\\\"upgradePackages\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":true,\\\"description\\\":\\\"Upgrade OS packages?\\\"},\\\"username\\\":{\\\"type\\\":\\\"string\\\",\\\"proposals\\\":[\\\"devcontainer\\\",\\\"vscode\\\",\\\"codespace\\\",\\\"none\\\",\\\"automatic\\\"],\\\"default\\\":\\\"automatic\\\",\\\"description\\\":\\\"Enter name of a non-root user to configure or none to skip\\\"},\\\"userUid\\\":{\\\"type\\\":\\\"string\\\",\\\"proposals\\\":[\\\"1001\\\",\\\"automatic\\\"],\\\"default\\\":\\\"automatic\\\",\\\"description\\\":\\\"Enter UID for non-root user\\\"},\\\"userGid\\\":{\\\"type\\\":\\\"string\\\",\\\"proposals\\\":[\\\"1001\\\",\\\"automatic\\\"],\\\"default\\\":\\\"automatic\\\",\\\"description\\\":\\\"Enter GID for non-root user\\\"},\\\"nonFreePackages\\\":{\\\"type\\\":\\\"boolean\\\",\\\"default\\\":false,\\\"description\\\":\\\"Add packages from non-free Debian repository? (Debian only)\\\"}}}\",\n \"com.github.package.type\": \"devcontainer_feature\"\n }\n },\n \"manifestDigest\": \"sha256:e9e1d402031416ed5fc500f242c27ffa1043a27b5ba612e6596ea62503c8ae70\",\n \"featureRef\": {\n \"id\": \"common-utils\",\n \"owner\": \"devcontainers\",\n \"namespace\": \"devcontainers/features\",\n \"registry\": \"ghcr.io\",\n \"resource\": \"ghcr.io/devcontainers/features/common-utils\",\n \"path\": \"devcontainers/features/common-utils\",\n \"version\": \"latest\",\n \"tag\": \"latest\"\n },\n \"userFeatureId\": \"ghcr.io/devcontainers/features/common-utils\",\n \"userFeatureIdWithoutVersion\": \"ghcr.io/devcontainers/features/common-utils\"\n },\n \"features\": [\n {\n \"id\": \"common-utils\",\n \"included\": true,\n \"value\": {}\n }\n ]\n },\n \"dependsOn\": [],\n \"installsAfter\": [],\n \"roundPriority\": 0,\n \"featureIdAliases\": [\n \"common-utils\"\n ]\n }\n ],\n \"roundPriority\": 0,\n \"featureSet\": {\n \"sourceInformation\": {\n \"type\": \"oci\",\n \"manifest\": {\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.devcontainers\",\n \"digest\": \"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n \"size\": 0\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.devcontainers.layer.v1+tar\",\n \"digest\": \"sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad\",\n \"size\": 28160,\n \"annotations\": {\n \"org.opencontainers.image.title\": \"devcontainer-feature-desktop-lite.tgz\"\n }\n }\n ],\n \"annotations\": {\n \"com.github.package.type\": \"devcontainer_feature\"\n }\n },\n \"manifestDigest\": \"sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7\",\n \"featureRef\": {\n \"id\": \"desktop-lite\",\n \"owner\": \"devcontainers\",\n \"namespace\": \"devcontainers/features\",\n \"registry\": \"ghcr.io\",\n \"resource\": \"ghcr.io/devcontainers/features/desktop-lite\",\n \"path\": \"devcontainers/features/desktop-lite\",\n \"version\": \"1\",\n \"tag\": \"1\"\n },\n \"userFeatureId\": \"ghcr.io/devcontainers/features/desktop-lite:1\",\n \"userFeatureIdWithoutVersion\": \"ghcr.io/devcontainers/features/desktop-lite\"\n },\n \"features\": [\n {\n \"id\": \"desktop-lite\",\n \"included\": true,\n \"value\": {},\n \"version\": \"1.0.8\",\n \"name\": \"Light-weight Desktop\",\n \"documentationURL\": \"https://github.com/devcontainers/features/tree/main/src/desktop-lite\",\n \"description\": \"Adds a lightweight Fluxbox based desktop to the container that can be accessed using a VNC viewer or the web. GUI-based commands executed from the built-in VS code terminal will open on the desktop automatically.\",\n \"options\": {\n \"version\": {\n \"type\": \"string\",\n \"proposals\": [\n \"latest\"\n ],\n \"default\": \"latest\",\n \"description\": \"Currently Unused!\"\n },\n \"noVncVersion\": {\n \"type\": \"string\",\n \"proposals\": [\n \"1.2.0\"\n ],\n \"default\": \"1.2.0\",\n \"description\": \"NoVnc Version\"\n },\n \"password\": {\n \"type\": \"string\",\n \"proposals\": [\n \"vscode\",\n \"codespaces\",\n \"password\"\n ],\n \"default\": \"vscode\",\n \"description\": \"Enter a password for desktop connections\"\n },\n \"webPort\": {\n \"type\": \"string\",\n \"proposals\": [\n \"6080\"\n ],\n \"default\": \"6080\",\n \"description\": \"Enter a port for the VNC web client\"\n },\n \"vncPort\": {\n \"type\": \"string\",\n \"proposals\": [\n \"5901\"\n ],\n \"default\": \"5901\",\n \"description\": \"Enter a port for the desktop VNC server\"\n }\n },\n \"init\": true,\n \"entrypoint\": \"/usr/local/share/desktop-init.sh\",\n \"containerEnv\": {\n \"DISPLAY\": \":1\"\n },\n \"installsAfter\": [\n \"ghcr.io/devcontainers/features/common-utils\"\n ]\n }\n ]\n },\n \"featureIdAliases\": [\n \"desktop-lite\"\n ]\n }\n]"}
{"type":"text","level":1,"timestamp":1716804266382,"text":"[raw worklist]: ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":3,"timestamp":1716804266382,"text":"Soft-dependency 'ghcr.io/devcontainers/features/common-utils' is not required. Removing from installation order..."}
{"type":"text","level":1,"timestamp":1716804266382,"text":"[worklist-without-dangling-soft-deps]: ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804266382,"text":"Starting round-based Feature install order calculation from worklist..."}
{"type":"text","level":1,"timestamp":1716804266382,"text":"\n[round] ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804266382,"text":"[round-candidates] ghcr.io/devcontainers/features/desktop-lite:1 (0)"}
{"type":"text","level":1,"timestamp":1716804266382,"text":"[round-after-filter-priority] (maxPriority=0) ghcr.io/devcontainers/features/desktop-lite:1 (0)"}
{"type":"text","level":1,"timestamp":1716804266383,"text":"[round-after-comparesTo] ghcr.io/devcontainers/features/desktop-lite:1"}
{"type":"text","level":1,"timestamp":1716804266383,"text":"--- Fetching User Features ----"}
{"type":"text","level":2,"timestamp":1716804266383,"text":"* Fetching feature: desktop-lite_0_oci"}
{"type":"text","level":1,"timestamp":1716804266383,"text":"Fetching from OCI"}
{"type":"text","level":1,"timestamp":1716804266384,"text":"blob url: https://ghcr.io/v2/devcontainers/features/desktop-lite/blobs/sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad"}
{"type":"text","level":1,"timestamp":1716804266384,"text":"[httpOci] Applying cachedAuthHeader for registry ghcr.io..."}
{"type":"text","level":1,"timestamp":1716804266615,"text":"[httpOci] 200 (Cached): https://ghcr.io/v2/devcontainers/features/desktop-lite/blobs/sha256:9b79df4771f1f348da15db16e84ae640164027b2ea89ea86643394c6c2ff4dad"}
{"type":"text","level":1,"timestamp":1716804266617,"text":"./ : Directory"}
{"type":"text","level":1,"timestamp":1716804266617,"text":"./NOTES.md : File"}
{"type":"text","level":1,"timestamp":1716804266618,"text":"./README.md : File"}
{"type":"text","level":1,"timestamp":1716804266618,"text":"./devcontainer-feature.json : File"}
{"type":"text","level":1,"timestamp":1716804266618,"text":"./install.sh : File"}
{"type":"text","level":1,"timestamp":1716804266621,"text":"Files extracted from blob: ./NOTES.md, ./README.md, ./devcontainer-feature.json, ./install.sh"}
{"type":"text","level":2,"timestamp":1716804266623,"text":"* Fetched feature: desktop-lite_0_oci version 1.0.8"}
{"type":"start","level":2,"timestamp":1716804266682,"text":"Run: docker inspect --type image mcr.microsoft.com/devcontainers/typescript-node:18-bookworm"}
{"type":"stop","level":2,"timestamp":1716804266705,"text":"Run: docker inspect --type image mcr.microsoft.com/devcontainers/typescript-node:18-bookworm","startTimestamp":1716804266682}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> input: mcr.microsoft.com/devcontainers/typescript-node:18-bookworm"}
{"type":"text","level":1,"timestamp":1716804266706,"text":">"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> resource: mcr.microsoft.com/devcontainers/typescript-node"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> id: typescript-node"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> owner: devcontainers"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> namespace: devcontainers"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> registry: mcr.microsoft.com"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> path: devcontainers/typescript-node"}
{"type":"text","level":1,"timestamp":1716804266706,"text":">"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> version: 18-bookworm"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> tag?: 18-bookworm"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"> digest?: undefined"}
{"type":"text","level":1,"timestamp":1716804266706,"text":"manifest url: https://mcr.microsoft.com/v2/devcontainers/typescript-node/manifests/18-bookworm"}
{"type":"text","level":1,"timestamp":1716804266932,"text":"[httpOci] 404 (NoAuth): https://mcr.microsoft.com/v2/devcontainers/typescript-node/manifests/18-bookworm"}
{"type":"text","level":1,"timestamp":1716804266932,"text":"Did not fetch target with expected mimetype 'application/vnd.docker.distribution.manifest.v2+json': {\"errors\":[{\"code\":\"MANIFEST_UNKNOWN\",\"message\":\"OCI index found, but accept header does not support OCI indexes\"}]}\n"}
{"type":"text","level":1,"timestamp":1716804267105,"text":"[httpOci] 200 (NoAuth): https://mcr.microsoft.com/v2/devcontainers/typescript-node/manifests/18-bookworm"}
{"type":"text","level":1,"timestamp":1716804267105,"text":"Fetched: {\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.index.v1+json\",\n \"manifests\": [\n {\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"digest\": \"sha256:a3193b69f2d1f0ce6d6511b85c913579c17f4e7fe0ad8fb71c3d53c717580f6b\",\n \"size\": 4485,\n \"platform\": {\n \"architecture\": \"amd64\",\n \"os\": \"linux\"\n }\n },\n {\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"digest\": \"sha256:e9a4f6e413715d8989a0fa381b6b3fb3144d15d729367cb0fd4cda6b3e4544e9\",\n \"size\": 4485,\n \"platform\": {\n \"architecture\": \"arm64\",\n \"os\": \"linux\"\n }\n },\n {\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"digest\": \"sha256:73d619643bd152d04f7fa9f777f2825633a529e278e5c2bdc2e438feecf15daa\",\n \"size\": 566,\n \"annotations\": {\n \"vnd.docker.reference.digest\": \"sha256:a3193b69f2d1f0ce6d6511b85c913579c17f4e7fe0ad8fb71c3d53c717580f6b\",\n \"vnd.docker.reference.type\": \"attestation-manifest\"\n },\n \"platform\": {\n \"architecture\": \"unknown\",\n \"os\": \"unknown\"\n }\n },\n {\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"digest\": \"sha256:3375f4eed28c1b8a3082b8a0d9d6f0e3ed74c32d67a2e319e22a84ed97c289c7\",\n \"size\": 566,\n \"annotations\": {\n \"vnd.docker.reference.digest\": \"sha256:e9a4f6e413715d8989a0fa381b6b3fb3144d15d729367cb0fd4cda6b3e4544e9\",\n \"vnd.docker.reference.type\": \"attestation-manifest\"\n },\n \"platform\": {\n \"architecture\": \"unknown\",\n \"os\": \"unknown\"\n }\n }\n ]\n}"}
{"type":"text","level":1,"timestamp":1716804267426,"text":"[httpOci] 200 (NoAuth): https://mcr.microsoft.com/v2/devcontainers/typescript-node/manifests/sha256:a3193b69f2d1f0ce6d6511b85c913579c17f4e7fe0ad8fb71c3d53c717580f6b"}
{"type":"text","level":1,"timestamp":1716804267426,"text":"blob url: https://mcr.microsoft.com/v2/devcontainers/typescript-node/blobs/sha256:e01bfe3472dd64911ad4c13469b9400de923cdc3fc11367aef217cf5bab01988"}
{"type":"text","level":1,"timestamp":1716804267944,"text":"[httpOci] 200 (NoAuth): https://mcr.microsoft.com/v2/devcontainers/typescript-node/blobs/sha256:e01bfe3472dd64911ad4c13469b9400de923cdc3fc11367aef217cf5bab01988"}
```

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Bắt đầu với lệnh gọi được đề xuất `read-configuration --include-merged-configuration` và hai script devcontainers CLI được tham chiếu. Theo dõi cách Envbuilder đọc `devcontainer.json` của dự án và xử lý các features, sau đó so sánh kết quả với đầu ra ví dụ. Hoàn tất khi lệnh xuất ra một cấu hình đã hợp nhất, chứa các thiết lập của dự án và các đóng góp của features.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
docker, go
Lĩnh vực
cli, tooling
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.