openwrt-packages/utils/uvol/files/uci.uc

138 lines
3.4 KiB
Ucode

// SPDX-License-Identifier: GPL-2.0-or-later
// UCI tools for uvol
// (c) 2022 Daniel Golle <daniel@makrotopia.org>
let uci_spooldir = "/var/spool/uvol";
let init_spooldir = function(void) {
parentdir = fs.stat(fs.dirname(uci_spooldir));
if (!parentdir || parentdir.type != "directory")
fs.mkdir(fs.dirname(uci_spooldir), 0755);
fs.mkdir(uci_spooldir, 0700);
};
uvol_uci = {
uvol_uci_add: function(vol_name, dev_name, mode) {
try {
let autofs = false;
let uuid;
let target;
if (mode == "ro")
autofs = true;
let uciname = replace(vol_name, /[-.]/g, "_");
uciname = replace(uciname, /!([:alnum:]_)/g, "");
let bdinfo_p = fs.popen("/sbin/block info");
let bdinfo_l;
while (bdinfo_l = bdinfo_p.read("line")) {
if (substr(bdinfo_l, 0, length(dev_name) + 1) != dev_name + ":")
continue;
let bdinfo_e = split(bdinfo_l, " ");
shift(bdinfo_e);
for (let bdinfo_a in bdinfo_e) {
let bdinfo_v = split(bdinfo_a, "=");
if (bdinfo_v[0] && bdinfo_v[0] == "UUID") {
uuid = trim(bdinfo_v[1], "\"");
break;
}
}
break;
}
if (!uuid)
return 22;
if (uciname == "_meta")
target = "/tmp/run/uvol/.meta";
else if (substr(uciname, 0, 1) == "_")
return 1;
else
target = sprintf("/tmp/run/uvol/%s", vol_name);
init_spooldir();
let remspool = sprintf("%s/remove-%s", uci_spooldir, uciname);
if (fs.stat(remspool))
fs.unlink(remspool);
let addobj = {};
addobj.name=uciname;
addobj.uuid=uuid;
addobj.target=target;
addobj.options=mode;
addobj.autofs=autofs;
addobj.enabled=true;
let spoolfile = fs.open(sprintf("%s/add-%s", uci_spooldir, uciname), "w");
spoolfile.write(addobj);
spoolfile.close();
} catch(e) {
printf("adding UCI section to spool failed");
return -1;
}
return 0;
},
uvol_uci_remove: function(vol_name) {
let uciname = replace(vol_name, /[-.]/g, "_");
uciname = replace(uciname, /!([:alnum:]_)/g, "");
let addspool = sprintf("%s/add-%s", uci_spooldir, uciname);
if (fs.stat(addspool)) {
fs.unlink(addspool);
return 0;
}
init_spooldir();
let spoolfile = fs.open(sprintf("%s/remove-%s", uci_spooldir, uciname), "w");
spoolfile.write(uciname);
spoolfile.close();
return 0;
},
uvol_uci_commit: function(vol_name) {
try {
let uciname = null;
if (vol_name) {
uciname = replace(vol_name, /[-.]/g, "_");
uciname = replace(uciname, /!([:alnum:]_)/g, "");
}
for (let file in fs.glob(sprintf("%s/*-%s", uci_spooldir, uciname?uciname:"*"))) {
let action = split(fs.basename(file), "-")[0];
let spoolfd = fs.open(file, "r");
let spoolstr = spoolfd.read("all");
spoolfd.close();
fs.unlink(file);
if (action == "remove") {
cursor.delete("fstab", spoolstr);
} else if (action == "add") {
let spoolobj = json(spoolstr);
cursor.set("fstab", spoolobj.name, "mount");
for (key in keys(spoolobj)) {
if (key == "name")
continue;
cursor.set("fstab", spoolobj.name, key, spoolobj[key]);
}
}
}
cursor.commit();
} catch(e) {
printf("committing UCI spool failed");
return -1;
}
return 0;
},
uvol_uci_init: function () {
cursor.load("fstab");
let f = cursor.get("fstab", "@uvol[0]", "initialized");
if (f == 1)
return 0;
cursor.add("fstab", "uvol");
cursor.set("fstab", "@uvol[-1]", "initialized", true);
cursor.commit();
cursor.unload("fstab");
return 0;
}
};