mirror of
https://github.com/caprover/caprover
synced 2026-08-01 13:20:57 +00:00
ServiceManager Migrated
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const jwt = require("jsonwebtoken");
|
||||
const uuid = require("uuid/v4");
|
||||
const bcrypt = require("bcryptjs");
|
||||
@@ -148,10 +147,7 @@ class Authenticator {
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const authenticatorCache = {};
|
||||
exports = {
|
||||
get: function (namespace) {
|
||||
static get(namespace) {
|
||||
if (!namespace) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -162,6 +158,8 @@ exports = {
|
||||
}
|
||||
}
|
||||
return authenticatorCache[namespace];
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
const authenticatorCache = {};
|
||||
module.exports = Authenticator;
|
||||
//# sourceMappingURL=Authenticator.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,32 +1,34 @@
|
||||
const CaptainConstants = require('../utils/CaptainConstants');
|
||||
const Logger = require('../utils/Logger');
|
||||
const fs = require('fs-extra');
|
||||
const tar = require('tar');
|
||||
const path = require('path');
|
||||
const CaptainManager = require('./CaptainManager');
|
||||
const ApiStatusCodes = require('../api/ApiStatusCodes');
|
||||
const TemplateHelper = require('./TemplateHelper');
|
||||
const Authenticator = require('./Authenticator');
|
||||
const GitHelper = require('../utils/GitHelper');
|
||||
const uuid = require('uuid/v4');
|
||||
const requireFromString = require('require-from-string');
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const CaptainConstants = require("../utils/CaptainConstants");
|
||||
const Logger = require("../utils/Logger");
|
||||
const fs = require("fs-extra");
|
||||
const tar = require("tar");
|
||||
const path = require("path");
|
||||
const CaptainManager = require("./CaptainManager");
|
||||
const ApiStatusCodes = require("../api/ApiStatusCodes");
|
||||
const TemplateHelper = require("./TemplateHelper");
|
||||
const Authenticator = require("./Authenticator");
|
||||
const GitHelper = require("../utils/GitHelper");
|
||||
const uuid = require("uuid/v4");
|
||||
const requireFromString = require("require-from-string");
|
||||
const BUILD_LOG_SIZE = 50;
|
||||
const SOURCE_FOLDER_NAME = 'src';
|
||||
const DOCKER_FILE = 'Dockerfile';
|
||||
const CAPTAIN_DEFINITION_FILE = 'captain-definition';
|
||||
const PLACEHOLDER_DOCKER_FILE_CONTENT = 'FROM ' + CaptainConstants.appPlaceholderImageName +
|
||||
const SOURCE_FOLDER_NAME = "src";
|
||||
const DOCKER_FILE = "Dockerfile";
|
||||
const CAPTAIN_DEFINITION_FILE = "captain-definition";
|
||||
const PLACEHOLDER_DOCKER_FILE_CONTENT = "FROM " + CaptainConstants.appPlaceholderImageName +
|
||||
'\nCMD [ "npm", "start" ]';
|
||||
function getRawImageSourceFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainRawImagesDir + '/' + imageName + '/' + newVersionPulled + '/' + SOURCE_FOLDER_NAME;
|
||||
return CaptainConstants.captainRawImagesDir + "/" + imageName + "/" + newVersionPulled + "/" + SOURCE_FOLDER_NAME;
|
||||
}
|
||||
function getRawImageBaseFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainRawImagesDir + '/' + imageName + '/' + newVersionPulled;
|
||||
return CaptainConstants.captainRawImagesDir + "/" + imageName + "/" + newVersionPulled;
|
||||
}
|
||||
function getTarImageBaseFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainTarImagesDir + '/' + imageName + '/' + newVersionPulled;
|
||||
return CaptainConstants.captainTarImagesDir + "/" + imageName + "/" + newVersionPulled;
|
||||
}
|
||||
function getCaptainDefinitionTempFolder(serviceName, randomSuffix) {
|
||||
return CaptainConstants.captainDefinitionTempDir + '/' + serviceName + '/' + randomSuffix;
|
||||
return CaptainConstants.captainDefinitionTempDir + "/" + serviceName + "/" + randomSuffix;
|
||||
}
|
||||
class BuildLog {
|
||||
constructor(size) {
|
||||
@@ -34,8 +36,8 @@ class BuildLog {
|
||||
this.clear();
|
||||
}
|
||||
onBuildFailed(error) {
|
||||
this.log('----------------------');
|
||||
this.log('Deploy failed!');
|
||||
this.log("----------------------");
|
||||
this.log("Deploy failed!");
|
||||
this.log(error);
|
||||
this.isBuildFailed = true;
|
||||
}
|
||||
@@ -44,11 +46,11 @@ class BuildLog {
|
||||
this.firstLineNumber = -this.size;
|
||||
this.lines = [];
|
||||
for (let i = 0; i < this.size; i++) {
|
||||
this.lines.push('');
|
||||
this.lines.push("");
|
||||
}
|
||||
}
|
||||
log(msg) {
|
||||
msg = (msg || '') + '';
|
||||
msg = (msg || "") + "";
|
||||
this.lines.shift();
|
||||
this.lines.push(msg);
|
||||
this.firstLineNumber++;
|
||||
@@ -65,6 +67,9 @@ class BuildLog {
|
||||
}
|
||||
class ServiceManager {
|
||||
constructor(user, dockerApi, loadBalancerManager) {
|
||||
this.user = user;
|
||||
this.dockerApi = dockerApi;
|
||||
this.loadBalancerManager = loadBalancerManager;
|
||||
this.user = user;
|
||||
this.dataStore = user.dataStore;
|
||||
this.dockerApi = dockerApi;
|
||||
@@ -77,12 +82,12 @@ class ServiceManager {
|
||||
return this.isReady;
|
||||
}
|
||||
createTarFarFromCaptainContent(captainDefinitionContent, appName, tarDestination) {
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
let captainDefinitionDirPath;
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
let captainDefinitionDirPath = undefined;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
let temp = getCaptainDefinitionTempFolder(serviceName, uuid());
|
||||
const temp = getCaptainDefinitionTempFolder(serviceName, uuid());
|
||||
if (!fs.pathExistsSync(temp)) {
|
||||
captainDefinitionDirPath = temp;
|
||||
break;
|
||||
@@ -91,7 +96,7 @@ class ServiceManager {
|
||||
if (!captainDefinitionDirPath) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Cannot create a temp file! Something is seriously wrong with the temp folder");
|
||||
}
|
||||
return fs.outputFile(captainDefinitionDirPath + '/' + CAPTAIN_DEFINITION_FILE, captainDefinitionContent);
|
||||
return fs.outputFile(captainDefinitionDirPath + "/" + CAPTAIN_DEFINITION_FILE, captainDefinitionContent);
|
||||
})
|
||||
.then(function () {
|
||||
return tar.c({
|
||||
@@ -100,6 +105,9 @@ class ServiceManager {
|
||||
}, [CAPTAIN_DEFINITION_FILE]);
|
||||
})
|
||||
.then(function () {
|
||||
if (!captainDefinitionDirPath) {
|
||||
throw new Error("captainDefinitionDirPath is NULL");
|
||||
}
|
||||
return fs.remove(captainDefinitionDirPath);
|
||||
});
|
||||
}
|
||||
@@ -114,22 +122,22 @@ class ServiceManager {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
createImage(appName, source, gitHash) {
|
||||
Logger.d('Creating image for: ' + appName);
|
||||
Logger.d("Creating image for: " + appName);
|
||||
const self = this;
|
||||
let imageName = this.dataStore.getImageName(CaptainManager.get().getDockerAuthObject(), appName);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let newVersion = null;
|
||||
let rawImageSourceFolder = null;
|
||||
let rawImageBaseFolder = null;
|
||||
let tarImageBaseFolder = null;
|
||||
let tarballFilePath = null;
|
||||
let dockerFilePath = null;
|
||||
const imageName = this.dataStore.getImageName(CaptainManager.get().getDockerAuthObject(), appName);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let newVersion;
|
||||
let rawImageSourceFolder;
|
||||
let rawImageBaseFolder;
|
||||
let tarImageBaseFolder;
|
||||
let tarballFilePath;
|
||||
let dockerFilePath;
|
||||
this.activeBuilds[appName] = true;
|
||||
this.buildLogs[appName] = this.buildLogs[appName] || new BuildLog(BUILD_LOG_SIZE);
|
||||
this.buildLogs[appName].clear();
|
||||
this.buildLogs[appName].log('------------------------- ' + (new Date()));
|
||||
this.buildLogs[appName].log('Build started for ' + appName);
|
||||
this.buildLogs[appName].log("------------------------- " + (new Date()));
|
||||
this.buildLogs[appName].log("Build started for " + appName);
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return dataStore.getAppsDataStore().getNewVersion(appName);
|
||||
@@ -138,16 +146,16 @@ class ServiceManager {
|
||||
newVersion = newVersionPulled;
|
||||
rawImageSourceFolder = getRawImageSourceFolder(imageName, newVersionPulled);
|
||||
rawImageBaseFolder = getRawImageBaseFolder(imageName, newVersionPulled);
|
||||
dockerFilePath = rawImageBaseFolder + '/' + DOCKER_FILE;
|
||||
dockerFilePath = rawImageBaseFolder + "/" + DOCKER_FILE;
|
||||
tarImageBaseFolder = getTarImageBaseFolder(imageName, newVersionPulled);
|
||||
tarballFilePath = tarImageBaseFolder + '/image.tar';
|
||||
tarballFilePath = tarImageBaseFolder + "/image.tar";
|
||||
return fs.ensureDir(rawImageSourceFolder)
|
||||
.then(function () {
|
||||
return rawImageSourceFolder;
|
||||
});
|
||||
})
|
||||
.then(function (rawImageSourceFolder) {
|
||||
let promiseToFetchDirectory = null;
|
||||
let promiseToFetchDirectory;
|
||||
if (source.pathToSrcTarballFile) {
|
||||
promiseToFetchDirectory = tar
|
||||
.x({
|
||||
@@ -159,7 +167,7 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
else if (source.repoInfo) {
|
||||
let repoInfo = source.repoInfo;
|
||||
const repoInfo = source.repoInfo;
|
||||
promiseToFetchDirectory = GitHelper
|
||||
.clone(repoInfo.user, repoInfo.password, repoInfo.repo, repoInfo.branch, rawImageSourceFolder)
|
||||
.then(function () {
|
||||
@@ -174,18 +182,18 @@ class ServiceManager {
|
||||
return dataStore.getAppsDataStore().setGitHash(appName, newVersion, gitHashToSave);
|
||||
})
|
||||
.then(function () {
|
||||
return fs.pathExists(rawImageSourceFolder + '/' + CAPTAIN_DEFINITION_FILE);
|
||||
return fs.pathExists(rawImageSourceFolder + "/" + CAPTAIN_DEFINITION_FILE);
|
||||
})
|
||||
.then(function (exists) {
|
||||
if (!exists) {
|
||||
Logger.d('Captain Definition does not exist in the base tar. Looking inside...');
|
||||
Logger.d("Captain Definition does not exist in the base tar. Looking inside...");
|
||||
// check if there is only one child
|
||||
// check if it's a directory
|
||||
// check if captain definition exists in it
|
||||
// rename rawImageSourceFolder to rawImageSourceFolder+'.bak'
|
||||
// move the child directory out to base and rename it to rawImageSourceFolder
|
||||
// read captain definition from the folder and return it.
|
||||
let directoryInside = null;
|
||||
let directoryInside;
|
||||
return new Promise(function (resolve, reject) {
|
||||
fs.readdir(rawImageSourceFolder, function (err, files) {
|
||||
if (err) {
|
||||
@@ -207,14 +215,14 @@ class ServiceManager {
|
||||
if (!captainDefinitionExists) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Captain Definition file does not exist!");
|
||||
}
|
||||
const BAK = '.bak';
|
||||
const BAK = ".bak";
|
||||
fs.renameSync(rawImageSourceFolder, rawImageSourceFolder + BAK);
|
||||
fs.renameSync(path.join(rawImageSourceFolder + BAK, directoryInside), rawImageSourceFolder);
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
return fs.readJson(rawImageSourceFolder + '/' + CAPTAIN_DEFINITION_FILE);
|
||||
return fs.readJson(rawImageSourceFolder + "/" + CAPTAIN_DEFINITION_FILE);
|
||||
})
|
||||
.then(function (data) {
|
||||
if (!data) {
|
||||
@@ -224,11 +232,11 @@ class ServiceManager {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Captain Definition version is empty!");
|
||||
}
|
||||
if (data.schemaVersion === 1) {
|
||||
let templateIdTag = data.templateId;
|
||||
let dockerfileLines = data.dockerfileLines;
|
||||
let hasDockerfileLines = dockerfileLines && dockerfileLines.length > 0;
|
||||
const templateIdTag = data.templateId;
|
||||
const dockerfileLines = data.dockerfileLines;
|
||||
const hasDockerfileLines = dockerfileLines && dockerfileLines.length > 0;
|
||||
if (hasDockerfileLines && !templateIdTag) {
|
||||
return dockerfileLines.join('\n');
|
||||
return dockerfileLines.join("\n");
|
||||
}
|
||||
else if (!hasDockerfileLines && templateIdTag) {
|
||||
return TemplateHelper.get().getDockerfileContentFromTemplateTag(templateIdTag);
|
||||
@@ -258,30 +266,30 @@ class ServiceManager {
|
||||
return dockerApi
|
||||
.buildImageFromDockerFile(imageName, newVersion, tarballFilePath, self.buildLogs[appName])
|
||||
.catch(function (error) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ('' + error).trim());
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ("" + error).trim());
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
Logger.d('Cleaning up up the files... ' + tarImageBaseFolder + ' and ' + rawImageBaseFolder);
|
||||
Logger.d("Cleaning up up the files... " + tarImageBaseFolder + " and " + rawImageBaseFolder);
|
||||
return fs.remove(tarImageBaseFolder);
|
||||
})
|
||||
.then(function () {
|
||||
return fs.remove(rawImageBaseFolder);
|
||||
})
|
||||
.then(function () {
|
||||
let authObj = CaptainManager.get().getDockerAuthObject();
|
||||
const authObj = CaptainManager.get().getDockerAuthObject();
|
||||
if (!authObj) {
|
||||
Logger.d('No Docker Auth is found. Skipping pushing the image.');
|
||||
Logger.d("No Docker Auth is found. Skipping pushing the image.");
|
||||
return true;
|
||||
}
|
||||
Logger.d('Docker Auth is found. Pushing the image...');
|
||||
Logger.d("Docker Auth is found. Pushing the image...");
|
||||
return dockerApi
|
||||
.pushImage(imageName, newVersion, authObj, self.buildLogs[appName])
|
||||
.catch(function (error) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
Logger.e('PUSH FAILED');
|
||||
Logger.e("PUSH FAILED");
|
||||
Logger.e(error);
|
||||
reject(ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Push failed: ' + error));
|
||||
reject(ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Push failed: " + error));
|
||||
});
|
||||
});
|
||||
})
|
||||
@@ -300,14 +308,14 @@ class ServiceManager {
|
||||
const self = this;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
Logger.d('Verifying Captain owns domain: ' + customDomain);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(customDomain);
|
||||
Logger.d("Verifying Captain owns domain: " + customDomain);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(customDomain, undefined);
|
||||
})
|
||||
.then(function () {
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
Logger.d('Enabling SSL for: ' + appName + ' on ' + customDomain);
|
||||
Logger.d("Enabling SSL for: " + appName + " on " + customDomain);
|
||||
return self.dataStore.getAppsDataStore().verifyCustomDomainBelongsToApp(appName, customDomain);
|
||||
})
|
||||
.then(function () {
|
||||
@@ -324,20 +332,20 @@ class ServiceManager {
|
||||
const self = this;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
let rootDomain = self.dataStore.getRootDomain();
|
||||
let dotRootDomain = "." + rootDomain;
|
||||
const rootDomain = self.dataStore.getRootDomain();
|
||||
const dotRootDomain = "." + rootDomain;
|
||||
if (!customDomain || !(/^[a-z0-9\-\.]+$/.test(customDomain))) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, 'Domain name is not accepted. Please use alphanumerical domains such as myapp.google123.ca');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, "Domain name is not accepted. Please use alphanumerical domains such as myapp.google123.ca");
|
||||
}
|
||||
if (customDomain.length > 80) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, 'Domain name is not accepted. Please use alphanumerical domains less than 80 characters in length.');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, "Domain name is not accepted. Please use alphanumerical domains less than 80 characters in length.");
|
||||
}
|
||||
if (customDomain.indexOf('..') >= 0) {
|
||||
if (customDomain.indexOf("..") >= 0) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, 'Domain name is not accepted. You cannot have two consecutive periods ".." inside a domain name. Please use alphanumerical domains such as myapp.google123.ca');
|
||||
}
|
||||
if (customDomain.indexOf(dotRootDomain) >= 0 &&
|
||||
(customDomain.indexOf(dotRootDomain) + dotRootDomain.length) === customDomain.length) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, 'Domain name is not accepted. Custom domain cannot be subdomain of root domain.');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME, "Domain name is not accepted. Custom domain cannot be subdomain of root domain.");
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
@@ -345,9 +353,9 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
Logger.d('Enabling custom domain for: ' + appName);
|
||||
Logger.d("Enabling custom domain for: " + appName);
|
||||
return self.dataStore.getAppsDataStore().addCustomDomainForApp(appName, customDomain);
|
||||
})
|
||||
.then(function () {
|
||||
@@ -359,9 +367,9 @@ class ServiceManager {
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
Logger.d('Removing custom domain for: ' + appName);
|
||||
Logger.d("Removing custom domain for: " + appName);
|
||||
return self.dataStore.getAppsDataStore().removeCustomDomainForApp(appName, customDomain);
|
||||
})
|
||||
.then(function () {
|
||||
@@ -370,23 +378,22 @@ class ServiceManager {
|
||||
}
|
||||
enableSslForApp(appName) {
|
||||
const self = this;
|
||||
let rootDomain = null;
|
||||
let app = null;
|
||||
let rootDomain;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return self.verifyCaptainOwnsGenericSubDomain(appName);
|
||||
})
|
||||
.then(function () {
|
||||
Logger.d('Enabling SSL for: ' + appName);
|
||||
Logger.d("Enabling SSL for: " + appName);
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
return self.dataStore.getRootDomain();
|
||||
})
|
||||
.then(function (val) {
|
||||
rootDomain = val;
|
||||
if (!rootDomain) {
|
||||
throw new Error('No rootDomain! Cannot verify domain');
|
||||
throw new Error("No rootDomain! Cannot verify domain");
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
@@ -394,7 +401,7 @@ class ServiceManager {
|
||||
return self.dataStore.getAppsDataStore().getAppDefinition(appName);
|
||||
})
|
||||
.then(function () {
|
||||
return appName + '.' + rootDomain;
|
||||
return appName + "." + rootDomain;
|
||||
})
|
||||
.then(function (domainName) {
|
||||
return CaptainManager.get().requestCertificateForDomain(domainName);
|
||||
@@ -408,11 +415,11 @@ class ServiceManager {
|
||||
}
|
||||
verifyCaptainOwnsGenericSubDomain(appName) {
|
||||
const self = this;
|
||||
let rootDomain = null;
|
||||
let rootDomain;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
return self.dataStore.getRootDomain();
|
||||
})
|
||||
@@ -424,22 +431,22 @@ class ServiceManager {
|
||||
return self.dataStore.getAppsDataStore().getAppDefinition(appName);
|
||||
})
|
||||
.then(function () {
|
||||
return appName + '.' + rootDomain;
|
||||
return appName + "." + rootDomain;
|
||||
})
|
||||
.then(function (domainName) {
|
||||
Logger.d('Verifying Captain owns domain: ' + domainName);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(domainName);
|
||||
Logger.d("Verifying Captain owns domain: " + domainName);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(domainName, undefined);
|
||||
});
|
||||
}
|
||||
removeApp(appName) {
|
||||
Logger.d('Removing service for: ' + appName);
|
||||
Logger.d("Removing service for: " + appName);
|
||||
const self = this;
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
Logger.d('Check if service is running: ' + serviceName);
|
||||
Logger.d("Check if service is running: " + serviceName);
|
||||
return dockerApi
|
||||
.isServiceRunningByName(serviceName);
|
||||
})
|
||||
@@ -449,7 +456,7 @@ class ServiceManager {
|
||||
.removeService(serviceName);
|
||||
}
|
||||
else {
|
||||
Logger.w('Cannot delete service... It is not running: ' + serviceName);
|
||||
Logger.w("Cannot delete service... It is not running: " + serviceName);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
@@ -461,11 +468,11 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
getUnusedImages(mostRecentLimit) {
|
||||
Logger.d('Getting unused images, excluding most recent ones: ' + mostRecentLimit);
|
||||
Logger.d("Getting unused images, excluding most recent ones: " + mostRecentLimit);
|
||||
const self = this;
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let allImages = null;
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let allImages;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return dockerApi
|
||||
@@ -476,7 +483,7 @@ class ServiceManager {
|
||||
return dataStore.getAppsDataStore().getAppDefinitions();
|
||||
})
|
||||
.then(function (apps) {
|
||||
let unusedImages = [];
|
||||
const unusedImages = [];
|
||||
for (let i = 0; i < allImages.length; i++) {
|
||||
const img = allImages[i];
|
||||
let imageInUse = false;
|
||||
@@ -484,7 +491,7 @@ class ServiceManager {
|
||||
for (let j = 0; j < img.RepoTags.length; j++) {
|
||||
const repoTag = img.RepoTags[j];
|
||||
Object.keys(apps).forEach(function (key, index) {
|
||||
let app = apps[key];
|
||||
const app = apps[key];
|
||||
app.appName = key;
|
||||
for (let k = 0; k < (mostRecentLimit + 1); k++) {
|
||||
if (repoTag.indexOf(dataStore.getImageNameWithoutAuthObj(app.appName, Number(app.deployedVersion) - k)) >= 0) {
|
||||
@@ -497,7 +504,7 @@ class ServiceManager {
|
||||
if (!imageInUse) {
|
||||
unusedImages.push({
|
||||
id: img.Id,
|
||||
description: (img.RepoTags && img.RepoTags.length) ? img.RepoTags[0] : 'untagged'
|
||||
description: (img.RepoTags && img.RepoTags.length) ? img.RepoTags[0] : "untagged"
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -505,11 +512,9 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
deleteImages(imageIds) {
|
||||
Logger.d('Deleting images...');
|
||||
Logger.d("Deleting images...");
|
||||
const self = this;
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let allImages = null;
|
||||
const dockerApi = this.dockerApi;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return dockerApi
|
||||
@@ -517,44 +522,43 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
ensureServiceInitedAndUpdated(appName, version) {
|
||||
Logger.d('Ensure service inited and Updated for: ' + appName);
|
||||
Logger.d("Ensure service inited and Updated for: " + appName);
|
||||
const self = this;
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerAuthObject = CaptainManager.get().getDockerAuthObject();
|
||||
let imageName = this.dataStore.getImageName(dockerAuthObject, appName, version);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let app = null;
|
||||
const imageName = this.dataStore.getImageName(dockerAuthObject, appName, version);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let app;
|
||||
return dataStore.getAppsDataStore().setDeployedVersion(appName, version)
|
||||
.then(function () {
|
||||
return dataStore.getAppsDataStore().getAppDefinition(appName);
|
||||
})
|
||||
.then(function (appFound) {
|
||||
app = appFound;
|
||||
Logger.d('Check if service is running: ' + serviceName);
|
||||
Logger.d("Check if service is running: " + serviceName);
|
||||
return dockerApi
|
||||
.isServiceRunningByName(serviceName);
|
||||
})
|
||||
.then(function (isRunning) {
|
||||
if (isRunning) {
|
||||
Logger.d('Service is already running: ' + serviceName);
|
||||
Logger.d("Service is already running: " + serviceName);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Logger.d('Creating service: ' + serviceName + ' with image: ' + imageName);
|
||||
Logger.d("Creating service: " + serviceName + " with image: " + imageName);
|
||||
// if we pass in networks here. Almost always it results in a delayed update which causes
|
||||
// update errors if they happen right away!
|
||||
return dockerApi
|
||||
.createServiceOnNodeId(imageName, serviceName);
|
||||
.createServiceOnNodeId(imageName, serviceName, undefined, undefined, undefined, undefined, undefined);
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
return self.createPreDeployFunctionIfExist(app);
|
||||
})
|
||||
.then(function (preDeployFunction) {
|
||||
Logger.d('Updating service: ' + serviceName + ' with image: ' + imageName);
|
||||
return dockerApi
|
||||
.updateService(serviceName, imageName, app.volumes, app.networks, app.envVars, null, dockerAuthObject, Number(app.instanceCount), app.nodeId, dataStore.getNameSpace(), app, preDeployFunction);
|
||||
Logger.d("Updating service: " + serviceName + " with image: " + imageName);
|
||||
return dockerApi.updateService(serviceName, imageName, app.volumes, app.networks, app.envVars, undefined, dockerAuthObject, Number(app.instanceCount), app.nodeId, dataStore.getNameSpace(), undefined, app, preDeployFunction);
|
||||
})
|
||||
.then(function () {
|
||||
return new Promise(function (resolve) {
|
||||
@@ -569,7 +573,7 @@ class ServiceManager {
|
||||
createPreDeployFunctionIfExist(app) {
|
||||
let preDeployFunction = app.preDeployFunction;
|
||||
if (!preDeployFunction) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
/*
|
||||
////////////////////////////////// Expected content of the file //////////////////////////
|
||||
@@ -585,15 +589,15 @@ class ServiceManager {
|
||||
});
|
||||
};
|
||||
*/
|
||||
preDeployFunction = preDeployFunction + '\n\n module.exports = preDeployFunction';
|
||||
preDeployFunction = preDeployFunction + "\n\n module.exports = preDeployFunction";
|
||||
return requireFromString(preDeployFunction);
|
||||
}
|
||||
updateAppDefinition(appName, instanceCount, envVars, volumes, nodeId, notExposeAsWebApp, forceSsl, ports, appPushWebhook, customNginxConfig, preDeployFunction) {
|
||||
const self = this;
|
||||
const dataStore = this.dataStore;
|
||||
const dockerApi = this.dockerApi;
|
||||
let serviceName = null;
|
||||
let checkIfNodeIdExists = function (nodeIdToCheck) {
|
||||
let serviceName;
|
||||
const checkIfNodeIdExists = function (nodeIdToCheck) {
|
||||
return dockerApi
|
||||
.getNodesInfo()
|
||||
.then(function (nodeInfo) {
|
||||
@@ -666,13 +670,13 @@ class ServiceManager {
|
||||
* @returns the active build that it finds
|
||||
*/
|
||||
isAnyBuildRunning() {
|
||||
let activeBuilds = this.activeBuilds;
|
||||
for (let appName in activeBuilds) {
|
||||
const activeBuilds = this.activeBuilds;
|
||||
for (const appName in activeBuilds) {
|
||||
if (!!activeBuilds[appName]) {
|
||||
return appName;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
getBuildStatus(appName) {
|
||||
const self = this;
|
||||
@@ -684,17 +688,17 @@ class ServiceManager {
|
||||
};
|
||||
}
|
||||
logBuildFailed(appName, error) {
|
||||
error = (error || '') + '';
|
||||
error = (error || "") + "";
|
||||
this.buildLogs[appName] = this.buildLogs[appName] || new BuildLog(BUILD_LOG_SIZE);
|
||||
this.buildLogs[appName].onBuildFailed(error);
|
||||
}
|
||||
updateServiceOnDefinitionUpdate(appName) {
|
||||
const self = this;
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerAuthObject = CaptainManager.get().getDockerAuthObject();
|
||||
const dataStore = this.dataStore;
|
||||
const dockerApi = this.dockerApi;
|
||||
let appFound = null;
|
||||
let appFound;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return dataStore.getAppsDataStore().getAppDefinition(appName);
|
||||
@@ -702,24 +706,24 @@ class ServiceManager {
|
||||
.then(function (app) {
|
||||
appFound = app;
|
||||
if (!appFound) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'App name not found!');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "App name not found!");
|
||||
}
|
||||
return self.createPreDeployFunctionIfExist(app);
|
||||
})
|
||||
.then(function (preDeployFunction) {
|
||||
if (!appFound) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'App name not found!');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "App name not found!");
|
||||
}
|
||||
return dockerApi
|
||||
.updateService(serviceName, null, appFound.volumes, appFound.networks, appFound.envVars, null, dockerAuthObject, Number(appFound.instanceCount), appFound.nodeId, dataStore.getNameSpace(), appFound.ports, appFound, preDeployFunction);
|
||||
.updateService(serviceName, undefined, appFound.volumes, appFound.networks, appFound.envVars, undefined, dockerAuthObject, Number(appFound.instanceCount), appFound.nodeId, dataStore.getNameSpace(), appFound.ports, appFound, preDeployFunction);
|
||||
});
|
||||
}
|
||||
reloadLoadBalancer() {
|
||||
Logger.d('Updating Load Balancer');
|
||||
Logger.d("Updating Load Balancer");
|
||||
const self = this;
|
||||
return self.loadBalancerManager.rePopulateNginxConfigFile(self.dataStore)
|
||||
.then(function () {
|
||||
Logger.d('sendReloadSignal...');
|
||||
Logger.d("sendReloadSignal...");
|
||||
return self.loadBalancerManager.sendReloadSignal();
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Generated
+13
@@ -97,6 +97,11 @@
|
||||
"@types/tough-cookie": "*"
|
||||
}
|
||||
},
|
||||
"@types/require-from-string": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/require-from-string/-/require-from-string-1.2.0.tgz",
|
||||
"integrity": "sha512-5vE9WoOOC9/DoD3Zj53UISpM+5tSvh8k0mL4fe2zFI6vO715/W4IQ3EdVUrWVMrFi1/NZhyMvm2iKsDFkEGddQ=="
|
||||
},
|
||||
"@types/ssh2": {
|
||||
"version": "0.5.36",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.36.tgz",
|
||||
@@ -115,6 +120,14 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tar": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.0.tgz",
|
||||
"integrity": "sha512-YybbEHNngcHlIWVCYsoj7Oo1JU9JqONuAlt1LlTH/lmL8BMhbzdFUgReY87a05rY1j8mfK47Del+TCkaLAXwLw==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.4.tgz",
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
"@types/jsonwebtoken": "^8.3.0",
|
||||
"@types/request": "^2.48.1",
|
||||
"@types/require-from-string": "^1.2.0",
|
||||
"@types/ssh2": "^0.5.36",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@types/uuid": "^3.4.4",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"body-parser": "^1.18.3",
|
||||
|
||||
@@ -259,16 +259,8 @@ class Authenticator {
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface IHash {
|
||||
[details: string]: Authenticator;
|
||||
}
|
||||
|
||||
const authenticatorCache: IHash = {};
|
||||
|
||||
exports = {
|
||||
get: function(namespace: string): Authenticator | undefined {
|
||||
static get(namespace: string): Authenticator|undefined {
|
||||
if (!namespace) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -285,5 +277,13 @@ exports = {
|
||||
}
|
||||
|
||||
return authenticatorCache[namespace];
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface IHash {
|
||||
[details: string]: Authenticator;
|
||||
}
|
||||
|
||||
const authenticatorCache: IHash = {};
|
||||
|
||||
export = Authenticator;
|
||||
|
||||
@@ -875,7 +875,7 @@ class CaptainManager {
|
||||
*
|
||||
* @returns {Promise.<boolean>}
|
||||
*/
|
||||
verifyCaptainOwnsDomainOrThrow(domainName: string, identifierSuffix: string) {
|
||||
verifyCaptainOwnsDomainOrThrow(domainName: string, identifierSuffix: string|undefined) {
|
||||
|
||||
const self = this;
|
||||
const randomUuid = uuid();
|
||||
|
||||
@@ -1,50 +1,55 @@
|
||||
const CaptainConstants = require('../utils/CaptainConstants');
|
||||
const Logger = require('../utils/Logger');
|
||||
const fs = require('fs-extra');
|
||||
const tar = require('tar');
|
||||
const path = require('path');
|
||||
const CaptainManager = require('./CaptainManager');
|
||||
const ApiStatusCodes = require('../api/ApiStatusCodes');
|
||||
const TemplateHelper = require('./TemplateHelper');
|
||||
const Authenticator = require('./Authenticator');
|
||||
const GitHelper = require('../utils/GitHelper');
|
||||
const uuid = require('uuid/v4');
|
||||
const requireFromString = require('require-from-string');
|
||||
import CaptainConstants = require("../utils/CaptainConstants");
|
||||
import Logger = require("../utils/Logger");
|
||||
import fs = require("fs-extra");
|
||||
import tar = require("tar");
|
||||
import path = require("path");
|
||||
import CaptainManager = require("./CaptainManager");
|
||||
import LoadBalancerManager = require("./LoadBalancerManager");
|
||||
import DockerApi = require("../docker/DockerApi");
|
||||
import DataStore = require("../datastore/DataStoreImpl");
|
||||
import ApiStatusCodes = require("../api/ApiStatusCodes");
|
||||
import TemplateHelper = require("./TemplateHelper");
|
||||
import Authenticator = require("./Authenticator");
|
||||
import GitHelper = require("../utils/GitHelper");
|
||||
import uuid = require("uuid/v4");
|
||||
import requireFromString = require("require-from-string");
|
||||
|
||||
const BUILD_LOG_SIZE = 50;
|
||||
const SOURCE_FOLDER_NAME = 'src';
|
||||
const DOCKER_FILE = 'Dockerfile';
|
||||
const CAPTAIN_DEFINITION_FILE = 'captain-definition';
|
||||
const PLACEHOLDER_DOCKER_FILE_CONTENT = 'FROM ' + CaptainConstants.appPlaceholderImageName +
|
||||
const SOURCE_FOLDER_NAME = "src";
|
||||
const DOCKER_FILE = "Dockerfile";
|
||||
const CAPTAIN_DEFINITION_FILE = "captain-definition";
|
||||
const PLACEHOLDER_DOCKER_FILE_CONTENT = "FROM " + CaptainConstants.appPlaceholderImageName +
|
||||
'\nCMD [ "npm", "start" ]';
|
||||
|
||||
function getRawImageSourceFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainRawImagesDir + '/' + imageName + '/' + newVersionPulled + '/' + SOURCE_FOLDER_NAME;
|
||||
function getRawImageSourceFolder(imageName: string, newVersionPulled: string) {
|
||||
return CaptainConstants.captainRawImagesDir + "/" + imageName + "/" + newVersionPulled + "/" + SOURCE_FOLDER_NAME;
|
||||
}
|
||||
|
||||
function getRawImageBaseFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainRawImagesDir + '/' + imageName + '/' + newVersionPulled;
|
||||
function getRawImageBaseFolder(imageName: string, newVersionPulled: string) {
|
||||
return CaptainConstants.captainRawImagesDir + "/" + imageName + "/" + newVersionPulled;
|
||||
}
|
||||
|
||||
function getTarImageBaseFolder(imageName, newVersionPulled) {
|
||||
return CaptainConstants.captainTarImagesDir + '/' + imageName + '/' + newVersionPulled;
|
||||
function getTarImageBaseFolder(imageName: string, newVersionPulled: string) {
|
||||
return CaptainConstants.captainTarImagesDir + "/" + imageName + "/" + newVersionPulled;
|
||||
}
|
||||
|
||||
function getCaptainDefinitionTempFolder(serviceName, randomSuffix) {
|
||||
return CaptainConstants.captainDefinitionTempDir + '/' + serviceName + '/' + randomSuffix;
|
||||
function getCaptainDefinitionTempFolder(serviceName: string, randomSuffix: string) {
|
||||
return CaptainConstants.captainDefinitionTempDir + "/" + serviceName + "/" + randomSuffix;
|
||||
}
|
||||
|
||||
|
||||
class BuildLog {
|
||||
|
||||
constructor(size) {
|
||||
this.size = size;
|
||||
private isBuildFailed: boolean;
|
||||
private firstLineNumber: number;
|
||||
private lines: string[];
|
||||
constructor(private size: number) {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
onBuildFailed(error) {
|
||||
this.log('----------------------');
|
||||
this.log('Deploy failed!');
|
||||
onBuildFailed(error: string) {
|
||||
this.log("----------------------");
|
||||
this.log("Deploy failed!");
|
||||
this.log(error);
|
||||
this.isBuildFailed = true;
|
||||
}
|
||||
@@ -54,12 +59,12 @@ class BuildLog {
|
||||
this.firstLineNumber = -this.size;
|
||||
this.lines = [];
|
||||
for (let i = 0; i < this.size; i++) {
|
||||
this.lines.push('');
|
||||
this.lines.push("");
|
||||
}
|
||||
}
|
||||
|
||||
log(msg) {
|
||||
msg = (msg || '') + '';
|
||||
log(msg: string) {
|
||||
msg = (msg || "") + "";
|
||||
this.lines.shift();
|
||||
this.lines.push(msg);
|
||||
this.firstLineNumber++;
|
||||
@@ -79,7 +84,12 @@ class BuildLog {
|
||||
|
||||
class ServiceManager {
|
||||
|
||||
constructor(user, dockerApi, loadBalancerManager) {
|
||||
private dataStore: DataStore;
|
||||
private activeBuilds: any;
|
||||
private buildLogs: any;
|
||||
private isReady: boolean;
|
||||
|
||||
constructor(private user: any, private dockerApi: DockerApi, private loadBalancerManager: LoadBalancerManager) {
|
||||
this.user = user;
|
||||
this.dataStore = user.dataStore;
|
||||
this.dockerApi = dockerApi;
|
||||
@@ -95,17 +105,17 @@ class ServiceManager {
|
||||
return this.isReady;
|
||||
}
|
||||
|
||||
createTarFarFromCaptainContent(captainDefinitionContent, appName, tarDestination) {
|
||||
createTarFarFromCaptainContent(captainDefinitionContent: string, appName: string, tarDestination: string) {
|
||||
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
|
||||
let captainDefinitionDirPath;
|
||||
let captainDefinitionDirPath: string| undefined = undefined;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
let temp = getCaptainDefinitionTempFolder(serviceName, uuid());
|
||||
const temp = getCaptainDefinitionTempFolder(serviceName, uuid());
|
||||
if (!fs.pathExistsSync(temp)) {
|
||||
captainDefinitionDirPath = temp;
|
||||
break;
|
||||
@@ -116,7 +126,7 @@ class ServiceManager {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Cannot create a temp file! Something is seriously wrong with the temp folder");
|
||||
}
|
||||
|
||||
return fs.outputFile(captainDefinitionDirPath + '/' + CAPTAIN_DEFINITION_FILE, captainDefinitionContent);
|
||||
return fs.outputFile(captainDefinitionDirPath + "/" + CAPTAIN_DEFINITION_FILE, captainDefinitionContent);
|
||||
|
||||
})
|
||||
.then(function () {
|
||||
@@ -129,6 +139,10 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
if (!captainDefinitionDirPath) {
|
||||
throw new Error("captainDefinitionDirPath is NULL");
|
||||
}
|
||||
|
||||
return fs.remove(captainDefinitionDirPath);
|
||||
|
||||
});
|
||||
@@ -144,28 +158,28 @@ class ServiceManager {
|
||||
* @param gitHash
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
createImage(appName, source, gitHash) {
|
||||
createImage(appName: string, source: any, gitHash: string) {
|
||||
|
||||
Logger.d('Creating image for: ' + appName);
|
||||
Logger.d("Creating image for: " + appName);
|
||||
|
||||
const self = this;
|
||||
|
||||
let imageName = this.dataStore.getImageName(CaptainManager.get().getDockerAuthObject(), appName);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let newVersion = null;
|
||||
let rawImageSourceFolder = null;
|
||||
let rawImageBaseFolder = null;
|
||||
let tarImageBaseFolder = null;
|
||||
let tarballFilePath = null;
|
||||
let dockerFilePath = null;
|
||||
const imageName = this.dataStore.getImageName(CaptainManager.get().getDockerAuthObject(), appName);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let newVersion: number;
|
||||
let rawImageSourceFolder: string;
|
||||
let rawImageBaseFolder: string;
|
||||
let tarImageBaseFolder: string;
|
||||
let tarballFilePath: string;
|
||||
let dockerFilePath: string;
|
||||
|
||||
this.activeBuilds[appName] = true;
|
||||
this.buildLogs[appName] = this.buildLogs[appName] || new BuildLog(BUILD_LOG_SIZE);
|
||||
|
||||
this.buildLogs[appName].clear();
|
||||
this.buildLogs[appName].log('------------------------- ' + (new Date()));
|
||||
this.buildLogs[appName].log('Build started for ' + appName);
|
||||
this.buildLogs[appName].log("------------------------- " + (new Date()));
|
||||
this.buildLogs[appName].log("Build started for " + appName);
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
@@ -179,20 +193,20 @@ class ServiceManager {
|
||||
|
||||
rawImageSourceFolder = getRawImageSourceFolder(imageName, newVersionPulled);
|
||||
rawImageBaseFolder = getRawImageBaseFolder(imageName, newVersionPulled);
|
||||
dockerFilePath = rawImageBaseFolder + '/' + DOCKER_FILE;
|
||||
dockerFilePath = rawImageBaseFolder + "/" + DOCKER_FILE;
|
||||
|
||||
tarImageBaseFolder = getTarImageBaseFolder(imageName, newVersionPulled);
|
||||
tarballFilePath = tarImageBaseFolder + '/image.tar';
|
||||
tarballFilePath = tarImageBaseFolder + "/image.tar";
|
||||
|
||||
|
||||
return fs.ensureDir(rawImageSourceFolder)
|
||||
.then(function () {
|
||||
return rawImageSourceFolder
|
||||
return rawImageSourceFolder;
|
||||
});
|
||||
})
|
||||
.then(function (rawImageSourceFolder) {
|
||||
|
||||
let promiseToFetchDirectory = null;
|
||||
let promiseToFetchDirectory: Promise<string>;
|
||||
|
||||
if (source.pathToSrcTarballFile) {
|
||||
promiseToFetchDirectory = tar
|
||||
@@ -204,7 +218,7 @@ class ServiceManager {
|
||||
return gitHash;
|
||||
});
|
||||
} else if (source.repoInfo) {
|
||||
let repoInfo = source.repoInfo;
|
||||
const repoInfo = source.repoInfo;
|
||||
promiseToFetchDirectory = GitHelper
|
||||
.clone(repoInfo.user, repoInfo.password, repoInfo.repo, repoInfo.branch, rawImageSourceFolder)
|
||||
.then(function () {
|
||||
@@ -222,14 +236,14 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return fs.pathExists(rawImageSourceFolder + '/' + CAPTAIN_DEFINITION_FILE)
|
||||
return fs.pathExists(rawImageSourceFolder + "/" + CAPTAIN_DEFINITION_FILE);
|
||||
|
||||
})
|
||||
.then(function (exists) {
|
||||
|
||||
if (!exists) {
|
||||
|
||||
Logger.d('Captain Definition does not exist in the base tar. Looking inside...');
|
||||
Logger.d("Captain Definition does not exist in the base tar. Looking inside...");
|
||||
|
||||
// check if there is only one child
|
||||
// check if it's a directory
|
||||
@@ -238,7 +252,7 @@ class ServiceManager {
|
||||
// move the child directory out to base and rename it to rawImageSourceFolder
|
||||
// read captain definition from the folder and return it.
|
||||
|
||||
let directoryInside = null;
|
||||
let directoryInside: string;
|
||||
|
||||
return new Promise(
|
||||
function (resolve, reject) {
|
||||
@@ -259,7 +273,7 @@ class ServiceManager {
|
||||
|
||||
});
|
||||
})
|
||||
.then(function (directory) {
|
||||
.then(function (directory: string) {
|
||||
|
||||
directoryInside = directory;
|
||||
|
||||
@@ -272,7 +286,7 @@ class ServiceManager {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Captain Definition file does not exist!");
|
||||
}
|
||||
|
||||
const BAK = '.bak';
|
||||
const BAK = ".bak";
|
||||
|
||||
fs.renameSync(rawImageSourceFolder, rawImageSourceFolder + BAK);
|
||||
fs.renameSync(path.join(rawImageSourceFolder + BAK, directoryInside), rawImageSourceFolder);
|
||||
@@ -282,7 +296,7 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return fs.readJson(rawImageSourceFolder + '/' + CAPTAIN_DEFINITION_FILE);
|
||||
return fs.readJson(rawImageSourceFolder + "/" + CAPTAIN_DEFINITION_FILE);
|
||||
|
||||
})
|
||||
.then(function (data) {
|
||||
@@ -297,13 +311,13 @@ class ServiceManager {
|
||||
|
||||
if (data.schemaVersion === 1) {
|
||||
|
||||
let templateIdTag = data.templateId;
|
||||
let dockerfileLines = data.dockerfileLines;
|
||||
let hasDockerfileLines = dockerfileLines && dockerfileLines.length > 0;
|
||||
const templateIdTag = data.templateId;
|
||||
const dockerfileLines = data.dockerfileLines;
|
||||
const hasDockerfileLines = dockerfileLines && dockerfileLines.length > 0;
|
||||
|
||||
if (hasDockerfileLines && !templateIdTag) {
|
||||
|
||||
return dockerfileLines.join('\n');
|
||||
return dockerfileLines.join("\n");
|
||||
|
||||
} else if (!hasDockerfileLines && templateIdTag) {
|
||||
|
||||
@@ -345,14 +359,14 @@ class ServiceManager {
|
||||
|
||||
return dockerApi
|
||||
.buildImageFromDockerFile(imageName, newVersion, tarballFilePath, self.buildLogs[appName])
|
||||
.catch(function (error) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ('' + error).trim());
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ("" + error).trim());
|
||||
});
|
||||
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
Logger.d('Cleaning up up the files... ' + tarImageBaseFolder + ' and ' + rawImageBaseFolder);
|
||||
Logger.d("Cleaning up up the files... " + tarImageBaseFolder + " and " + rawImageBaseFolder);
|
||||
|
||||
return fs.remove(tarImageBaseFolder);
|
||||
|
||||
@@ -364,23 +378,23 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
let authObj = CaptainManager.get().getDockerAuthObject();
|
||||
const authObj = CaptainManager.get().getDockerAuthObject();
|
||||
|
||||
if (!authObj) {
|
||||
Logger.d('No Docker Auth is found. Skipping pushing the image.');
|
||||
Logger.d("No Docker Auth is found. Skipping pushing the image.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger.d('Docker Auth is found. Pushing the image...');
|
||||
Logger.d("Docker Auth is found. Pushing the image...");
|
||||
|
||||
return dockerApi
|
||||
.pushImage(imageName, newVersion, authObj, self.buildLogs[appName])
|
||||
.catch(function (error) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
Logger.e('PUSH FAILED');
|
||||
Logger.e("PUSH FAILED");
|
||||
Logger.e(error);
|
||||
reject(ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Push failed: ' + error));
|
||||
})
|
||||
reject(ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Push failed: " + error));
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
@@ -392,29 +406,29 @@ class ServiceManager {
|
||||
self.activeBuilds[appName] = false;
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(error);
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
enableCustomDomainSsl(appName, customDomain) {
|
||||
enableCustomDomainSsl(appName: string, customDomain: string) {
|
||||
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
Logger.d('Verifying Captain owns domain: ' + customDomain);
|
||||
Logger.d("Verifying Captain owns domain: " + customDomain);
|
||||
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(customDomain);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(customDomain, undefined);
|
||||
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
|
||||
Logger.d('Enabling SSL for: ' + appName + ' on ' + customDomain);
|
||||
Logger.d("Enabling SSL for: " + appName + " on " + customDomain);
|
||||
|
||||
return self.dataStore.getAppsDataStore().verifyCustomDomainBelongsToApp(appName, customDomain);
|
||||
|
||||
@@ -436,27 +450,27 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
addCustomDomain(appName, customDomain) {
|
||||
addCustomDomain(appName: string, customDomain: string) {
|
||||
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
let rootDomain = self.dataStore.getRootDomain();
|
||||
let dotRootDomain = "." + rootDomain;
|
||||
const rootDomain = self.dataStore.getRootDomain();
|
||||
const dotRootDomain = "." + rootDomain;
|
||||
|
||||
if (!customDomain || !(/^[a-z0-9\-\.]+$/.test(customDomain))) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME,
|
||||
'Domain name is not accepted. Please use alphanumerical domains such as myapp.google123.ca');
|
||||
"Domain name is not accepted. Please use alphanumerical domains such as myapp.google123.ca");
|
||||
}
|
||||
|
||||
if (customDomain.length > 80) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME,
|
||||
'Domain name is not accepted. Please use alphanumerical domains less than 80 characters in length.');
|
||||
"Domain name is not accepted. Please use alphanumerical domains less than 80 characters in length.");
|
||||
}
|
||||
|
||||
if (customDomain.indexOf('..') >= 0) {
|
||||
if (customDomain.indexOf("..") >= 0) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME,
|
||||
'Domain name is not accepted. You cannot have two consecutive periods ".." inside a domain name. Please use alphanumerical domains such as myapp.google123.ca');
|
||||
}
|
||||
@@ -464,7 +478,7 @@ class ServiceManager {
|
||||
if (customDomain.indexOf(dotRootDomain) >= 0 &&
|
||||
(customDomain.indexOf(dotRootDomain) + dotRootDomain.length) === customDomain.length) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_BAD_NAME,
|
||||
'Domain name is not accepted. Custom domain cannot be subdomain of root domain.');
|
||||
"Domain name is not accepted. Custom domain cannot be subdomain of root domain.");
|
||||
}
|
||||
|
||||
|
||||
@@ -477,10 +491,10 @@ class ServiceManager {
|
||||
.then(function () {
|
||||
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
|
||||
Logger.d('Enabling custom domain for: ' + appName);
|
||||
Logger.d("Enabling custom domain for: " + appName);
|
||||
|
||||
return self.dataStore.getAppsDataStore().addCustomDomainForApp(appName, customDomain);
|
||||
|
||||
@@ -492,17 +506,17 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
removeCustomDomain(appName, customDomain) {
|
||||
removeCustomDomain(appName: string, customDomain: string) {
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
|
||||
Logger.d('Removing custom domain for: ' + appName);
|
||||
Logger.d("Removing custom domain for: " + appName);
|
||||
|
||||
return self.dataStore.getAppsDataStore().removeCustomDomainForApp(appName, customDomain);
|
||||
|
||||
@@ -514,12 +528,11 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
enableSslForApp(appName) {
|
||||
enableSslForApp(appName: string) {
|
||||
|
||||
const self = this;
|
||||
|
||||
let rootDomain = null;
|
||||
let app = null;
|
||||
let rootDomain: string;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
@@ -529,10 +542,10 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
Logger.d('Enabling SSL for: ' + appName);
|
||||
Logger.d("Enabling SSL for: " + appName);
|
||||
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
|
||||
return self.dataStore.getRootDomain();
|
||||
@@ -543,7 +556,7 @@ class ServiceManager {
|
||||
rootDomain = val;
|
||||
|
||||
if (!rootDomain) {
|
||||
throw new Error('No rootDomain! Cannot verify domain');
|
||||
throw new Error("No rootDomain! Cannot verify domain");
|
||||
}
|
||||
|
||||
})
|
||||
@@ -555,7 +568,7 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return appName + '.' + rootDomain;
|
||||
return appName + "." + rootDomain;
|
||||
|
||||
})
|
||||
.then(function (domainName) {
|
||||
@@ -575,17 +588,17 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
verifyCaptainOwnsGenericSubDomain(appName) {
|
||||
verifyCaptainOwnsGenericSubDomain(appName: string) {
|
||||
|
||||
const self = this;
|
||||
|
||||
let rootDomain = null;
|
||||
let rootDomain: string;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
if (!appName) {
|
||||
throw new Error('No App Name! Cannot verify domain');
|
||||
throw new Error("No App Name! Cannot verify domain");
|
||||
}
|
||||
|
||||
return self.dataStore.getRootDomain();
|
||||
@@ -604,30 +617,30 @@ class ServiceManager {
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return appName + '.' + rootDomain;
|
||||
return appName + "." + rootDomain;
|
||||
|
||||
})
|
||||
.then(function (domainName) {
|
||||
|
||||
Logger.d('Verifying Captain owns domain: ' + domainName);
|
||||
Logger.d("Verifying Captain owns domain: " + domainName);
|
||||
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(domainName);
|
||||
return CaptainManager.get().verifyCaptainOwnsDomainOrThrow(domainName, undefined);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
removeApp(appName) {
|
||||
Logger.d('Removing service for: ' + appName);
|
||||
removeApp(appName: string) {
|
||||
Logger.d("Removing service for: " + appName);
|
||||
const self = this;
|
||||
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
Logger.d('Check if service is running: ' + serviceName);
|
||||
Logger.d("Check if service is running: " + serviceName);
|
||||
return dockerApi
|
||||
.isServiceRunningByName(serviceName);
|
||||
|
||||
@@ -637,7 +650,7 @@ class ServiceManager {
|
||||
return dockerApi
|
||||
.removeService(serviceName);
|
||||
} else {
|
||||
Logger.w('Cannot delete service... It is not running: ' + serviceName);
|
||||
Logger.w("Cannot delete service... It is not running: " + serviceName);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -654,13 +667,13 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
getUnusedImages(mostRecentLimit) {
|
||||
Logger.d('Getting unused images, excluding most recent ones: ' + mostRecentLimit);
|
||||
getUnusedImages(mostRecentLimit: number) {
|
||||
Logger.d("Getting unused images, excluding most recent ones: " + mostRecentLimit);
|
||||
const self = this;
|
||||
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let allImages = null;
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let allImages: any[];
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
@@ -672,11 +685,11 @@ class ServiceManager {
|
||||
|
||||
allImages = images;
|
||||
|
||||
return dataStore.getAppsDataStore().getAppDefinitions()
|
||||
return dataStore.getAppsDataStore().getAppDefinitions();
|
||||
})
|
||||
.then(function (apps) {
|
||||
|
||||
let unusedImages = [];
|
||||
const unusedImages = [];
|
||||
|
||||
for (let i = 0; i < allImages.length; i++) {
|
||||
const img = allImages[i];
|
||||
@@ -685,7 +698,7 @@ class ServiceManager {
|
||||
for (let j = 0; j < img.RepoTags.length; j++) {
|
||||
const repoTag = img.RepoTags[j];
|
||||
Object.keys(apps).forEach(function (key, index) {
|
||||
let app = apps[key];
|
||||
const app = apps[key];
|
||||
app.appName = key;
|
||||
for (let k = 0; k < (mostRecentLimit + 1); k++) {
|
||||
if (repoTag.indexOf(dataStore.getImageNameWithoutAuthObj(app.appName, Number(app.deployedVersion) - k)) >= 0) {
|
||||
@@ -699,8 +712,8 @@ class ServiceManager {
|
||||
if (!imageInUse) {
|
||||
unusedImages.push({
|
||||
id: img.Id,
|
||||
description: (img.RepoTags && img.RepoTags.length) ? img.RepoTags[0] : 'untagged'
|
||||
})
|
||||
description: (img.RepoTags && img.RepoTags.length) ? img.RepoTags[0] : "untagged"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,14 +722,12 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
deleteImages(imageIds) {
|
||||
deleteImages(imageIds: string[]) {
|
||||
|
||||
Logger.d('Deleting images...');
|
||||
Logger.d("Deleting images...");
|
||||
const self = this;
|
||||
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let allImages = null;
|
||||
const dockerApi = this.dockerApi;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
@@ -726,17 +737,17 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
ensureServiceInitedAndUpdated(appName, version) {
|
||||
ensureServiceInitedAndUpdated(appName: string, version: number) {
|
||||
|
||||
Logger.d('Ensure service inited and Updated for: ' + appName);
|
||||
Logger.d("Ensure service inited and Updated for: " + appName);
|
||||
const self = this;
|
||||
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerAuthObject = CaptainManager.get().getDockerAuthObject();
|
||||
let imageName = this.dataStore.getImageName(dockerAuthObject, appName, version);
|
||||
let dockerApi = this.dockerApi;
|
||||
let dataStore = this.dataStore;
|
||||
let app = null;
|
||||
const imageName = this.dataStore.getImageName(dockerAuthObject, appName, version);
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
let app: any;
|
||||
|
||||
return dataStore.getAppsDataStore().setDeployedVersion(appName, version)
|
||||
.then(function () {
|
||||
@@ -745,20 +756,20 @@ class ServiceManager {
|
||||
.then(function (appFound) {
|
||||
app = appFound;
|
||||
|
||||
Logger.d('Check if service is running: ' + serviceName);
|
||||
Logger.d("Check if service is running: " + serviceName);
|
||||
return dockerApi
|
||||
.isServiceRunningByName(serviceName);
|
||||
})
|
||||
.then(function (isRunning) {
|
||||
if (isRunning) {
|
||||
Logger.d('Service is already running: ' + serviceName);
|
||||
Logger.d("Service is already running: " + serviceName);
|
||||
return true;
|
||||
} else {
|
||||
Logger.d('Creating service: ' + serviceName + ' with image: ' + imageName);
|
||||
Logger.d("Creating service: " + serviceName + " with image: " + imageName);
|
||||
// if we pass in networks here. Almost always it results in a delayed update which causes
|
||||
// update errors if they happen right away!
|
||||
return dockerApi
|
||||
.createServiceOnNodeId(imageName, serviceName);
|
||||
.createServiceOnNodeId(imageName, serviceName, undefined, undefined, undefined, undefined, undefined);
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
@@ -768,12 +779,11 @@ class ServiceManager {
|
||||
})
|
||||
.then(function (preDeployFunction) {
|
||||
|
||||
Logger.d('Updating service: ' + serviceName + ' with image: ' + imageName);
|
||||
Logger.d("Updating service: " + serviceName + " with image: " + imageName);
|
||||
|
||||
return dockerApi
|
||||
.updateService(serviceName, imageName, app.volumes, app.networks, app.envVars, null,
|
||||
dockerAuthObject, Number(app.instanceCount), app.nodeId, dataStore.getNameSpace(),
|
||||
app, preDeployFunction);
|
||||
return dockerApi.updateService(serviceName, imageName, app.volumes, app.networks, app.envVars,
|
||||
undefined, dockerAuthObject, Number(app.instanceCount), app.nodeId,
|
||||
dataStore.getNameSpace(), undefined, app, preDeployFunction);
|
||||
|
||||
})
|
||||
.then(function () {
|
||||
@@ -788,12 +798,12 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
createPreDeployFunctionIfExist(app) {
|
||||
createPreDeployFunctionIfExist(app: any) {
|
||||
|
||||
let preDeployFunction = app.preDeployFunction;
|
||||
|
||||
if (!preDeployFunction) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -811,20 +821,22 @@ class ServiceManager {
|
||||
};
|
||||
*/
|
||||
|
||||
preDeployFunction = preDeployFunction + '\n\n module.exports = preDeployFunction';
|
||||
preDeployFunction = preDeployFunction + "\n\n module.exports = preDeployFunction";
|
||||
|
||||
return requireFromString(preDeployFunction);
|
||||
}
|
||||
|
||||
updateAppDefinition(appName, instanceCount, envVars, volumes, nodeId, notExposeAsWebApp, forceSsl, ports, appPushWebhook, customNginxConfig, preDeployFunction) {
|
||||
updateAppDefinition(appName: string, instanceCount: number, envVars: any[], volumes: any[],
|
||||
nodeId: string, notExposeAsWebApp: boolean, forceSsl: boolean, ports: any[],
|
||||
appPushWebhook: any , customNginxConfig: string, preDeployFunction: string) {
|
||||
|
||||
const self = this;
|
||||
const dataStore = this.dataStore;
|
||||
const dockerApi = this.dockerApi;
|
||||
|
||||
let serviceName = null;
|
||||
let serviceName: string;
|
||||
|
||||
let checkIfNodeIdExists = function (nodeIdToCheck) {
|
||||
const checkIfNodeIdExists = function (nodeIdToCheck: string) {
|
||||
return dockerApi
|
||||
.getNodesInfo()
|
||||
.then(function (nodeInfo) {
|
||||
@@ -867,14 +879,14 @@ class ServiceManager {
|
||||
|
||||
return dockerApi
|
||||
.isServiceRunningByName(serviceName)
|
||||
.then(function (isRunning) {
|
||||
.then(function (isRunning: boolean) {
|
||||
if (!isRunning) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "Cannot find the service. Try again in a minute...");
|
||||
}
|
||||
return dockerApi
|
||||
.getNodeIdByServiceName(serviceName);
|
||||
})
|
||||
.then(function (nodeIdRunningService) {
|
||||
.then(function (nodeIdRunningService: string) {
|
||||
if (!nodeIdRunningService) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "No NodeId was found. Try again in a minute...");
|
||||
}
|
||||
@@ -901,7 +913,8 @@ class ServiceManager {
|
||||
.then(function () {
|
||||
|
||||
return dataStore.getAppsDataStore().updateAppDefinitionInDb(appName, instanceCount, envVars, volumes, nodeId,
|
||||
notExposeAsWebApp, forceSsl, ports, appPushWebhook, Authenticator.get(dataStore.getNameSpace()),
|
||||
notExposeAsWebApp, forceSsl, ports,
|
||||
appPushWebhook, Authenticator.get(dataStore.getNameSpace()),
|
||||
customNginxConfig, preDeployFunction);
|
||||
|
||||
})
|
||||
@@ -913,7 +926,7 @@ class ServiceManager {
|
||||
});
|
||||
}
|
||||
|
||||
isAppBuilding(appName) {
|
||||
isAppBuilding(appName: string) {
|
||||
return !!this.activeBuilds[appName];
|
||||
}
|
||||
|
||||
@@ -923,18 +936,18 @@ class ServiceManager {
|
||||
*/
|
||||
isAnyBuildRunning() {
|
||||
|
||||
let activeBuilds = this.activeBuilds;
|
||||
const activeBuilds = this.activeBuilds;
|
||||
|
||||
for (let appName in activeBuilds) {
|
||||
for (const appName in activeBuilds) {
|
||||
if (!!activeBuilds[appName]) {
|
||||
return appName;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getBuildStatus(appName) {
|
||||
getBuildStatus(appName: string) {
|
||||
const self = this;
|
||||
this.buildLogs[appName] = this.buildLogs[appName] || new BuildLog(BUILD_LOG_SIZE);
|
||||
|
||||
@@ -942,24 +955,24 @@ class ServiceManager {
|
||||
isAppBuilding: self.isAppBuilding(appName),
|
||||
logs: self.buildLogs[appName].getLogs(),
|
||||
isBuildFailed: self.buildLogs[appName].isBuildFailed
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
logBuildFailed(appName, error) {
|
||||
error = (error || '') + '';
|
||||
logBuildFailed(appName: string, error: string) {
|
||||
error = (error || "") + "";
|
||||
this.buildLogs[appName] = this.buildLogs[appName] || new BuildLog(BUILD_LOG_SIZE);
|
||||
this.buildLogs[appName].onBuildFailed(error);
|
||||
}
|
||||
|
||||
updateServiceOnDefinitionUpdate(appName) {
|
||||
updateServiceOnDefinitionUpdate(appName: string) {
|
||||
|
||||
const self = this;
|
||||
let serviceName = this.dataStore.getServiceName(appName);
|
||||
const serviceName = this.dataStore.getServiceName(appName);
|
||||
const dockerAuthObject = CaptainManager.get().getDockerAuthObject();
|
||||
|
||||
const dataStore = this.dataStore;
|
||||
const dockerApi = this.dockerApi;
|
||||
let appFound = null;
|
||||
let appFound: any;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
@@ -970,7 +983,7 @@ class ServiceManager {
|
||||
appFound = app;
|
||||
|
||||
if (!appFound) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'App name not found!');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "App name not found!");
|
||||
}
|
||||
|
||||
return self.createPreDeployFunctionIfExist(app);
|
||||
@@ -979,11 +992,11 @@ class ServiceManager {
|
||||
.then(function (preDeployFunction) {
|
||||
|
||||
if (!appFound) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'App name not found!');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "App name not found!");
|
||||
}
|
||||
|
||||
return dockerApi
|
||||
.updateService(serviceName, null, appFound.volumes, appFound.networks, appFound.envVars, null,
|
||||
.updateService(serviceName, undefined, appFound.volumes, appFound.networks, appFound.envVars, undefined,
|
||||
dockerAuthObject, Number(appFound.instanceCount), appFound.nodeId, dataStore.getNameSpace(),
|
||||
appFound.ports, appFound, preDeployFunction);
|
||||
});
|
||||
@@ -992,11 +1005,11 @@ class ServiceManager {
|
||||
|
||||
reloadLoadBalancer() {
|
||||
|
||||
Logger.d('Updating Load Balancer');
|
||||
Logger.d("Updating Load Balancer");
|
||||
const self = this;
|
||||
return self.loadBalancerManager.rePopulateNginxConfigFile(self.dataStore)
|
||||
.then(function () {
|
||||
Logger.d('sendReloadSignal...');
|
||||
Logger.d("sendReloadSignal...");
|
||||
return self.loadBalancerManager.sendReloadSignal();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user