Migrate dhcp options and tags into UCI (#1738)

* Migrate DHCP option/tag files into UCI
This commit is contained in:
Tim Wilkinson 2024-12-02 21:28:41 -08:00 committed by GitHub
parent e011cb61df
commit d87814c2db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 114 additions and 95 deletions

View File

@ -50,7 +50,7 @@ if (request.env.REQUEST_METHOD === "PUT") {
}
}
if (!uciMesh.get("setup", "dhcpreservations")) {
uciMesh.set("setup", "dhcpreservations", "reservation");
uciMesh.set("setup", "dhcpreservations", "dhcpreservations");
}
if (length(reservations)) {
uciMesh.set("setup", "dhcpreservations", "reservation", reservations);
@ -63,28 +63,40 @@ if (request.env.REQUEST_METHOD === "PUT") {
if ("advtags" in request.args) {
configuration.prepareChanges();
const advtags = json(request.args.advtags);
const dhcp = configuration.getDHCP();
let f = fs.open(dhcp.dhcptags, "w");
if (f) {
for (let i = 0; i < length(advtags); i++) {
const t = advtags[i];
f.write(`${t.name} ${t.type} ${t.match}\n`);
}
f.close();
const tags = [];
for (let i = 0; i < length(advtags); i++) {
const t = advtags[i];
push(tags, `${t.name} ${t.type} ${t.match}`);
}
if (!uciMesh.get("setup", "dhcptags")) {
uciMesh.set("setup", "dhcptags", "dhcptags");
}
if (length(tags)) {
uciMesh.set("setup", "dhcptags", "tag", tags);
}
else {
uciMesh.delete("setup", "dhcptags", "tag");
}
uciMesh.commit("setup");
}
if ("advoptions" in request.args) {
configuration.prepareChanges();
const advoptions = json(request.args.advoptions);
const dhcp = configuration.getDHCP();
let f = fs.open(dhcp.dhcpoptions, "w");
if (f) {
for (let i = 0; i < length(advoptions); i++) {
const o = advoptions[i];
f.write(`${o.name} ${o.always ? "force" : "onrequest"} ${o.type} ${o.value}\n`);
}
f.close();
const options = [];
for (let i = 0; i < length(advoptions); i++) {
const o = advoptions[i];
push(options, `${o.name} ${o.always ? "force" : "onrequest"} ${o.type} ${o.value}`);
}
if (!uciMesh.get("setup", "dhcpoptions")) {
uciMesh.set("setup", "dhcpoptions", "dhcpoptions");
}
if (length(options)) {
uciMesh.set("setup", "dhcpoptions", "option", options);
}
else {
uciMesh.delete("setup", "dhcpoptions", "option");
}
uciMesh.commit("setup");
}
print(_R("changes"));
return;
@ -120,7 +132,7 @@ for (let i = 0; i < length(res); i++) {
}
}
}
let f = fs.open(dhcp.leases);
const f = fs.open(dhcp.leases);
if (f) {
for (let l = f.read("line"); length(l); l = f.read("line")) {
// ?, mac, ip, name, ?
@ -142,27 +154,21 @@ if (f) {
}
f.close();
}
f = fs.open(dhcp.dhcptags);
if (f) {
for (let l = f.read("line"); length(l); l = f.read("line")) {
const m = match(replace(l, /\n+$/, ""), /^([^\W_]+)\s(\w+)\s(.+)$/);
if (m) {
const p = replace(replace(replace(m[3], /"/g, "&quot;"), /</g, "&lt;"), />/g, "&gt;");
push(advtags, { name: m[1], type: m[2], match: p });
}
const tags = uciMesh.get("setup", "dhcptags", "tag") || [];
for (let i = 0; i < length(tags); i++) {
const m = match(replace(tags[i], /\n+$/, ""), /^([^\W_]+)\s(\w+)\s(.+)$/);
if (m) {
const p = replace(replace(replace(m[3], /"/g, "&quot;"), /</g, "&lt;"), />/g, "&gt;");
push(advtags, { name: m[1], type: m[2], match: p });
}
f.close();
}
f = fs.open(dhcp.dhcpoptions);
if (f) {
for (let l = f.read("line"); length(l); l = f.read("line")) {
const m = match(replace(l, /\n+$/, ""), /^(\S*)\s(force|onrequest)\s(\d+)\s(.*)$/);
if (m) {
const p = replace(replace(replace(m[4], /"/g, "&quot;"), /</g, "&lt;"), />/g, "&gt;");
push(advoptions, { name: m[1], always: m[2] === "force", type: int(m[3]), value: p });
}
const opts = uciMesh.get("setup", "dhcpoptions", "option") || [];
for (let i = 0; i < length(opts); i++) {
const m = match(replace(opts[i], /\n+$/, ""), /^(\S*)\s(force|onrequest)\s(\d+)\s(.*)$/);
if (m) {
const p = replace(replace(replace(m[4], /"/g, "&quot;"), /</g, "&lt;"), />/g, "&gt;");
push(advoptions, { name: m[1], always: m[2] === "force", type: int(m[3]), value: p });
}
f.close();
}
const dhcpOptionTypes = {
"1": ["netmask", "mask"],

View File

@ -39,7 +39,7 @@
let at = 0;
let ao = 0;
if (dhcp.enabled) {
let f = fs.open(dhcp.leases);
const f = fs.open(dhcp.leases);
if (f) {
while (length(f.read("line"))) {
da++;
@ -47,20 +47,8 @@
f.close();
}
dr = length(uciMesh.get("setup", "dhcpreservations", "reservation") || []);
f = fs.open(dhcp.dhcptags);
if (f) {
while (length(f.read("line"))) {
at++;
}
f.close();
}
f = fs.open(dhcp.dhcpoptions);
if (f) {
while (length(f.read("line"))) {
ao++;
}
f.close();
}
at = length(uciMesh.get("setup", "dhcptags", "tag") || []);
ao = length(uciMesh.get("setup", "dhcpoptions", "option") || []);
}
%}
{% if (dhcp.enabled) { %}

View File

@ -100,12 +100,60 @@ if not c:get("setup", "dhcpreservations") then
end
end
-- Migrate the old school _setup.dhcptags.{nat,dmz} files
if not c:get("setup", "dhcptags") then
local file = "/etc/config.mesh/_setup.dhcptags."
if (nixio.fs.stat(file .. "nat", "size") or -1) > 0 then
file = file .. "nat"
elseif (nixio.fs.stat(file .. "dmz", "size") or -1) > 0 then
file = file .. "dmz"
else
file = nil
end
if file then
local dhcp = {}
for line in io.lines(file)
do
dhcp[#dhcp + 1] = line
end
c:set("setup", "dhcptags", "dhcptags")
c:set("setup", "dhcptags", "tag", dhcp)
c:commit("setup")
end
end
-- Migrate the old school _setup.dhcpoptions.{nat,dmz} files
if not c:get("setup", "dhcpoptions") then
local file = "/etc/config.mesh/_setup.dhcpoptions."
if (nixio.fs.stat(file .. "nat", "size") or -1) > 0 then
file = file .. "nat"
elseif (nixio.fs.stat(file .. "dmz", "size") or -1) > 0 then
file = file .. "dmz"
else
file = nil
end
if file then
local dhcp = {}
for line in io.lines(file)
do
dhcp[#dhcp + 1] = line
end
c:set("setup", "dhcpoptions", "dhcpoptions")
c:set("setup", "dhcpoptions", "option", dhcp)
c:commit("setup")
end
end
-- Dont remove this yet otherwise we cannot revert this node
-- os.remove("/etc/config.mesh/_setup")
-- os.remove("/etc/config.mesh/_setup.service.dmz")
-- os.remove("/etc/config.mesh/_setup.service.nat")
-- os.remove("/etc/config.mesh/_setup.dhcp.dmz")
-- os.remove("/etc/config.mesh/_setup.dhcp.nat")
-- os.remove("/etc/config.mesh/_setup.dhcptags.dmz")
-- os.remove("/etc/config.mesh/_setup.dhcptags.nat")
-- os.remove("/etc/config.mesh/_setup.dhcpoptions.dmz")
-- os.remove("/etc/config.mesh/_setup.dhcpoptions.nat")
__EOF__
/usr/bin/lua /tmp/setup_migrate

View File

@ -309,18 +309,12 @@ end
-- select ports and dhcp files based on mode
local portfile = "/etc/config.mesh/_setup.ports"
local dhcptagsfile = "/etc/config.mesh/_setup.dhcptags"
local dhcpoptionsfile = "/etc/config.mesh/_setup.dhcpoptions"
local aliasfile = "/etc/config.mesh/aliases"
if is_nat_mode() then
portfile = portfile .. ".nat"
dhcptagsfile = dhcptagsfile .. ".nat"
dhcpoptionsfile = dhcpoptionsfile .. ".nat"
aliasfile = aliasfile .. ".nat"
else
portfile = portfile .. ".dmz"
dhcptagsfile = dhcptagsfile .. ".dmz"
dhcpoptionsfile = dhcpoptionsfile .. ".dmz"
aliasfile = aliasfile .. ".dmz"
end
@ -774,38 +768,31 @@ if is_nat_mode() then
end
-- setup node lan dhcp
local function load_dhcp_tags(dhcptagsfile)
local function load_dhcp_tags()
local dhcp_tags = {}
for line in io.lines(dhcptagsfile)
local tags = cm:get_all("setup", "dhcptags", "tag") or {}
for _, tag in ipairs(tags)
do
if not (line:match("^%s*#") or line:match("^%s*$")) then
local name, condition, pattern = line:match("(%S+)%s+(%S+)%s+(.*)")
if pattern then
table.insert(get_subtable(dhcp_tags, condition),
{name = name, pattern = pattern})
end
local name, condition, pattern = tag:match("(%S+)%s+(%S+)%s+(.*)")
if pattern then
table.insert(get_subtable(dhcp_tags, condition), { name = name, pattern = pattern })
end
end
return dhcp_tags
end
local function load_dhcp_options(dhcpoptionsfile)
local function load_dhcp_options()
local dhcp_options = {}
if nixio.fs.access(dhcpoptionsfile) then
for line in io.lines(dhcpoptionsfile)
do
if not (line:match("^%s*#") or line:match("^%s*$")) then
local tag, force, opt_num, opt_val = line:match("(%S*)%s+(%w+)%s+(%d+)%s+(.*)")
if opt_val then
local by_tag = get_subtable(dhcp_options, tag)
if tag == "" and force == FORCED then
force = UNFORCED -- force is unsupported for untagged options
end
table.insert(get_subtable(by_tag, force),
{num = opt_num, val = opt_val})
end
local opts = cm:get_all("setup", "dhcpoptions", "option") or {}
for _, option in ipairs(opts)
do
local tag, force, opt_num, opt_val = option:match("(%S*)%s+(%w+)%s+(%d+)%s+(.*)")
if opt_val then
local by_tag = get_subtable(dhcp_options, tag)
if tag == "" and force == FORCED then
force = UNFORCED -- force is unsupported for untagged options
end
table.insert(get_subtable(by_tag, force), { num = opt_num, val = opt_val })
end
end
return dhcp_options
@ -877,13 +864,10 @@ do
table.insert(dhcp_option_list, "3")
end
local advanced_options = load_dhcp_options(dhcpoptionsfile)
if nixio.fs.access(dhcptagsfile) then
for condition, cond_list in pairs(load_dhcp_tags(dhcptagsfile))
do
create_classifying_section(condition, cond_list)
end
local advanced_options = load_dhcp_options()
for condition, cond_list in pairs(load_dhcp_tags())
do
create_classifying_section(condition, cond_list)
end
for tag, forcelist in pairs(advanced_options)

View File

@ -222,8 +222,6 @@ export function getDHCP(mode)
cidr: network.netmaskToCIDR(setup.lan_mask),
leases: "/tmp/dhcp.leases",
ports: "/etc/config.mesh/_setup.ports.nat",
dhcptags: "/etc/config.mesh/_setup.dhcptags.nat",
dhcpoptions: "/etc/config.mesh/_setup.dhcpoptions.nat",
aliases: "/etc/config.mesh/aliases.nat"
};
}
@ -244,8 +242,6 @@ export function getDHCP(mode)
cidr: network.netmaskToCIDR(setup.lan_mask),
leases: "/tmp/dhcp.leases",
ports: "/etc/config.mesh/_setup.ports.dmz",
dhcptags: "/etc/config.mesh/_setup.dhcptags.dmz",
dhcpoptions: "/etc/config.mesh/_setup.dhcpoptions.dmz",
aliases: "/etc/config.mesh/aliases.dmz"
};
}
@ -265,10 +261,7 @@ export function getDHCP(mode)
mask: setup.dmz_lan_mask,
cidr: network.netmaskToCIDR(setup.dmz_lan_mask),
leases: "/tmp/dhcp.leases",
services: "/etc/config.mesh/_setup.services.dmz",
ports: "/etc/config.mesh/_setup.ports.dmz",
dhcptags: "/etc/config.mesh/_setup.dhcptags.dmz",
dhcpoptions: "/etc/config.mesh/_setup.dhcpoptions.dmz",
aliases: "/etc/config.mesh/aliases.dmz"
};
}