1 | import R from "ramda";
|
2 | import Promise from "bluebird";
|
3 | import pm2 from "./pm2";
|
4 | import prettyBytes from "pretty-bytes";
|
5 | import { promises } from "./util";
|
6 | import log from "./log";
|
7 | import packageJson from "../package.json";
|
8 |
|
9 | const HOST_NAME = process.env.HOSTNAME || "unknown";
|
10 |
|
11 |
|
12 |
|
13 | export default (apps) => {
|
14 | const processNameToAppId = (name) => name.split(":")[0];
|
15 | const getApp = (id) => {
|
16 | id = processNameToAppId(id);
|
17 | return R.find(app => app.id === id, apps);
|
18 | };
|
19 |
|
20 |
|
21 | const getAppStatus = (app, processItem) => {
|
22 | return new Promise((resolve, reject) => {
|
23 | if (!app || !processItem) {
|
24 | resolve();
|
25 | return;
|
26 | }
|
27 |
|
28 | const status = {
|
29 | id: app.id,
|
30 | status: processItem.pm2_env.status,
|
31 | route: `${ app.route.toString() } ⇨ ${ app.port }`,
|
32 | repository: `${ app.repo.name }:${ app.branch }`,
|
33 | resources: {
|
34 | memory: prettyBytes(processItem.monit.memory),
|
35 | cpu: processItem.monit.cpu
|
36 | }
|
37 | };
|
38 |
|
39 | const gettingVersion = app.version().catch(err => reject(err));
|
40 | gettingVersion.then(version => {
|
41 | status.version = {
|
42 | local: version.local,
|
43 | remote: version.remote
|
44 | };
|
45 | if (version.isUpdateRequired) { status.version.isUpdateRequired = true; }
|
46 | if (version.isDependenciesChanged) { status.version.isDependenciesChanged = true; }
|
47 | if (version.isDownloading) {
|
48 | status.status += `, updating to v${ version.remote }`;
|
49 | status.version.isDownloading = true;
|
50 | }
|
51 | resolve(status);
|
52 | });
|
53 | });
|
54 | };
|
55 |
|
56 |
|
57 |
|
58 | const getRunningApps = () => {
|
59 | return new Promise((resolve, reject) => {
|
60 | Promise.coroutine(function*() {
|
61 | const processes = yield pm2.apps();
|
62 | let { results } = yield promises(processes.map(item => getAppStatus(getApp(item.name), item))).catch(err => reject(err));
|
63 | results = R.reject(R.isNil)(results);
|
64 | results = R.sortBy(R.prop("id"))(results);
|
65 | resolve(results);
|
66 | })();
|
67 | });
|
68 | };
|
69 |
|
70 |
|
71 |
|
72 | return {
|
73 | getStatuses(req, res) {
|
74 | getRunningApps()
|
75 | .then(appsStatus => res.send({
|
76 | host: HOST_NAME,
|
77 | version: packageJson.version,
|
78 | apps: appsStatus
|
79 | }))
|
80 | .catch(err => {
|
81 | log.error(err);
|
82 | res.status(500).send({
|
83 | error: "Failed while getting the status of running applications",
|
84 | message: err.message
|
85 | });
|
86 | });
|
87 | },
|
88 |
|
89 | getAppStatus(req, res) {
|
90 | Promise.coroutine(function*() {
|
91 | const id = req.params.app;
|
92 | const app = getApp(id);
|
93 | const sendFail = (err) => res.status(500).send({ message: `Failed while getting the status of the application '${ id }'.`, err: err.message });
|
94 | if (!app) {
|
95 | res.status(404).send({ error: `The application '${ id }' does not exist.` });
|
96 | } else {
|
97 | const processes = yield pm2
|
98 | .apps(item => processNameToAppId(item.name) === id)
|
99 | .catch(err => sendFail(err));
|
100 |
|
101 | const item = processes[0];
|
102 | const status = yield getAppStatus(getApp(item.name), item).catch(err => sendFail(err));
|
103 | res.send(status);
|
104 | }
|
105 | })();
|
106 | }
|
107 | };
|
108 | };
|