2323DEVCONTAINER_DIR = ".devcontainer"
2424DEVCONTAINER_FILE = "devcontainer.json"
2525DEVCONTAINER_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
2931class 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" ] = {}
0 commit comments