src/vs/platform/sandbox/node/sandboxHelper.ts

167 LOC · 90 covered · 77 uncovered · 23 ranges · 9 concepts · 9 introducers · 17 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/node/osReleaseInfo.ts · 74 LOCnode/osReleaseInfo.tsosReleaseInfo.ts ×5 · 54 introduced LOCosReleaseInfo.ts ×5sandboxHelper.ts ×1 · 2 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×1 · 2 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×1 · 5 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×4 · 7 introduced LOCsandboxHelper.ts ×4sandboxHelper.ts ×1 · 1 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×1 · 6 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×1 · 2 introduced LOCsandboxHelper.ts ×1sandboxHelper.ts ×12 · 74 introduced LOCsandboxHelper.ts ×12sandboxHelper.test|title=SandboxHelperService detects apk for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects apk for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects apt for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects apt for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects apt-get for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects apt-get for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects dnf for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects dnf for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects pacman for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects pacman for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects yum for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects yum for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService detects zypper for dependency installation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService detects zypper for dependency installation|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService does not inspect sandbox dependencies on non-Linux platforms|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService does not inspect sandbox dependencies on non-Linux platforms|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService does not offer dependency installation to a non-root user without sudo|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService does not offer dependency installation to a non-root user without sudo|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService does not offer dependency installation without a supported package manager|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService does not offer dependency installation without a supported package manager|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService does not use sudo for chained apt-get commands when running as root|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService does not use sudo for chained apt-get commands when running as root|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService does not use sudo when running as root|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService does not use sudo when running as root|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService reports bubblewrap usable when its capability probe succeeds|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService reports bubblewrap usable when its capability probe succeeds|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService reports missing bubblewrap without running its capability probe|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService reports missing bubblewrap without running its capability probe|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService reports the probe error when bubblewrap is unusable|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService reports the probe error when bubblewrap is unusable|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService uses ID_LIKE to detect a derivative distribution|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService uses ID_LIKE to detect a derivative distribution|occurrence=1sandboxHelper.test|title…sandboxHelper.test|title=SandboxHelperService uses the native package manager when multiple managers are available|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/sandbox/test/node/sandboxHelper.test|title=SandboxHelperService uses the native package manager when multiple managers are available|occurrence=1sandboxHelper.test|title…Focused file · src/vs/platform/sandbox/node/sandboxHelper.ts · 167 LOCnode/sandboxHelper.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- sandboxHelper.ts ×12
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { execFile } from 'child_process';
7 > import { getCaseInsensitive } from '../../../base/common/objects.js';
8 > import { win32 } from '../../../base/common/path.js';
9 > import { isLinux, isWindows } from '../../../base/common/platform.js';
10 > import { getOSReleaseInfo } from '../../../base/node/osReleaseInfo.js';
11 > import { findExecutable } from '../../../base/node/processes.js';
12 > import { ISandboxDependencyStatus, ISandboxHelperService, type IWindowsMxcConfig, IWindowsMxcFilesystemPolicy, type IWindowsMxcPolicyContainment, type IWindowsMxcSandboxPolicy } from '../common/sandboxHelperService.js';
13 >
14 > type FindCommand = (command: string) => Promise<string | undefined>;
15 > type BubblewrapProbe = (command: string) => Promise<{ usable: boolean; error?: string }>;
16 > type ResolveLinuxInstallEnvironment = () => Promise<{ distributionIds: readonly string[]; isRoot: boolean }>;
17 >
18 > const linuxDependencyInstallCommands: readonly { distributionIds: readonly string[]; commands: readonly [executable: string, command: string][] }[] = [
19 > { distributionIds: ['debian', 'ubuntu', 'linuxmint', 'pop', 'elementary', 'kali', 'raspbian'], commands: [['apt-get', 'apt-get update && apt-get install -y'], ['apt', 'apt update && apt install -y']] },
20 > { distributionIds: ['fedora', 'rhel', 'centos', 'rocky', 'almalinux'], commands: [['dnf', 'dnf install -y'], ['yum', 'yum install -y']] },
21 > { distributionIds: ['arch', 'manjaro', 'endeavouros'], commands: [['pacman', 'pacman -S --needed --noconfirm']] },
22 > { distributionIds: ['suse', 'opensuse', 'opensuse-leap', 'opensuse-tumbleweed'], commands: [['zypper', 'zypper --non-interactive install']] },
23 > { distributionIds: ['alpine'], commands: [['apk', 'apk add']] },
24 > ];
25 >
26 > export class SandboxHelperService implements ISandboxHelperService {
27 > declare readonly _serviceBrand: undefined;
28 >
29 > static async checkSandboxDependenciesWith(findCommand: FindCommand, linux: boolean = isLinux, probeBubblewrap: BubblewrapProbe = command => SandboxHelperService._probeBubblewrap(command), resolveInstallEnvironment: ResolveLinuxInstallEnvironment = () => SandboxHelperService._resolveLinuxInstallEnvironment()): Promise<ISandboxDependencyStatus | undefined> {
30 > if (!linux) {
31 > return undefined; sandboxHelper.ts ×1
32 > }
34 > const [bubblewrapPath, socatPath] = await Promise.all([
35 > findCommand('bwrap'),
36 > findCommand('socat'),
37 > ]);
38 > const bubblewrapProbe = bubblewrapPath ? await probeBubblewrap(bubblewrapPath) : { usable: false };
39 > const dependencyInstallCommand = !bubblewrapPath || !socatPath sandboxHelper.ts ×12
40 > ? await SandboxHelperService._findDependencyInstallCommand(findCommand, resolveInstallEnvironment) sandboxHelper.ts ×4
41 > : undefined; sandboxHelper.ts ×1
43 > return {
44 > bubblewrapInstalled: !!bubblewrapPath,
45 > bubblewrapUsable: bubblewrapProbe.usable,
46 > bubblewrapError: bubblewrapProbe.error,
47 > socatInstalled: !!socatPath,
48 > dependencyInstallCommand,
49 > };
50 > }
51 >
52 > private static async _findDependencyInstallCommand(findCommand: FindCommand, resolveInstallEnvironment: ResolveLinuxInstallEnvironment): Promise<string | undefined> {
53 > const environment = await resolveInstallEnvironment(); sandboxHelper.ts ×4
54 > const installer = linuxDependencyInstallCommands.find(candidate => candidate.distributionIds.some(id => environment.distributionIds.includes(id)));
55 > if (!installer) {
56 > return undefined; sandboxHelper.ts ×1
57 > }
58 > const elevation = environment.isRoot ? '' : await findCommand('sudo') ? 'sudo ' : undefined; sandboxHelper.ts ×4
59 > if (elevation === undefined) {
60 > return undefined; sandboxHelper.ts ×1
61 > }
62 > for (const [executable, command] of installer.commands) { sandboxHelper.ts ×1
63 > if (await findCommand(executable)) {
64 > return command.split(' && ').map(command => `${elevation}${command}`).join(' && ');
65 > }
66 > }
67 return undefined;
70 > private static async _resolveLinuxInstallEnvironment(): Promise<{ distributionIds: readonly string[]; isRoot: boolean }> {
71 > const releaseInfo = await getOSReleaseInfo(() => { }); osReleaseInfo.ts ×5
72 > return {
73 > distributionIds: [releaseInfo?.id, ...releaseInfo?.id_like?.split(/\s+/) ?? []].filter((id): id is string => !!id),
74 > isRoot: process.getuid?.() === 0,
75 > };
76 > }
78 > checkSandboxDependencies(): Promise<ISandboxDependencyStatus | undefined> {
79 return SandboxHelperService.checkSandboxDependenciesWith(findExecutable);
80 }
82 > private static _probeBubblewrap(command: string): Promise<{ usable: boolean; error?: string }> {
83 return new Promise(resolve => {
84 execFile(command, ['--unshare-net', '--dev-bind', '/', '/', 'echo', 'ok'], { encoding: 'utf8', timeout: 5000 }, (error, stdout, stderr) => {
85 if (!error && stdout.trim() === 'ok') {
86 resolve({ usable: true });
87 return;
88 }
89
90 const detail = stderr.trim() || error?.message || `Unexpected output: ${stdout.trim()}`;
91 resolve({ usable: false, error: detail.slice(0, 1000) });
92 });
93 });
94 }
96 > async getWindowsMxcFilesystemPolicy(): Promise<IWindowsMxcFilesystemPolicy | undefined> {
97 if (!isWindows) {
98 return undefined;
99 }
100
101 const { getAvailableToolsPolicy, getUserProfilePolicy, getTemporaryFilesPolicy } = await import('@microsoft/mxc-sdk');
102 const availableToolsPolicy = getAvailableToolsPolicy(process.env, { containerType: 'processcontainer' });
103 const userProfilePolicy = getUserProfilePolicy();
104 const temporaryFilesPolicy = getTemporaryFilesPolicy(process.env);
105 const psHome = await this._getPSHome();
106 return {
107 readonlyPaths: [...new Set([...availableToolsPolicy.readonlyPaths, ...userProfilePolicy.readonlyPaths, ...temporaryFilesPolicy.readonlyPaths, ...(psHome ? [psHome] : [])])],
108 readwritePaths: [...new Set([...availableToolsPolicy.readwritePaths, ...userProfilePolicy.readwritePaths, ...temporaryFilesPolicy.readwritePaths])],
109 };
110 }
112 > async getWindowsMxcEnvironment(): Promise<string[] | undefined> {
113 if (!isWindows) {
114 return undefined;
115 }
116
117 const env: string[] = [];
118 for (const variable of ['SystemRoot', 'PATH', 'ComSpec', 'PATHEXT', 'PSModulePath']) {
119 const value = getCaseInsensitive(process.env, variable);
120 if (typeof value === 'string' && value) {
121 env.push(`${variable}=${value}`);
122 }
123 }
124 const userProfile = getCaseInsensitive(process.env, 'USERPROFILE');
125 if (typeof userProfile === 'string' && userProfile) {
126 env.push(`USERPROFILE=${userProfile}`);
127 }
128 const appData = getCaseInsensitive(process.env, 'APPDATA');
129 if (typeof appData === 'string' && appData) {
130 env.push(`APPDATA=${appData}`);
131 }
132 const localAppData = this._getLocalAppData();
133 if (typeof localAppData === 'string' && localAppData) {
134 env.push(`LOCALAPPDATA=${localAppData}`);
135 }
136
137 const psHome = await this._getPSHome();
138 if (psHome) {
139 env.push(`PSHOME=${psHome}`);
140 }
141 return env;
142 }
144 > async buildWindowsMxcSandboxPayload(commandLine: string, policy: IWindowsMxcSandboxPolicy, workingDirectory?: string, containerName?: string, containment: IWindowsMxcPolicyContainment = 'process'): Promise<IWindowsMxcConfig | undefined> {
145 if (!isWindows) {
146 return undefined;
147 }
148
149 const { buildSandboxPayload } = await import('@microsoft/mxc-sdk');
150 return buildSandboxPayload(commandLine, policy, workingDirectory, containerName, containment);
151 }
153 > private async _getPSHome(): Promise<string | undefined> {
154 const psHome = getCaseInsensitive(process.env, 'PSHOME');
155 if (typeof psHome === 'string' && psHome) {
156 return psHome;
157 }
158
159 const powerShellPath = await findExecutable('pwsh') ?? await findExecutable('powershell');
160 return powerShellPath ? win32.dirname(powerShellPath) : undefined;
161 }
163 > private _getLocalAppData(): string | undefined {
164 const localAppData = getCaseInsensitive(process.env, 'LOCALAPPDATA');
165 return typeof localAppData === 'string' && localAppData ? localAppData : undefined;
166 }