UNPKG

mongodb-memory-server-core

Version:

MongoDB Server for testing (core package, without autodownload). The server will allow you to connect your favourite ODM or client library to the MongoDB Server and run parallel integration tests isolated from each other.

466 lines 18.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoBinaryDownloadUrl = void 0; const tslib_1 = require("tslib"); const getos_1 = require("./getos"); const resolveConfig_1 = require("./resolveConfig"); const debug_1 = (0, tslib_1.__importDefault)(require("debug")); const semver = (0, tslib_1.__importStar)(require("semver")); const utils_1 = require("./utils"); const url_1 = require("url"); const errors_1 = require("./errors"); const util_1 = require("util"); const log = (0, debug_1.default)('MongoMS:MongoBinaryDownloadUrl'); /** * Download URL generator */ class MongoBinaryDownloadUrl { constructor(opts) { this.version = opts.version; this.platform = this.translatePlatform(opts.platform); this.arch = MongoBinaryDownloadUrl.translateArch(opts.arch, this.platform); this.os = opts.os; } /** * Assemble the URL to download * Calls all the necessary functions to determine the URL */ getDownloadUrl() { var _a; return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () { const downloadUrl = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_URL); if (downloadUrl) { log(`Using "${downloadUrl}" as the Download-URL`); const url = new url_1.URL(downloadUrl); // check if this is an valid url return url.toString(); } const archive = yield this.getArchiveName(); log(`Using "${archive}" as the Archive String`); const mirror = (_a = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_MIRROR)) !== null && _a !== void 0 ? _a : 'https://fastdl.mongodb.org'; log(`Using "${mirror}" as the mirror`); const url = new url_1.URL(mirror); // ensure that the "mirror" path ends with "/" if (!url.pathname.endsWith('/')) { url.pathname = url.pathname + '/'; } // no extra "/" between "pathname" and "platfrom", because of the "if" statement above to ensure "url.pathname" to end with "/" url.pathname = `${url.pathname}${this.platform}/${archive}`; return url.toString(); }); } /** * Get the archive */ getArchiveName() { return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () { const archive_name = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.ARCHIVE_NAME); // double-"!" to not include falsy values if (!!archive_name) { return archive_name; } switch (this.platform) { case 'osx': return this.getArchiveNameOsx(); case 'win32': case 'windows': return this.getArchiveNameWin(); case 'linux': return this.getArchiveNameLinux(); default: throw new errors_1.UnknownPlatformError(this.platform); } }); } /** * Get the archive for Windows * (from: https://www.mongodb.org/dl/win32) */ getArchiveNameWin() { let name = `mongodb-${this.platform}-${this.arch}`; if (!(0, utils_1.isNullOrUndefined)(semver.coerce(this.version))) { if (semver.satisfies(this.version, '4.2.x')) { name += '-2012plus'; } else if (semver.lt(this.version, '4.1.0')) { name += '-2008plus-ssl'; } } name += `-${this.version}.zip`; return name; } /** * Get the archive for OSX (Mac) * (from: https://www.mongodb.org/dl/osx) */ getArchiveNameOsx() { let name = `mongodb-osx`; const version = semver.coerce(this.version); if (!(0, utils_1.isNullOrUndefined)(version) && semver.gte(version, '3.2.0')) { name += '-ssl'; } if ((0, utils_1.isNullOrUndefined)(version) || semver.gte(version, '4.2.0')) { name = `mongodb-macos`; // somehow these files are not listed in https://www.mongodb.org/dl/osx } if (this.arch === 'aarch64') { log('getArchiveNameOsx: Arch is "aarch64", using x64 binary'); this.arch = 'x86_64'; } name += `-${this.arch}-${this.version}.tgz`; return name; } /** * Get the archive for Linux * (from: https://www.mongodb.org/dl/linux) */ getArchiveNameLinux() { return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () { let osString; // the highest version for "i686" seems to be 3.3 if (this.arch !== 'i686') { if (!this.os) { this.os = yield (0, getos_1.getOS)(); } osString = this.getLinuxOSVersionString(this.os); } // this is below, to allow overwriting the arch (like arm64 to aarch64) let name = `mongodb-linux-${this.arch}`; if (!!osString) { name += `-${osString}`; } name += `-${this.version}.tgz`; return name; }); } /** * Get the version string (with distro) * @param os LinuxOS Object */ getLinuxOSVersionString(os) { var _a; if (regexHelper(/ubuntu/i, os)) { return this.getUbuntuVersionString(os); } else if (regexHelper(/amzn/i, os)) { return this.getAmazonVersionString(os); } else if (regexHelper(/suse/i, os)) { return this.getSuseVersionString(os); } else if (regexHelper(/(rhel|centos|scientific)/i, os)) { return this.getRhelVersionString(os); } else if (regexHelper(/fedora/i, os)) { return this.getFedoraVersionString(os); } else if (regexHelper(/debian/i, os)) { return this.getDebianVersionString(os); } else if (regexHelper(/alpine/i, os)) { console.warn('There is no offical build of MongoDB for Alpine!'); // Match "arch", "archlinux", "manjaro", "manjarolinux", "arco", "arcolinux" } else if (regexHelper(/(arch|manjaro|arco)(?:linux)?$/i, os)) { console.warn(`There is no official build of MongoDB for ArchLinux (${os.dist}). Falling back to Ubuntu 20.04 release.`); return this.getUbuntuVersionString({ os: 'linux', dist: 'Ubuntu Linux', release: '20.04', }); } else if (regexHelper(/gentoo/i, os)) { // it seems like debian binaries work for gentoo too (at least most), see https://github.com/nodkz/mongodb-memory-server/issues/639 console.warn(`There is no official build of MongoDB for Gentoo (${os.dist}). Falling back to Debian.`); return this.getDebianVersionString({ os: 'linux', dist: 'Debian', release: '11', }); } else if (regexHelper(/unknown/i, os)) { // "unknown" is likely to happen if no release file / command could be found console.warn('Couldnt parse dist information, please report this to https://github.com/nodkz/mongodb-memory-server/issues'); } // warn for the fallback console.warn(`Unknown/unsupported linux "${os.dist}(${(_a = os.id_like) === null || _a === void 0 ? void 0 : _a.join(', ')})". Falling back to legacy MongoDB build!`); return this.getLegacyVersionString(); } /** * Get the version string for Debian * @param os LinuxOS Object */ getDebianVersionString(os) { let name = 'debian'; const release = parseFloat(os.release); if (release >= 11 || ['unstable', 'testing'].includes(os.release)) { // Debian 11 is compatible with the binaries for debian 10 // but does not have binaries for before 5.0.8 if (semver.lt(this.version, '5.0.8')) { log('debian11 detected, but version below 5.0.8 requested, using debian10'); name += '10'; } else { name += '11'; } } else if (release >= 10) { name += '10'; } else if (release >= 9) { name += '92'; } else if (release >= 8.1) { name += '81'; } else if (release >= 7.1) { name += '71'; } if (release >= 10) { if (semver.lt(this.version, '4.2.1')) { throw new errors_1.KnownVersionIncompatibilityError(`Debian ${release}`, this.version, '>=4.2.1', 'Mongodb does not provide binaries for versions before 4.2.1 for Debian 10+ and also cannot be mapped to a previous Debian release'); } } return name; } /** * Get the version string for Fedora * @param os LinuxOS Object */ getFedoraVersionString(os) { let name = 'rhel'; const fedoraVer = parseInt(os.release, 10); // 36 and onwards dont ship with libcrypto.so.1.1 anymore and need to be manually installed ("openssl1.1") // 34 onward dosnt have "compat-openssl10" anymore, and only build from 4.0.24 are available for "rhel80" if (fedoraVer >= 34) { name += '80'; } if (fedoraVer < 34 && fedoraVer >= 19) { name += '70'; } if (fedoraVer < 19 && fedoraVer >= 12) { name += '62'; } if (fedoraVer < 12 && fedoraVer >= 6) { name += '55'; } return name; } /** * Get the version string for Red Hat Enterprise Linux * @param os LinuxOS Object */ getRhelVersionString(os) { let name = 'rhel'; const { release } = os; if (release) { if (this.arch === 'aarch64') { if (!/^8/.test(release)) { throw new errors_1.KnownVersionIncompatibilityError(`Rhel ${release}`, this.version, '>=4.4.2', 'ARM64(aarch64) support for rhel is only for rhel82 or higher'); } if (semver.satisfies(this.version, '<4.4.2')) { throw new errors_1.KnownVersionIncompatibilityError(`Rhel ${release}`, this.version, '>=4.4.2'); } // rhel aarch64 support is only for rhel 8 and only for 82 name += '82'; } else if (/^8/.test(release)) { name += '80'; } else if (/^7/.test(release)) { name += '70'; } else if (/^6/.test(release)) { name += '62'; } else if (/^5/.test(release)) { name += '55'; } } // fallback if name has not been modified yet if (name === 'rhel') { log('getRhelVersionString: falling back to "70"'); // fallback to "70", because that is what currently is supporting 3.6 to 5.0 and should work with many name += '70'; } return name; } /** * Get the version string for Amazon Distro * @param os LinuxOS Object */ getAmazonVersionString(os) { let name = 'amazon'; const release = parseInt(os.release, 10); if (release >= 2 && release <= 3) { name += '2'; } // dont add anthing as fallback, because for "amazon 1", mongodb just uses "amazon" return name; } /** * Linux Fallback */ getLegacyVersionString() { return ''; } /** * Get the version string for Suse / OpenSuse * @param os LinuxOS Object */ // TODO: add tests for getSuseVersionString getSuseVersionString(os) { const releaseMatch = os.release.match(/(^11|^12|^15)/); return releaseMatch ? `suse${releaseMatch[0]}` : ''; } /** * Get the version string for Ubuntu * @param os LinuxOS Object */ getUbuntuVersionString(os) { let ubuntuOS = undefined; // "id_like" processing (version conversion) [this is an block to be collapsible] { if (/^linux\s?mint\s*$/i.test(os.dist)) { const mintToUbuntuRelease = { 17: '14.04', 18: '16.04', 19: '18.04', 20: '20.04', }; ubuntuOS = { os: 'linux', dist: 'ubuntu', release: mintToUbuntuRelease[parseInt(os.release.split('.')[0])] || mintToUbuntuRelease[20], }; } if (/^elementary\s?os\s*$/i.test(os.dist)) { const elementaryToUbuntuRelease = { 3: '14.04', 4: '16.04', 5: '18.04', 6: '20.04', }; // untangle elemenatary versioning from hell https://en.wikipedia.org/wiki/Elementary_OS#Development const [elementaryMajor, elementaryMinor] = os.release.split('.').map((el) => parseInt(el)); const realMajor = elementaryMajor || elementaryMinor; ubuntuOS = { os: 'linux', dist: 'ubuntu', release: elementaryToUbuntuRelease[realMajor] || elementaryToUbuntuRelease[6], }; } } if ((0, utils_1.isNullOrUndefined)(ubuntuOS)) { // Warn against distros that have a ID_LIKE set to "ubuntu", but no other upstream information and are not specially mapped (see above) if (!/^ubuntu(?:| linux)\s*$/i.test(os.dist)) { console.warn(`Unmapped distro "${os.dist}" with ID_LIKE "ubuntu", defaulting to highest ubuntu version!\n` + 'This means that your distro does not have a internal mapping in MMS or does not have a upstream release file (like "/etc/upstream-release/lsb-release"), but has set a ID_LIKE'); ubuntuOS = { os: 'linux', dist: 'ubuntu', release: '20.04', // TODO: try to keep this up-to-date to the latest LTS }; } else { ubuntuOS = os; } } const ubuntuYear = parseInt(ubuntuOS.release.split('.')[0], 10); if (this.arch === 'aarch64') { // this is because, before version 4.1.10, everything for "arm64" / "aarch64" were just "arm64" and for "ubuntu1604" if (semver.satisfies(this.version, '<4.1.10')) { this.arch = 'arm64'; return 'ubuntu1604'; } // this is because versions below "4.4.0" did not provide an binary for anything above 1804 if (semver.satisfies(this.version, '>=4.1.10 <4.4.0')) { return 'ubuntu1804'; } } if (ubuntuOS.release === '14.10') { return 'ubuntu1410-clang'; } // there are no MongoDB 3.x binary distributions for ubuntu >= 18 // https://www.mongodb.org/dl/linux/x86_64-ubuntu1604 if (ubuntuYear >= 18 && semver.satisfies(this.version, '3.x.x')) { log(`getUbuntuVersionString: ubuntuYear is "${ubuntuYear}", which dosnt have an 3.x.x version, defaulting to "1604"`); return 'ubuntu1604'; } // there are no MongoDB <=4.3.x binary distributions for ubuntu > 18 // https://www.mongodb.org/dl/linux/x86_64-ubuntu1804 if (ubuntuYear > 18 && semver.satisfies(this.version, '<=4.3.x')) { log(`getUbuntuVersionString: ubuntuYear is "${ubuntuYear}", which dosnt have an "<=4.3.x" version, defaulting to "1804"`); return 'ubuntu1804'; } // there are not binaries for ubuntu 21.04, so defaulting to one version below for now // see https://github.com/nodkz/mongodb-memory-server/issues/582 if (ubuntuYear >= 21) { return 'ubuntu2004'; } // TODO: change or remove "14" default, since it no-longer is supported above 4.0 // the "04" version always exists for ubuntu, use that as default return `ubuntu${ubuntuYear || 14}04`; } /** * Translate input platform to mongodb useable platform * @example * darwin -> osx * @param platform The Platform to translate */ translatePlatform(platform) { switch (platform) { case 'darwin': return 'osx'; case 'win32': const version = semver.coerce(this.version); if ((0, utils_1.isNullOrUndefined)(version)) { return 'windows'; } return semver.gte(version, '4.3.0') ? 'windows' : 'win32'; case 'linux': case 'elementary OS': return 'linux'; case 'sunos': (0, util_1.deprecate)(() => { }, 'mongodb-memory-server will fully drop support for sunos in 9.0', 'MMS002')(); return 'sunos5'; default: throw new errors_1.UnknownPlatformError(platform); } } /** * Translate input arch to mongodb useable arch * @example * x64 -> x86_64 * @param platform The Platform to translate */ static translateArch(arch, mongoPlatform) { switch (arch) { case 'ia32': (0, util_1.deprecate)(() => { }, 'mongodb-memory-server will fully drop support for ia32 in 9.0', 'MMS001')(); if (mongoPlatform === 'linux') { return 'i686'; } else if (mongoPlatform === 'win32') { return 'i386'; } throw new errors_1.UnknownArchitectureError(arch, mongoPlatform); case 'x86_64': case 'x64': return 'x86_64'; case 'arm64': case 'aarch64': return 'aarch64'; default: throw new errors_1.UnknownArchitectureError(arch); } } } exports.MongoBinaryDownloadUrl = MongoBinaryDownloadUrl; exports.default = MongoBinaryDownloadUrl; /** * Helper function to reduce code / regex duplication */ function regexHelper(regex, os) { return (regex.test(os.dist) || (!(0, utils_1.isNullOrUndefined)(os.id_like) ? os.id_like.filter((v) => regex.test(v)).length >= 1 : false)); } //# sourceMappingURL=MongoBinaryDownloadUrl.js.map