From b5611ff41dab1424c2f5bdf8e83f58963cbfa2cb Mon Sep 17 00:00:00 2001 From: Jonathan Carter Date: Mon, 30 Jan 2017 12:07:26 -0800 Subject: [PATCH 1/2] Add Windows support for shell attach --- commands/open-shell-container.ts | 18 +++++++++++++----- commands/utils/docker-endpoint.ts | 23 ++++++++++++++++++++++- typings/dockerode.d.ts | 7 ++++++- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/commands/open-shell-container.ts b/commands/open-shell-container.ts index e88f872f1a..4ec32b37ed 100644 --- a/commands/open-shell-container.ts +++ b/commands/open-shell-container.ts @@ -1,12 +1,20 @@ -import vscode = require('vscode'); +import * as vscode from 'vscode'; import {ContainerItem, quickPickContainer} from './utils/quick-pick-container'; +import {DockerEngineType, docker} from './utils/docker-endpoint'; + +const engineTypeShellCommands = { + [DockerEngineType.Linux]: "/bin/sh", + [DockerEngineType.Windows]: "cmd" +} export function openShellContainer() { - quickPickContainer().then(function (selectedItem: ContainerItem) { + quickPickContainer().then((selectedItem: ContainerItem) => { if (selectedItem) { - let terminal = vscode.window.createTerminal(`sh ${selectedItem.label}`); - terminal.sendText(`docker exec -it ${selectedItem.ids[0]} /bin/sh`); - terminal.show(); + docker.getEngineType().then((engineType: DockerEngineType) => { + const terminal = vscode.window.createTerminal(`Shell: ${selectedItem.label}`); + terminal.sendText(`docker exec -it ${selectedItem.ids[0]} ${engineTypeShellCommands[engineType]}`); + terminal.show(); + }); } }); } \ No newline at end of file diff --git a/commands/utils/docker-endpoint.ts b/commands/utils/docker-endpoint.ts index b3a7cc894f..b3f01052ed 100644 --- a/commands/utils/docker-endpoint.ts +++ b/commands/utils/docker-endpoint.ts @@ -1,8 +1,11 @@ import * as Docker from 'dockerode'; +export enum DockerEngineType { + Linux, + Windows +} class DockerClient { - private endPoint:Docker; constructor() { @@ -39,6 +42,24 @@ class DockerClient { return this.endPoint.getContainer(id); } + public getEngineType() : Thenable { + if (process.platform === 'win32') { + return new Promise((resolve, reject) => { + this.endPoint.info((error, info) => { + if (error) { + return reject(error); + } + + return resolve(info.OSType === "windows" ? DockerEngineType.Windows : DockerEngineType.Linux); + }); + }); + }; + + // On Linux or macOS, this can only ever be linux, + // so short-circuit the Docker call entirely. + return Promise.resolve(DockerEngineType.Linux); + } + public getImage(id:string): Docker.Image { return this.endPoint.getImage(id); } diff --git a/typings/dockerode.d.ts b/typings/dockerode.d.ts index 3d05acb1a5..f0dbd2dd09 100644 --- a/typings/dockerode.d.ts +++ b/typings/dockerode.d.ts @@ -23,6 +23,10 @@ declare module Docker { stdin?: boolean; } + interface EngineInfo { + OSType: string; + } + interface ExecInspectData { ExitCode: number; } @@ -69,11 +73,12 @@ declare module Docker { } } - declare class Docker { modem: Docker.Modem; constructor(options: Docker.DockerOptions); + info(cb: (err: Error, data: Docker.EngineInfo) => void): void; + listImages(cb: (err:Error , images: Docker.ImageDesc[])=>void): void; getImage(id:string): Docker.Image; From ef4e3acbd34f381d227d0273e7cca6a577b5327f Mon Sep 17 00:00:00 2001 From: Jonathan Carter Date: Tue, 31 Jan 2017 12:59:12 -0800 Subject: [PATCH 2/2] Use Powershell by default on Windows --- commands/open-shell-container.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/open-shell-container.ts b/commands/open-shell-container.ts index 4ec32b37ed..f7a773dcfe 100644 --- a/commands/open-shell-container.ts +++ b/commands/open-shell-container.ts @@ -4,7 +4,7 @@ import {DockerEngineType, docker} from './utils/docker-endpoint'; const engineTypeShellCommands = { [DockerEngineType.Linux]: "/bin/sh", - [DockerEngineType.Windows]: "cmd" + [DockerEngineType.Windows]: "powershell" } export function openShellContainer() {