skeleton for one click deploy is done. Untested.

This commit is contained in:
Kasra Bigdeli
2018-12-27 20:33:40 -08:00
parent e0bff77d81
commit dfd7fd30de
5 changed files with 165 additions and 6 deletions
+18
View File
@@ -3,6 +3,7 @@ import Logger from "../utils/Logger";
import { IAppDef } from "../containers/apps/AppDefinition";
import { IRegistryInfo } from "../models/IRegistryInfo";
import Utils from "../utils/Utils";
import { ICaptainDefinition } from "../models/ICaptainDefinition";
const URL = process.env.REACT_APP_API_URL + "/api/v2";
Logger.dev("API URL: " + URL);
@@ -94,6 +95,23 @@ export default class ApiManager {
);
}
uploadCaptainDefinitionContent(
appName: string,
captainDefinition: ICaptainDefinition,
detached: boolean
) {
const http = this.http;
return Promise.resolve() //
.then(
http.fetch(
http.POST,
"/user/apps/appData/" + appName + (detached ? "?detached=1" : ""),
{ captainDefinitionContent: JSON.stringify(captainDefinition) }
)
);
}
updateConfigAndSave(appName: string, appDefinition: IAppDef) {
var instanceCount = appDefinition.instanceCount;
var envVars = appDefinition.envVars;
@@ -22,7 +22,8 @@ export interface IOneClickVariable {
}
export interface IDockerComposeService {
image: string;
image?: string;
dockerFileLines?: string[]; // This is our property, not DockerCompose. We use this instead of image if we need to extend the image.
volumes?: string[];
ports?: string[];
environment?: IHashMapGeneric<string>;
@@ -5,6 +5,8 @@ import {
IDockerComposeService
} from "./OneClickAppConfigPage";
import Utils from "../../../utils/Utils";
import { IAppDef } from "../AppDefinition";
import OneClickAppDeploymentHelper from "./OneClickAppDeploymentHelper";
const REGISTERING = "REGISTERING";
const CONFIGURING = "CONFIGURING";
@@ -22,14 +24,14 @@ export interface IDeploymentState {
}
export default class OneClickAppDeployHelper {
private apiManager: ApiManager;
private deploymentHelper: OneClickAppDeploymentHelper = new OneClickAppDeploymentHelper();
private template: IOneClickTemplate | undefined;
constructor(
private onDeploymentStateChanged: (
deploymentState: IDeploymentState
) => void
) {
this.apiManager = new ApiManager();
//
}
startDeployProcess(
@@ -201,10 +203,31 @@ export default class OneClickAppDeployHelper {
dockerComposeService: IDockerComposeService
): IDeploymentStep[] {
const promises: IDeploymentStep[] = [];
const self = this;
// promise to create
// promise to update
// promise to deploy
promises.push({
stepName: `Registering ${appName}`,
stepPromise: self.deploymentHelper.createRegisterPromise(
appName,
dockerComposeService
)
});
promises.push({
stepName: `Configuring ${appName} (volumes, ports, environmental variables)`,
stepPromise: self.deploymentHelper.createConfigurationPromise(
appName,
dockerComposeService
)
});
promises.push({
stepName: `Deploying ${appName} (might take up to a minute)`,
stepPromise: self.deploymentHelper.createDeploymentPromise(
appName,
dockerComposeService
)
});
return promises;
}
@@ -0,0 +1,111 @@
import { IDockerComposeService } from "./OneClickAppConfigPage";
import ApiManager from "../../../api/ApiManager";
import { IAppDef } from "../AppDefinition";
import { ICaptainDefinition } from "../../../models/ICaptainDefinition";
import Utils from "../../../utils/Utils";
export default class OneClickAppDeploymentHelper {
private apiManager: ApiManager = new ApiManager();
createRegisterPromise(
appName: string,
dockerComposeService: IDockerComposeService
) {
const self = this;
return Promise.resolve().then(function() {
return self.apiManager.registerNewApp(
appName,
!!dockerComposeService.volumes && !!dockerComposeService.volumes.length
);
});
}
createConfigurationPromise(
appName: string,
dockerComposeService: IDockerComposeService
) {
const self = this;
return Promise.resolve().then(function() {
return self.apiManager
.getAllApps()
.then(function(data) {
const appDefs = data.appDefinitions as IAppDef[];
for (let index = 0; index < appDefs.length; index++) {
const element = appDefs[index];
if (element.appName === appName) {
return Utils.copyObject(element);
}
}
})
.then(function(appDef) {
if (!appDef) {
throw new Error("App was not found right after registering!!");
}
appDef.volumes = appDef.volumes || [];
const vols = dockerComposeService.volumes || [];
for (let i = 0; i < vols.length; i++) {
const elements = vols[i].split(":");
if (elements[0].startsWith("/")) {
appDef.volumes.push({
hostPath: elements[0],
containerPath: elements[1]
});
} else {
appDef.volumes.push({
volumeName: elements[0],
containerPath: elements[1]
});
}
}
appDef.ports = appDef.ports || [];
const ports = dockerComposeService.ports || [];
for (let i = 0; i < ports.length; i++) {
const elements = ports[i].split(":");
appDef.ports.push({
hostPort: Number(elements[0]),
containerPort: Number(elements[1])
});
}
appDef.envVars = appDef.envVars || [];
const environment = dockerComposeService.environment || {};
Object.keys(environment).forEach(function(envKey) {
appDef.envVars.push({
key: envKey,
value: environment[envKey]
});
});
return self.apiManager.updateConfigAndSave(appName, appDef);
});
});
}
createDeploymentPromise(
appName: string,
dockerComposeService: IDockerComposeService
) {
const self = this;
return Promise.resolve().then(function() {
let captainDefinition: ICaptainDefinition = {
schemaVersion: 2
};
if (dockerComposeService.image) {
captainDefinition.imageName = dockerComposeService.image;
} else {
captainDefinition.dockerfileLines =
dockerComposeService.dockerFileLines;
}
return self.apiManager.uploadCaptainDefinitionContent(
appName,
captainDefinition,
false
);
});
}
}
@@ -0,0 +1,6 @@
export interface ICaptainDefinition {
schemaVersion: number
dockerfileLines?: string[]
imageName?: string
templateId?: string
}