Skip to content

Commit b4a8730

Browse files
committed
Add config to enable code in exec shell
1 parent 47195f6 commit b4a8730

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

internal/pkg/devcontainers/dockerutils.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func ExecInDevContainer(containerIDOrName string, workDir string, args []string)
132132
return err
133133
}
134134

135+
// Get container ID
135136
for _, devcontainer := range devcontainerList {
136137
if devcontainer.ContainerName == containerIDOrName ||
137138
devcontainer.DevcontainerName == containerIDOrName ||
@@ -179,13 +180,46 @@ func ExecInDevContainer(containerIDOrName string, workDir string, args []string)
179180
fmt.Println("Continuing without setting SSH_AUTH_SOCK...")
180181
}
181182

183+
containerPath, err := getContainerEnvVar(containerID, "PATH")
184+
if err == nil {
185+
// Got the PATH
186+
vscodeServerPath, err := getVscodeServerPath(containerID)
187+
if err == nil {
188+
// Got the VS Code server location - add bin subfolder to PATH
189+
containerPath = strings.TrimSpace(containerPath)
190+
containerPath = fmt.Sprintf("%s/bin:%s", vscodeServerPath, containerPath)
191+
} else {
192+
// output error and continue without adding to PATH value
193+
fmt.Printf("Warning: Failed to get VS Code server location: %s\n", err)
194+
fmt.Println("Continuing without adding VS Code Server to PATH...")
195+
}
196+
} else {
197+
// output error and continue without adding to PATH value
198+
containerPath = ""
199+
fmt.Printf("Warning: Failed to get PATH value for container: %s\n", err)
200+
fmt.Println("Continuing without overriding PATH...")
201+
}
202+
203+
ipcSock, err := getVscodeIpcSock(containerID)
204+
if err != nil {
205+
ipcSock = ""
206+
fmt.Printf("Warning; Failed to get VS Code IPC SOCK: %s\n", err)
207+
fmt.Println("Continuing without setting VSCODE_IPC_HOOK_CLI...")
208+
}
209+
182210
dockerArgs := []string{"exec", "-it", "--workdir", workDir}
183211
if userName != "" {
184212
dockerArgs = append(dockerArgs, "--user", userName)
185213
}
186214
if sshAuthSockValue != "" {
187215
dockerArgs = append(dockerArgs, "--env", "SSH_AUTH_SOCK="+sshAuthSockValue)
188216
}
217+
if containerPath != "" {
218+
dockerArgs = append(dockerArgs, "--env", "PATH="+containerPath)
219+
}
220+
if ipcSock != "" {
221+
dockerArgs = append(dockerArgs, "--env", "VSCODE_IPC_HOOK_CLI="+ipcSock)
222+
}
189223
dockerArgs = append(dockerArgs, containerID)
190224
dockerArgs = append(dockerArgs, args...)
191225

@@ -219,8 +253,20 @@ func getSshAuthSockValue(containerID string) (string, error) {
219253
// Host has SSH_AUTH_SOCK set, so expecting the dev container to have forwarding set up
220254
// Find the latest /tmp/vscode-ssh-auth-<...>.sock
221255

222-
dockerArgs := []string{"exec", containerID, "bash", "-c", "ls -t -d -1 \"${TMPDIR:-/tmp}\"/vscode-ssh-auth-*"}
256+
return getLatestFileMatch(containerID, "\"${TMPDIR:-/tmp}\"/vscode-ssh-auth-*")
257+
}
258+
259+
func getVscodeServerPath(containerID string) (string, error) {
260+
return getLatestFileMatch(containerID, "/vscode/vscode-server/bin/x64/*")
261+
}
262+
func getVscodeIpcSock(containerID string) (string, error) {
263+
return getLatestFileMatch(containerID, "\"${TMPDIR:-/tmp}\"/vscode-ipc-*")
264+
}
265+
266+
// getLatestFileMatch lists files matching `pattern` in the container and returns the latest filename
267+
func getLatestFileMatch(containerID string, pattern string) (string, error) {
223268

269+
dockerArgs := []string{"exec", containerID, "bash", "-c", fmt.Sprintf("ls -t -d -1 %s", pattern)}
224270
dockerCmd := exec.Command("docker", dockerArgs...)
225271
buf, err := dockerCmd.CombinedOutput()
226272
if err != nil {
@@ -235,3 +281,17 @@ func getSshAuthSockValue(containerID string) (string, error) {
235281
}
236282
return strings.TrimSpace(lines[0]), nil
237283
}
284+
285+
func getContainerEnvVar(containerID string, varName string) (string, error) {
286+
287+
// could inspect the docker container as an alternative approach
288+
dockerArgs := []string{"exec", containerID, "bash", "-c", fmt.Sprintf("echo $%s", varName)}
289+
dockerCmd := exec.Command("docker", dockerArgs...)
290+
buf, err := dockerCmd.CombinedOutput()
291+
if err != nil {
292+
errMessage := string(buf)
293+
return "", fmt.Errorf("Docker exec error: %s (%s)", err, strings.TrimSpace(errMessage))
294+
}
295+
296+
return string(buf), nil
297+
}

0 commit comments

Comments
 (0)