UNPKG

@devmn/cloud-cli

Version:

CLI tool for Intelligo Cloud.

182 lines 9.56 kB
"use strict"; 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