Skip to content

Commit e17c0d2

Browse files
authored
Fix running under docker (#5135)
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.
1 parent 7003a9b commit e17c0d2

File tree

5 files changed

+44
-5
lines changed

5 files changed

+44
-5
lines changed

news/1 Enhancements/5047.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support running under docker.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2398,8 +2398,8 @@
23982398
"mocha-junit-reporter": "^1.17.0",
23992399
"mocha-multi-reporters": "^1.1.7",
24002400
"node-has-native-dependencies": "^1.0.2",
2401-
"node-sass": "^4.11.0",
24022401
"node-html-parser": "^1.1.13",
2402+
"node-sass": "^4.11.0",
24032403
"nyc": "^13.3.0",
24042404
"raw-loader": "^0.5.1",
24052405
"react": "^16.5.2",

src/client/datascience/constants.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,15 @@ export namespace RegExpValues {
4848
export const CheckJupyterRegEx = IS_WINDOWS ? /^jupyter?\.exe$/ : /^jupyter?$/;
4949
export const PyKernelOutputRegEx = /.*\s+(.+)$/m;
5050
export const KernelSpecOutputRegEx = /^\s*(\S+)\s+(\S+)$/;
51-
export const UrlPatternRegEx = /(https?:\/\/[^\s]+)/ ;
51+
// This next one has to be a string because uglifyJS isn't handling the groups. We use named-js-regexp to parse it
52+
// instead.
53+
export const UrlPatternRegEx = '(?<PREFIX>https?:\\/\\/)((\\(.+\\s+or\\s+(?<IP>.+)\\))|(?<LOCAL>[^\\s]+))(?<REST>:.+)' ;
54+
export interface IUrlPatternGroupType {
55+
LOCAL: string | undefined;
56+
PREFIX: string | undefined;
57+
REST: string | undefined;
58+
IP: string | undefined;
59+
}
5260
export const HttpPattern = /https?:\/\//;
5361
export const ExtractPortRegex = /https?:\/\/[^\s]+:(\d+)[^\s]+/;
5462
export const ConvertToRemoteUri = /(https?:\/\/)([^\s])+(:\d+[^\s]*)/;

src/client/datascience/jupyter/jupyterConnection.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import { RegExpValues } from '../constants';
1818
import { IConnection } from '../types';
1919
import { JupyterConnectError } from './jupyterConnectError';
2020

21+
// tslint:disable-next-line:no-require-imports no-var-requires no-any
22+
const namedRegexp = require('named-js-regexp');
23+
const urlMatcher = namedRegexp(RegExpValues.UrlPatternRegEx);
24+
2125
export type JupyterServerInfo = {
2226
base_url: string;
2327
notebook_dir: string;
@@ -130,14 +134,19 @@ class JupyterConnectionWaiter {
130134

131135
// tslint:disable-next-line:no-any
132136
private getJupyterURLFromString(data: any) {
133-
const urlMatch = RegExpValues.UrlPatternRegEx.exec(data);
134-
if (urlMatch && !this.startPromise.completed) {
137+
const urlMatch = urlMatcher.exec(data) as any;
138+
const groups = urlMatch.groups() as RegExpValues.IUrlPatternGroupType;
139+
if (urlMatch && !this.startPromise.completed && groups && (groups.LOCAL || groups.IP)) {
140+
// Rebuild the URI from our group hits
141+
const host = groups.LOCAL ? groups.LOCAL : groups.IP;
142+
const uriString = `${groups.PREFIX}${host}${groups.REST}`;
143+
135144
// URL is not being found for some reason. Pull it in forcefully
136145
// tslint:disable-next-line:no-require-imports
137146
const URL = require('url').URL;
138147
let url: URL;
139148
try {
140-
url = new URL(urlMatch[0]);
149+
url = new URL(uriString);
141150
} catch (err) {
142151
// Failed to parse the url either via server infos or the string
143152
this.rejectStartPromise(localize.DataScience.jupyterLaunchNoURL());

src/client/datascience/jupyter/jupyterExecution.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
import { JupyterConnection, JupyterServerInfo } from './jupyterConnection';
3737
import { JupyterKernelSpec } from './jupyterKernelSpec';
3838
import { JupyterWaitForIdleError } from './jupyterWaitForIdleError';
39+
import { execSync } from 'child_process';
3940

4041
enum ModuleExistsResult {
4142
NotFound,
@@ -351,6 +352,26 @@ export class JupyterExecutionBase implements IJupyterExecution {
351352
extraArgs.push('--debug');
352353
}
353354

355+
// Check for a docker situation.
356+
try {
357+
if (await this.fileSystem.fileExists('/proc/self/cgroup')) {
358+
const cgroup = await this.fileSystem.readFile('/proc/self/cgroup');
359+
if (cgroup.includes('docker')) {
360+
// We definitely need an ip address.
361+
extraArgs.push('--ip');
362+
extraArgs.push('127.0.0.1');
363+
364+
// Now see if we need --allow-root.
365+
const idResults = execSync('id', {encoding: 'utf-8'});
366+
if (idResults.includes('(root)')) {
367+
extraArgs.push('--allow-root');
368+
}
369+
}
370+
}
371+
} catch {
372+
noop();
373+
}
374+
354375
// Use this temp file and config file to generate a list of args for our command
355376
const args: string[] = [...['--no-browser', `--notebook-dir=${tempDir.path}`], ...extraArgs];
356377

0 commit comments

Comments
 (0)