From 6a3d2b9fb94716c5feb3db89721ad2caa4243a83 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Tue, 14 Sep 2021 14:09:37 +0200 Subject: [PATCH] fix(install-deps): make it work without sudo (#8914) --- src/utils/dependencies.ts | 21 ++++++++++++++++----- src/utils/utils.ts | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/utils/dependencies.ts b/src/utils/dependencies.ts index c5052fb251..1d9a5e67b1 100644 --- a/src/utils/dependencies.ts +++ b/src/utils/dependencies.ts @@ -69,11 +69,22 @@ export async function installDependenciesLinux(targets: Set) { commands.push(['apt-get', 'install', '-y', '--no-install-recommends', ...uniqueLibraries, ].join(' ')); - const isRoot = (process.getuid() === 0); - const child = isRoot ? - childProcess.spawn('sh', ['-c', `${commands.join('; ')}`], { stdio: 'inherit' }) : - childProcess.spawn('sudo', ['--', 'sh', '-c', `${commands.join('; ')}`], { stdio: 'inherit' }); - await new Promise(f => child.on('exit', f)); + const [command, args] = await buildAptProcessArgs(commands); + const child = childProcess.spawn(command, args, { stdio: 'inherit' }); + await new Promise((resolve, reject) => { + child.on('exit', resolve); + child.on('error', reject); + }); +} + +async function buildAptProcessArgs(commands: string[]): Promise<[string, string[]]> { + const isRoot = process.getuid() === 0; + if (isRoot) + return ['sh', ['-c', `${commands.join('&& ')}`]]; + const sudoExists = await utils.spawnAsync('which', ['sudo']); + if (sudoExists.code === 0) + return ['sudo', ['--', 'sh', '-c', `${commands.join('&& ')}`]]; + return ['su', ['root', '-c', `${commands.join('&& ')}`]]; } export async function validateDependenciesWindows(windowsExeAndDllDirectories: string[]) { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 2d4d0b5195..fd51742a1d 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -20,7 +20,7 @@ import stream from 'stream'; import removeFolder from 'rimraf'; import * as crypto from 'crypto'; import os from 'os'; -import { spawn } from 'child_process'; +import { spawn, SpawnOptions } from 'child_process'; import { getProxyForUrl } from 'proxy-from-env'; import * as URL from 'url'; import { getUbuntuVersionSync } from './ubuntuVersion'; @@ -131,7 +131,7 @@ export function downloadFile(url: string, destinationPath: string, options: {pro } } -export function spawnAsync(cmd: string, args: string[], options: any): Promise<{stdout: string, stderr: string, code: number, error?: Error}> { +export function spawnAsync(cmd: string, args: string[], options?: SpawnOptions): Promise<{stdout: string, stderr: string, code: number, error?: Error}> { const process = spawn(cmd, args, options); return new Promise(resolve => {