Merge pull request #2688 from lemoer/pr_config_mode_ui_for_interface_roles_v2
Config-Mode UI for Interface Role Assignment (v2)
This commit is contained in:
commit
10e52bec3a
@ -29,6 +29,7 @@ files["package/**/check_site.lua"] = {
|
|||||||
"need",
|
"need",
|
||||||
"need_alphanumeric_key",
|
"need_alphanumeric_key",
|
||||||
"need_array",
|
"need_array",
|
||||||
|
"need_array_elements_exclusive",
|
||||||
"need_array_of",
|
"need_array_of",
|
||||||
"need_boolean",
|
"need_boolean",
|
||||||
"need_chanlist",
|
"need_chanlist",
|
||||||
@ -50,6 +51,7 @@ files["package/**/check_site.lua"] = {
|
|||||||
|
|
||||||
files["package/**/luasrc/lib/gluon/config-mode/*"] = {
|
files["package/**/luasrc/lib/gluon/config-mode/*"] = {
|
||||||
globals = {
|
globals = {
|
||||||
|
"MultiListValue",
|
||||||
"DynamicList",
|
"DynamicList",
|
||||||
"Flag",
|
"Flag",
|
||||||
"Form",
|
"Form",
|
||||||
|
@ -448,13 +448,8 @@ interfaces \: optional
|
|||||||
The ``client`` role requires exclusive control over an interface. When
|
The ``client`` role requires exclusive control over an interface. When
|
||||||
the ``client`` role is assigned to an interface at the same time as other
|
the ``client`` role is assigned to an interface at the same time as other
|
||||||
roles (like ``'client', 'mesh'`` in the above example), the other roles take
|
roles (like ``'client', 'mesh'`` in the above example), the other roles take
|
||||||
precedence (enabling ``mesh``, but not ``client`` in the example).
|
precedence (enabling ``mesh``, but not ``client`` in the example). In that
|
||||||
|
case, the ``client`` role is removed from the config of the interface.
|
||||||
Such a default configuration still fulfills a purpose (and is in fact the
|
|
||||||
recommended way to enable "Mesh-on-LAN" by default): The "LAN interface
|
|
||||||
meshing" checkbox in the advanced network settings will only add or remove
|
|
||||||
the ``mesh`` role, so the ``client`` role must already be in the configuration
|
|
||||||
to make the LAN port a regular client interface when the checkbox is disabled.
|
|
||||||
|
|
||||||
All interface settings are optional. If unset, the following defaults are
|
All interface settings are optional. If unset, the following defaults are
|
||||||
used:
|
used:
|
||||||
|
File diff suppressed because one or more lines are too long
@ -273,6 +273,10 @@ input[type=checkbox] {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.7em;
|
font-size: 1.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[disabled] + label {
|
||||||
|
background-color: #dcdcdc !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=radio] {
|
input[type=radio] {
|
||||||
@ -366,6 +370,13 @@ input[type=password] {
|
|||||||
min-width: 20em;
|
min-width: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gluon-multi-list-option-descr {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 0.35em;
|
||||||
|
margin-left: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
.gluon-button {
|
.gluon-button {
|
||||||
@include button;
|
@include button;
|
||||||
|
|
||||||
|
@ -77,7 +77,11 @@ need_boolean(in_domain({'mesh', 'vxlan'}), false)
|
|||||||
|
|
||||||
local interfaces_roles = {'client', 'uplink', 'mesh'}
|
local interfaces_roles = {'client', 'uplink', 'mesh'}
|
||||||
for _, config in ipairs({'wan', 'lan', 'single'}) do
|
for _, config in ipairs({'wan', 'lan', 'single'}) do
|
||||||
need_array_of(in_site({'interfaces', config, 'default_roles'}), interfaces_roles, false)
|
local default_roles = in_site({'interfaces', config, 'default_roles'})
|
||||||
|
|
||||||
|
need_array_of(default_roles, interfaces_roles, false)
|
||||||
|
need_array_elements_exclusive(default_roles, 'client', 'mesh', false)
|
||||||
|
need_array_elements_exclusive(default_roles, 'client', 'uplink', false)
|
||||||
end
|
end
|
||||||
|
|
||||||
obsolete({'mesh_on_wan'}, 'Use interfaces.wan.default_roles.')
|
obsolete({'mesh_on_wan'}, 'Use interfaces.wan.default_roles.')
|
||||||
|
@ -55,6 +55,14 @@ local function merge(a, b)
|
|||||||
return m
|
return m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function contains(table, val)
|
||||||
|
for i=1,#table do
|
||||||
|
if table[i] == val then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
local function path_to_string(path)
|
local function path_to_string(path)
|
||||||
if path.is_value then
|
if path.is_value then
|
||||||
@ -370,6 +378,21 @@ function M.need_array_of(path, array, required)
|
|||||||
return M.need_array(path, function(e) M.need_one_of(e, array) end, required)
|
return M.need_array(path, function(e) M.need_one_of(e, array) end, required)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.need_array_elements_exclusive(path, a, b, required)
|
||||||
|
local val = need_type(path, 'table', required, 'be an array')
|
||||||
|
if not val then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if contains(val, a) and contains(val, b) then
|
||||||
|
config_error(conf_src(path),
|
||||||
|
'expected %s to contain only one of the elements %s and %s, but not both.',
|
||||||
|
path_to_string(path), format(a), format(b))
|
||||||
|
end
|
||||||
|
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
|
||||||
function M.need_chanlist(path, channels, required)
|
function M.need_chanlist(path, channels, required)
|
||||||
local valid_chanlist = check_chanlist(channels)
|
local valid_chanlist = check_chanlist(channels)
|
||||||
return M.need(path, valid_chanlist, required,
|
return M.need(path, valid_chanlist, required,
|
||||||
|
@ -63,4 +63,19 @@ for iface in pairs(interfaces) do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Fix invalid role configurations
|
||||||
|
|
||||||
|
uci:foreach('gluon', 'interface', function(interface)
|
||||||
|
|
||||||
|
local function has_role(role)
|
||||||
|
return util.contains(interface.role, role)
|
||||||
|
end
|
||||||
|
|
||||||
|
if has_role('client') and (has_role('mesh') or has_role('uplink')) then
|
||||||
|
-- remove 'client' role
|
||||||
|
util.remove_from_set(interface.role, 'client')
|
||||||
|
uci:set('gluon', interface['.name'], 'role', interface.role)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
uci:save('gluon')
|
uci:save('gluon')
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
<%
|
||||||
|
local br = self.orientation == "horizontal" and '   ' or '<br>'
|
||||||
|
local entries = self:entries()
|
||||||
|
local util = require 'gluon.util'
|
||||||
|
%>
|
||||||
|
<div>
|
||||||
|
<% for i, entry in pairs(entries) do %>
|
||||||
|
<label<%=
|
||||||
|
attr("data-index", i) ..
|
||||||
|
attr("data-depends", self:deplist(entry.deps))
|
||||||
|
%>>
|
||||||
|
<input data-update="click change" type="checkbox"<%=
|
||||||
|
attr("id", id.."."..entry.key) ..
|
||||||
|
attr("name", id) ..
|
||||||
|
attr("value", entry.key) ..
|
||||||
|
attr("checked", (util.contains(self:cfgvalue(), entry.key)) and "checked") ..
|
||||||
|
attr("data-exclusive-with", self.exclusions[entry.key]) ..
|
||||||
|
attr("data-update", "change")
|
||||||
|
%>>
|
||||||
|
<label<%= attr("for", id.."."..entry.key)%>></label>
|
||||||
|
<span class="gluon-multi-list-option-descr"><%|entry.value%></span>
|
||||||
|
</label>
|
||||||
|
<% if i ~= #entries then write(br) end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
@ -1,19 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
SPDX-License-Identifier: Apache-2.0
|
||||||
Copyright 2008-2012 Jo-Philipp Wich <jow@openwrt.org>
|
SPDX-FileCopyrightText: 2008, Steven Barth <steven@midlink.org>
|
||||||
Copyright 2017 Matthias Schiffer <mschiffer@universe-factory.net>
|
SPDX-FileCopyrightText: 2008-2012, Jo-Philipp Wich <jow@openwrt.org>
|
||||||
|
SPDX-FileCopyrightText: 2017, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
SPDX-FileCopyrightText: 2023, Leonardo Mörlein <me@irrelefant.net>
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Build using:
|
Build using:
|
||||||
|
|
||||||
uglifyjs javascript/gluon-web-model.js -o javascript/gluon-web-model.min.js -c -m --support-ie8
|
uglifyjs javascript/gluon-web-model.js -o javascript/gluon-web-model.min.js -c -m --ie
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -219,6 +215,20 @@
|
|||||||
parent.parentNode.style.display = (parent.options.length <= 1) ? 'none' : '';
|
parent.parentNode.style.display = (parent.options.length <= 1) ? 'none' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nodes = document.querySelectorAll('[data-exclusive-with]');
|
||||||
|
for (var i = 0, node; (node = nodes[i]) !== undefined; i++) {
|
||||||
|
var exclusive_with = JSON.parse(node.getAttribute('data-exclusive-with'));
|
||||||
|
|
||||||
|
node.disabled = false;
|
||||||
|
for (var list_item of exclusive_with) {
|
||||||
|
var el = document.getElementById(node.name + '.' + list_item);
|
||||||
|
node.disabled ||= el.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.disabled)
|
||||||
|
node.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,8 +1,10 @@
|
|||||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
-- SPDX-License-Identifier: Apache-2.0
|
||||||
-- Copyright 2017-2018 Matthias Schiffer <mschiffer@universe-factory.net>
|
-- SPDX-FileCopyrightText: 2008, Steven Barth <steven@midlink.org>
|
||||||
-- Licensed to the public under the Apache License 2.0.
|
-- SPDX-FileCopyrightText: 2017-2018, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
-- SPDX-FileCopyrightText: 2023, Leonardo Mörlein <me@irrelefant.net>
|
||||||
|
|
||||||
local util = require "gluon.web.util"
|
local util = require "gluon.web.util"
|
||||||
|
local gluon_util = require "gluon.util"
|
||||||
|
|
||||||
local datatypes = require "gluon.web.model.datatypes"
|
local datatypes = require "gluon.web.model.datatypes"
|
||||||
local class = util.class
|
local class = util.class
|
||||||
@ -361,6 +363,83 @@ function ListValue:validate()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local MultiListValue = class(AbstractValue)
|
||||||
|
M.MultiListValue = MultiListValue
|
||||||
|
|
||||||
|
function MultiListValue:__init__(...)
|
||||||
|
AbstractValue.__init__(self, ...)
|
||||||
|
self.subtemplate = "model/mlvalue"
|
||||||
|
|
||||||
|
self.size = 1
|
||||||
|
|
||||||
|
self.keys = {}
|
||||||
|
self.entry_list = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:value(key, val, ...)
|
||||||
|
key = tostring(key)
|
||||||
|
|
||||||
|
if self.keys[key] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.keys[key] = true
|
||||||
|
self.exclusions = {}
|
||||||
|
|
||||||
|
val = val or key
|
||||||
|
table.insert(self.entry_list, {
|
||||||
|
key = key,
|
||||||
|
value = tostring(val),
|
||||||
|
deps = {...},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:entries()
|
||||||
|
local ret = {unpack(self.entry_list)}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:validate()
|
||||||
|
for _, val in ipairs(self.data) do
|
||||||
|
if not self.keys[val] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for key, exclusive_with in pairs(self.exclusions) do
|
||||||
|
if gluon_util.contains(self.data, key) then
|
||||||
|
for _, exclusion in ipairs(exclusive_with) do
|
||||||
|
if gluon_util.contains(self.data, exclusion) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:exclusive(a, b)
|
||||||
|
if not self.exclusions[a] then
|
||||||
|
self.exclusions[a] = {}
|
||||||
|
end
|
||||||
|
if not self.exclusions[b] then
|
||||||
|
self.exclusions[b] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
gluon_util.add_to_set(self.exclusions[a], b)
|
||||||
|
gluon_util.add_to_set(self.exclusions[b], a)
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:defaultvalue()
|
||||||
|
return self.default or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function MultiListValue:formvalue(http)
|
||||||
|
return http:formvaluetable(self:id())
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local DynamicList = class(AbstractValue)
|
local DynamicList = class(AbstractValue)
|
||||||
M.DynamicList = DynamicList
|
M.DynamicList = DynamicList
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
|
-- SPDX-License-Identifier: Apache-2.0
|
||||||
-- Copyright 2017 Matthias Schiffer <mschiffer@universe-factory.net>
|
-- SPDX-FileCopyrightText: 2010, Jo-Philipp Wich <jow@openwrt.org>
|
||||||
-- Licensed to the public under the Apache License 2.0.
|
-- SPDX-FileCopyrightText: 2017, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
@ -28,15 +28,6 @@ msgstr "PoE-Passthrough aktivieren"
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr "PoE-Ausgabe auf Port %s aktivieren"
|
msgstr "PoE-Ausgabe auf Port %s aktivieren"
|
||||||
|
|
||||||
msgid "Enable meshing on the Ethernet interface"
|
|
||||||
msgstr "Mesh auf dem Ethernet-Port aktivieren"
|
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
|
||||||
msgstr "Mesh auf dem LAN-Port aktivieren"
|
|
||||||
|
|
||||||
msgid "Enable meshing on the WAN interface"
|
|
||||||
msgstr "Mesh auf dem WAN-Port aktivieren"
|
|
||||||
|
|
||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr "Gateway"
|
msgstr "Gateway"
|
||||||
|
|
||||||
@ -49,6 +40,12 @@ msgstr "IPv4"
|
|||||||
msgid "IPv6"
|
msgid "IPv6"
|
||||||
msgstr "IPv6"
|
msgstr "IPv6"
|
||||||
|
|
||||||
|
msgid "Interface"
|
||||||
|
msgstr "Interface"
|
||||||
|
|
||||||
|
msgid "LAN Interfaces"
|
||||||
|
msgstr "LAN-Interfaces"
|
||||||
|
|
||||||
msgid "Netmask"
|
msgid "Netmask"
|
||||||
msgstr "Netzmaske"
|
msgstr "Netzmaske"
|
||||||
|
|
||||||
@ -61,5 +58,8 @@ msgstr "Statisch"
|
|||||||
msgid "Static DNS servers"
|
msgid "Static DNS servers"
|
||||||
msgstr "Statische DNS-Server"
|
msgstr "Statische DNS-Server"
|
||||||
|
|
||||||
|
msgid "WAN Interfaces"
|
||||||
|
msgstr "WAN-Interfaces"
|
||||||
|
|
||||||
msgid "WAN connection"
|
msgid "WAN connection"
|
||||||
msgstr "WAN-Verbindung"
|
msgstr "WAN-Verbindung"
|
||||||
|
@ -28,15 +28,6 @@ msgstr ""
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable meshing on the Ethernet interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
|
||||||
msgstr "Activer le réseau MESH sur le port LAN"
|
|
||||||
|
|
||||||
msgid "Enable meshing on the WAN interface"
|
|
||||||
msgstr "Activer le réseau MESH sur les ports WAN"
|
|
||||||
|
|
||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr "Passerelle"
|
msgstr "Passerelle"
|
||||||
|
|
||||||
|
@ -19,15 +19,6 @@ msgstr ""
|
|||||||
msgid "Enable PoE Power Port %s"
|
msgid "Enable PoE Power Port %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Enable meshing on the Ethernet interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Enable meshing on the LAN interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Enable meshing on the WAN interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -40,6 +31,12 @@ msgstr ""
|
|||||||
msgid "IPv6"
|
msgid "IPv6"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Interface"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "LAN Interfaces"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Netmask"
|
msgid "Netmask"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -52,5 +49,8 @@ msgstr ""
|
|||||||
msgid "Static DNS servers"
|
msgid "Static DNS servers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "WAN Interfaces"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "WAN connection"
|
msgid "WAN connection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
--[[
|
-- SPDX-License-Identifier: Apache-2.0
|
||||||
Copyright 2014 Nils Schneider <nils@nilsschneider.net>
|
-- SPDX-FileCopyrightText: 2014, Nils Schneider <nils@nilsschneider.net>
|
||||||
|
-- SPDX-FileCopyrightText: 2023, Leonardo Mörlein <me@irrelefant.net>
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local uci = require("simple-uci").cursor()
|
local uci = require("simple-uci").cursor()
|
||||||
local sysconfig = require 'gluon.sysconfig'
|
|
||||||
local util = require 'gluon.util'
|
|
||||||
|
|
||||||
local wan = uci:get_all("network", "wan")
|
local wan = uci:get_all("network", "wan")
|
||||||
local wan6 = uci:get_all("network", "wan6")
|
local wan6 = uci:get_all("network", "wan6")
|
||||||
local dns_static = uci:get_first("gluon-wan-dnsmasq", "static")
|
local dns_static = uci:get_first("gluon-wan-dnsmasq", "static")
|
||||||
|
|
||||||
|
|
||||||
local f = Form(translate("WAN connection"))
|
local f = Form(translate("WAN connection"))
|
||||||
|
|
||||||
local s = f:section(Section)
|
local s = f:section(Section)
|
||||||
@ -76,36 +69,30 @@ end
|
|||||||
|
|
||||||
s = f:section(Section)
|
s = f:section(Section)
|
||||||
|
|
||||||
local wired_mesh_help = {
|
local pretty_ifnames = {
|
||||||
single = translate('Enable meshing on the Ethernet interface'),
|
["/wan"] = translate("WAN Interfaces"),
|
||||||
wan = translate('Enable meshing on the WAN interface'),
|
["/single"] = translate("Interface"),
|
||||||
lan = translate('Enable meshing on the LAN interface'),
|
["/lan"] = translate("LAN Interfaces")
|
||||||
}
|
}
|
||||||
|
|
||||||
local function wired_mesh(iface)
|
uci:foreach('gluon', 'interface', function(config)
|
||||||
if not sysconfig[iface .. '_ifname'] then return end
|
local section_name = config['.name']
|
||||||
local iface_roles = uci:get_list('gluon', 'iface_' .. iface, 'role')
|
local ifaces = s:option(MultiListValue, section_name, pretty_ifnames[config.name] or config.name)
|
||||||
|
|
||||||
local option = s:option(Flag, 'mesh_' .. iface, wired_mesh_help[iface])
|
ifaces.orientation = 'horizontal'
|
||||||
option.default = util.contains(iface_roles, 'mesh') ~= false
|
ifaces:value('uplink', 'Uplink')
|
||||||
|
ifaces:value('mesh', 'Mesh')
|
||||||
|
ifaces:value('client', 'Client')
|
||||||
|
ifaces:exclusive('uplink', 'client')
|
||||||
|
ifaces:exclusive('mesh', 'client')
|
||||||
|
|
||||||
function option:write(data)
|
ifaces.default = config.role
|
||||||
local roles = uci:get_list('gluon', 'iface_' .. iface, 'role')
|
|
||||||
if data then
|
function ifaces:write(data)
|
||||||
util.add_to_set(roles, 'mesh')
|
uci:set_list("gluon", section_name, "role", data)
|
||||||
else
|
|
||||||
util.remove_from_set(roles, 'mesh')
|
|
||||||
end
|
end
|
||||||
uci:set_list('gluon', 'iface_' .. iface, 'role', roles)
|
end)
|
||||||
|
|
||||||
-- Reconfigure on next reboot
|
|
||||||
uci:set('gluon', 'core', 'reconfigure', true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
wired_mesh('single')
|
|
||||||
wired_mesh('wan')
|
|
||||||
wired_mesh('lan')
|
|
||||||
|
|
||||||
local section
|
local section
|
||||||
uci:foreach("system", "gpio_switch", function(si)
|
uci:foreach("system", "gpio_switch", function(si)
|
||||||
@ -166,4 +153,5 @@ function f:write()
|
|||||||
uci:commit('system')
|
uci:commit('system')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
Loading…
Reference in New Issue
Block a user