diff --git a/src/helper.ts b/src/helper.ts index 13ea6741aca7a..eb1404503a314 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -18,12 +18,14 @@ import * as crypto from 'crypto'; import { EventEmitter } from 'events'; import * as fs from 'fs'; +import * as os from 'os'; import * as removeFolder from 'rimraf'; import * as util from 'util'; import * as types from './types'; import { Progress } from './progress'; const removeFolderAsync = util.promisify(removeFolder); +const readFileAsync = util.promisify(fs.readFile.bind(fs)); export type RegisteredListener = { emitter: EventEmitter; @@ -325,6 +327,45 @@ class Helper { } } +export async function getUbuntuVersion(): Promise { + if (os.platform() !== 'linux') + return ''; + const osReleaseText = await readFileAsync('/etc/os-release', 'utf8').catch(e => ''); + if (!osReleaseText) + return ''; + return getUbuntuVersionInternal(osReleaseText); +} + +export function getUbuntuVersionSync(): string { + if (os.platform() !== 'linux') + return ''; + try { + const osReleaseText = fs.readFileSync('/etc/os-release', 'utf8'); + if (!osReleaseText) + return ''; + return getUbuntuVersionInternal(osReleaseText); + } catch (e) { + return ''; + } +} + +function getUbuntuVersionInternal(osReleaseText: string): string { + const fields = new Map(); + for (const line of osReleaseText.split('\n')) { + const tokens = line.split('='); + const name = tokens.shift(); + let value = tokens.join('=').trim(); + if (value.startsWith('"') && value.endsWith('"')) + value = value.substring(1, value.length - 1); + if (!name) + continue; + fields.set(name.toLowerCase(), value); + } + if (!fields.get('name') || fields.get('name').toLowerCase() !== 'ubuntu') + return ''; + return fields.get('version_id') || ''; +} + export function assert(value: any, message?: string): asserts value { if (!value) throw new Error(message); diff --git a/src/install/browserFetcher.ts b/src/install/browserFetcher.ts index dfba1626ac2ca..1df3177c0d190 100644 --- a/src/install/browserFetcher.ts +++ b/src/install/browserFetcher.ts @@ -58,7 +58,8 @@ const ENV_DOWNLOAD_HOSTS: { [key: string]: string } = { function getDownloadUrl(browserName: BrowserName, revision: number, platform: BrowserPlatform): string | undefined { if (browserName === 'chromium') { return new Map([ - ['linux', '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip'], + ['ubuntu18.04', '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip'], + ['ubuntu20.04', '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip'], ['mac10.13', '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip'], ['mac10.14', '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip'], ['mac10.15', '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip'], @@ -71,7 +72,8 @@ function getDownloadUrl(browserName: BrowserName, revision: number, platform: Br const FIREFOX_RENAME_LINUX_TO_UBUNTU_REVISION = 1139; return revision < FIREFOX_RENAME_LINUX_TO_UBUNTU_REVISION ? new Map([ - ['linux', '%s/builds/firefox/%s/firefox-linux.zip'], + ['ubuntu18.04', '%s/builds/firefox/%s/firefox-linux.zip'], + ['ubuntu20.04', '%s/builds/firefox/%s/firefox-linux.zip'], ['mac10.13', '%s/builds/firefox/%s/firefox-mac.zip'], ['mac10.14', '%s/builds/firefox/%s/firefox-mac.zip'], ['mac10.15', '%s/builds/firefox/%s/firefox-mac.zip'], @@ -79,7 +81,8 @@ function getDownloadUrl(browserName: BrowserName, revision: number, platform: Br ['win64', '%s/builds/firefox/%s/firefox-win64.zip'], ]).get(platform) : new Map([ - ['linux', '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip'], + ['ubuntu18.04', '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip'], + ['ubuntu20.04', '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip'], ['mac10.13', '%s/builds/firefox/%s/firefox-mac.zip'], ['mac10.14', '%s/builds/firefox/%s/firefox-mac.zip'], ['mac10.15', '%s/builds/firefox/%s/firefox-mac.zip'], @@ -92,7 +95,8 @@ function getDownloadUrl(browserName: BrowserName, revision: number, platform: Br const WEBKIT_RENAME_LINUX_TO_UBUNTU_REVISION = 1315; return revision < WEBKIT_RENAME_LINUX_TO_UBUNTU_REVISION ? new Map([ - ['linux', '%s/builds/webkit/%s/minibrowser-gtk-wpe.zip'], + ['ubuntu18.04', '%s/builds/webkit/%s/minibrowser-gtk-wpe.zip'], + ['ubuntu20.04', '%s/builds/webkit/%s/minibrowser-gtk-wpe.zip'], ['mac10.13', undefined], ['mac10.14', '%s/builds/webkit/%s/minibrowser-mac-10.14.zip'], ['mac10.15', '%s/builds/webkit/%s/minibrowser-mac-10.15.zip'], @@ -100,7 +104,8 @@ function getDownloadUrl(browserName: BrowserName, revision: number, platform: Br ['win64', '%s/builds/webkit/%s/minibrowser-win64.zip'], ]).get(platform) : new Map([ - ['linux', '%s/builds/webkit/%s/minibrowser-gtk-wpe-ubuntu-18.04.zip'], + ['ubuntu18.04', '%s/builds/webkit/%s/minibrowser-gtk-wpe-ubuntu-18.04.zip'], + ['ubuntu20.04', '%s/builds/webkit/%s/minibrowser-gtk-wpe-ubuntu-20.04.zip'], ['mac10.13', undefined], ['mac10.14', '%s/builds/webkit/%s/minibrowser-mac-10.14.zip'], ['mac10.15', '%s/builds/webkit/%s/minibrowser-mac-10.15.zip'], diff --git a/src/install/browserPaths.ts b/src/install/browserPaths.ts index 6de762ac2341e..27eda3f18572c 100644 --- a/src/install/browserPaths.ts +++ b/src/install/browserPaths.ts @@ -18,13 +18,13 @@ import { execSync } from 'child_process'; import * as os from 'os'; import * as path from 'path'; -import { getFromENV } from '../helper'; +import { getFromENV, getUbuntuVersionSync } from '../helper'; export type BrowserName = 'chromium'|'webkit'|'firefox'; -export type BrowserPlatform = 'win32'|'win64'|'mac10.13'|'mac10.14'|'mac10.15'|'linux'; +export type BrowserPlatform = 'win32'|'win64'|'mac10.13'|'mac10.14'|'mac10.15'|'ubuntu18.04'|'ubuntu20.04'; export type BrowserDescriptor = { - name: BrowserName, - revision: string + name: BrowserName, + revision: string }; export const hostPlatform = ((): BrowserPlatform => { @@ -33,8 +33,14 @@ export const hostPlatform = ((): BrowserPlatform => { const macVersion = execSync('sw_vers -productVersion').toString('utf8').trim().split('.').slice(0, 2).join('.'); return `mac${macVersion}` as BrowserPlatform; } - if (platform === 'linux') - return 'linux'; + if (platform === 'linux') { + const ubuntuVersion = getUbuntuVersionSync(); + if (ubuntuVersion === '20.04') + return 'ubuntu20.04'; + // For the sake of downloading logic, consider any other Linux distribution + // to be "ubuntu18.04". + return 'ubuntu18.04'; + } if (platform === 'win32') return os.arch() === 'x64' ? 'win64' : 'win32'; return platform as BrowserPlatform; @@ -58,7 +64,8 @@ export function executablePath(browserPath: string, browser: BrowserDescriptor): let tokens: string[] | undefined; if (browser.name === 'chromium') { tokens = new Map([ - ['linux', ['chrome-linux', 'chrome']], + ['ubuntu18.04', ['chrome-linux', 'chrome']], + ['ubuntu20.04', ['chrome-linux', 'chrome']], ['mac10.13', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']], ['mac10.14', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']], ['mac10.15', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']], @@ -69,7 +76,8 @@ export function executablePath(browserPath: string, browser: BrowserDescriptor): if (browser.name === 'firefox') { tokens = new Map([ - ['linux', ['firefox', 'firefox']], + ['ubuntu18.04', ['firefox', 'firefox']], + ['ubuntu20.04', ['firefox', 'firefox']], ['mac10.13', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']], ['mac10.14', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']], ['mac10.15', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']], @@ -80,7 +88,8 @@ export function executablePath(browserPath: string, browser: BrowserDescriptor): if (browser.name === 'webkit') { tokens = new Map([ - ['linux', ['pw_run.sh']], + ['ubuntu18.04', ['pw_run.sh']], + ['ubuntu20.04', ['pw_run.sh']], ['mac10.13', undefined], ['mac10.14', ['pw_run.sh']], ['mac10.15', ['pw_run.sh']], diff --git a/src/server/validateDependencies.ts b/src/server/validateDependencies.ts index e4055f233b5dc..1185e30b965dc 100644 --- a/src/server/validateDependencies.ts +++ b/src/server/validateDependencies.ts @@ -17,14 +17,14 @@ import * as fs from 'fs'; import * as util from 'util'; import * as path from 'path'; import * as os from 'os'; -import {spawn} from 'child_process'; -import {linuxLddDirectories, BrowserDescriptor} from '../install/browserPaths.js'; +import { spawn } from 'child_process'; +import { getUbuntuVersion } from '../helper'; +import { linuxLddDirectories, BrowserDescriptor } from '../install/browserPaths.js'; const accessAsync = util.promisify(fs.access.bind(fs)); const checkExecutable = (filePath: string) => accessAsync(filePath, fs.constants.X_OK).then(() => true).catch(e => false); const statAsync = util.promisify(fs.stat.bind(fs)); const readdirAsync = util.promisify(fs.readdir.bind(fs)); -const readFileAsync = util.promisify(fs.readFile.bind(fs)); export async function validateDependencies(browserPath: string, browser: BrowserDescriptor) { // We currently only support Linux. @@ -122,26 +122,6 @@ function lddAsync(filePath: string): Promise<{stdout: string, stderr: string, co }); } -async function getUbuntuVersion(): Promise { - const osRelease = await readFileAsync('/etc/os-release', 'utf8').catch(e => ''); - if (!osRelease) - return ''; - const fields = new Map(); - for (const line of osRelease.split('\n')) { - const tokens = line.split('='); - const name = tokens.shift(); - let value = tokens.join('=').trim(); - if (value.startsWith('"') && value.endsWith('"')) - value = value.substring(1, value.length - 1); - if (!name) - continue; - fields.set(name.toLowerCase(), value); - } - if (!fields.get('name') || fields.get('name').toLowerCase() !== 'ubuntu') - return ''; - return fields.get('version_id') || ''; -} - // This list is generated with https://gist.github.com/aslushnikov/2766200430228c3700537292fccad064 const LIBRARY_TO_PACKAGE_NAME_UBUNTU_18_04: { [s: string]: string} = { 'libEGL.so.1': 'libegl1',