@devmn/cloud-cli
Version:
CLI tool for Intelligo Cloud.
182 lines • 9.56 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs-extra");
const path = require("path");
const child_process_1 = require("child_process");
const ProgressBar = require("progress");
const StdOutUtil_1 = require("../utils/StdOutUtil");
const CliApiManager_1 = require("../api/CliApiManager");
class DeployHelper {
constructor(ssl) {
this.ssl = ssl;
this.lastLineNumberPrinted = -10000; // we want to show all lines to begin with!
}
startDeploy(deployParams) {
return __awaiter(this, void 0, void 0, function* () {
const appName = deployParams.appName;
const branchToPush = deployParams.deploySource.branchToPush;
const tarFilePath = deployParams.deploySource.tarFilePath;
const imageName = deployParams.deploySource.imageName;
const machineToDeploy = deployParams.captainMachine;
if (!appName || !machineToDeploy) {
StdOutUtil_1.default.printError("Can't deploy: missing CapRover machine or app name.\n", true);
return false;
}
if ((branchToPush ? 1 : 0) +
(imageName ? 1 : 0) +
(tarFilePath ? 1 : 0) !==
1) {
StdOutUtil_1.default.printError("Can't deploy: only one of branch, tarFile or imageName can be present.\n", true);
return false;
}
let gitHash = '';
let tarFileCreatedByCli = false;
const tarFileNameToDeploy = tarFilePath
? tarFilePath
: 'temporary-captain-to-deploy.tar';
const tarFileFullPath = tarFileNameToDeploy.startsWith('/')
? tarFileNameToDeploy
: path.join(process.cwd(), tarFileNameToDeploy);
if (branchToPush) {
tarFileCreatedByCli = true;
StdOutUtil_1.default.printMessage(`Saving tar file to: "${tarFileFullPath}"`);
gitHash = yield this.gitArchiveFile(tarFileFullPath, branchToPush);
}
StdOutUtil_1.default.printMessage(`Deploying ${StdOutUtil_1.default.getColoredAppName(appName)} to ${machineToDeploy.name
? StdOutUtil_1.default.getColoredMachineName(machineToDeploy.name)
: StdOutUtil_1.default.getColoredMachineUrl(machineToDeploy.baseUrl)}...\n`);
try {
if (imageName) {
yield CliApiManager_1.default.get(machineToDeploy).uploadCaptainDefinitionContent(appName, { schemaVersion: 2, imageName }, '', true);
}
else {
yield CliApiManager_1.default.get(machineToDeploy).uploadAppData(appName, this.getFileStream(tarFileFullPath), gitHash);
}
StdOutUtil_1.default.printMessage('Building your source code...\n');
if (machineToDeploy.appToken) {
StdOutUtil_1.default.printMessage(`Deploying ${StdOutUtil_1.default.getColoredAppName(appName)} using app token is in progress. Build logs aren't retrieved when using app token.\nWait a few minutes until your app is built and deployed`);
}
else {
this.startFetchingBuildLogs(machineToDeploy, appName);
}
return true;
}
catch (e) {
throw e;
}
finally {
if (tarFileCreatedByCli && fs.pathExistsSync(tarFileFullPath)) {
fs.removeSync(tarFileFullPath);
}
}
});
}
gitArchiveFile(zipFileFullPath, branchToPush) {
return new Promise(function (resolve, reject) {
if (fs.pathExistsSync(zipFileFullPath)) {
fs.removeSync(zipFileFullPath);
} // Removes the temporary file created
child_process_1.exec(`git archive --format tar --output "${zipFileFullPath}" ${branchToPush}`, (error, stdout1, stderr1) => {
if (error) {
StdOutUtil_1.default.printError(`TAR file failed.\n${error}\n`);
if (fs.pathExistsSync(zipFileFullPath)) {
fs.removeSync(zipFileFullPath);
}
reject(new Error('TAR file failed'));
return;
}
child_process_1.exec(`git rev-parse ${branchToPush}`, (err, stdout2, stderr2) => {
const gitHash = (stdout2 || '').trim();
if (err || !/^[a-f0-9]{40}$/.test(gitHash)) {
StdOutUtil_1.default.printError(`Cannot find hash of last commit on branch "${branchToPush}": ${gitHash}\n${err}\n`);
if (fs.pathExistsSync(zipFileFullPath)) {
fs.removeSync(zipFileFullPath);
}
reject(new Error('rev-parse failed'));
return;
}
StdOutUtil_1.default.printMessage(`Using last commit on "${branchToPush}": ${gitHash}\n`);
resolve(gitHash);
});
});
});
}
getFileStream(zipFileFullPath) {
const fileSize = fs.statSync(zipFileFullPath).size;
const fileStream = fs.createReadStream(zipFileFullPath);
const barOpts = { width: 20, total: fileSize, clear: false };
const bar = new ProgressBar('Uploading [:bar] :percent (ETA :etas)', barOpts);
fileStream.on('data', chunk => bar.tick(chunk.length));
fileStream.on('end', () => {
StdOutUtil_1.default.printGreenMessage(`Upload done.\n`);
StdOutUtil_1.default.printMessage('This might take several minutes. PLEASE BE PATIENT...\n');
});
return fileStream;
}
onLogRetrieved(data, machineToDeploy, appName) {
return __awaiter(this, void 0, void 0, function* () {
if (data) {
const lines = data.logs.lines;
const firstLineNumberOfLogs = data.logs.firstLineNumber;
let firstLinesToPrint = 0;
if (firstLineNumberOfLogs > this.lastLineNumberPrinted) {
if (firstLineNumberOfLogs < 0) {
// This is the very first fetch, probably firstLineNumberOfLogs is around -50
firstLinesToPrint = -firstLineNumberOfLogs;
}
else {
StdOutUtil_1.default.printMessage('[[ TRUNCATED ]]');
}
}
else {
firstLinesToPrint =
this.lastLineNumberPrinted - firstLineNumberOfLogs;
}
this.lastLineNumberPrinted = firstLineNumberOfLogs + lines.length;
for (let i = firstLinesToPrint; i < lines.length; i++) {
StdOutUtil_1.default.printMessage((lines[i] || '').trim());
}
}
if (data && !data.isAppBuilding) {
if (!data.isBuildFailed) {
let appUrl = machineToDeploy.baseUrl
.replace('https://', 'http://')
.replace('//captain.', `//${appName}.`);
if (this.ssl) {
appUrl = appUrl.replace('http://', 'https://');
}
StdOutUtil_1.default.printGreenMessage(`\nDeployed successfully ${StdOutUtil_1.default.getColoredAppName(appName)}`);
StdOutUtil_1.default.printGreenMessage(`App is available at ${StdOutUtil_1.default.getColoredMachineUrl(appUrl)}\n`, true);
}
else {
StdOutUtil_1.default.printError(`\nSomething bad happened. Cannot deploy ${StdOutUtil_1.default.getColoredAppName(appName)} at ${StdOutUtil_1.default.getColoredMachineName(machineToDeploy.name || machineToDeploy.baseUrl)}.\n`, true);
}
}
else {
setTimeout(() => this.startFetchingBuildLogs(machineToDeploy, appName), 2000);
}
});
}
startFetchingBuildLogs(machineToDeploy, appName) {
return __awaiter(this, void 0, void 0, function* () {
try {
const data = yield CliApiManager_1.default.get(machineToDeploy).fetchBuildLogs(appName);
this.onLogRetrieved(data, machineToDeploy, appName);
}
catch (error) {
StdOutUtil_1.default.printError(`\nSomething bad happened while retrieving ${StdOutUtil_1.default.getColoredAppName(appName)} app build logs.\n${error.message || error}\n`);
this.onLogRetrieved(undefined, machineToDeploy, appName);
}
});
}
}
exports.default = DeployHelper;
//# sourceMappingURL=DeployHelper.js.map