Spaces:
Running
Running
File size: 4,746 Bytes
b39afbe |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
/**
* Copyright (c) 2023 MERCENARIES.AI PTE. LTD.
* All rights reserved.
*/
// NO THIRD PARTY DEPS
const { spawn, spawnSync, execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { omniCwd } = require('./utils.js');
const packagejson = JSON.parse(
fs.readFileSync(path.join(omniCwd(), 'package.json'), { encoding: 'utf-8' }));
const { unzip, sleep, checkInternet } = require('./utils');
const depjson = packagejson.dependenciesBin;
const VERSION_MARKER = '##version##';
const DB_ID = 'pocketbase';
const platform = os.platform();
const arch = os.arch();
const ownedProcesses = new Array();
function verifyInstall(path) {
return fs.existsSync(path);
}
function downloadURL() {
let file = depjson[DB_ID].zipfile[platform][arch];
let version = packagejson.engines[DB_ID];
return `${depjson[DB_ID].base_url}/${file}`.replaceAll(VERSION_MARKER, version);
}
async function fetchAndExtract(zipfile, destdir) {
const curl = `curl -L -o ${zipfile} ${downloadURL()}`;
execSync(curl, { stdio: 'inherit' });
console.log(`\nDownload completed, now extracting to ${path.dirname(destdir)}...`);
unzip(zipfile, destdir);
}
async function createDefaultAdmin(installpath) {
let timeout_guard = 10000;
console.log('Pre-warm pocketbase...');
let dbprocess = spawn(path.join(installpath, getExecutable()), ['serve'], { stdio: 'inherit' });
ownedProcesses.push(dbprocess);
// ensure initial boot of pocketbase to create base tables
while (!fs.existsSync(path.join(installpath, 'pb_data'))) {
await sleep(1000);
timeout_guard -= 1000;
if (timeout_guard <= 0) {
console.error('Failed to initialize DB');
process.exit(1);
}
}
// ready to administrate
console.log('Creating default DB Admin ' + depjson[DB_ID].admin);
spawnSync(path.join(installpath, getExecutable()), ['admin', 'create', depjson[DB_ID].admin, depjson[DB_ID].admin]);
// create default tables for OMNI
console.log(`Success!`);
let pbSchemas = require('../packages/omni-server/src/services/DBService/pb_schema.json');
const PocketBase = (await import('pocketbase')).default;
let pb = new PocketBase('http://127.0.0.1:8090');
await pb.admins.authWithPassword(depjson[DB_ID].admin, depjson[DB_ID].admin);
for (const schema of pbSchemas) {
console.log('Creating collection - ' + schema.name);
await pb.collections.create(schema);
const record = pb.collection(schema.name);
// validate get, if not found, throw
await record.getList();
}
pb.autoCancellation(false);
// shutdown pocketbase serve
console.info('PocketBase initial configuration completed - READY FOR USE...');
dbprocess.kill();
ownedProcesses.pop();
}
// move to config
function getExecutable() {
switch (`${platform}`) {
case 'win32':
return 'pocketbase.exe';
case 'darwin':
return 'pocketbase';
case 'linux':
return 'pocketbase';
}
throw new Error('Unhandled executable type for ' + platform);
}
function successCleanup(installpath) {
fs.rmSync(installpath + '/_download.zip');
}
async function failCleanup(installpath) {
console.error('Installation failed. Cleaning up.');
while (ownedProcesses.length > 0) {
ownedProcesses.pop().kill();
}
// there are cases when the shutdown isn't complete
// and rm fails, we retry until it succeeds or throw
let retries = 30;
while (true) {
try {
fs.rmSync(installpath, { recursive: true, force: true });
break;
} catch (e) {
if (retries-- <= 0) {
throw e;
}
await sleep(100);
}
}
}
async function installPocketBase(installpath) {
// create directory
console.log('Creating dir ' + installpath);
fs.mkdirSync(installpath, { recursive: true });
const downloadfile = installpath + '/_download.zip';
await fetchAndExtract(downloadfile, installpath);
console.log('Installation successful');
await createDefaultAdmin(installpath);
}
async function ensure_online() {
if (!(await checkInternet())) {
console.error('DNS resolution failed. Please check your internet connection.');
process.exit(1);
}
console.log('Connectivity OK!');
}
async function ensure(installpath) {
// check if installed
if (verifyInstall(path.join(installpath, getExecutable()))) {
console.info(`Found installation for PocketBase`);
return true;
} else {
ensure_online();
console.info(`Missing PocketBase DB - Installing...`);
try {
await installPocketBase(installpath);
successCleanup(installpath);
return true;
} catch (e) {
console.error(e);
await failCleanup(installpath);
return false;
}
}
}
module.exports = {
ensure
};
|