"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadPL2Module = void 0; const node_fs_1 = __importDefault(require("node:fs")); const systemStateContainer_1 = require("../../state/systemStateContainer"); const runCmd_1 = require("../../helpers/runCmd"); const logging_1 = require("../../logging"); const getProLinuxInfo_1 = require("../../helpers/getProLinuxInfo"); const secureSwitchRole_1 = require("./server/secureSwitchRole"); const config = systemStateContainer_1.state.config; async function setHostname() { // Set system hostname if (config.pl2.hostname) { logging_1.log.info("Setting system hostname to " + config.pl2.hostname); await (0, runCmd_1.runCmd)("hostnamectl", ["--transient", "set-hostname", config.pl2.hostname]); await (0, runCmd_1.runCmd)("sh", ["-c", `echo ${config.pl2.hostname} > /etc/hostname`]); } else { logging_1.log.error("No hostname configured, skipping hostname setup"); } } async function startDeviceSpecificServices() { const prolinuxInfo = await (0, getProLinuxInfo_1.getProLinuxInfo)(); // Since sineware-arm64 is a generic image, detect models at runtime let compatible = "unknown"; try { compatible = node_fs_1.default.readFileSync("/sys/firmware/devicetree/base/compatible", "utf-8"); } catch (e) { logging_1.log.error("Failed to read compatible from /sys/firmware/devicetree/base/compatible: " + e.message); } logging_1.log.info("Running on platform '" + prolinuxInfo.deviceinfoCodename + "' with comaptible '" + compatible + "'"); // SDM845 Modem Support if (compatible.includes("qcom,sdm845")) { logging_1.log.info("Starting SDM845 Support Services..."); // append "test-quick-suspend-resume" argument to ExecStart for ModemManager /usr/lib/systemd/system/ModemManager.service // making sure it doesn't already exist await (0, runCmd_1.runCmd)("/usr/bin/bash", ["-c", String.raw `if ! grep -q "test-quick-suspend-resume" /usr/lib/systemd/system/ModemManager.service; then sed -i 's/ExecStart=\/usr\/bin\/ModemManager/ExecStart=\/usr\/bin\/ModemManager --test-quick-suspend-resume/g' /usr/lib/systemd/system/ModemManager.service; fi`]); //qrtr-ns replaced with in-kernel? //await runCmd("systemctl", ["start", "qrtr-ns"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "rmtfs"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "msm-modem-uim-selection"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "pd-mapper"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "tqftpserv"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "ModemManager"]); } // PinePhone/PinePhone Pro if (compatible.includes("pine64,pinephone") || compatible.includes("pine64,pinephone-pro")) { logging_1.log.info("Starting EG25 Modem Support Services..."); await (0, runCmd_1.runCmd)("systemctl", ["start", "eg25-manager"]); await (0, runCmd_1.runCmd)("systemctl", ["start", "ModemManager"]); } } async function startPasswordService() { // Start password service logging_1.log.info("Starting password service..."); // If config.pl2.user_shadow is not "", then replace the user: line in /etc/shadow with it if (config.pl2.user_shadow !== "") { logging_1.log.info("Setting user password from config..."); const shadow = node_fs_1.default.readFileSync("/etc/shadow", "utf-8"); const newShadow = shadow.split("\n").map((line) => { if (line.startsWith("user:")) { return config.pl2.user_shadow; } else { return line; } }).join("\n"); await node_fs_1.default.promises.writeFile("/etc/shadow", newShadow); } // Watches /etc/shadow for password changes, and persists them to the config systemStateContainer_1.state.untracked.passwordServiceWatcher = node_fs_1.default.watch("/etc/shadow", async (eventType, filename) => { logging_1.log.info("Shadow file (password) updated: " + eventType + ", " + filename); const shadow = await node_fs_1.default.promises.readFile("/etc/shadow", "utf-8"); const user_shadow = shadow.split("\n").filter((line) => { return line.startsWith("user:"); })[0]; config.pl2.user_shadow = user_shadow; }); } async function startNMNetworksService() { // we know that saved networks are in /etc/NetworkManager/system-connections // this function is similar to the password service, in that it watches for changes to the network configuration // but here we instead copy the file to /sineware/data/customization/etc/NetworkManager/system-connections logging_1.log.info("Starting NetworkManager networks sync service..."); systemStateContainer_1.state.untracked.NMNetworksServiceWatcher = node_fs_1.default.watch("/etc/NetworkManager/system-connections", async (eventType, filename) => { try { logging_1.log.info("NetworkManager configuration updated: " + eventType + ", " + filename); const network = await node_fs_1.default.promises.readFile("/etc/NetworkManager/system-connections/" + filename, "utf-8"); const targetDir = "/sineware/data/customization/etc/NetworkManager/system-connections"; await node_fs_1.default.promises.mkdir(targetDir, { recursive: true }); await node_fs_1.default.promises.writeFile(`${targetDir}/${filename}`, network); } catch (e) { // NM creates temp files that can disappear before we can read it console.log("Caught in NMNetworksServiceWatcher", e); } }); } /* Boot-time setup */ async function loadPL2Module() { await setHostname(); await startDeviceSpecificServices(); await startPasswordService(); await startNMNetworksService(); // ensure /sineware/data/server is created await (0, runCmd_1.runCmd)("mkdir", ["-pv", "/sineware/data/server"]); if (systemStateContainer_1.state.extraConfig.server_roles.webserver?.enabled) { logging_1.log.info("Starting Webserver Server Role..."); logging_1.log.info("Stub: todo"); // Start webserver } if (systemStateContainer_1.state.extraConfig.server_roles.secure_switch?.enabled) { try { await (0, secureSwitchRole_1.startSecureSwitchRole)(); } catch (e) { logging_1.log.error("Failed to start SecureSwitch Appliance Server Role: " + e.message); } } logging_1.log.info("ProLinux 2 Module loaded!"); // return cleanup function return async () => { logging_1.log.info("Cleaning up PL2 Module..."); await (0, secureSwitchRole_1.stopSecureSwichRole)(); }; } exports.loadPL2Module = loadPL2Module; //# sourceMappingURL=index.js.map