Files
hp-devkit/npm/lib/command-handler.js
2022-09-29 15:03:09 +05:30

235 lines
7.3 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const appenv = require('../appenv');
const { exec } = require('./child-proc');
const {
CONSTANTS,
initializeDeploymentCluster,
runOnContainer,
executeOnContainer,
teardownDeploymentCluster,
isExists,
updateDockerImages,
archiveDirectory
} = require('./common');
const { success, error, info, warn } = require('./logger');
function version() {
info(`command: version`);
try {
const res = exec(`npm -g list ${CONSTANTS.npmPackageName} --depth=0`);
const splitted = res.toString().split('\n');
if (splitted.length > 1) {
success(`\n${splitted[1].split('@')[1]}\n`);
return;
}
}
catch (e) { }
error(`\n${CONSTANTS.npmPackageName} is not installed.`);
}
function codeGen(platform, apptype, projName) {
info("Code generator\n");
if (fs.existsSync(projName)) {
error(`Directory '${projName}' already exists.`);
return;
}
try {
runOnContainer(CONSTANTS.codegenContainerName, null, null, null, null, `${platform} ${apptype} ${projName}`, 'codegen');
exec(`docker cp ${CONSTANTS.codegenContainerName}:${CONSTANTS.codegenOutputDir} ./${projName}`);
success(`Project '${projName}' created.`);
}
catch (e) {
error(`Project '${projName}' generation failed.`);
}
finally {
if (isExists(CONSTANTS.codegenContainerName))
exec(`docker rm ${CONSTANTS.codegenContainerName}`, false);
}
}
function deploy(contractPath) {
info(`command: deploy (cluster: ${appenv.cluster})`);
initializeDeploymentCluster();
// If copying a directory, delete target bundle directory. If not create empty target bundle directory to copy a file.
const prepareBundleDir = contractPath ?
`rm -rf ${CONSTANTS.bundleMount}` :
`mkdir -p ${CONSTANTS.bundleMount} && rm -rf ${CONSTANTS.bundleMount}/* ${CONSTANTS.bundleMount}/.??*`;
executeOnContainer(CONSTANTS.deploymentContainerName, prepareBundleDir);
exec(`docker cp ${contractPath} "${CONSTANTS.deploymentContainerName}:${CONSTANTS.bundleMount}"`);
// Sync contract bundle to all instance directories in the cluster.
executeOnContainer(CONSTANTS.deploymentContainerName, 'cluster stop ; cluster sync ; cluster start');
if (appenv.defaultNode > 0) {
info(`Streaming logs of node ${appenv.defaultNode}:`);
executeOnContainer(CONSTANTS.deploymentContainerName, `cluster logs ${appenv.defaultNode}`);
}
}
function bundle(nodePublicKey, contractDirectoryPath) {
info(`command: bundle`);
try {
contractDirectoryPath = path.normalize(contractDirectoryPath);
let stats = fs.statSync(contractDirectoryPath);
if (!stats.isDirectory())
throw 'You are supposed to provide a path of the contract directory.';
const overrideConfigPath = path.resolve(contractDirectoryPath, CONSTANTS.confOverrideFile);
const contractConfigPath = path.resolve(contractDirectoryPath, CONSTANTS.contractCfgFile);
const prerequisiteInstaller = path.resolve(contractDirectoryPath, CONSTANTS.prerequisiteInstaller);
const overrideConfig = JSON.parse(fs.readFileSync(overrideConfigPath).toString());
const contractConfigs = {
"version": "2.0",
"unl": [
`${nodePublicKey}`
],
"bin_path": `${overrideConfig?.contract.bin_path}`,
"bin_args": `${overrideConfig?.contract.bin_args}`,
"environment": "",
"max_input_ledger_offset": 10,
"consensus": {
"mode": "private",
"roundtime": 8000,
"stage_slice": 25,
"threshold": 50
},
"npl": {
"mode": "private"
},
"appbill": {
"mode": "",
"bin_args": ""
},
"round_limits": {
"user_input_bytes": 0,
"user_output_bytes": 0,
"npl_output_bytes": 0,
"proc_cpu_seconds": 0,
"proc_mem_bytes": 0,
"proc_ofd_count": 0
}
}
// Write contract.config file content.
fs.writeFileSync(contractConfigPath, JSON.stringify(contractConfigs, null, 4));
info(`Prepared ${CONSTANTS.contractCfgFile} file.`);
// Add prerequisite install script.
fs.writeFileSync(prerequisiteInstaller,
`#!/bin/bash\n` +
`echo "Prerequisite installer script"\n` +
`exit 0`, null);
// Change permission pre-requisite installer.
fs.chmodSync(prerequisiteInstaller, 0o755);
info("Added prerequisite installer script.");
const bundleTargetPath = path.normalize(`${contractDirectoryPath}/../bundle`);
if (!fs.existsSync(bundleTargetPath)) {
fs.mkdirSync(bundleTargetPath);
}
archiveDirectory(contractDirectoryPath, bundleTargetPath);
} catch (e) {
error(e);
}
}
function clean() {
info(`command: clean (cluster: ${appenv.cluster})`);
teardownDeploymentCluster();
}
function logs(nodeNumber) {
info(`command: logs (cluster: ${appenv.cluster})`);
runOnContainer(null, null, true, true, null, `logs ${nodeNumber}`, 'cluster');
}
function start(nodeNumber) {
info(`command: start (cluster: ${appenv.cluster})`);
runOnContainer(null, null, true, true, null, `start ${nodeNumber}`, 'cluster');
}
function stop(nodeNumber) {
info(`command: stop (cluster: ${appenv.cluster})`);
runOnContainer(null, null, true, true, null, `stop ${nodeNumber}`, 'cluster');
}
function update() {
info(`command: update`);
// Update npm package if outdated (Docker images will be updated from there). Otherwise only update the docker images.
try {
exec(`npm -g outdated ${CONSTANTS.npmPackageName}`);
info('\nUpdating docker images...');
updateDockerImages();
}
catch (e) {
const splitted = e.stdout.toString().trim().split('\n').map(l => l.trim().split(/\s+/));
if (splitted.length > 1) {
info(`\nUpdating ${CONSTANTS.npmPackageName} npm package...`);
exec(`npm -g install ${CONSTANTS.npmPackageName}@${splitted[1][3]}`, true);
}
}
success('\nUpdate Completed !!');
warn('NOTE: You need to re-deploy your contracts to make the new changes effective.');
}
function uninstall() {
info(`command: uninstall`);
info(`\nUninstalling ${CONSTANTS.npmPackageName} npm package...`);
exec(`npm -g uninstall ${CONSTANTS.npmPackageName}`, true);
// Remove deployment cluster if exist.
if (isExists(CONSTANTS.deploymentContainerName)) {
info('\nCleaning the deployed contracts...');
teardownDeploymentCluster();
}
// Remove docker images if exist.
if (isExists(appenv.devkitImage, 'image')) {
info('\nRemoving devkit docker image...');
exec(`docker image rm ${appenv.devkitImage}`, true);
}
if (isExists(appenv.instanceImage, 'image')) {
info('\nRemoving instance docker image...');
exec(`docker image rm ${appenv.instanceImage}`, true);
}
success('\nUninstalled hpdevkit !!');
}
module.exports = {
version,
codeGen,
deploy,
bundle,
clean,
logs,
start,
stop,
update,
uninstall
};