Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
Refactor build-linux-bundle.mjs to include package version and build number from environment variables and package.json. Update headless.js to streamline initialization and improve error handling. Introduce serverVersion.js to centralize version information retrieval, replacing redundant code in localserver.js. Enhance logging in index.js to display build number and version more clearly.
185 lines
4.9 KiB
JavaScript
185 lines
4.9 KiB
JavaScript
import { fileURLToPath } from "node:url";
|
|
import path from "node:path";
|
|
import { loadConfig } from "./config.js";
|
|
import axios from "axios";
|
|
import log4js from "log4js";
|
|
import { createElectronWindow } from "./electron/window.js";
|
|
import { setupIPC } from "./electron/ipc.js";
|
|
import { LOCAL_SERVER_PORT, LocalServer } from "./localserver/localserver.js";
|
|
import { SocketClient } from "./socket/socketclient.js";
|
|
|
|
if (!process.env.NODE_ENV) {
|
|
process.env.NODE_ENV = "production";
|
|
}
|
|
|
|
// Load configuration
|
|
const config = loadConfig();
|
|
|
|
const logger = log4js.getLogger("App");
|
|
logger.level = config.logLevel;
|
|
|
|
const isHeadless = process.argv.includes("--headless");
|
|
const isInfo = process.argv.includes("--info");
|
|
|
|
const printerHostInfo = (host) => {
|
|
var ref = host?._reference || "Unknown";
|
|
|
|
if (ref != "Unknown") {
|
|
ref = "HST:" + ref;
|
|
}
|
|
|
|
logger.info("Reference:", ref);
|
|
logger.info("Name:", host?.name || "Unknown");
|
|
logger.info("Tags: -", host?.tags?.[0] || "n/a");
|
|
for (var i = 0; i < host?.tags?.length - 1; i++) {
|
|
const tag = host?.tags[i + 1];
|
|
logger.info(" -", tag);
|
|
}
|
|
logger.info("State:", host?.state?.type || "Unknown");
|
|
};
|
|
|
|
function getArgValue(flag) {
|
|
const withEquals = process.argv.find((arg) => arg.startsWith(`${flag}=`));
|
|
if (withEquals) {
|
|
return withEquals.slice(flag.length + 1);
|
|
}
|
|
|
|
const index = process.argv.indexOf(flag);
|
|
if (index !== -1 && index + 1 < process.argv.length) {
|
|
return process.argv[index + 1];
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
const otpCode = getArgValue("--otp") || undefined;
|
|
|
|
async function checkRunning() {
|
|
try {
|
|
const response = await axios.get(
|
|
`http://127.0.0.1:${LOCAL_SERVER_PORT}/info`,
|
|
{ timeout: 1000 },
|
|
);
|
|
if (response.data?.running === true) {
|
|
return response.data;
|
|
}
|
|
} catch (err) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function authenticateWithOtp(otpCode) {
|
|
try {
|
|
const response = await axios.post(
|
|
`http://127.0.0.1:${LOCAL_SERVER_PORT}/otpAuth`,
|
|
{ otp: otpCode },
|
|
{ timeout: 30000 },
|
|
);
|
|
return response.data;
|
|
} catch (err) {
|
|
if (err.response?.data) {
|
|
return err.response.data;
|
|
}
|
|
throw new Error("Failed to authenticate with OTP");
|
|
}
|
|
}
|
|
export async function init(options = {}) {
|
|
const headless = options.headless ?? isHeadless;
|
|
|
|
logger.info("⌛ Checking if Farm Control Server is running...");
|
|
|
|
const runningServer = await checkRunning();
|
|
|
|
if (otpCode != undefined || isInfo == true) {
|
|
logger.info("✔ Farm Control Server is running.");
|
|
}
|
|
|
|
if (isInfo) {
|
|
const buildNumber =
|
|
runningServer.buildNumber ?? runningServer.build ?? "n/a";
|
|
|
|
logger.info("-----FarmControl Server-----");
|
|
logger.info(
|
|
"Version:",
|
|
runningServer.version ? `v${runningServer.version}` : "n/a",
|
|
);
|
|
logger.info(
|
|
"Build:",
|
|
buildNumber === "dev" ? "dev" : `b${buildNumber}`,
|
|
);
|
|
logger.info(
|
|
"Authenticated:",
|
|
runningServer.authenticated == true ? "Yes" : "No",
|
|
);
|
|
logger.info("------------Host------------");
|
|
printerHostInfo(runningServer.host);
|
|
logger.info("----------------------------");
|
|
return runningServer;
|
|
}
|
|
|
|
if (otpCode != undefined) {
|
|
logger.info("🔒 Authenticating with OTP...");
|
|
const authenticatedServer = await authenticateWithOtp(otpCode);
|
|
if (authenticatedServer.valid == false) {
|
|
logger.error(
|
|
"✘ Failed to authenticate with OTP -",
|
|
authenticatedServer.error,
|
|
);
|
|
} else {
|
|
logger.info("✔ Authenticated with OTP.");
|
|
logger.info("------------Host------------");
|
|
printerHostInfo(authenticatedServer.host);
|
|
logger.info("----------------------------");
|
|
return authenticatedServer;
|
|
}
|
|
return authenticatedServer;
|
|
}
|
|
|
|
if (runningServer != false) {
|
|
logger.warn("✘ Farm Control Server is already running.");
|
|
return runningServer;
|
|
}
|
|
|
|
if (!headless) {
|
|
// Create Electron window first
|
|
logger.info("Creating electron window...");
|
|
await createElectronWindow().catch((err) => {
|
|
logger.warn("Failed to create Electron window:", err);
|
|
});
|
|
|
|
// Setup IPC communication after window is created
|
|
setupIPC().catch((err) => {
|
|
logger.warn("Failed to setup IPC:", err);
|
|
});
|
|
} else {
|
|
logger.info("Running in headless mode. Skipping window creation.");
|
|
}
|
|
|
|
const socketClient = new SocketClient();
|
|
// Make socket client globally accessible for IPC handlers
|
|
global.socketClient = socketClient;
|
|
|
|
const localServer = new LocalServer(socketClient);
|
|
await localServer.start();
|
|
|
|
socketClient.connect();
|
|
|
|
process.on("SIGINT", () => {
|
|
logger.info("Shutting down...");
|
|
socketClient.disconnect();
|
|
localServer.stop();
|
|
process.exit(0);
|
|
});
|
|
}
|
|
|
|
const isMainModule =
|
|
process.argv[1] &&
|
|
fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
|
|
if (isMainModule && !process.env.FC_HEADLESS_ENTRY) {
|
|
init().catch((err) => {
|
|
logger.error(err.message);
|
|
process.exit(1);
|
|
});
|
|
}
|