Tools for building the sdcard image
This commit is contained in:
149
scripts/util.js
Normal file
149
scripts/util.js
Normal file
@@ -0,0 +1,149 @@
|
||||
const { execSync } = require("child_process");
|
||||
const { statSync } = require("fs");
|
||||
const { exit } = require("process");
|
||||
|
||||
module.exports = {
|
||||
info,
|
||||
runCommand,
|
||||
logErrorAndExit,
|
||||
registerSignalHandler,
|
||||
initSignalHandlers,
|
||||
assertOS,
|
||||
assertEffectiveRoot,
|
||||
assertFileExists,
|
||||
assertInstalled
|
||||
};
|
||||
|
||||
let signalHandlers = [];
|
||||
|
||||
function registerSignalHandler(cb) {
|
||||
signalHandlers.push(cb);
|
||||
|
||||
return () => (signalHandlers = signalHandlers.filter(h => h === cb));
|
||||
}
|
||||
|
||||
function initSignalHandlers() {
|
||||
process.on("SIGTERM", handle);
|
||||
process.on("SIGINT", handle);
|
||||
process.on("SIGHUP", handle);
|
||||
}
|
||||
|
||||
function handle(signal) {
|
||||
console.log(`Received ${signal}`);
|
||||
|
||||
for (const handler of signalHandlers) {
|
||||
handler(signal);
|
||||
}
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
console.log(`\n${msg}`);
|
||||
}
|
||||
|
||||
function runCommand(command, _options) {
|
||||
const options = {
|
||||
encoding: "utf8",
|
||||
..._options,
|
||||
shell: true
|
||||
};
|
||||
|
||||
const { onError } = options;
|
||||
delete options["onError"];
|
||||
|
||||
try {
|
||||
const result = execSync(command, options);
|
||||
|
||||
return (typeof result === "string")
|
||||
? result.trim()
|
||||
: result;
|
||||
} catch (error) {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function logErrorAndExit(msg, error) {
|
||||
const lines = msg.split("\n");
|
||||
|
||||
// Get rid of leading blank lines
|
||||
while (lines.length) {
|
||||
if (lines[0].trim().length == 0) {
|
||||
lines.shift();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of trailing blank lines
|
||||
while (lines.length) {
|
||||
if (lines.at(-1).trim().length == 0) {
|
||||
lines.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const [ whitespace ] = lines[0].match(/^\s*/);
|
||||
|
||||
console.error(lines
|
||||
.map(line => line.replace(whitespace, "").trimEnd())
|
||||
.join("\n")
|
||||
);
|
||||
|
||||
if (error) {
|
||||
console.error("Error:", JSON.stringify({
|
||||
name: error.name,
|
||||
code: error.code,
|
||||
status: error.status,
|
||||
signal: error.signal,
|
||||
error: error.error,
|
||||
pid: error.pid,
|
||||
output: error.output,
|
||||
msg: error.msg,
|
||||
message: error.message
|
||||
}, null, 4));
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function assertOS() {
|
||||
if (process.platform !== "linux") {
|
||||
logErrorAndExit("This script requires linux.");
|
||||
}
|
||||
}
|
||||
|
||||
function assertEffectiveRoot() {
|
||||
if (process.geteuid() !== 0) {
|
||||
logErrorAndExit("Please run this script as root");
|
||||
}
|
||||
}
|
||||
|
||||
function assertFileExists(file) {
|
||||
const stats = statSync(file);
|
||||
if (!stats.isFile) {
|
||||
logErrorAndExit(`${file} does not exist`);
|
||||
}
|
||||
}
|
||||
|
||||
function assertInstalled(tools) {
|
||||
const missingTools = [];
|
||||
|
||||
for (const tool of tools) {
|
||||
runCommand(`command -v ${tool}`, {
|
||||
onError: () => missingTools.push(tool)
|
||||
});
|
||||
}
|
||||
|
||||
if (missingTools.length) {
|
||||
logErrorAndExit(`
|
||||
This script requires some tools that are not installed.
|
||||
|
||||
Install them via:
|
||||
apt-get install -y ${missingTools.join(" ")}
|
||||
`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user