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

View File

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

View File

@ -100,12 +100,60 @@ if not c:get("setup", "dhcpreservations") then
end end
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 -- Dont remove this yet otherwise we cannot revert this node
-- os.remove("/etc/config.mesh/_setup") -- os.remove("/etc/config.mesh/_setup")
-- os.remove("/etc/config.mesh/_setup.service.dmz") -- os.remove("/etc/config.mesh/_setup.service.dmz")
-- os.remove("/etc/config.mesh/_setup.service.nat") -- os.remove("/etc/config.mesh/_setup.service.nat")
-- os.remove("/etc/config.mesh/_setup.dhcp.dmz") -- os.remove("/etc/config.mesh/_setup.dhcp.dmz")
-- os.remove("/etc/config.mesh/_setup.dhcp.nat") -- 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__ __EOF__
/usr/bin/lua /tmp/setup_migrate /usr/bin/lua /tmp/setup_migrate

View File

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

View File

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