Skip to content

Commit

Permalink
Fix running under docker (#5135)
Browse files Browse the repository at this point in the history
For #5047

<!--
  If an item below does not apply to you, then go ahead and check it off as "done" and strikethrough the text, e.g.:
    - [x] ~Has unit tests & system/integration tests~
-->
- [x] Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
- [x] Title summarizes what is changing
- [x] Has a [news entry](https://github.com/Microsoft/vscode-python/tree/master/news) file (remember to thank yourself!)
- [ ] Has sufficient logging.
- [ ] Has telemetry for enhancements.
- [ ] Unit tests & system/integration tests are added/updated
- [ ] [Test plan](https://github.com/Microsoft/vscode-python/blob/master/.github/test_plan.md) is updated as appropriate
- [ ] [`package-lock.json`](https://github.com/Microsoft/vscode-python/blob/master/package-lock.json) has been regenerated by running `npm install` (if dependencies have changed)
- [ ] The wiki is updated with any design decisions/details.
  • Loading branch information
rchiodo committed Apr 5, 2019
1 parent 7003a9b commit e17c0d2
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
1 change: 1 addition & 0 deletions news/1 Enhancements/5047.md
@@ -0,0 +1 @@
Support running under docker.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -2398,8 +2398,8 @@
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7",
"node-has-native-dependencies": "^1.0.2",
"node-sass": "^4.11.0",
"node-html-parser": "^1.1.13",
"node-sass": "^4.11.0",
"nyc": "^13.3.0",
"raw-loader": "^0.5.1",
"react": "^16.5.2",
Expand Down
10 changes: 9 additions & 1 deletion src/client/datascience/constants.ts
Expand Up @@ -48,7 +48,15 @@ export namespace RegExpValues {
export const CheckJupyterRegEx = IS_WINDOWS ? /^jupyter?\.exe$/ : /^jupyter?$/;
export const PyKernelOutputRegEx = /.*\s+(.+)$/m;
export const KernelSpecOutputRegEx = /^\s*(\S+)\s+(\S+)$/;
export const UrlPatternRegEx = /(https?:\/\/[^\s]+)/ ;
// This next one has to be a string because uglifyJS isn't handling the groups. We use named-js-regexp to parse it
// instead.
export const UrlPatternRegEx = '(?<PREFIX>https?:\\/\\/)((\\(.+\\s+or\\s+(?<IP>.+)\\))|(?<LOCAL>[^\\s]+))(?<REST>:.+)' ;
export interface IUrlPatternGroupType {
LOCAL: string | undefined;
PREFIX: string | undefined;
REST: string | undefined;
IP: string | undefined;
}
export const HttpPattern = /https?:\/\//;
export const ExtractPortRegex = /https?:\/\/[^\s]+:(\d+)[^\s]+/;
export const ConvertToRemoteUri = /(https?:\/\/)([^\s])+(:\d+[^\s]*)/;
Expand Down
15 changes: 12 additions & 3 deletions src/client/datascience/jupyter/jupyterConnection.ts
Expand Up @@ -18,6 +18,10 @@ import { RegExpValues } from '../constants';
import { IConnection } from '../types';
import { JupyterConnectError } from './jupyterConnectError';

// tslint:disable-next-line:no-require-imports no-var-requires no-any
const namedRegexp = require('named-js-regexp');
const urlMatcher = namedRegexp(RegExpValues.UrlPatternRegEx);

export type JupyterServerInfo = {
base_url: string;
notebook_dir: string;
Expand Down Expand Up @@ -130,14 +134,19 @@ class JupyterConnectionWaiter {

// tslint:disable-next-line:no-any
private getJupyterURLFromString(data: any) {
const urlMatch = RegExpValues.UrlPatternRegEx.exec(data);
if (urlMatch && !this.startPromise.completed) {
const urlMatch = urlMatcher.exec(data) as any;
const groups = urlMatch.groups() as RegExpValues.IUrlPatternGroupType;
if (urlMatch && !this.startPromise.completed && groups && (groups.LOCAL || groups.IP)) {
// Rebuild the URI from our group hits
const host = groups.LOCAL ? groups.LOCAL : groups.IP;
const uriString = `${groups.PREFIX}${host}${groups.REST}`;

// URL is not being found for some reason. Pull it in forcefully
// tslint:disable-next-line:no-require-imports
const URL = require('url').URL;
let url: URL;
try {
url = new URL(urlMatch[0]);
url = new URL(uriString);
} catch (err) {
// Failed to parse the url either via server infos or the string
this.rejectStartPromise(localize.DataScience.jupyterLaunchNoURL());
Expand Down
21 changes: 21 additions & 0 deletions src/client/datascience/jupyter/jupyterExecution.ts
Expand Up @@ -36,6 +36,7 @@ import {
import { JupyterConnection, JupyterServerInfo } from './jupyterConnection';
import { JupyterKernelSpec } from './jupyterKernelSpec';
import { JupyterWaitForIdleError } from './jupyterWaitForIdleError';
import { execSync } from 'child_process';

enum ModuleExistsResult {
NotFound,
Expand Down Expand Up @@ -351,6 +352,26 @@ export class JupyterExecutionBase implements IJupyterExecution {
extraArgs.push('--debug');
}

// Check for a docker situation.
try {
if (await this.fileSystem.fileExists('/proc/self/cgroup')) {
const cgroup = await this.fileSystem.readFile('/proc/self/cgroup');
if (cgroup.includes('docker')) {
// We definitely need an ip address.
extraArgs.push('--ip');
extraArgs.push('127.0.0.1');

// Now see if we need --allow-root.
const idResults = execSync('id', {encoding: 'utf-8'});
if (idResults.includes('(root)')) {
extraArgs.push('--allow-root');
}
}
}
} catch {
noop();
}

// Use this temp file and config file to generate a list of args for our command
const args: string[] = [...['--no-browser', `--notebook-dir=${tempDir.path}`], ...extraArgs];

Expand Down

0 comments on commit e17c0d2

Please sign in to comment.