Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support all DOCKER_* environment variables as VS Code settings #998

Merged
merged 5 commits into from
Jun 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const env = process.env;
function test(): cp.ChildProcess {
env.DEBUGTELEMETRY = '1';
env.CODE_TESTS_WORKSPACE = path.join(__dirname, 'test/test.code-workspace');
env.MOCHA_timeout = String(10 * 1000);
env.CODE_TESTS_PATH = path.join(__dirname, 'dist/test');
return spawn('node', ['./node_modules/vscode/bin/test'], { stdio: 'inherit', env });
}
Expand Down
17 changes: 16 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,22 @@
"docker.host": {
"type": "string",
"default": "",
"description": "Full host address to connect to (with protocol). Equivalent to setting the DOCKER_HOST environment variable"
"description": "Equivalent to setting the DOCKER_HOST environment variable."
},
"docker.certPath": {
"type": "string",
"default": "",
"description": "Equivalent to setting the DOCKER_CERT_PATH environment variable."
},
"docker.tlsVerify": {
"type": "string",
"default": "",
"description": "Equivalent to setting the DOCKER_TLS_VERIFY environment variable."
},
"docker.machineName": {
"type": "string",
"default": "",
"description": "Equivalent to setting the DOCKER_MACHINE_NAME environment variable."
},
"docker.importCertificates": {
"oneOf": [
Expand Down
40 changes: 15 additions & 25 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { DockerComposeParser } from './dockerCompose/dockerComposeParser';
import { DockerfileCompletionItemProvider } from './dockerfileCompletionItemProvider';
import { ext } from './extensionVariables';
import { registerTrees } from './tree/registerTrees';
import { addDockerSettingsToEnv } from './utils/addDockerSettingsToEnv';
import { addUserAgent } from './utils/addUserAgent';
import { getTrustedCertificates } from './utils/getTrustedCertificates';
import { Keytar } from './utils/keytar';
Expand Down Expand Up @@ -269,32 +270,21 @@ function activateLanguageClient(): void {
});
}

/**
* Dockerode parses and handles the well-known `DOCKER_*` environment variables, but it doesn't let us pass those values as-is to the constructor
* Thus we will temporarily update `process.env` and pass nothing to the constructor
*/
function refreshDockerode(): void {
const value: string = vscode.workspace.getConfiguration("docker").get("host", "");
if (value) {
let newHost: string = '';
let newPort: number = 2375;
let sep: number = -1;

sep = value.lastIndexOf(':');

const errorMessage = 'The docker.host configuration setting must be entered as <host>:<port>, e.g. dockerhost:2375';
if (sep < 0) {
vscode.window.showErrorMessage(errorMessage);
} else {
newHost = value.slice(0, sep);
newPort = Number(value.slice(sep + 1));
if (isNaN(newPort)) {
vscode.window.showErrorMessage(errorMessage);
} else {
ext.dockerode = new Dockerode({ host: newHost, port: newPort });
}
}
}

if (!ext.dockerode || !value) {
// Pass no options so that the defaultOpts of docker-modem will be used if the endpoint wasn't created
// or the user went from configured setting to empty settign
const oldEnv = process.env;
try {
process.env = { ...process.env }; // make a clone before we change anything
addDockerSettingsToEnv(process.env, oldEnv);
ext.dockerodeInitError = undefined;
ext.dockerode = new Dockerode();
} catch (error) {
// This will be displayed in the tree
ext.dockerodeInitError = error;
} finally {
process.env = oldEnv;
}
}
1 change: 1 addition & 0 deletions src/extensionVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export namespace ext {
export let terminalProvider: ITerminalProvider;
export let keytar: IKeytar | undefined;
export let dockerode: Dockerode;
export let dockerodeInitError: unknown;

export let imagesTree: AzExtTreeDataProvider;
export let imagesTreeView: TreeView<AzExtTreeItem>;
Expand Down
9 changes: 7 additions & 2 deletions src/tree/LocalRootTreeItemBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { ConfigurationChangeEvent, ConfigurationTarget, TreeView, TreeViewVisibilityChangeEvent, workspace, WorkspaceConfiguration } from "vscode";
import { AzExtParentTreeItem, AzExtTreeItem, AzureWizard, GenericTreeItem, IActionContext, InvalidTreeItem, registerEvent } from "vscode-azureextensionui";
import { configPrefix } from "../constants";
import { ext } from "../extensionVariables";
import { nonNullProp } from "../utils/nonNull";
import { isLinux } from "../utils/osUtils";
import { getThemedIconPath } from "./IconPath";
Expand Down Expand Up @@ -293,8 +294,12 @@ export abstract class LocalRootTreeItemBase<TItem extends ILocalItem, TProperty
}

private async getSortedItems(): Promise<TItem[]> {
const items: TItem[] = await this.getItems() || [];
return items.sort((a, b) => a.treeId.localeCompare(b.treeId));
if (ext.dockerodeInitError === undefined) {
const items: TItem[] = await this.getItems() || [];
return items.sort((a, b) => a.treeId.localeCompare(b.treeId));
} else {
throw ext.dockerodeInitError;
}
}

private async hasChanged(): Promise<boolean> {
Expand Down
9 changes: 3 additions & 6 deletions src/utils/TerminalProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import * as vscode from 'vscode';
import { Terminal } from 'vscode';
import { addDockerSettingsToEnv } from './addDockerSettingsToEnv';

export interface ITerminalProvider {
createTerminal(name: string): Terminal;
Expand All @@ -14,12 +15,8 @@ export class DefaultTerminalProvider {
public createTerminal(name: string): Terminal {
let terminalOptions: vscode.TerminalOptions = {};
terminalOptions.name = name;
const value: string = vscode.workspace.getConfiguration("docker").get("host", "");
if (value) {
terminalOptions.env = {
DOCKER_HOST: value
};
}
terminalOptions.env = {};
addDockerSettingsToEnv(terminalOptions.env, process.env);
return vscode.window.createTerminal(terminalOptions);
}
}
32 changes: 32 additions & 0 deletions src/utils/addDockerSettingsToEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { workspace } from 'vscode';
import { configPrefix } from '../constants';
import { ext } from '../extensionVariables';

export function addDockerSettingsToEnv(env: {}, oldEnv: {}): void {
addDockerSettingToEnv("host", 'DOCKER_HOST', env, oldEnv);
addDockerSettingToEnv("certPath", 'DOCKER_CERT_PATH', env, oldEnv);
addDockerSettingToEnv("tlsVerify", 'DOCKER_TLS_VERIFY', env, oldEnv);
addDockerSettingToEnv("machineName", 'DOCKER_MACHINE_NAME', env, oldEnv);
}

function addDockerSettingToEnv(settingKey: string, envVar: string, env: {}, oldEnv: {}): void {
const value = workspace.getConfiguration(configPrefix).get<string>(settingKey, '');

const expectedType = "string";
const actualType = typeof value;
if (expectedType !== actualType) {
ext.outputChannel.appendLine(`WARNING: Ignoring setting "${configPrefix}.${settingKey}" because type "${actualType}" does not match expected type "${expectedType}".`);
} else if (value) {
if (oldEnv[envVar] && oldEnv[envVar] !== value) {
ext.outputChannel.appendLine(`WARNING: Overwriting environment variable "${envVar}" with VS Code setting "${configPrefix}.${settingKey}".`);
}

env[envVar] = value;
}
}