Skip to content

Commit d5ee249

Browse files
authored
Update devcontainer to use the modern developer environment image (#51762)
### What does this PR do? This modifies the default dev container config to use our standard [dev env images](https://datadoghq.dev/datadog-agent/reference/images/dev/). ### Motivation We want engineers to have consistency such that any dev env deployment has the same capabilities. ### Additional Notes This was [blocked](#42292) for some time due to permissions issues which have since been [fixed](DataDog/datadog-agent-buildimages#1089). Co-authored-by: ofek.lev <ofek.lev@datadoghq.com>
1 parent e5c2530 commit d5ee249

3 files changed

Lines changed: 38 additions & 18 deletions

File tree

.github/workflows/test-devcontainer.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ jobs:
5858
run: |
5959
cat > files-of-interest.txt <<'EOF'
6060
.github/workflows/test-devcontainer.yml
61+
tasks/devcontainer.py
6162
EOF
6263
6364
if grep -Fx -f files-of-interest.txt changed-files.txt >/dev/null; then
@@ -107,14 +108,8 @@ jobs:
107108
echo "::endgroup::"
108109
df -h
109110
110-
- name: Build image
111-
run: |
112-
git clone https://github.com/DataDog/datadog-agent-buildimages.git
113-
cd datadog-agent-buildimages
114-
dda run build devcontainer legacy-devenv
115-
116111
- name: Create Dev Container config
117-
run: dda inv -- devcontainer.setup --image legacy-devenv
112+
run: dda inv -- devcontainer.setup
118113

119114
- name: Ensure mount paths exist
120115
run: |
@@ -126,15 +121,15 @@ jobs:
126121
- name: Start Dev Container
127122
run: devcontainer up --workspace-folder .
128123

129-
- name: Grant the datadog user access to host Docker socket
124+
- name: Grant the dd user access to host Docker socket
130125
run: |
131126
docker exec -u root datadog-agent-devcontainer sh -lc '
132127
set -e
133128
sock=/var/run/docker.sock
134129
gid=$(stat -c %g "$sock")
135130
getent group "$gid" >/dev/null || groupadd -g "$gid" dockersock
136131
gname=$(getent group "$gid" | cut -d: -f1)
137-
id -nG datadog | tr " " "\n" | grep -qx "$gname" || usermod -aG "$gname" datadog
132+
id -nG dd | tr " " "\n" | grep -qx "$gname" || usermod -aG "$gname" dd
138133
'
139134
140135
- name: Test Agent build

tasks/devcontainer.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
DEVCONTAINER_DIR = ".devcontainer"
2424
DEVCONTAINER_FILE = "devcontainer.json"
2525
DEVCONTAINER_NAME = "datadog-agent-devcontainer"
26-
DEVCONTAINER_IMAGE = "registry.ddbuild.io/ci/datadog-agent-devenv:1-arm64"
26+
# This is our standard Linux developer environment image, built from the buildimages
27+
# repo (https://github.com/DataDog/datadog-agent-buildimages/tree/main/dev-envs/linux).
28+
DEVCONTAINER_IMAGE = "datadog/agent-dev-env-linux"
2729

2830

2931
class SkaffoldProfile(Enum):
@@ -40,7 +42,7 @@ def setup(
4042
build_exclude=None,
4143
skaffoldProfile=None,
4244
flavor=AgentFlavor.base.name,
43-
image='',
45+
image=DEVCONTAINER_IMAGE,
4446
claude_code=False,
4547
):
4648
"""
@@ -93,19 +95,36 @@ def setup(
9395
]
9496
if devcontainer.get("image") and "amd64" in devcontainer["image"].casefold():
9597
devcontainer["runArgs"].append("--platform=linux/amd64")
98+
if sys.platform != "win32":
99+
# The image's entrypoint realigns its user to this UID/GID so writes to bind
100+
# mounts keep host ownership. We pass them as explicit `docker run` env vars
101+
# because no devcontainer variable resolves to the host UID/GID. (`os.getuid`/
102+
# `os.getgid` are absent on Windows, but the platform check short-circuits first.)
103+
devcontainer["runArgs"] += ["-e", f"HOST_UID={os.getuid()}", "-e", f"HOST_GID={os.getgid()}"]
96104
devcontainer["features"] = {}
97-
devcontainer["remoteUser"] = "datadog"
105+
# Keep the image's entrypoint, which realigns `dd` to the host's UID/GID and runs
106+
# the image's startup before exec'ing its long-running command. Otherwise the dev
107+
# container CLI replaces the entrypoint with its own keep-alive command and skips
108+
# that setup.
109+
devcontainer["overrideCommand"] = False
110+
# The image provides this user, and its entrypoint realigns it to the host's UID/GID
111+
# (via HOST_UID/HOST_GID above).
112+
devcontainer["remoteUser"] = "dd"
113+
# The host home directory is `USERPROFILE` on Windows and `HOME` elsewhere. We use a
114+
# single variable rather than concatenating both, because some Windows shells also
115+
# set `HOME`, which would otherwise produce a doubled, invalid path.
116+
home_env = "${localEnv:USERPROFILE}" if sys.platform == "win32" else "${localEnv:HOME}"
98117
devcontainer["mounts"] = [
99118
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
100-
"source=${localEnv:HOME}/.ssh,target=/home/datadog/.ssh,type=bind",
119+
f"source={home_env}/.ssh,target=/home/dd/.ssh,type=bind",
101120
]
102121
devcontainer["customizations"] = {
103122
"vscode": {
104123
"settings": {
105124
"go.toolsManagement.checkForUpdates": "local",
106125
"go.useLanguageServer": True,
107-
"go.gopath": "/home/datadog/go",
108-
"go.goroot": "/usr/local/go",
126+
# GOPATH and GOROOT are auto-detected from the image's environment, so
127+
# they are intentionally left unset here.
109128
"go.buildTags": local_build_tags,
110129
"go.testTags": local_build_tags,
111130
"go.lintTool": "golangci-lint",
@@ -126,7 +145,12 @@ def setup(
126145
# onCreateCommand runs the install-tools and deps tasks only when the devcontainer is created and not each time
127146
# the container is started. Set the github token to prevent rate limiting on creation.
128147
devcontainer["onCreateCommand"] = (
129-
"git config --global --add safe.directory /workspaces/${localWorkspaceFolderBasename}"
148+
# The image rewrites github.com to SSH so it can clone private repos, but the
149+
# devcontainer authenticates over HTTPS with GITHUB_TOKEN, so we undo that
150+
# rewrite (the `|| true` tolerates its absence if the image stops setting it).
151+
# See https://github.com/DataDog/datadog-agent-buildimages/blob/main/dev-envs/linux/ssh.sh
152+
"git config --global --unset url.ssh://git@github.com/.insteadOf || true"
153+
" && git config --global --add safe.directory /workspaces/${localWorkspaceFolderBasename}"
130154
" && dda config set github.auth.token \"$GITHUB_TOKEN\""
131155
" && dda inv -- -e install-tools && dda inv -- -e deps"
132156
)
@@ -161,7 +185,7 @@ def configure_claude_code(devcontainer: dict, claude_code: bool):
161185
claude_data_path = Path.home() / ".devcontainer" / "claude-data"
162186
Path(claude_data_path).mkdir(parents=True, exist_ok=True)
163187
devcontainer["mounts"].append(
164-
"source=${localWorkspaceFolder}/.devcontainer/claude-data/,target=/home/datadog/.claude,type=bind"
188+
"source=${localWorkspaceFolder}/.devcontainer/claude-data/,target=/home/dd/.claude,type=bind"
165189
)
166190

167191
devcontainer["features"]["ghcr.io/devcontainers/features/node:1"] = {}

tasks/vscode.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def setup_devcontainer(
112112
build_include=build_include,
113113
build_exclude=build_exclude,
114114
flavor=flavor,
115-
image=image,
115+
# Fall back to the default developer environment image when none is given.
116+
image=image or devcontainer.DEVCONTAINER_IMAGE,
116117
)
117118

118119

0 commit comments

Comments
 (0)