From 034d44ede447a73ebb2bdaf32fd2584ff6c3898b Mon Sep 17 00:00:00 2001 From: Gregg Miskelly Date: Wed, 23 Nov 2016 17:06:33 -0800 Subject: [PATCH] Add detection logic for missing OpenSSL symlinks on macOS (#986) By far our most common EE error is due to folks not having the OpenSSL symlinks created. This checkin adds detection logic so that we will not install the debugger unless they are present. This resolves https://github.com/OmniSharp/omnisharp-vscode/issues/779 --- src/coreclr-debug/activate.ts | 47 +++++++++++++++++++++++----------- src/coreclr-debug/proxy.ts | 48 ++++++++++++++++++++--------------- src/coreclr-debug/util.ts | 20 +++++++++++++++ src/main.ts | 2 +- 4 files changed, 80 insertions(+), 37 deletions(-) diff --git a/src/coreclr-debug/activate.ts b/src/coreclr-debug/activate.ts index f4bbd4fdc..4da059888 100644 --- a/src/coreclr-debug/activate.ts +++ b/src/coreclr-debug/activate.ts @@ -15,7 +15,7 @@ let _debugUtil: CoreClrDebugUtil = null; let _reporter: TelemetryReporter = null; let _logger: Logger = null; -export function activate(context: vscode.ExtensionContext, reporter: TelemetryReporter, logger: Logger) { +export function activate(context: vscode.ExtensionContext, reporter: TelemetryReporter, logger: Logger, channel: vscode.OutputChannel) { _debugUtil = new CoreClrDebugUtil(context.extensionPath, logger); _reporter = reporter; _logger = logger; @@ -24,7 +24,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe PlatformInformation.GetCurrent().then((info) => { if (info.runtimeId) { logger.appendLine("[ERROR]: C# Extension failed to install the debugger package"); - showInstallErrorMessage(); + showInstallErrorMessage(channel); } else { if (info.isLinux) { logger.appendLine(`[WARNING]: The current Linux distribution '${info.distribution.name}' version '${info.distribution.version}' is not currently supported by the .NET Core debugger. Debugging will not be available.`); @@ -35,22 +35,38 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe }, (err) => { // Somehow we couldn't figure out the platform we are on logger.appendLine("[ERROR]: C# Extension failed to install the debugger package"); - showInstallErrorMessage(); + showInstallErrorMessage(channel); }); } else if (!CoreClrDebugUtil.existsSync(_debugUtil.installCompleteFilePath())) { _debugUtil.checkDotNetCli() .then((dotnetInfo: DotnetInfo) => { - let installer = new debugInstall.DebugInstaller(_debugUtil); - installer.finishInstall() - .then(() => { - vscode.window.setStatusBarMessage('Successfully installed .NET Core Debugger.'); - }) - .catch((err) => { - logger.appendLine("[ERROR]: An error occured while installing the .NET Core Debugger:"); - logger.appendLine(err); - showInstallErrorMessage(); - // TODO: log telemetry? - }); + _debugUtil.checkOpenSSLInstalledIfRequired().then((isInstalled) => { + if (isInstalled) { + let installer = new debugInstall.DebugInstaller(_debugUtil); + installer.finishInstall() + .then(() => { + vscode.window.setStatusBarMessage('Successfully installed .NET Core Debugger.'); + }) + .catch((err) => { + logger.appendLine("[ERROR]: An error occured while installing the .NET Core Debugger:"); + logger.appendLine(err); + showInstallErrorMessage(channel); + // TODO: log telemetry? + }); + } else { + logger.appendLine("[ERROR] The debugger cannot be installed. A required component, OpenSSL, is not correctly configured."); + logger.appendLine("In order to use the debugger, open a terminal window and execute the following instructions."); + logger.appendLine("See https://www.microsoft.com/net/core#macos for more details."); + logger.appendLine(); + logger.appendLine(" brew update"); + logger.appendLine(" brew install openssl"); + logger.appendLine(" mkdir -p /usr/local/lib"); + logger.appendLine(" ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/"); + logger.appendLine(" ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/"); + channel.show(); + vscode.window.showErrorMessage("The .NET Core debugger cannot be installed. OpenSSL is not correctly configured. See the C# output channel for details."); + } + }); }, (err) => { // Check for dotnet tools failed. pop the UI // err is a DotNetCliError but use defaults in the unexpected case that it's not @@ -61,7 +77,8 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe } } -function showInstallErrorMessage() { +function showInstallErrorMessage(channel: vscode.OutputChannel) { + channel.show(); vscode.window.showErrorMessage("An error occured during installation of the .NET Core Debugger. The C# extension may need to be reinstalled."); } diff --git a/src/coreclr-debug/proxy.ts b/src/coreclr-debug/proxy.ts index 17f9f2079..9bc143a0f 100644 --- a/src/coreclr-debug/proxy.ts +++ b/src/coreclr-debug/proxy.ts @@ -70,27 +70,33 @@ function proxy() { //first check if dotnet is on the path and new enough util.checkDotNetCli() .then((dotnetInfo) => { - // next check if we have begun installing packages - common.installFileExists(common.InstallFileType.Begin) - .then((beginExists: boolean) => { - if (beginExists) { - // packages manager has begun - sendStillDownloadingMessage(); - } else { - // begin doesn't exist. There is a chance we finished downloading and begin had been deleted. Check if lock exists - common.installFileExists(common.InstallFileType.Lock) - .then((lockExists) => { - if (lockExists) { - // packages have finished installing but we had not finished rewriting our manifest when F5 came in - sendStillDownloadingMessage(); - } - else { - // no install files existed when we checked. we have likely not been activated - sendDownloadingNotStartedMessage(); - } - }); - } - }); + util.checkOpenSSLInstalledIfRequired().then((isInstalled) => { + if (isInstalled) { + // next check if we have begun installing packages + common.installFileExists(common.InstallFileType.Begin) + .then((beginExists: boolean) => { + if (beginExists) { + // packages manager has begun + sendStillDownloadingMessage(); + } else { + // begin doesn't exist. There is a chance we finished downloading and begin had been deleted. Check if lock exists + common.installFileExists(common.InstallFileType.Lock) + .then((lockExists) => { + if (lockExists) { + // packages have finished installing but we had not finished rewriting our manifest when F5 came in + sendStillDownloadingMessage(); + } + else { + // no install files existed when we checked. we have likely not been activated + sendDownloadingNotStartedMessage(); + } + }); + } + }); + } else { + sendErrorMessage("The .NET Core debugger cannot be started. OpenSSL is not correctly configured. See the C# output channel for details."); + } + }); }, (err) => { // error from checkDotNetCli sendErrorMessage(err.ErrorMessage || util.defaultDotNetCliErrorMessage()); diff --git a/src/coreclr-debug/util.ts b/src/coreclr-debug/util.ts index d3ed91b76..60585f470 100644 --- a/src/coreclr-debug/util.ts +++ b/src/coreclr-debug/util.ts @@ -6,6 +6,7 @@ import * as path from 'path'; import * as fs from 'fs'; +import * as os from 'os'; import * as semver from 'semver'; import { execChildProcess } from './../common'; import { Logger } from './../logger'; @@ -75,6 +76,25 @@ export class CoreClrDebugUtil return 'Failed to find up to date dotnet cli on the path.'; } + public checkOpenSSLInstalledIfRequired(): Promise { + if (os.platform() !== "darwin") { + // We only need special handling on OSX + return Promise.resolve(true); + } + + return new Promise((resolve, reject) => { + fs.access("/usr/local/lib/libcrypto.1.0.0.dylib", (err1) => { + if (err1) { + resolve(false); + } else { + fs.access("/usr/local/lib/libssl.1.0.0.dylib", (err2) => { + resolve(!err2); + }); + } + }); + }); + } + // This function checks for the presence of dotnet on the path and ensures the Version // is new enough for us. // Returns: a promise that returns a DotnetInfo class diff --git a/src/main.ts b/src/main.ts index a371f152b..9b7d8a57c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,7 +35,7 @@ export function activate(context: vscode.ExtensionContext): any { OmniSharp.activate(context, reporter); // activate coreclr-debug - coreclrdebug.activate(context, reporter, logger); + coreclrdebug.activate(context, reporter, logger, _channel); }); }