summaryrefslogtreecommitdiff
path: root/Components/CoreDaemon/index.js
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-11-28 17:31:34 +0100
committerMinteck <contact@minteck.org>2022-11-28 17:31:34 +0100
commit7923aa8942b55884320ef2428417e3ee4b121613 (patch)
tree7993632f2898b1998f25b11ce40a8d2eb3d44730 /Components/CoreDaemon/index.js
downloadmistyos-og-7923aa8942b55884320ef2428417e3ee4b121613.tar.gz
mistyos-og-7923aa8942b55884320ef2428417e3ee4b121613.tar.bz2
mistyos-og-7923aa8942b55884320ef2428417e3ee4b121613.zip
Initial commitHEADmane
Diffstat (limited to 'Components/CoreDaemon/index.js')
-rw-r--r--Components/CoreDaemon/index.js352
1 files changed, 352 insertions, 0 deletions
diff --git a/Components/CoreDaemon/index.js b/Components/CoreDaemon/index.js
new file mode 100644
index 0000000..5e830b8
--- /dev/null
+++ b/Components/CoreDaemon/index.js
@@ -0,0 +1,352 @@
+let arguments = JSON.parse(process.argv[2]);
+const chalk = require(__dirname + '/../../MistyCore/node_modules/chalk');
+const YAML = require(__dirname + '/../../MistyCore/node_modules/yaml');
+const si = require(__dirname + '/../../MistyCore/node_modules/systeminformation');
+const fs = require('fs');
+const net = require("net");
+let systemRoot = "/System/Library";
+
+function size(bytes) {
+ if (bytes > 1024) {
+ if (bytes > 1024**2) {
+ if (bytes > 1024**3) {
+ if (bytes > 1024**4) {
+ return (bytes / 1024**4).toFixed(2) + "T";
+ } else {
+ return (bytes / 1024**3).toFixed(2) + "G";
+ }
+ } else {
+ return (bytes / 1024**2).toFixed(2) + "M";
+ }
+ } else {
+ return (bytes / 1024).toFixed(2) + "K";
+ }
+ } else {
+ return bytes + "B";
+ }
+}
+
+function waitForState(daemon, status) {
+ return new Promise((resolve) => {
+ let i = 0;
+ let me = setInterval(() => {
+ if (status === "running") {
+ if (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() !== "-1" && fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() !== "-3" && fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() !== "-2") {
+ clearInterval(me);
+
+ if (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() !== "0") {
+ console.log(daemon + " is now running with PID " + fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim());
+ } else if (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() !== "-2") {
+ console.log(daemon + " has failed\nRun 'CoreDaemon -Status " + daemon + "' for details; 'CoreDaemon -ForceStop " + daemon + "' to force stop.");
+ process.exit(2);
+ } else {
+ console.log(daemon + " has now started");
+ }
+
+ resolve();
+ }
+ } else if (status === "stopped") {
+ if (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() === "-1") {
+ clearInterval(me);
+ console.log(daemon + " is now stopped");
+ resolve();
+ }
+ if (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString().trim() === "-2") {
+ clearInterval(me);
+ console.log(daemon + " has failed\nRun 'CoreDaemon -Status " + daemon + "' for details; 'CoreDaemon -ForceStop " + daemon + "' to force stop.");
+ process.exit(2);
+ resolve();
+ }
+ } else {
+ clearInterval(me);
+ resolve();
+ }
+
+ if (i >= 100) {
+ console.log("Timed out waiting for " + daemon + " after 10 seconds. Has the launch daemon failed?\nRun 'CoreDaemon -Status " + daemon + "' for details; 'CoreDaemon -ForceStop " + daemon + "' to force stop.");
+ process.exit(2);
+ }
+
+ i++;
+ }, 100);
+ });
+}
+
+(async () => {
+ let processes = (await si.processes()).list;
+
+ if (arguments['start'] && !arguments['stop'] && !arguments['restart'] && !arguments['status'] && !arguments['forcestop']) {
+ if (arguments['_finals'].length > 0) {
+ if (!fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0])) {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("No such launch daemon: ") + arguments['_finals'][0]);
+ return;
+ }
+
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ if (state === "running") {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("The launch daemon is not stopped or failed"));
+ return;
+ }
+
+ const socket = net.createConnection(systemRoot + "/../Volumes/VM/MistyCore-Socket", () => {
+ console.log("Waiting for " + arguments['_finals'][0] + " to have started...");
+ socket.write(JSON.stringify({
+ action: "SERVICE",
+ payload: {
+ option: "start",
+ service: arguments['_finals'][0] + ".yml"
+ }
+ }));
+ waitForState(arguments['_finals'][0], "running");
+ });
+ } else {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("Missing operand"));
+ }
+ } else if (arguments['stop'] && !arguments['start'] && !arguments['restart'] && !arguments['status'] && !arguments['forcestop']) {
+ if (arguments['_finals'].length > 0) {
+ if (!fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0])) {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("No such launch daemon: ") + arguments['_finals'][0]);
+ return;
+ }
+
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ if (state !== "running") {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("The launch daemon is not running"));
+ return;
+ }
+
+ const socket = net.createConnection(systemRoot + "/../Volumes/VM/MistyCore-Socket", async () => {
+ console.log("Waiting for " + arguments['_finals'][0] + " to have stopped...");
+ socket.write(JSON.stringify({
+ action: "SERVICE",
+ payload: {
+ option: "stop",
+ service: arguments['_finals'][0] + ".yml"
+ }
+ }));
+ await waitForState(arguments['_finals'][0], "stopped");
+ });
+ } else {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("Missing operand"));
+ }
+ } else if (arguments['forcestop'] && !arguments['start'] && !arguments['restart'] && !arguments['status'] && !arguments['stop']) {
+ if (arguments['_finals'].length > 0) {
+ if (!fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0])) {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("No such launch daemon: ") + arguments['_finals'][0]);
+ return;
+ }
+
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ if (state !== "running") {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("The launch daemon is not running"));
+ return;
+ }
+
+ const socket = net.createConnection(systemRoot + "/../Volumes/VM/MistyCore-Socket", async () => {
+ console.log("Waiting for " + arguments['_finals'][0] + " to have force-stopped...");
+ socket.write(JSON.stringify({
+ action: "SERVICE",
+ payload: {
+ option: "forcestop",
+ service: arguments['_finals'][0] + ".yml"
+ }
+ }));
+ await waitForState(arguments['_finals'][0], "stopped");
+ });
+ } else {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("Missing operand"));
+ }
+ } else if (arguments['restart'] && !arguments['stop'] && !arguments['start'] && !arguments['status'] && !arguments['forcestop']) {
+ if (arguments['_finals'].length > 0) {
+ if (!fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0])) {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("No such launch daemon: ") + arguments['_finals'][0]);
+ return;
+ }
+
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ if (state !== "running") {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("The launch daemon is not running"));
+ return;
+ }
+
+ const socket = net.createConnection(systemRoot + "/../Volumes/VM/MistyCore-Socket", async () => {
+ console.log("Waiting for " + arguments['_finals'][0] + " to have restarted...");
+ socket.write(JSON.stringify({
+ action: "SERVICE",
+ payload: {
+ option: "restart",
+ service: arguments['_finals'][0] + ".yml"
+ }
+ }));
+ await waitForState(arguments['_finals'][0], "running");
+ });
+ } else {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("Missing operand"));
+ }
+ } else if (arguments['status'] && !arguments['stop'] && !arguments['restart'] && !arguments['start'] && !arguments['forcestop']) {
+ if (arguments['_finals'].length > 0) {
+ if (!fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0])) {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("No such launch daemon: ") + arguments['_finals'][0]);
+ return;
+ }
+
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-3": state = "starting"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ let name = arguments['_finals'][0], displayName = arguments['_finals'][0];
+ let service = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name + ".yml").toString());
+
+ let memoryUsage;
+ let pid;
+ let parent = "-";
+
+ switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()) {
+ case "0":
+ case "-1":
+ case "-2":
+ case "-3":
+ memoryUsage = "-";
+ pid = "-";
+ break;
+
+ default:
+ let _processInfo = processes.filter(i => i.pid === parseInt(fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString()));
+
+ if (_processInfo.length > 0) {
+ pid = fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString() + " (" + _processInfo[0].name + ")";
+
+ let _parentInfo = processes.filter(i => i.pid === _processInfo[0].parentPid);
+ if (_parentInfo.length > 0) {
+ parent = _processInfo[0].parentPid + " (" + _parentInfo[0].name + ")";
+ } else {
+ parent = _processInfo[0].parentPid;
+ }
+
+ memoryUsage = size(_processInfo[0].memVsz);
+ } else {
+ pid = fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + arguments['_finals'][0]).toString();
+ memoryUsage = "-";
+ }
+
+ break;
+ }
+
+ let statusColor;
+
+ switch (state) {
+ case "running":
+ statusColor = chalk.green("running");
+ break;
+
+ case "starting":
+ statusColor = chalk.yellow("starting");
+ break;
+
+ case "failed":
+ statusColor = chalk.cyan("failed");
+ break;
+
+ case "stopped":
+ statusColor = chalk.red("stopped");
+ break;
+
+ default:
+ statusColor = chalk.gray("unknown");
+ break;
+ }
+
+ let reachDate = "-";
+
+ if (fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + arguments['_finals'][0])) {
+ reachDate = new Date(parseInt(fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + arguments['_finals'][0]).toString())).toString();
+ }
+
+ let autoStart;
+ if (service.metadata.target === false) {
+ autoStart = chalk.gray("manual");
+ } else {
+ if (!isNaN(parseInt(service.metadata.target)) && parseInt(service.metadata.target) > -1 && parseInt(service.metadata.target) < 10) {
+ autoStart = "on target " + parseInt(service.metadata.target);
+ } else {
+ autoStart = chalk.red("invalid");
+ }
+ }
+
+ console.log(name + " - " + (service.metadata.description ?? "<no description>"));
+ console.log(chalk.cyan(" Loaded from:") + " " + systemRoot + "/LaunchDaemons/" + name + ".yml");
+ console.log(chalk.cyan(" Auto-start:") + " " + autoStart);
+ console.log(chalk.cyan(" Status:") + " " + statusColor);
+ console.log(chalk.cyan(" Reached:") + " " + reachDate);
+ console.log(chalk.cyan(" Main PID:") + " " + pid);
+ console.log(chalk.cyan(" Initiator:") + " " + parent);
+ console.log(chalk.cyan(" Memory:") + " " + memoryUsage);
+
+ if (service.commands.stop || service.commands.restart) {
+ console.log(chalk.cyan(" Type:") + " MistyCore:RunOnce");
+ } else {
+ console.log(chalk.cyan(" Type:") + " MistyCore:Daemon");
+ }
+
+ console.log("");
+
+ switch (state) {
+ case "running":
+ console.log("Run 'Logger -Unit " + name + "' to view logs; 'CoreDaemon -Stop " + name + "' to stop.");
+ break;
+
+ case "starting":
+ console.log("Run 'Logger -Unit " + name + "' to view logs; 'CoreDaemon -ForceStop " + name + "' to abort.");
+ break;
+
+ case "failed":
+ console.log("Run 'Logger -Unit " + name + "' to view logs; 'CoreDaemon -Start " + name + "' to start.");
+ break;
+
+ case "stopped":
+ console.log("Run 'Logger -Unit " + name + "' to view logs; 'CoreDaemon -Start " + name + "' to start.");
+ break;
+
+ default:
+ console.log("Run 'Logger -Unit " + name + "' to view logs");
+ break;
+ }
+ } else {
+ for (let name of fs.readdirSync(systemRoot + "/LaunchDaemons")) {
+ let daemon = name.substring(0, name.length - 4);
+
+ if (fs.existsSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon)) {
+ let state; switch (fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + daemon).toString()) { case "0": state = "running"; break; case "-1": state = "stopped"; break; case "-3": state = "starting"; break; case "-2": state = "failed"; break; default: state = "running"; break }
+
+ switch (state) {
+ case "running":
+ console.log(" [ " + chalk.green("+") + " ] " + daemon);
+ break;
+
+ case "starting":
+ console.log(" [ " + chalk.yellow("W") + " ] " + daemon);
+ break;
+
+ case "failed":
+ console.log(" [ " + chalk.cyan("x") + " ] " + daemon);
+ break;
+
+ case "stopped":
+ console.log(" [ " + chalk.red("-") + " ] " + daemon);
+ break;
+
+ default:
+ console.log(" [ " + chalk.gray("?") + " ] " + daemon);
+ break;
+ }
+ } else {
+ console.log(" [ " + chalk.gray("?") + " ] " + daemon);
+ }
+ }
+ }
+ } else {
+ console.log(chalk.bgYellow.white("<!>") + " " + chalk.yellow("Only exactly one operation can be done at a time"));
+ }
+})(); \ No newline at end of file