vscode-docker/commands/start-container.ts

112 строки
4.5 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import * as fse from 'fs-extra';
import os = require('os');
import vscode = require('vscode');
import { IActionContext, parseError } from 'vscode-azureextensionui';
import { ImageNode } from '../explorer/models/imageNode';
import { RootNode } from '../explorer/models/rootNode';
import { ext } from '../extensionVariables';
import { docker, DockerEngineType } from './utils/docker-endpoint';
import { ImageItem, quickPickImage } from './utils/quick-pick-image';
/**
* Image -> Run
*/
export async function startContainer(actionContext: IActionContext, context: RootNode | ImageNode | undefined): Promise<void> {
return await startContainerCore(actionContext, context, false);
}
export async function startContainerCore(actionContext: IActionContext, context: RootNode | ImageNode | undefined, interactive: boolean): Promise<void> {
let imageName: string;
let imageToStart: Docker.ImageDesc;
if (context instanceof ImageNode && context.imageDesc) {
imageToStart = context.imageDesc;
imageName = context.label;
} else {
const selectedItem: ImageItem = await quickPickImage(actionContext, false)
if (selectedItem) {
imageToStart = selectedItem.imageDesc;
imageName = selectedItem.label;
}
}
if (imageToStart) {
let ports: string[] = [];
try {
ports = await docker.getExposedPorts(imageToStart.Id);
} catch (error) {
vscode.window.showWarningMessage(`Unable to retrieve exposed ports: ${parseError(error).message}`);
}
let options = `--rm ${interactive ? '-it' : '-d'}`;
if (ports.length) {
const portMappings = ports.map((port) => `-p ${port.split("/")[0]}:${port}`); //'port' is of the form number/protocol, eg. 8080/udp.
// In the command, the host port has just the number (mentioned in the EXPOSE step), while the destination port can specify the protocol too
options += ` ${portMappings.join(' ')}`;
}
const terminal = ext.terminalProvider.createTerminal(imageName);
terminal.sendText(`docker run ${options} ${imageName}`);
terminal.show();
}
}
/**
* Image -> Run Interactive
*/
export async function startContainerInteractive(actionContext: IActionContext, context: ImageNode): Promise<void> {
await startContainerCore(actionContext, context, true);
}
export async function startAzureCLI(actionContext: IActionContext): Promise<cp.ChildProcess> {
// block of we are running windows containers...
const engineType: DockerEngineType = await docker.getEngineType();
actionContext.properties.engineType = DockerEngineType[engineType];
if (engineType === DockerEngineType.Windows) {
const selected = await vscode.window.showErrorMessage<vscode.MessageItem>(
'Currently, you can only run the Azure CLI when running Linux based containers.',
{
title: 'More Information',
},
{
title: 'Close',
isCloseAffordance: true
}
);
if (!selected || selected.isCloseAffordance) {
return;
}
return cp.exec('start https://docs.docker.com/docker-for-windows/#/switch-between-windows-and-linux-containers');
} else {
const option: string = process.platform === 'linux' ? '--net=host' : '';
// volume map .azure folder so don't have to log in every time
const homeDir: string = process.platform === 'win32' ? os.homedir().replace(/\\/g, '/') : os.homedir();
let vol: string = '';
if (fse.existsSync(`${homeDir}/.azure`)) {
vol += ` -v ${homeDir}/.azure:/root/.azure`;
}
if (fse.existsSync(`${homeDir}/.ssh`)) {
vol += ` -v ${homeDir}/.ssh:/root/.ssh`;
}
if (fse.existsSync(`${homeDir}/.kube`)) {
vol += ` -v ${homeDir}/.kube:/root/.kube`;
}
const cmd: string = `docker run ${option} ${vol.trim()} -it --rm azuresdk/azure-cli-python:latest`;
const terminal: vscode.Terminal = vscode.window.createTerminal('Azure CLI');
terminal.sendText(cmd);
terminal.show();
}
}