ad4m-host
Version:
Self hosting ad4m service
165 lines (138 loc) • 5.15 kB
text/typescript
/**
* Copy binaries from pkg to os file system, https://github.com/vercel/pkg/issues/342
*/
import type { Arguments, Argv } from 'yargs';
import path from 'path';
import fs from 'fs-extra';
// @ts-ignore
import utils from 'util';
import { fetchLatestBootstrapSeed, MAINNET_SEED } from '../utils/fetchLatestBootstrapSeed';
import { CONFIG, getConfig } from '../utils/config';
import ReadlineSync from 'readline-sync';
import os from 'os'
import { ad4mDataDirectory } from '../ad4mDataDirectory';
const copyFile = utils.promisify(fs.copyFile);
const copyDir = utils.promisify(fs.copy)
const chmod = utils.promisify(fs.chmod);
async function copy(source, target) {
//@ts-ignore
if (process.pkg) {
// use stream pipe to reduce memory usage
// when loading a large file into memory.
return new Promise<void>((resolve, reject) => {
let readStream = fs.createReadStream(source);
let writeStream = fs.createWriteStream(target);
readStream.pipe(writeStream);
readStream.on('error', reject);
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
} else {
await copyFile(source, target);
}
}
type Options = {
hcOnly?: boolean;
dataPath?: string;
networkBootstrapSeed?: string;
overrideConfig?: boolean;
};
export const command: string = 'init';
export const desc: string = 'Init ad4m service with prebuild binary.';
export const builder = (yargs: Argv) =>
yargs
.options({
hcOnly: { type: "boolean" },
dataPath: {
type: 'string',
describe: 'Name of directory to store ad4m data in the systems app data path',
alias: 'rp'
},
networkBootstrapSeed: {
type: 'string',
describe: 'Path to the seed file',
alias: 'nbf'
},
overrideConfig: {
type: 'boolean',
describe: 'Override the existing config file',
},
});
export const handler = async (argv: Arguments<Options>): Promise<void> => {
const { hcOnly, dataPath = '', networkBootstrapSeed, overrideConfig } = argv;
const appDataPath = ad4mDataDirectory(dataPath)
const binaryPath = path.join(appDataPath, 'binary')
if(!fs.existsSync(binaryPath)) {
fs.mkdirSync(binaryPath, { recursive: true })
}
const platform = os.platform();
const holochain = platform === 'win32' ? 'holochain.exe' : 'holochain';
const lair = platform === 'win32' ? 'lair-keystore.exe' : 'lair-keystore';
const hc = platform === 'win32' ? 'hc.exe' : 'hc';
if(!hcOnly) {
const holochainSource = path.join(__dirname, `../temp/binary/${holochain}`);
const holochaintarget = path.join(binaryPath, holochain);
await copy(holochainSource, holochaintarget);
await chmod(holochaintarget, '755');
const lairSource = path.join(__dirname, `../temp/binary/${lair}`);
const lairTarget = path.join(binaryPath, lair);
await copy(lairSource, lairTarget);
await chmod(lairTarget, '755');
}
const hcSource = path.join(__dirname, `../temp/binary/${hc}`);
const hcTarget = path.join(binaryPath, hc);
await copy(hcSource, hcTarget);
await chmod(hcTarget, '755');
await getSeedConfig(dataPath, networkBootstrapSeed, overrideConfig);
const swiplSource = path.join(__dirname, `../temp/swipl`);
const swiplTarget = path.join(appDataPath, 'swipl')
await copyDir(swiplSource, swiplTarget)
process.exit();
};
async function getSeedFilePath(dataPath?: string, networkBootstrapSeed?: string) {
const appDataPath = ad4mDataDirectory(dataPath)
if (!networkBootstrapSeed) {
console.log("No bootstrap seed supplied... downloading the latest AD4M bootstrap seed");
await fetchLatestBootstrapSeed(appDataPath);
return path.join(appDataPath, MAINNET_SEED);
} else {
return path.isAbsolute(networkBootstrapSeed) ? networkBootstrapSeed: path.join(__dirname, networkBootstrapSeed);
}
}
async function getSeedConfig(dataPath?: string, networkBootstrapSeed?: string, override?: boolean) {
let seedPath;
let configDataPath;
let globalConfig;
try {
globalConfig = getConfig();
if (dataPath || networkBootstrapSeed) {
let decision;
if (override === undefined) {
decision = ReadlineSync.question("There is a already a config present, do you want to override it? (Y|N): ");
}
if (decision === 'Y' || decision === 'y' || override) {
configDataPath = dataPath;
seedPath = await getSeedFilePath(dataPath, networkBootstrapSeed);
}
} else {
if (!globalConfig[dataPath]) {
configDataPath = dataPath;
seedPath = await getSeedFilePath(dataPath, networkBootstrapSeed)
} else {
seedPath = globalConfig[dataPath].seedPath;
configDataPath = globalConfig[dataPath].dataPath;
}
}
} catch (e) {
console.log(e)
configDataPath = dataPath;
seedPath = getSeedFilePath(dataPath, networkBootstrapSeed)
}
const config = {
dataPath: configDataPath,
seedPath
}
const dest = path.join(ad4mDataDirectory(), CONFIG);
globalConfig[configDataPath] = config;
fs.writeFileSync(dest, JSON.stringify(globalConfig))
}