fix: make execaSudo and setupAptPack synchronous

apt is not thread-safe
This commit is contained in:
Amin Yahyaabadi 2022-04-27 00:02:35 -07:00
parent 9ce1b85f0d
commit 18f813f0d6
13 changed files with 42 additions and 42 deletions

View File

@ -199,7 +199,7 @@ ENTRYPOINT [ "/bin/bash" ]
FROM base AS builder FROM base AS builder
ADD ./dev/cpp_vcpkg_project /home/app ADD ./dev/cpp_vcpkg_project /home/app
WORKDIR /home/app WORKDIR /home/app
RUN bash -c 'source ~/.cpprc \ RUN bash -c 'source ~/.cpprc \
&& make build' && make build'
### Running environment ### Running environment

2
dist/setup_cpp.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -48,7 +48,7 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
installationInfo = await setupBin("doxygen", version, getDoxygenPackageInfo, setupDir, arch) installationInfo = await setupBin("doxygen", version, getDoxygenPackageInfo, setupDir, arch)
} catch (err) { } catch (err) {
info(`Failed to download doxygen binary. ${err}. Falling back to apt-get.`) info(`Failed to download doxygen binary. ${err}. Falling back to apt-get.`)
installationInfo = await setupAptPack("doxygen", undefined) installationInfo = setupAptPack("doxygen", undefined)
} }
await setupGraphviz(getVersion("graphviz", undefined), "", arch) await setupGraphviz(getVersion("graphviz", undefined), "", arch)
return installationInfo return installationInfo

View File

@ -37,20 +37,20 @@ export async function setupGcc(version: string, _setupDir: string, arch: string)
} }
case "linux": { case "linux": {
if (arch === "x64") { if (arch === "x64") {
await setupAptPack("gcc", version, [ setupAptPack("gcc", version, [
"deb http://dk.archive.ubuntu.com/ubuntu/ xenial main", "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main",
"deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe", "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe",
"ppa:ubuntu-toolchain-r/test", "ppa:ubuntu-toolchain-r/test",
]) ])
binDir = (await setupAptPack("g++", version, [])).binDir binDir = setupAptPack("g++", version, []).binDir
} else { } else {
info(`Install g++-multilib because gcc for ${arch} was requested`) info(`Install g++-multilib because gcc for ${arch} was requested`)
await setupAptPack("gcc-multilib", version, [ setupAptPack("gcc-multilib", version, [
"deb http://dk.archive.ubuntu.com/ubuntu/ xenial main", "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main",
"deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe", "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe",
"ppa:ubuntu-toolchain-r/test", "ppa:ubuntu-toolchain-r/test",
]) ])
binDir = (await setupAptPack("g++-multilib", version, [])).binDir binDir = setupAptPack("g++-multilib", version, []).binDir
} }
break break
} }

View File

@ -42,12 +42,12 @@ async function buildKcov(file: string, dest: string) {
await setupCmake(getVersion("cmake", undefined), join(untildify(""), "cmake"), "") await setupCmake(getVersion("cmake", undefined), join(untildify(""), "cmake"), "")
} }
if (process.platform === "linux") { if (process.platform === "linux") {
await setupAptPack("libdw-dev") setupAptPack("libdw-dev")
await setupAptPack("libcurl4-openssl-dev") setupAptPack("libcurl4-openssl-dev")
} }
await execa("cmake", ["-S", "./", "-B", "./build"], { cwd: out, stdio: "inherit" }) await execa("cmake", ["-S", "./", "-B", "./build"], { cwd: out, stdio: "inherit" })
await execa("cmake", ["--build", "./build", "--config", "Release"], { cwd: out, stdio: "inherit" }) await execa("cmake", ["--build", "./build", "--config", "Release"], { cwd: out, stdio: "inherit" })
await execSudo("cmake", ["--install", "./build"], out) execSudo("cmake", ["--install", "./build"], out)
return out return out
} }
@ -55,7 +55,7 @@ export async function setupKcov(version: string, setupDir: string, arch: string)
switch (process.platform) { switch (process.platform) {
case "linux": { case "linux": {
const installationInfo = await setupBin("kcov", version, getKcovPackageInfo, setupDir, arch) const installationInfo = await setupBin("kcov", version, getKcovPackageInfo, setupDir, arch)
await setupAptPack("libbinutils") setupAptPack("libbinutils")
return installationInfo return installationInfo
} }
default: { default: {

View File

@ -268,7 +268,7 @@ async function _setupLLVM(version: string, setupDir: string, arch: string) {
if (process.platform === "linux") { if (process.platform === "linux") {
// install llvm build dependencies // install llvm build dependencies
await setupGcc(getVersion("gcc", undefined), "", arch) // using llvm requires ld, an up to date libstdc++, etc. So, install gcc first await setupGcc(getVersion("gcc", undefined), "", arch) // using llvm requires ld, an up to date libstdc++, etc. So, install gcc first
await setupAptPack("libtinfo-dev") setupAptPack("libtinfo-dev")
} }
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
didInit = true didInit = true

View File

@ -21,7 +21,7 @@ export async function setupPython(version: string, setupDir: string, arch: strin
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function setupPythonViaSystem(version: string, setupDir: string, _arch: string) { export function setupPythonViaSystem(version: string, setupDir: string, _arch: string) {
switch (process.platform) { switch (process.platform) {
case "win32": { case "win32": {
if (setupDir) { if (setupDir) {
@ -39,8 +39,8 @@ export async function setupPythonViaSystem(version: string, setupDir: string, _a
return setupBrewPack("python3", version) return setupBrewPack("python3", version)
} }
case "linux": { case "linux": {
const installInfo = await setupAptPack("python3", version) const installInfo = setupAptPack("python3", version)
await setupAptPack("python3-pip") setupAptPack("python3-pip")
return installInfo return installInfo
} }
default: { default: {

View File

@ -3,12 +3,12 @@ import { isRoot } from "../env/sudo"
export function execSudo(file: string, args: string[], cwd?: string) { export function execSudo(file: string, args: string[], cwd?: string) {
if (isRoot()) { if (isRoot()) {
return execa.command(`sudo ${[file, ...args].map((arg) => `'${arg}'`).join(" ")}`, { return execa.commandSync(`sudo ${[file, ...args].map((arg) => `'${arg}'`).join(" ")}`, {
shell: true, shell: true,
cwd, cwd,
stdio: "inherit", stdio: "inherit",
}) })
} else { } else {
return execa(file, args, { stdio: "inherit" }) return execa.sync(file, args, { stdio: "inherit" })
} }
} }

View File

@ -11,11 +11,11 @@ let didUpdate: boolean = false
let didInit: boolean = false let didInit: boolean = false
/** A function that installs a package using apt */ /** A function that installs a package using apt */
export async function setupAptPack( export function setupAptPack(
name: string, name: string,
version?: string, version?: string,
repositories: boolean | string[] = true repositories: boolean | string[] = true
): Promise<InstallationInfo> { ): InstallationInfo {
info(`Installing ${name} ${version ?? ""} via apt`) info(`Installing ${name} ${version ?? ""} via apt`)
const apt = "apt-get" const apt = "apt-get"
@ -23,7 +23,7 @@ export async function setupAptPack(
process.env.DEBIAN_FRONTEND = "noninteractive" process.env.DEBIAN_FRONTEND = "noninteractive"
if (!didUpdate) { if (!didUpdate) {
await execSudo(apt, ["update", "-y"]) execSudo(apt, ["update", "-y"])
didUpdate = true didUpdate = true
} }
@ -32,7 +32,7 @@ export async function setupAptPack(
// set time - zone // set time - zone
// TZ = Canada / Pacific // TZ = Canada / Pacific
// ln - snf / usr / share / zoneinfo / $TZ / etc / localtime && echo $TZ > /etc/timezone // ln - snf / usr / share / zoneinfo / $TZ / etc / localtime && echo $TZ > /etc/timezone
await execSudo(apt, [ execSudo(apt, [
"install", "install",
"--fix-broken", "--fix-broken",
"-y", "-y",
@ -42,9 +42,9 @@ export async function setupAptPack(
"gnupg", "gnupg",
]) ])
try { try {
await execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "3B4FE6ACC0B21F32"]) execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "3B4FE6ACC0B21F32"])
await execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "40976EAF437D05B5"]) execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "40976EAF437D05B5"])
await execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "1E9377A2BA9EF27F"]) execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "1E9377A2BA9EF27F"])
} catch (err) { } catch (err) {
warning(`Failed to add keys: ${err}`) warning(`Failed to add keys: ${err}`)
} }
@ -54,19 +54,19 @@ export async function setupAptPack(
if (Array.isArray(repositories)) { if (Array.isArray(repositories)) {
for (const repo of repositories) { for (const repo of repositories) {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await execSudo("add-apt-repository", ["--update", "-y", repo]) execSudo("add-apt-repository", ["--update", "-y", repo])
} }
await execSudo(apt, ["update", "-y"]) execSudo(apt, ["update", "-y"])
} }
if (version !== undefined && version !== "") { if (version !== undefined && version !== "") {
try { try {
await execSudo(apt, ["install", "--fix-broken", "-y", `${name}=${version}`]) execSudo(apt, ["install", "--fix-broken", "-y", `${name}=${version}`])
} catch { } catch {
await execSudo(apt, ["install", "--fix-broken", "-y", `${name}-${version}`]) execSudo(apt, ["install", "--fix-broken", "-y", `${name}-${version}`])
} }
} else { } else {
await execSudo(apt, ["install", "--fix-broken", "-y", name]) execSudo(apt, ["install", "--fix-broken", "-y", name])
} }
return { binDir: "/usr/bin/" } return { binDir: "/usr/bin/" }

View File

@ -88,9 +88,9 @@ export async function setupBin(
if (!didInit) { if (!didInit) {
if (process.platform === "linux") { if (process.platform === "linux") {
// extraction dependencies // extraction dependencies
await setupAptPack("unzip") setupAptPack("unzip")
await setupAptPack("tar") setupAptPack("tar")
await setupAptPack("xz-utils") setupAptPack("xz-utils")
} }
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
didInit = true didInit = true

View File

@ -42,7 +42,7 @@ export async function setupPipPack(name: string, version?: string): Promise<Inst
execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" }) execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
} else if (process.platform === "linux") { } else if (process.platform === "linux") {
// ensure that pip is installed on Linux (happens when python is found but pip not installed) // ensure that pip is installed on Linux (happens when python is found but pip not installed)
await setupAptPack("python3-pip") setupAptPack("python3-pip")
} }
} }

View File

@ -12,16 +12,16 @@ import { InstallationInfo } from "../utils/setup/setupBin"
let hasVCPKG = false let hasVCPKG = false
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function setupVcpkg(_version: string, setupDir: string, _arch: string): Promise<InstallationInfo> { export function setupVcpkg(_version: string, setupDir: string, _arch: string): InstallationInfo {
if (!hasVCPKG || which.sync("vcpkg", { nothrow: true }) === null) { if (!hasVCPKG || which.sync("vcpkg", { nothrow: true }) === null) {
if (process.platform === "linux") { if (process.platform === "linux") {
// vcpkg download and extraction dependencies // vcpkg download and extraction dependencies
await setupAptPack("curl") setupAptPack("curl")
await setupAptPack("zip") setupAptPack("zip")
await setupAptPack("unzip") setupAptPack("unzip")
await setupAptPack("tar") setupAptPack("tar")
await setupAptPack("git") setupAptPack("git")
await setupAptPack("pkg-config") setupAptPack("pkg-config")
} }
if (!existsSync(join(setupDir, addShellExtension("bootstrap-vcpkg")))) { if (!existsSync(join(setupDir, addShellExtension("bootstrap-vcpkg")))) {
@ -38,7 +38,7 @@ export async function setupVcpkg(_version: string, setupDir: string, _arch: stri
isRoot() && isRoot() &&
process.env.SUDO_USER !== undefined process.env.SUDO_USER !== undefined
) { ) {
await execSudo("chown", ["-R", process.env.SUDO_USER, setupDir], setupDir) execSudo("chown", ["-R", process.env.SUDO_USER, setupDir], setupDir)
} }
addPath(setupDir) addPath(setupDir)