86 lines
3.0 KiB
JavaScript
86 lines
3.0 KiB
JavaScript
const {Client} = require("ssh2");
|
|
const fs = require("fs");
|
|
|
|
const services = fs.readdirSync(__dirname + "/apps").map((item) => item.replace(".js", ""));
|
|
module.exports = (io, socket) => {
|
|
let session = new Client();
|
|
let connected = false;
|
|
let queue = [];
|
|
|
|
socket.on("disconnect", () => session.end());
|
|
|
|
socket.on("login", (msg) => {
|
|
if (session._sock || connected) return;
|
|
|
|
session.on("ready", () => {
|
|
connected = true;
|
|
socket.emit("login", {status: "success"});
|
|
}).connect({host: msg.host, port: msg.port || 22, username: msg.username || "root",
|
|
password: msg.password, privateKey: msg.privateKey
|
|
}).on("error", (err) => {
|
|
socket.emit("login", {status: "failed", message: err.message});
|
|
});
|
|
});
|
|
|
|
const execQueue = () => {
|
|
if (queue.length === 0) {
|
|
socket.emit("install", {status: "finished"});
|
|
return;
|
|
}
|
|
|
|
const {command, step} = queue[0];
|
|
|
|
session.exec(command, (err, stream) => {
|
|
if (err) return socket.emit("install", {status: "failed", message: err.message, step});
|
|
stream.on("close", (code) => {
|
|
if (code !== 0) {
|
|
queue = [];
|
|
return socket.emit("install", {status: "failed", message: "Error while installing", step});
|
|
}
|
|
socket.emit("install", {status: "success", step});
|
|
queue.shift();
|
|
execQueue();
|
|
}).on("data", () => {});
|
|
});
|
|
}
|
|
|
|
socket.on("install", (msg) => {
|
|
if (!connected) return socket.emit("install", {status: "failed", message: "Not connected"});
|
|
if (queue.length > 0) return socket.emit("install", {status: "failed", message: "Another installation is in progress"});
|
|
|
|
const serviceName = msg.name.toLowerCase();
|
|
|
|
if (!services.includes(serviceName)) return socket.emit("install", {status: "failed", message: "Service not found"});
|
|
|
|
const app = require(`./apps/${serviceName}`);
|
|
|
|
let infoData = [];
|
|
|
|
app.steps.map((mappedItem, index) => {
|
|
let item = {...mappedItem};
|
|
Object.keys(app.variables).map((key) => {
|
|
item.command = item.command.replace(new RegExp(`{${key}}`, "g"), msg.data[key] || app.variables[key]);
|
|
});
|
|
|
|
if (item.condition) {
|
|
const [key, value] = item.condition.split("=");
|
|
if (msg?.data[key] !== value) return;
|
|
}
|
|
|
|
if (item.replace) {
|
|
Object.keys(item.replace).map((key) => {
|
|
item.command = item.command.replace(new RegExp(`{${key}}`, "g"), item.replace[key]());
|
|
});
|
|
}
|
|
|
|
queue.push({...item, step: index+1});
|
|
|
|
if (item.description)
|
|
infoData.push({description: item.description, step: index+1});
|
|
});
|
|
|
|
socket.emit("install", {status: "info", data: infoData});
|
|
|
|
execQueue();
|
|
});
|
|
} |