2024-09-03 15:16:55 +08:00
|
|
|
import { tmpdir } from "os"
|
2024-04-03 15:15:43 +08:00
|
|
|
import { execRootSync } from "admina"
|
2024-09-03 17:34:11 +08:00
|
|
|
import { error, info } from "ci-log"
|
2024-09-03 15:16:55 +08:00
|
|
|
import { readFile, writeFile } from "fs/promises"
|
|
|
|
import { DownloaderHelper } from "node-downloader-helper"
|
|
|
|
import { dirname, join } from "patha"
|
|
|
|
import { hasNala, installAptPack, qualifiedNeededAptPackage } from "setup-apt"
|
2022-07-25 15:40:05 +08:00
|
|
|
import which from "which"
|
2024-08-16 06:22:07 +08:00
|
|
|
import { isUbuntu } from "../utils/env/isUbuntu.js"
|
2022-07-25 15:40:05 +08:00
|
|
|
|
|
|
|
let binDir: string | undefined
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2022-07-28 10:07:30 +08:00
|
|
|
export async function setupNala(version: string, _setupDir: string, _arch: string) {
|
2022-07-25 15:46:23 +08:00
|
|
|
if (!isUbuntu()) {
|
2022-07-25 15:40:05 +08:00
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
if (typeof binDir === "string") {
|
|
|
|
return { binDir }
|
|
|
|
}
|
|
|
|
|
|
|
|
const maybeBinDir = which.sync("nala", { nothrow: true })
|
|
|
|
if (maybeBinDir !== null) {
|
|
|
|
binDir = dirname(maybeBinDir)
|
|
|
|
return { binDir }
|
|
|
|
}
|
|
|
|
|
2024-08-16 16:50:32 +08:00
|
|
|
await installAptPack([{ name: "python3-apt" }])
|
2024-08-09 07:16:36 +08:00
|
|
|
|
2024-09-03 15:16:55 +08:00
|
|
|
binDir = "/usr/bin" // eslint-disable-line require-atomic-updates
|
|
|
|
|
|
|
|
// If nala is available in the default repositories, install it
|
2024-09-03 17:34:11 +08:00
|
|
|
try {
|
|
|
|
const nalaPack = await qualifiedNeededAptPackage({ name: "nala", version })
|
|
|
|
if (nalaPack !== undefined) {
|
|
|
|
await installAptPack([{ name: nalaPack }])
|
|
|
|
return { binDir }
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
// ignore
|
|
|
|
info(`Failed to install nala: ${err}`)
|
2022-07-25 15:40:05 +08:00
|
|
|
}
|
|
|
|
|
2024-09-03 15:16:55 +08:00
|
|
|
// Nala is not available in the default repositories
|
|
|
|
// Check if the legacy version is available
|
2024-09-03 17:34:11 +08:00
|
|
|
try {
|
|
|
|
const nalaLegacyPack = await qualifiedNeededAptPackage({ name: "nala-legacy" })
|
|
|
|
if (nalaLegacyPack !== undefined) {
|
|
|
|
await installAptPack([{ name: nalaLegacyPack }], true)
|
|
|
|
return { binDir }
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
// ignore
|
|
|
|
info(`Failed to install nala-legacy: ${err}`)
|
2024-09-03 15:16:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Install via the installer script
|
|
|
|
await setupNalaViaInstaller()
|
2022-07-25 15:40:05 +08:00
|
|
|
|
|
|
|
return { binDir }
|
|
|
|
}
|
2023-07-16 12:46:28 +08:00
|
|
|
|
2024-09-03 15:16:55 +08:00
|
|
|
async function setupNalaViaInstaller() {
|
|
|
|
const installer = new DownloaderHelper(
|
|
|
|
"https://gitlab.com/volian/volian-archive/-/raw/main/install-nala.sh",
|
|
|
|
tmpdir(),
|
|
|
|
{ fileName: "install-nala.sh" },
|
|
|
|
)
|
|
|
|
installer.on("error", (err) => {
|
|
|
|
throw new Error(`Failed to download install-nala.sh: ${err}`)
|
|
|
|
})
|
|
|
|
await installer.start()
|
|
|
|
|
|
|
|
const installerPath = join(tmpdir(), "install-nala.sh")
|
|
|
|
|
|
|
|
// Patch the installer script to not use sudo explicitly
|
|
|
|
const script = await readFile(installerPath, "utf8")
|
|
|
|
await writeFile(installerPath, script.replace(/sudo/g, ""))
|
|
|
|
|
2024-09-03 17:34:11 +08:00
|
|
|
await installAptPack([{ name: "wget" }])
|
|
|
|
|
|
|
|
try {
|
|
|
|
execRootSync("bash", [installerPath])
|
|
|
|
} catch (err) {
|
|
|
|
error(`Failed to install nala via installer: ${err}`)
|
|
|
|
execRootSync("apt", ["install", "-y", "-t", "nala", "nala"])
|
|
|
|
}
|
2024-09-03 15:16:55 +08:00
|
|
|
}
|
|
|
|
|
2023-07-16 12:46:28 +08:00
|
|
|
export function bashWithNala(script: string) {
|
|
|
|
if (hasNala()) {
|
|
|
|
return `apt-get() { nala $@; }; export -f apt-get; ${script}; unset -f apt-get`
|
|
|
|
}
|
|
|
|
return script
|
|
|
|
}
|