@medflyt/test-db-service
Version:
Developer tool to instantly provision test PostgreSQL databases from a template
140 lines • 5.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.runBinariesJarFileProcess = void 0;
const AdmZip = require("adm-zip");
const fs = require("fs");
const promises_1 = require("fs/promises");
const makeDir = require("make-dir");
const path = require("path");
const promisify_child_process_1 = require("promisify-child-process");
const request = require("request");
const tempDir_1 = require("./DownloadUtils/tempDir");
function getBinariesDownloadJarUrl(platform, cpuArch, postgresVersion) {
return `https://repo1.maven.org/maven2/io/zonky/test/postgres/embedded-postgres-binaries-${platform}-${cpuArch}/${postgresVersion}/embedded-postgres-binaries-${platform}-${cpuArch}-${postgresVersion}.jar`;
}
async function runBinariesJarFileProcess(appName, platform, cpuArch, postgresVersion, targetDir) {
const url = getBinariesDownloadJarUrl(platform, cpuArch, postgresVersion);
const exists = await checkIfLinkExists(url);
if (!exists) {
throw new Error(`Binary Download of PostgreSQL version ${postgresVersion} not available for ${platform}`);
}
await makeDir(path.dirname(targetDir));
const extractDir = await promises_1.mkdtemp(targetDir + "-tmp-");
await withTempExtractPostgresTo(appName, url, targetDir, extractDir);
}
exports.runBinariesJarFileProcess = runBinariesJarFileProcess;
async function withTempExtractPostgresTo(appName, url, targetDir, extractDir) {
await tempDir_1.withTempDir(appName, async (tmpDir) => {
const jarFilePath = path.join(tmpDir, "tmp.jar");
await downloadFileWithRetry(url, jarFilePath);
await makeDir(extractDir);
console.log("extracting to", extractDir);
const jarFile = new AdmZip(jarFilePath);
const txzFile = jarFile
.getEntries()
.find((f) => f.entryName.endsWith(".txz"));
if (txzFile === undefined) {
throw new Error("No txz file found in jar");
}
jarFile.extractEntryTo(txzFile, tmpDir, false, true);
const txzFilePath = path.join(tmpDir, txzFile.name);
if (url.endsWith(".zip")) {
await new Promise((resolve, reject) => {
const zip = new AdmZip(txzFilePath);
zip.extractAllToAsync(extractDir, true, (err) => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/consistent-type-assertions
if (err) {
reject(err);
return;
}
resolve();
});
});
}
else {
// Not clear on why this doesn't work.
// await tar.x({
// f: txzFilePath,
// C: extractDir
// });
const result = await promisify_child_process_1.spawn("tar", ["xf", txzFilePath, "-C", extractDir], { stdio: "inherit", encoding: "utf8" });
if (result.code !== 0) {
throw new Error(`Failed to extract txz file: ${result.stderr}`);
}
}
try {
await new Promise((resolve, reject) => {
fs.rename(extractDir, targetDir, (err) => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/consistent-type-assertions
if (err !== null) {
reject(err);
return;
}
resolve();
});
});
}
catch (err) {
if (err.code === "ENOTEMPTY") {
// The target directory already exists. We can ignore, because
// it means that some concurrent process was racing us to
// install it and finished before us
console.log(`Target directory already exists (created by a concurrent process)`);
// Cleanup after ourselves:
await tempDir_1.rimrafIgnoreErrors(extractDir);
}
else {
throw err;
}
}
});
}
async function checkIfLinkExists(url) {
try {
await request(url, { method: "HEAD" });
return true;
}
catch (err) {
return false;
}
}
function downloadFile(url, filePath) {
return new Promise((resolve, reject) => {
const stream = request(url).pipe(fs.createWriteStream(filePath));
stream.on("finish", () => {
resolve();
});
stream.on("error", (err) => {
reject(err);
});
});
}
async function downloadFileWithRetry(url, filePath) {
const MAX_RETRIES = 10;
let retryCount = 0;
while (true) {
try {
console.log("Downloading:", url);
const result = await downloadFile(url, filePath);
return result;
}
catch (err) {
retryCount++;
if (retryCount === MAX_RETRIES) {
throw err;
}
console.log("Error downloading:", url);
console.log();
console.log(err);
console.log();
console.log("Sleeping...");
await delay(10000);
}
}
}
function delay(millis) {
return new Promise((resolve, _reject) => {
setTimeout(resolve, millis);
});
}
//# sourceMappingURL=download_postgres.js.map