systemd-to-openrc/magic.js
Lenny Andreu 331d7980be Add working module based clone from original openrc-run generator
See http://openrc.run/

This able to split the same working piece as a node and browser module
2025-05-17 20:38:35 -04:00

315 lines
No EOL
8.9 KiB
JavaScript

function parseINIString(data) {
var regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,
param: /^\s*([^=]+?)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/
};
var value = {};
var lines = data.split(/[\r\n]+/);
var section = null;
lines.forEach(function (line) {
if (regex.comment.test(line)) {
return;
} else if (regex.param.test(line)) {
var match = line.match(regex.param);
if (section) {
value[section][match[1]] = match[2];
} else {
value[match[1]] = match[2];
}
} else if (regex.section.test(line)) {
var match = line.match(regex.section);
value[match[1]] = {};
section = match[1];
} else if (line.length == 0 && section) {
section = null;
}
});
return value;
}
function parseEnvironment(raw) {
var parts = raw.match(/\S+|"[^"]+"/g)
console.log(parts);
var result = {};
for (var i = 0; i < parts.length; i++) {
var key = parts[i].substr(0, parts[i].indexOf('='));
console.log("Key is", key);
result[key] = parts[i].substr(parts[i].indexOf('=') + 1);
}
return result;
}
function validate(parsed) {
if (!parsed.hasOwnProperty('Service')) {
return "No [Service] section found";
}
if (parsed.Service.hasOwnProperty('EnvironmentFile')) {
return "Environment= is not supported in openrc";
}
return null;
}
function unitToRC(name) {
var table = {
"network.target": "net",
"remote-fs.target": "netmount",
"nss-lookup.target": "dns"
}
if (table.hasOwnProperty(name)) {
return table[name];
} else {
return name.substr(0, name.indexOf('.'));
}
}
function unitsToRC(units) {
var names = units.split(/[ ]+/);
var result = "";
console.log(names);
for (var i = 0; i < names.length; i++) {
result += unitToRC(names[i]) + " ";
}
return result;
}
function generateDepend(unit) {
var depend = "";
if (unit.Unit.hasOwnProperty('After')) {
depend += "\tafter " + unitsToRC(unit.Unit.After) + "\n";
}
if (unit.Unit.hasOwnProperty('Before')) {
depend += "\tbefore " + unitsToRC(unit.Unit.Before) + "\n";
}
if (unit.Unit.hasOwnProperty('Requires')) {
depend += "\tneed " + unitsToRC(unit.Unit.Requires) + "\n";
}
if (unit.Unit.hasOwnProperty('Wants')) {
depend += "\tuse " + unitsToRC(unit.Unit.Wants) + "\n";
}
if (depend.length > 0) {
return "\ndepend() {\n" + depend + "}\n";
}
return "";
}
function generateSuperviseArgs(unit) {
var result = "";
if (unit.Service.hasOwnProperty('WorkingDirectory')) {
result += ' -d ' + unit.Service.WorkingDirectory;
}
if (unit.Service.hasOwnProperty('RootDirectory')) {
result += ' -r ' + unit.Service.RootDirectory;
}
if (unit.Service.hasOwnProperty('UMask')) {
result += ' -k ' + unit.Service.UMask;
}
if (unit.Service.hasOwnProperty('Nice')) {
result += ' -N ' + unit.Service.Nice;
}
if (unit.Service.hasOwnProperty('IOSchedulingClass')) {
if (unit.Service.hasOwnProperty('IOSchedulingPriority')) {
result += ' -I ' + unit.Service.IOSchedulingClass + ":" + unit.Service.IOSchedulingPriority;
} else {
result += ' -I ' + unit.Service.IOSchedulingClass;
}
}
if (unit.Service.hasOwnProperty('StandardOutput')) {
if (unit.Service.StandardOutput.substr(0, 5) === "file:") {
result += ' -1 ' + unit.Service.StandardOutput.substr(5);
if (!unit.Service.hasOwnProperty('StandardError')) {
unit.Service.StandardError = unit.Service.StandardOutput;
}
}
}
if (unit.Service.hasOwnProperty('StandardError')) {
if (unit.Service.StandardError.substr(0, 5) === "file:") {
result += ' -2 ' + unit.Service.StandardError.substr(5);
}
}
if (unit.Service.hasOwnProperty('Environment')) {
var env = parseEnvironment(unit.Service.Environment);
for (var key in env) {
if (env.hasOwnProperty(key)) {
result += ' -e ' + key + '=\\"' + env[key] + '\\"';
console.log(key, env[key]);
}
}
}
if (result.length > 0) {
return 'supervise_daemon_args="' + result + '"\n';
} else {
return '';
}
}
function generateSSDArgs(unit) {
var result = "";
if (unit.Service.hasOwnProperty('WorkingDirectory')) {
result += ' -d ' + unit.Service.WorkingDirectory;
}
if (unit.Service.hasOwnProperty('RootDirectory')) {
result += ' -r ' + unit.Service.RootDirectory;
}
if (unit.Service.hasOwnProperty('UMask')) {
result += ' -k ' + unit.Service.UMask;
}
if (unit.Service.hasOwnProperty('Nice')) {
result += ' -N ' + unit.Service.Nice;
}
if (unit.Service.hasOwnProperty('IOSchedulingClass')) {
if (unit.Service.hasOwnProperty('IOSchedulingPriority')) {
result += ' -I ' + unit.Service.IOSchedulingClass + ":" + unit.Service.IOSchedulingPriority;
} else {
result += ' -I ' + unit.Service.IOSchedulingClass;
}
}
if (unit.Service.hasOwnProperty('CPUSchedulingPolicy')) {
if (unit.Service.hasOwnProperty('CPUSchedulingPriority')) {
result += ' -I ' + unit.Service.CPUSchedulingPolicy + ":" + unit.Service.CPUSchedulingPriority;
} else {
result += ' -I ' + unit.Service.CPUSchedulingPolicy;
}
}
if (result.length > 0) {
return 'start_stop_daemon_args="' + result + '"\n';
} else {
return '';
}
}
function generateForking(unit) {
var cmd = unit.Service.ExecStart;
var pidfile = unit.Service.PIDFile;
var executable = cmd.substr(0, cmd.indexOf(' '));
var args = cmd.substr(cmd.indexOf(' ') + 1);
var result = "";
result += 'command="' + executable + '"\n';
result += 'command_args="' + args + '"\n';
result += 'pidfile="' + pidfile + '"\n';
return result;
}
function generateSimple(unit) {
var cmd = unit.Service.ExecStart;
var executable = cmd.substr(0, cmd.indexOf(' '));
var args = cmd.substr(cmd.indexOf(' ') + 1);
var result = "";
result += 'supervisor="supervise-daemon"\n';
result += 'command="' + executable + '"\n';
result += 'command_args="' + args + '"\n';
return result;
}
function generateOneshot(unit) {
var cmd = unit.Service.ExecStart;
var executable = cmd.substr(0, cmd.indexOf(' '));
var args = cmd.substr(cmd.indexOf(' ') + 1);
var result = "";
result += 'command="' + executable + '"\n';
result += 'command_args="' + args + '"\n';
return result;
}
function generateUser(unit) {
if (unit.Service.hasOwnProperty('User')) {
if (unit.Service.hasOwnProperty('Group')) {
return 'command_user="' + unit.Service.User + ':' + unit.Service.Group + '"\n'
} else {
return 'command_user="' + unit.Service.User + '"\n'
}
}
return "";
}
function generateStop(unit) {
if (!unit.Service.hasOwnProperty('ExecStop')) {
return "";
}
var result = "\nstop() {\n";
result += '\tebegin "Stopping $RC_SVCNAME"\n';
result += '\t' + unit.Service.ExecStop + '\n';
result += '\teend $?\n';
result += "}\n";
return result;
}
function generateReload(unit) {
if (!unit.Service.hasOwnProperty('ExecReload')) {
return "";
}
var result = "\nreload() {\n";
result += '\tebegin "Reloading $RC_SVCNAME"\n';
result += '\t' + unit.Service.ExecReload + '\n';
result += '\teend $?\n';
result += "}\n";
return result;
}
export function convert(raw) {
var parsed = parseINIString(raw);
var validated = validate(parsed);
console.log(parsed);
var result = '#!/sbin/openrc-run\n\nname=$RC_SVCNAME\ndescription="' + parsed.Unit.Description + '"\n';
if (!parsed.Service.hasOwnProperty('Type')) {
var type = 'simple';
} else {
var type = parsed.Service.Type;
}
console.log("Generating " + type + " unit");
switch (type) {
case "simple":
case "exec":
result += generateSimple(parsed);
result += generateSuperviseArgs(parsed);
break;
case "oneshot":
result += generateOneshot(parsed);
result += generateSSDArgs(parsed);
break;
case "forking":
result += generateForking(parsed);
result += generateSSDArgs(parsed);
break;
}
result += generateUser(parsed);
result += generateDepend(parsed);
result += generateStop(parsed);
result += generateReload(parsed);
var response = {
validated,
parsed,
result
}
return response;
}
// This does not run a function like the default