315 lines
No EOL
9.1 KiB
JavaScript
315 lines
No EOL
9.1 KiB
JavaScript
const { currentLoad, mem, networkStats, fsSize, dockerContainerStats, networkInterfaces } = require('systeminformation');
|
|
var Docker = require('dockerode');
|
|
var docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
|
const { dashCard } = require('../components/dashCard');
|
|
const { Readable } = require('stream');
|
|
|
|
const Containers = require('../database/ContainerSettings');
|
|
|
|
// export docker
|
|
module.exports.docker = docker;
|
|
|
|
|
|
let IPv4 = '';
|
|
networkInterfaces().then(data => {
|
|
IPv4 = data[0].ip4;
|
|
});
|
|
|
|
let hidden = '';
|
|
module.exports.hiddenContainers = async function () {
|
|
hidden = await Containers.findAll({ where: {visibility:false}});
|
|
hidden = hidden.map(a => a.name);
|
|
}
|
|
|
|
module.exports.serverStats = async function () {
|
|
const cpuUsage = await currentLoad();
|
|
const ramUsage = await mem();
|
|
const netUsage = await networkStats();
|
|
const diskUsage = await fsSize();
|
|
|
|
const info = {
|
|
cpu: Math.round(cpuUsage.currentLoad),
|
|
ram: Math.round((ramUsage.active / ramUsage.total) * 100),
|
|
tx: netUsage[0].tx_bytes,
|
|
rx: netUsage[0].rx_bytes,
|
|
disk: diskUsage[0].use,
|
|
};
|
|
|
|
return info;
|
|
}
|
|
|
|
|
|
|
|
module.exports.containerList = async function () {
|
|
let card_list = '';
|
|
|
|
const data = await docker.listContainers({ all: true });
|
|
for (const container of data) {
|
|
|
|
|
|
if (!hidden.includes(container.Names[0].slice(1))) {
|
|
|
|
let imageVersion = container.Image.split('/');
|
|
let service = imageVersion[imageVersion.length - 1].split(':')[0];
|
|
|
|
let containerId = docker.getContainer(container.Id);
|
|
let containerInfo = await containerId.inspect();
|
|
|
|
// Get ports //////////////////////////
|
|
let ports_list = [];
|
|
try {
|
|
for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) {
|
|
let ports = {
|
|
check : 'checked',
|
|
external: value[0].HostPort,
|
|
internal: key.split('/')[0],
|
|
protocol: key.split('/')[1]
|
|
}
|
|
ports_list.push(ports);
|
|
}
|
|
} catch {
|
|
// console.log('no ports')
|
|
}
|
|
|
|
for (let i = 0; i < 12; i++) {
|
|
if (ports_list[i] == undefined) {
|
|
let ports = {
|
|
check : '',
|
|
external: '',
|
|
internal: '',
|
|
protocol: ''
|
|
}
|
|
ports_list[i] = ports;
|
|
}
|
|
} /////////////////////////////////////
|
|
|
|
|
|
// Get volumes ////////////////////////
|
|
let volumes_list = [];
|
|
try { for (const [key, value] of Object.entries(containerInfo.HostConfig.Binds)) {
|
|
let volumes = {
|
|
check : 'checked',
|
|
bind: value.split(':')[0],
|
|
container: value.split(':')[1],
|
|
readwrite: value.split(':')[2]
|
|
}
|
|
volumes_list.push(volumes);
|
|
}} catch {
|
|
// console.log('no volumes')
|
|
}
|
|
for (let i = 0; i < 12; i++) {
|
|
if (volumes_list[i] == undefined) {
|
|
let volumes = {
|
|
check : '',
|
|
bind: '',
|
|
container: '',
|
|
readwrite: ''
|
|
}
|
|
volumes_list[i] = volumes;
|
|
}
|
|
} /////////////////////////////////////
|
|
|
|
|
|
// Get environment variables.
|
|
let environment_variables = [];
|
|
try { for (const [key, value] of Object.entries(containerInfo.Config.Env)) {
|
|
let env = {
|
|
check : 'checked',
|
|
name: value.split('=')[0],
|
|
default: value.split('=')[1]
|
|
}
|
|
environment_variables.push(env);
|
|
}} catch { console.log('no env') }
|
|
for (let i = 0; i < 12; i++) {
|
|
if (environment_variables[i] == undefined) {
|
|
let env = {
|
|
check : '',
|
|
name: '',
|
|
default: ''
|
|
}
|
|
environment_variables[i] = env;
|
|
}
|
|
}
|
|
|
|
// Get labels.
|
|
let labels = [];
|
|
for (const [key, value] of Object.entries(containerInfo.Config.Labels)) {
|
|
let label = {
|
|
check : 'checked',
|
|
name: key,
|
|
value: value
|
|
}
|
|
labels.push(label);
|
|
}
|
|
for (let i = 0; i < 12; i++) {
|
|
if (labels[i] == undefined) {
|
|
let label = {
|
|
check : '',
|
|
name: '',
|
|
value: ''
|
|
}
|
|
labels[i] = label;
|
|
}
|
|
}
|
|
|
|
|
|
let container_info = {
|
|
name: container.Names[0].slice(1),
|
|
service: service,
|
|
id: container.Id,
|
|
state: container.State,
|
|
image: container.Image,
|
|
external_port: ports_list[0].external || 0,
|
|
internal_port: ports_list[0].internal || 0,
|
|
ports: ports_list,
|
|
volumes: volumes_list,
|
|
environment_variables: environment_variables,
|
|
labels: labels,
|
|
IPv4: IPv4,
|
|
style: "Compact"
|
|
}
|
|
|
|
let dockerCard = dashCard(container_info);
|
|
|
|
card_list += dockerCard;
|
|
}
|
|
|
|
}
|
|
|
|
return card_list;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports.containerStats = async function () {
|
|
|
|
let container_stats = [];
|
|
const data = await docker.listContainers({ all: true });
|
|
|
|
for (const container of data) {
|
|
|
|
if (!hidden.includes(container.Names[0].slice(1))) {
|
|
const stats = await dockerContainerStats(container.Id);
|
|
|
|
let container_stat = {
|
|
name: container.Names[0].slice(1),
|
|
cpu: Math.round(stats[0].cpuPercent),
|
|
ram: Math.round(stats[0].memPercent)
|
|
}
|
|
|
|
//push stats to an array
|
|
container_stats.push(container_stat);
|
|
}
|
|
}
|
|
return container_stats;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports.containerAction = async function (data) {
|
|
|
|
let { user, role, action, container, state } = data;
|
|
|
|
console.log(`${user} wants to: ${action} ${container}`);
|
|
|
|
if (role == 'admin') {
|
|
var containerName = docker.getContainer(container);
|
|
|
|
if ((action == 'start') && (state == 'stopped')) {
|
|
containerName.start();
|
|
} else if ((action == 'start') && (state == 'paused')) {
|
|
containerName.unpause();
|
|
} else if ((action == 'stop') && (state != 'stopped')) {
|
|
containerName.stop();
|
|
} else if ((action == 'pause') && (state == 'running')) {
|
|
containerName.pause();
|
|
} else if ((action == 'pause') && (state == 'paused')) {
|
|
containerName.unpause();
|
|
} else if (action == 'restart') {
|
|
containerName.restart();
|
|
}
|
|
} else {
|
|
console.log('User is not an admin');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
module.exports.containerExec = async function (data) {
|
|
|
|
let { container, command } = data;
|
|
|
|
var containerName = docker.getContainer(container);
|
|
|
|
var options = {
|
|
Cmd: ['/bin/sh', '-c', command],
|
|
AttachStdout: true,
|
|
AttachStderr: true,
|
|
Tty: true
|
|
};
|
|
|
|
containerName.exec(options, function (err, exec) {
|
|
if (err) return;
|
|
|
|
exec.start(function (err, stream) {
|
|
if (err) return;
|
|
|
|
containerName.modem.demuxStream(stream, process.stdout, process.stderr);
|
|
|
|
exec.inspect(function (err, data) {
|
|
if (err) return;
|
|
|
|
|
|
});
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports.containerLogs = function (data) {
|
|
return new Promise((resolve, reject) => {
|
|
let logString = '';
|
|
|
|
var options = {
|
|
follow: false,
|
|
stdout: true,
|
|
stderr: false,
|
|
timestamps: false
|
|
};
|
|
|
|
var containerName = docker.getContainer(data);
|
|
|
|
containerName.logs(options, function (err, stream) {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
|
|
const readableStream = Readable.from(stream);
|
|
|
|
readableStream.on('data', function (chunk) {
|
|
logString += chunk.toString('utf8');
|
|
});
|
|
|
|
readableStream.on('end', function () {
|
|
resolve(logString);
|
|
});
|
|
});
|
|
});
|
|
}; |