Skip to content

Commit

Permalink
Logman
Browse files Browse the repository at this point in the history
  • Loading branch information
willnode committed Jan 7, 2024
1 parent 1d1f8cd commit 062bcec
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 32 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/domcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,44 @@ jobs:
webhook_secret: ${{ secrets.WEBHOOK_SECRET_SGA }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_SGA }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
- name: Invoke NYC deployment hook
uses: distributhor/workflow-webhook@v2
env:
webhook_url: https://my.domcloud.co/api/githubdeploy
webhook_secret: ${{ secrets.WEBHOOK_SECRET_NYC }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_NYC }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
- name: Invoke FRA deployment hook
uses: distributhor/workflow-webhook@v2
env:
webhook_url: https://my.domcloud.co/api/githubdeploy
webhook_secret: ${{ secrets.WEBHOOK_SECRET_FRA }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_FRA }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
- name: Invoke OSA deployment hook
uses: distributhor/workflow-webhook@v2
env:
webhook_url: https://my.domcloud.co/api/githubdeploy
webhook_secret: ${{ secrets.WEBHOOK_SECRET_OSA }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_OSA }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
- name: Invoke BLR deployment hook
uses: distributhor/workflow-webhook@v2
env:
webhook_url: https://my.domcloud.co/api/githubdeploy
webhook_secret: ${{ secrets.WEBHOOK_SECRET_BLR }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_BLR }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
- name: Invoke SAO deployment hook
uses: distributhor/workflow-webhook@v2
env:
webhook_url: https://my.domcloud.co/api/githubdeploy
webhook_secret: ${{ secrets.WEBHOOK_SECRET_SAO }}
webhook_auth: ${{ secrets.WEBHOOK_AUTH_SAO }}
data: >-
{"commands":["git pull","sudo systemctl restart bridge"]}
{"commands":["git pull","npm i","sudo systemctl restart bridge"]}
74 changes: 57 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "domcloud-bridge",
"version": "0.38.1",
"version": "0.39.2",
"description": "Deployment runner for DOM Cloud",
"main": "app.js",
"engines": {
Expand All @@ -17,10 +17,11 @@
"license": "MIT",
"type": "module",
"dependencies": {
"axios": "^1.6.3",
"axios": "^1.6.5",
"cli": "^1.0.1",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"fast-xml-parser": "^4.3.2",
"nginx-conf": "^2.1.0",
"node-abort-controller": "^3.1.1",
"proper-lockfile": "^4.1.2",
Expand Down
26 changes: 26 additions & 0 deletions src/controllers/logman.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import express from 'express';
import {
iptablesExec as executor
} from '../executor/iptables.js';
import {
checkGet,
checkPost
} from '../util.js';
import { virtualminExec } from '../executor/virtualmin.js';
import { logmanExec } from '../executor/logman.js';

export default function () {
var router = express.Router();
router.get('/get', checkGet(['domain', 'type']), async function (req, res, next) {
try {
let domain = await virtualminExec.getDomainInfo(req.query.domain.toString());
let type = req.query.type.toString()
let n = parseInt(req.query.n.toString()) || 100;
let output = await logmanExec.getLog(domain, type, n);
return res.json(output);
} catch (error) {
next(error);
}
});
return router;
}
94 changes: 94 additions & 0 deletions src/executor/logman.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
cat,
executeLock,
spawnSudoUtil,
writeTo
} from '../util.js';
import { XMLParser } from "fast-xml-parser";

class LogmanExecutor {
constructor() {
if (process.env.PASSENGERLOG) {
this.PASSENGERLOG = '/var/log/nginx/passenger.log';
}
}
/**
* @param {any} domain
* @param {string} type
* @param {number} n
*/
async getLog(domain, type, n) {
switch (type) {
case 'access':
if (!domain['Access log']) {
return {
code: 255,
stdout: 'No access log found',
}
}
return await spawnSudoUtil("SHELL_SUDO", ["root",
"tail", "-n", n, domain['Access log']]);
case 'error':
if (!domain['Error log']) {
return {
code: 255,
stdout: 'No error log found',
}
}
return await spawnSudoUtil("SHELL_SUDO", ["root",
"tail", "-n", n, domain['Error log']]);
case 'passenger':
const user = domain['Username'];
const pe = await spawnSudoUtil("SHELL_SUDO", [user,
"passenger-status", "--show=xml"]);
const peo = pe.stdout.trim();
if (!peo) {
return {
code: 255,
stdout: 'Passenger instance is not set here',
}
}
const parser = new XMLParser();
let peom = parser.parse(peo);
let peoma = peom?.info?.supergroups?.supergroup;
if (!peoma) {
return {
code: 255,
stderr: 'incomplete response from passenger-status',
stdout: ''
}
}
let peomaa = Array.isArray(peoma) ? peoma : [peoma];
let peomaps = peomaa.map(x => x.group.processes).filter(x => x);
if (!peomaps.length) {
return {
code: 255,
stderr: 'No processes from passenger-status is running',
stdout: ''
}
}
let procs = peomaps.reduce((a, b) => {
let x = (Array.isArray(b.process) ? b.process : [b.process]);
a[b.group.name] = x.map(y => y.pid).filter(y => typeof y === "number");
}, {});
let head = `List of passenger processes running:\n`;
head += JSON.stringify(procs, null, 2);
head += `\n------------------------\n`;
let pids = Object.values(procs).flatMap(x => x).join('\\|');
const pes = await spawnSudoUtil("SHELL_SUDO", ["root",
"bash", "-c", `grep -w "\\^App \\(${pids}\\)" "${this.PASSENGERLOG}" | tail -n ${n}`
]);
if (pes.code == 0) {
pes.stdout = head + pes.stdout;
}
return pes;
default:
return {
code: 255,
stdout: 'Unknown log type ' + type
}
}
}
}

export const logmanExec = new LogmanExecutor();
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from 'express'
import dotenv from 'dotenv'
import logman from './controllers/logman.js';
import named from './controllers/named.js';
import nginx from './controllers/nginx.js';
import status from './controllers/status.js';
Expand All @@ -23,6 +24,7 @@ app.use(express.static('public'));
app.use(express.json());
app.use('/status', status());
app.use(checkAuth);
app.use('/logman', logman());
app.use('/named', named());
app.use('/nginx', nginx());
app.use('/iptables', iptables());
Expand All @@ -35,8 +37,9 @@ app.use(function (err, req, res, next) {
res.json(err);
});
const port = process.env.PORT ? parseInt(process.env.PORT) : 2223;

app.listen(port, function () {
console.log(`Listening on ${port}`);
console.log(`Start time takes ` + (Date.now() - startTime) / 1000 + ` s`)
console.log(`Listening on ${port}`);
})

16 changes: 10 additions & 6 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,16 @@ export const initUtils = async () => {
}
return a;
}, {});
const phpPath = process.env.PHPFPM_REMILIST || '/etc/opt/remi/';
const phpFiles = fs.readdirSync(phpPath, { withFileTypes: true });
phpVersionsList = phpFiles
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name.replace(/php(\d)(\d+)/, '$1.$2'))
phpVersionsList = sortSemver(phpVersionsList).reverse();
try {
const phpPath = process.env.PHPFPM_REMILIST || '/etc/opt/remi/';
const phpFiles = fs.readdirSync(phpPath, { withFileTypes: true });
phpVersionsList = phpFiles
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name.replace(/php(\d)(\d+)/, '$1.$2'))
phpVersionsList = sortSemver(phpVersionsList).reverse();
} catch (error) {
phpVersionsList = [];
}
// TODO: detect OS/arch?
await axios.get('https://rvm_io.global.ssl.fastly.net/binaries/centos/9/x86_64/').then(res => {
// @ts-ignore
Expand Down

0 comments on commit 062bcec

Please sign in to comment.