From: Jo-Philipp Wich Date: Tue, 7 Aug 2018 15:50:34 +0000 (+0200) Subject: Merge pull request #2043 from Ansuel/materialfix X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=849a5bb54e0b53af46daf109157724c3c2540c2f;hp=35da63fa9a977ac579ee18ce2636d0db9d76353e;p=project%2Fluci.git Merge pull request #2043 from Ansuel/materialfix luci-theme-material: fix theme for applyreboot page changes --- diff --git a/applications/luci-app-adblock/luasrc/controller/adblock.lua b/applications/luci-app-adblock/luasrc/controller/adblock.lua index fad8834870..4c77244710 100644 --- a/applications/luci-app-adblock/luasrc/controller/adblock.lua +++ b/applications/luci-app-adblock/luasrc/controller/adblock.lua @@ -6,11 +6,9 @@ module("luci.controller.adblock", package.seeall) local sys = require("luci.sys") local util = require("luci.util") local http = require("luci.http") -local templ = require("luci.template") local i18n = require("luci.i18n") local json = require("luci.jsonc") local uci = require("luci.model.uci").cursor() -local fs = require("nixio.fs") function index() if not nixio.fs.access("/etc/config/adblock") then @@ -48,12 +46,10 @@ function status_update() rt_file = uci:get("adblock", "global", "adb_rtfile") or "/tmp/adb_runtime.json" - if fs.access(rt_file) then - content = json.parse(fs.readfile(rt_file)) - if content then - http.prepare_content("application/json") - http.write_json(content) - end + if nixio.fs.access(rt_file) then + content = json.parse(nixio.fs.readfile(rt_file) or "") + http.prepare_content("application/json") + http.write_json(content) end end diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua index 3bf7392914..2ecaaab726 100644 --- a/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua +++ b/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua @@ -3,7 +3,6 @@ local fs = require("nixio.fs") local uci = require("luci.model.uci").cursor() -local sys = require("luci.sys") local util = require("luci.util") local dump = util.ubus("network.interface", "dump", {}) @@ -13,10 +12,6 @@ m = Map("adblock", translate("Adblock"), .. "" .. "check the online documentation", "https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md")) -function m.on_apply(self) - luci.sys.call("/etc/init.d/adblock reload >/dev/null 2>&1") -end - -- Main adblock options s = m:section(NamedSection, "global", "adblock") diff --git a/applications/luci-app-adblock/luasrc/view/adblock/blocklist.htm b/applications/luci-app-adblock/luasrc/view/adblock/blocklist.htm index f59e518574..a6f2286513 100644 --- a/applications/luci-app-adblock/luasrc/view/adblock/blocklist.htm +++ b/applications/luci-app-adblock/luasrc/view/adblock/blocklist.htm @@ -14,39 +14,39 @@ local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "ano .cbi-section-table-row, .tr[data-title]::before { - text-align:left; - vertical-align:top; - margin-left:0px; - padding-left:2px; + text-align: left; + vertical-align: top; + margin-left: 0px; + padding-left: 2px; } .table.cbi-section-table .th { - white-space:nowrap; + white-space: nowrap; } .table.cbi-section-table input { - width:7em; + width: 7em; } .cbi-section-table-row > .cbi-value-field [data-dynlist] > input, .table.cbi-section-table input { - width:7em; + width: 7em; } .cbi-input-text { - text-align:left; - padding-left:2px; - outline:none; - box-shadow:none; - background:transparent; - width:7em; + text-align: left; + padding-left: 2px; + outline: none; + box-shadow: none; + background: transparent; + width: 7em; }
<% if self.title then -%> - <%=self.title%> +

<%=self.title%>

<%- end %>
<%=self.description%>
diff --git a/applications/luci-app-adblock/luasrc/view/adblock/logread.htm b/applications/luci-app-adblock/luasrc/view/adblock/logread.htm index bb8d652fbc..b505233490 100644 --- a/applications/luci-app-adblock/luasrc/view/adblock/logread.htm +++ b/applications/luci-app-adblock/luasrc/view/adblock/logread.htm @@ -4,6 +4,21 @@ This is free software, licensed under the Apache License, Version 2.0 -%> <%+header%> + +
-
<%:This form shows the syslog output, pre-filtered for travelmate related messages only.%>
- +
<%:The syslog output, pre-filtered for travelmate related messages only.%>
+
- - <%+footer%> diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/runtime.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/runtime.htm index 7e93efab91..272612600c 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/runtime.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/runtime.htm @@ -3,8 +3,142 @@ Copyright 2017-2018 Dirk Brenken (dev@brenken.org) This is free software, licensed under the Apache License, Version 2.0 -%> -<%+cbi/valueheader%> + - + + +

<%:Runtime Information%>

+
+ +
+ - +
+
+
+ +
+ - +
+
+
+ +
+ - +
+
+
+ +
+ - +
+
+
+ +
+ - +
+
+
+ +
+ - +
+
+
+
+ +
+ + +
+
diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm index 74542a9ca5..98e2e64bce 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/stations.htm @@ -4,75 +4,151 @@ This is free software, licensed under the Apache License, Version 2.0 -%> <%- - local write = io.write - local uci = require("luci.model.uci").cursor() - local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan" + local uci = require("luci.model.uci").cursor() + local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan" -%> <%+header%> +
-
- <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%> -
+
+ <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue, faulty stations in red.", trmiface)%> +
-
-
-
-
<%:Device%>
-
<%:SSID%>
-
<%:BSSID%>
-
<%:Encryption%>
-
 
-
-<% - uci:foreach("wireless", "wifi-iface", function(s) - local iface = s.network or "" - if iface == trmiface then - local section = s['.name'] or "" - local device = s.device or "-" - local ssid = s.ssid or "-" - local bssid = s.bssid or "-" - local encryption = s.encryption or "-" - local disabled = s.disabled or "" - local style = "text-align:left;color:#000000" - if disabled == "0" then - style = "text-align:left;color:#0069d6;font-weight:bold" - end -%> -
-
<%=device%>
-
<%=ssid%>
-
<%=bssid%>
-
<%=encryption%>
-
- - - - -
-
-<% - end - end) -%> -
-
-
-<% - uci:foreach("wireless", "wifi-device", function(s) - local device = s[".name"] -%> -
- - - -
-<% - end) -%> -
+
+
+
+
<%:Device%>
+
<%:SSID%>
+
<%:BSSID%>
+
<%:Encryption%>
+
<%:Action%>
+
+ <%- uci:foreach("wireless", "wifi-iface", function(s) + local iface = s.network or "" + if iface == trmiface then + local section = s['.name'] or "" + local device = s.device or "-" + local ssid = s.ssid or "-" + local bssid = s.bssid or "-" + local encr = s.encryption or "-" + -%> +
+
<%=device%>
+
<%=ssid%>
+
<%=bssid%>
+
<%=encr%>
+
+
+ + + + +
+
+
+ <%- end; end) -%> +
+
+
+ <%- uci:foreach("wireless", "wifi-device", function(s) + local device = s[".name"] + local hwmode = s.hwmode or "-" -%> +
+ + + +
+ <%- end) -%> +
<%+footer%> diff --git a/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm b/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm index 8a417d69c2..ab3fe77fbc 100644 --- a/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm +++ b/applications/luci-app-travelmate/luasrc/view/travelmate/wifi_scan.htm @@ -1,97 +1,99 @@ <%# -Copyright 2017 Dirk Brenken (dev@brenken.org) +Copyright 2017-2018 Dirk Brenken (dev@brenken.org) This is free software, licensed under the Apache License, Version 2.0 -%> <%- - local sys = require("luci.sys") - local utl = require("luci.util") - local dev = luci.http.formvalue("device") - local iw = luci.sys.wifi.getiwinfo(dev) - local wpa_label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")} + local sys = require("luci.sys") + local utl = require("luci.util") + local dev = luci.http.formvalue("device") + local iw = luci.sys.wifi.getiwinfo(dev) + local label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")} - if not iw then - luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations")) - end + if not iw then + luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations")) + end - function format_wifi_encryption(info) - if info.wep == true then - return translate("WEP") - elseif info.wpa > 0 then - return "%s (%s/%s)" %{wpa_label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)} - elseif info.enabled then - return translate("Unknown") - else - return translate("Open") - end - end + function format_wifi_encryption(info) + if info.wep == true then + return translate("WEP") + elseif info.wpa > 0 then + return "%s (%s/%s)" %{label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)} + elseif info.enabled then + return translate("Unknown") + else + return translate("Open") + end + end - function percent_wifi_signal(info) - local qc = info.quality or 0 - local qm = info.quality_max or 0 - if info.bssid and qc > 0 and qm > 0 then - return math.floor((100 / qm) * qc) - else - return 0 - end - end + function percent_wifi_signal(info) + local qc = info.quality or 0 + local qm = info.quality_max or 0 + if info.bssid and qc > 0 and qm > 0 then + return math.floor((100 / qm) * qc) + else + return 0 + end + end -%> <%+header%> -
-

<%:Wireless Scan%>

-
-
-
-
<%:Uplink SSID%>
-
<%:Uplink BSSID%>
-
<%:Encryption%>
-
<%:Signal strength%>
-
- <% for i, net in ipairs(iw.scanlist or { }) do %> -
-
- <%=net.ssid and utl.pcdata(net.ssid) or "%s" % translate("hidden")%> -
-
- <%=net.bssid and utl.pcdata(net.bssid)%> -
-
- <%=format_wifi_encryption(net.encryption)%> -
-
- <%=percent_wifi_signal(net)%> % -
-
-
- - - - - - <% if net.encryption.wpa then %> - - <% for _, v in ipairs(net.encryption.auth_suites) do %><% end %> - <% end %> - -
-
-
- <% end %> -
-
-
-
- -
-
- - - -
-
+

<%:Wireless Scan%>

+
+
+
+
<%:Uplink SSID%>
+
<%:Uplink BSSID%>
+
<%:Encryption%>
+
<%:Signal strength%>
+
<%:Action%>
+
+ <%- for i, net in ipairs(iw.scanlist or { }) do -%> +
+
+ <%=net.ssid and utl.pcdata(net.ssid) or "%s" % translate("hidden")%> +
+
+ <%=net.bssid and utl.pcdata(net.bssid)%> +
+
+ <%=format_wifi_encryption(net.encryption)%> +
+
+ <%=percent_wifi_signal(net)%> % +
+
+
+ + + + + + <%- if net.encryption.wpa then -%> + + <%- for _, v in ipairs(net.encryption.auth_suites) do -%> + + <%- end -%> + <%- end -%> + +
+
+
+ <%- end -%> +
+
+
+
+ +
+
+ + + +
+
<%+footer%> diff --git a/applications/luci-app-unbound/luasrc/controller/unbound.lua b/applications/luci-app-unbound/luasrc/controller/unbound.lua index 730ca724a4..ea3d26b919 100644 --- a/applications/luci-app-unbound/luasrc/controller/unbound.lua +++ b/applications/luci-app-unbound/luasrc/controller/unbound.lua @@ -1,151 +1,200 @@ -- Copyright 2008 Steven Barth -- Copyright 2008 Jo-Philipp Wich --- Copyright 2017 Eric Luehrsen +-- Copyright 2017 Eric Luehrsen -- Licensed to the public under the Apache License 2.0. module("luci.controller.unbound", package.seeall) function index() - local ucl = luci.model.uci.cursor() - local valexp = ucl:get_first("unbound", "unbound", "extended_luci") - local valman = ucl:get_first("unbound", "unbound", "manual_conf") + local fs = require "nixio.fs" + local ucl = luci.model.uci.cursor() + local valman = ucl:get_first("unbound", "unbound", "manual_conf") - if not nixio.fs.access("/etc/config/unbound") then - return - end + if not fs.access("/etc/config/unbound") then + return + end - if valexp == "1" then -- Expanded View - entry({"admin", "services", "unbound"}, firstchild(), _("Recursive DNS")).dependent = false + entry({"admin", "services", "unbound"}, + firstchild(), _("Recursive DNS")).dependent = false -- UCI Tab(s) - entry({"admin", "services", "unbound", "configure"}, cbi("unbound/configure"), _("Settings"), 10) + entry({"admin", "services", "unbound", "configure"}, + cbi("unbound/configure"), _("Unbound"), 10) + + + if (valman == "0") then + entry({"admin", "services", "unbound", "zones"}, + cbi("unbound/zones"), _("Zones"), 15) + end + -- Status Tab(s) - entry({"admin", "services", "unbound", "status"}, firstchild(), _("Status"), 20) - entry({"admin", "services", "unbound", "status", "syslog"}, call("QuerySysLog"), _("Log"), 50).leaf = true + entry({"admin", "services", "unbound", "status"}, + firstchild(), _("Status"), 20) + + entry({"admin", "services", "unbound", "status", "syslog"}, + call("QuerySysLog"), _("Log"), 50).leaf = true + + + if fs.access("/usr/sbin/unbound-control") then + -- Require unbound-control to execute + entry({"admin", "services", "unbound", "status", "statistics"}, + call("QueryStatistics"), _("Statistics"), 10).leaf = true + entry({"admin", "services", "unbound", "status", "localdata"}, + call("QueryLocalData"), _("Local Data"), 20).leaf = true - if nixio.fs.access("/usr/sbin/unbound-control") then - -- Require unbound-control to execute - entry({"admin", "services", "unbound", "status", "statistics"}, call("QueryStatistics"), _("Statistics"), 10).leaf = true - entry({"admin", "services", "unbound", "status", "localdata"}, call("QueryLocalData"), _("Local Data"), 20).leaf = true - entry({"admin", "services", "unbound", "status", "localzone"}, call("QueryLocalZone"), _("Local Zones"), 30).leaf = true + entry({"admin", "services", "unbound", "status", "localzone"}, + call("QueryLocalZone"), _("Local Zones"), 30).leaf = true else - entry({"admin", "services", "unbound", "status", "statistics"}, call("ShowEmpty"), _("Statistics"), 10).leaf = true + entry({"admin", "services", "unbound", "status", "statistics"}, + call("ShowEmpty"), _("Statistics"), 10).leaf = true end -- Raw File Tab(s) - entry({"admin", "services", "unbound", "files"}, firstchild(), _("Files"), 30) + entry({"admin", "services", "unbound", "files"}, + firstchild(), _("Files"), 30) - if valman ~= "1" then - entry({"admin", "services", "unbound", "files", "base"}, call("ShowUnboundConf"), _("UCI: Unbound"), 10).leaf = true + if (valman == "0") then + entry({"admin", "services", "unbound", "files", "uci"}, + form("unbound/uciedit"), _("Edit: UCI"), 5).leaf = true + + entry({"admin", "services", "unbound", "files", "base"}, + call("ShowUnboundConf"), _("Show: Unbound"), 10).leaf = true + else - entry({"admin", "services", "unbound", "files", "base"}, form("unbound/manual"), _("Edit: Unbound"), 10).leaf = true + entry({"admin", "services", "unbound", "files", "base"}, + form("unbound/manual"), _("Edit: Unbound"), 10).leaf = true end - entry({"admin", "services", "unbound", "files", "server"}, form("unbound/server"), _("Edit: Server"), 20).leaf = true - entry({"admin", "services", "unbound", "files", "extended"}, form("unbound/extended"), _("Edit: Extended"), 30).leaf = true + entry({"admin", "services", "unbound", "files", "server"}, + form("unbound/server"), _("Edit: Server"), 20).leaf = true + entry({"admin", "services", "unbound", "files", "extended"}, + form("unbound/extended"), _("Edit: Extended"), 30).leaf = true - if nixio.fs.access("/var/lib/unbound/unbound_dhcp.conf") then - entry({"admin", "services", "unbound", "files", "dhcp"}, call("ShowDHCPConf"), _("Include: DHCP"), 40).leaf = true + + if fs.access("/var/lib/unbound/dhcp.conf") then + entry({"admin", "services", "unbound", "files", "dhcp"}, + call("ShowDHCPConf"), _("Show: DHCP"), 40).leaf = true end - if nixio.fs.access("/var/lib/unbound/adb_list.overall") then - entry({"admin", "services", "unbound", "files", "adblock"}, call("ShowAdblock"), _("Include: Adblock"), 50).leaf = true + if fs.access("/var/lib/unbound/adb_list.overall") then + entry({"admin", "services", "unbound", "files", "adblock"}, + call("ShowAdblock"), _("Show: Adblock"), 50).leaf = true end - - else - -- Simple View to UCI only - entry({"admin", "services", "unbound"}, cbi("unbound/configure"), _("Recursive DNS")).dependent = false - end end function ShowEmpty() - local lclhead = "Unbound Control" - local lcldesc = luci.i18n.translate("This could display more statistics with the unbound-control package.") - luci.template.render("unbound/show-empty", {heading = lclhead, description = lcldesc}) + local lclhead = "Unbound Control" + local lcldesc = luci.i18n.translate( + "This could display more statistics with the unbound-control package.") + + luci.template.render("unbound/show-empty", + {heading = lclhead, description = lcldesc}) end function QuerySysLog() - local lclhead = "System Log" - local lcldata = luci.util.exec("logread | grep -i unbound") - local lcldesc = luci.i18n.translate("This shows syslog filtered for events involving Unbound.") - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local lcldata = luci.util.exec("logread | grep -i unbound") + local lcldesc = luci.i18n.translate( + "This shows syslog filtered for events involving Unbound.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function QueryStatistics() - local lclhead = "Unbound Control Stats" - local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf stats_noreset") - local lcldesc = luci.i18n.translate("This shows some performance statistics tracked by Unbound.") - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local lcldata = luci.util.exec( + "unbound-control -c /var/lib/unbound/unbound.conf stats_noreset") + + local lcldesc = luci.i18n.translate( + "This shows Unbound self reported performance statistics.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function QueryLocalData() - local lclhead = "Unbound Control Local Data" - local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf list_local_data") - local lcldesc = luci.i18n.translate("This shows local host records that shortcut recursion.") - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local lcldata = luci.util.exec( + "unbound-control -c /var/lib/unbound/unbound.conf list_local_data") + + local lcldesc = luci.i18n.translate( + "This shows Unbound 'local-data:' entries from default, .conf, or control.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function QueryLocalZone() - local lclhead = "Unbound Control Local Zones" - local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf list_local_zones") - local lcldesc = luci.i18n.translate("This shows local zone definitions that affect recursion routing or processing. ") - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local lcldata = luci.util.exec( + "unbound-control -c /var/lib/unbound/unbound.conf list_local_zones") + + local lcldesc = luci.i18n.translate( + "This shows Unbound 'local-zone:' entries from default, .conf, or control.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function ShowUnboundConf() - local unboundfile = "/var/lib/unbound/unbound.conf" - local lclhead = "Unbound Conf" - local lcldata = nixio.fs.readfile(unboundfile) - local lcldesc = luci.i18n.translate("This shows configuration generated by UCI:") - lcldesc = lcldesc .. " (" .. unboundfile .. ")" - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local unboundfile = "/var/lib/unbound/unbound.conf" + local lcldata = nixio.fs.readfile(unboundfile) + local lcldesc = luci.i18n.translate( + "This shows '" .. unboundfile .. "' generated from UCI configuration.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function ShowDHCPConf() - local dhcpfile = "/var/lib/unbound/unbound_dhcp.conf" - local lclhead = "DHCP Conf" - local lcldata = nixio.fs.readfile(dhcpfile) - local lcldesc = luci.i18n.translate("This shows LAN hosts added by DHCP hook scripts:") - lcldesc = lcldesc .. " (" .. dhcpfile .. ")" - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) + local dhcpfile = "/var/lib/unbound/dhcp.conf" + local lcldata = nixio.fs.readfile(dhcpfile) + local lcldesc = luci.i18n.translate( + "This shows '" .. dhcpfile .. "' list of hosts from DHCP hook scripts.") + + luci.template.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) end function ShowAdblock() - local adblockfile = "/var/lib/unbound/adb_list.overall" - local lclhead = "Adblock Conf" - local lcldata, lcldesc - - - if nixio.fs.stat(adblockfile).size > 262144 then - lcldesc = luci.i18n.translate("Adblock domain list is too large for LuCI:") - lcldesc = lcldesc .. " (" .. adblockfile .. ")" - luci.template.render("unbound/show-empty", {heading = lclhead, description = lcldesc}) - - else - lcldata = nixio.fs.readfile(adblockfile) - lcldesc = luci.i18n.translate("This shows blocked domains provided by Adblock scripts:") - lcldesc = lcldesc .. " (" .. adblockfile .. ")" - luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata}) - end + local fs = require "nixio.fs" + local tp = require "luci.template" + local tr = require "luci.i18n" + local adblockfile = "/var/lib/unbound/adb_list.overall" + local lcldata, lcldesc + + + if fs.stat(adblockfile).size > 262144 then + lcldesc = tr.translate( + "Adblock domain list '" .. adblockfile .. "' is too large for LuCI.") + + tp.render("unbound/show-empty", + {heading = "", description = lcldesc}) + + else + lcldata = fs.readfile(adblockfile) + lcldesc = tr.translate( + "This shows '" .. adblockfile .. "' list of adblock domains." ) + + tp.render("unbound/show-textbox", + {heading = "", description = lcldesc, content = lcldata}) + end end diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua index 256bbb8392..f665a2c9da 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua @@ -1,5 +1,5 @@ -- Copyright 2008 Steven Barth --- Copyright 2016 Eric Luehrsen +-- Copyright 2016 Eric Luehrsen -- Copyright 2016 Dan Luedtke -- Licensed to the public under the Apache License 2.0. @@ -9,307 +9,312 @@ local rlh, rpv, vld, nvd, eds, prt, tlm local ctl, dlk, dom, dty, lfq, wfq, exa local dp6, d64, pfx, qry, qrs local pro, tgr, rsc, rsn, ag2, stt -local rpn, din, dfw, ath +local rpn, din, ath + +local ut = require "luci.util" +local sy = require "luci.sys" +local ht = require "luci.http" +local ds = require "luci.dispatcher" local ucl = luci.model.uci.cursor() local valman = ucl:get_first("unbound", "unbound", "manual_conf") m1 = Map("unbound") +s1 = m1:section(TypedSection, "unbound", translate("DNS Resolver"), + translatef("Unbound (NLnet Labs)" + .. " is a validating, recursive, and caching DNS resolver.", + "https://www.unbound.net/")) -s1 = m1:section(TypedSection, "unbound") s1.addremove = false s1.anonymous = true --LuCI, Unbound, or Not -s1:tab("basic", translate("Basic"), - translatef("

Unbound Basic Settings

\n" - .. "Unbound (link)" - .. " is a validating, recursive, and caching DNS resolver. " - .. "UCI documentation can be found on " - .. "github (link).", - "https://www.unbound.net/", - "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md")) - - -if valman ~= "1" then - -- Not in manual configuration mode; show UCI - s1:tab("advanced", translate("Advanced"), - translatef("

Unbound Advanced Settings

\n" - .. "Domain manipulation, lookup protection, and workarounds for " - .. "Unbound " - .. " DNS resolver.", "https://www.unbound.net/")) - - s1:tab("DHCP", translate("DHCP"), - translatef("

Unbound DHCP Settings

\n" - .. "Link your DHCP server to " - .. "Unbound " - .. " DNS resolver.", "https://www.unbound.net/ ")) - - s1:tab("resource", translate("Resource"), - translatef("

Unbound Resource Settings

\n" - .. "Memory and protocol setttings for " - .. "Unbound " - .. " DNS resolver.", "https://www.unbound.net/")) -end +s1:tab("basic", translate("Basic")) -s1:tab("trigger", translate("Trigger"), - translatef("

Unbound Event Trigger Settings

\n" - .. "Start, reload, and save RFC5011 DNSKEY records for " - .. "Unbound " - .. " DNS resolver.", "https://www.unbound.net/")) +if (valman == "0") then + -- Not in manual configuration mode; show UCI + s1:tab("advanced", translate("Advanced")) + s1:tab("DHCP", translate("DHCP")) + s1:tab("resource", translate("Resource")) +end --Basic Tab, unconditional pieces ena = s1:taboption("basic", Flag, "enabled", translate("Enable Unbound:"), - translate("Enable the initialization scripts for Unbound")) + translate("Enable the initialization scripts for Unbound")) ena.rmempty = false mcf = s1:taboption("basic", Flag, "manual_conf", translate("Manual Conf:"), - translate("Skip UCI and use /etc/unbound/unbound.conf")) + translate("Skip UCI and use /etc/unbound/unbound.conf")) mcf.rmempty = false -lci = s1:taboption("basic", Flag, "extended_luci", translate("Extended Tabs:"), - translate("See detailed tabs for statistics, debug, and manual configuration")) -lci.rmempty = false - - -if valman ~= "1" then - -- Not in manual configuration mode; show UCI - --Basic Tab - lsv = s1:taboption("basic", Flag, "localservice", translate("Local Service:"), - translate("Accept queries only from local subnets")) - lsv.rmempty = false - - vld = s1:taboption("basic", Flag, "validator", translate("Enable DNSSEC:"), - translate("Enable the DNSSEC validator module")) - vld.rmempty = false - - nvd = s1:taboption("basic", Flag, "validator_ntp", translate("DNSSEC NTP Fix:"), - translate("Break the loop where DNSSEC needs NTP and NTP needs DNS")) - nvd.rmempty = false - nvd:depends({ validator = true }) - - d64 = s1:taboption("basic", Flag, "dns64", translate("Enable DNS64:"), - translate("Enable the DNS64 module")) - d64.rmempty = false - - pfx = s1:taboption("basic", Value, "dns64_prefix", translate("DNS64 Prefix:"), - translate("Prefix for generated DNS64 addresses")) - pfx.datatype = "ip6addr" - pfx.placeholder = "64:ff9b::/96" - pfx.optional = true - pfx:depends({ dns64 = true }) - - prt = s1:taboption("basic", Value, "listen_port", translate("Listening Port:"), - translate("Choose Unbounds listening port")) - prt.datatype = "port" - prt.rmempty = false - - --Avanced Tab - din = s1:taboption("advanced", DynamicList, "domain_insecure", - translate("Domain Insecure:"), - translate("List domains to bypass checks of DNSSEC")) - din:depends({ validator = true }) - - dfw = s1:taboption("advanced", DynamicList, "domain_forward", - translate("Domain Forward:"), - translate("List domains to simply forward to stub resolvers in /tmp/resolve.auto")) - - rlh = s1:taboption("advanced", Flag, "rebind_localhost", translate("Filter Localhost Rebind:"), - translate("Protect against upstream response of 127.0.0.0/8")) - rlh.rmempty = false - - rpv = s1:taboption("advanced", ListValue, "rebind_protection", translate("Filter Private Rebind:"), - translate("Protect against upstream responses within local subnets")) - rpv:value("0", translate("No Filter")) - rpv:value("1", translate("Filter RFC1918/4193")) - rpv:value("2", translate("Filter Entire Subnet")) - rpv.rmempty = false - - rpn = s1:taboption("advanced", Value, "rebind_interface", translate("Rebind Network Filter:"), - translate("Network subnets to filter from upstream responses")) - rpn.template = "cbi/network_netlist" - rpn.widget = "checkbox" - rpn.rmempty = true - rpn.cast = "string" - rpn.nocreate = true - rpn:depends({ rebind_protection = 2 }) - rpn:depends({ rebind_protection = 3 }) - - --DHCP Tab - dlk = s1:taboption("DHCP", ListValue, "dhcp_link", translate("DHCP Link:"), - translate("Link to supported programs to load DHCP into DNS")) - dlk:value("none", translate("No Link")) - dlk:value("dnsmasq", "dnsmasq") - dlk:value("odhcpd", "odhcpd") - dlk.rmempty = false - - dp6 = s1:taboption("DHCP", Flag, "dhcp4_slaac6", translate("DHCPv4 to SLAAC:"), - translate("Use DHCPv4 MAC to discover IP6 hosts SLAAC (EUI64)")) - dp6.rmempty = false - dp6:depends({ dhcp_link = "odhcpd" }) - - dom = s1:taboption("DHCP", Value, "domain", translate("Local Domain:"), - translate("Domain suffix for this router and DHCP clients")) - dom.placeholder = "lan" - dom:depends({ dhcp_link = "none" }) - dom:depends({ dhcp_link = "odhcpd" }) - - dty = s1:taboption("DHCP", ListValue, "domain_type", translate("Local Domain Type:"), - translate("How to treat queries of this local domain")) - dty:value("deny", translate("Ignored")) - dty:value("refuse", translate("Refused")) - dty:value("static", translate("Only Local")) - dty:value("transparent", translate("Also Forwarded")) - dty:depends({ dhcp_link = "none" }) - dty:depends({ dhcp_link = "odhcpd" }) - - lfq = s1:taboption("DHCP", ListValue, "add_local_fqdn", translate("LAN DNS:"), - translate("How to enter the LAN or local network router in DNS")) - lfq:value("0", translate("No Entry")) - lfq:value("1", translate("Hostname, Primary Address")) - lfq:value("2", translate("Hostname, All Addresses")) - lfq:value("3", translate("Host FQDN, All Addresses")) - lfq:value("4", translate("Interface FQDN, All Addresses")) - lfq:depends({ dhcp_link = "none" }) - lfq:depends({ dhcp_link = "odhcpd" }) - - wfq = s1:taboption("DHCP", ListValue, "add_wan_fqdn", translate("WAN DNS:"), - translate("Override the WAN side router entry in DNS")) - wfq:value("0", translate("Use Upstream")) - wfq:value("1", translate("Hostname, Primary Address")) - wfq:value("2", translate("Hostname, All Addresses")) - wfq:value("3", translate("Host FQDN, All Addresses")) - wfq:value("4", translate("Interface FQDN, All Addresses")) - wfq:depends({ dhcp_link = "none" }) - wfq:depends({ dhcp_link = "odhcpd" }) - - exa = s1:taboption("DHCP", ListValue, "add_extra_dns", translate("Extra DNS:"), - translate("Use extra DNS entries found in /etc/config/dhcp")) - exa:value("0", translate("Ignore")) - exa:value("1", translate("Include Network/Hostnames")) - exa:value("2", translate("Advanced MX/SRV RR")) - exa:value("3", translate("Advanced CNAME RR")) - exa:depends({ dhcp_link = "none" }) - exa:depends({ dhcp_link = "odhcpd" }) - - --TODO: dnsmasq needs to not reference resolve-file and get off port 53. - - --Resource Tuning Tab - ctl = s1:taboption("resource", ListValue, "unbound_control", translate("Unbound Control App:"), - translate("Enable access for unbound-control")) - ctl.rmempty = false - ctl:value("0", translate("No Remote Control")) - ctl:value("1", translate("Local Host, No Encryption")) - ctl:value("2", translate("Local Host, Encrypted")) - ctl:value("3", translate("Local Subnet, Encrypted")) - ctl:value("4", translate("Local Subnet, Static Encryption")) - - pro = s1:taboption("resource", ListValue, "protocol", translate("Recursion Protocol:"), - translate("Chose the protocol recursion queries leave on")) - pro:value("default", translate("Default")) - pro:value("ip4_only", translate("IP4 Only")) - pro:value("ip6_only", translate("IP6 Only")) - pro:value("ip6_prefer", translate("IP6 Preferred")) - pro:value("mixed", translate("IP4 and IP6")) - pro.rmempty = false - - rsc = s1:taboption("resource", ListValue, "resource", translate("Memory Resource:"), - translate("Use menu System/Processes to observe any memory growth")) - rsc:value("default", translate("Default")) - rsc:value("tiny", translate("Tiny")) - rsc:value("small", translate("Small")) - rsc:value("medium", translate("Medium")) - rsc:value("large", translate("Large")) - rsc.rmempty = false - - rsn = s1:taboption("resource", ListValue, "recursion", translate("Recursion Strength:"), - translate("Recursion activity affects memory growth and CPU load")) - rsn:value("default", translate("Default")) - rsn:value("passive", translate("Passive")) - rsn:value("aggressive", translate("Aggressive")) - rsn.rmempty = false - - qry = s1:taboption("resource", Flag, "query_minimize", translate("Query Minimize:"), - translate("Break down query components for limited added privacy")) - qry.rmempty = false - qry:depends({ recursion = "passive" }) - qry:depends({ recursion = "aggressive" }) - - qrs = s1:taboption("resource", Flag, "query_min_strict", translate("Strict Minimize:"), - translate("Strict version of 'query minimize' but it can break DNS")) - qrs.rmempty = false - qrs:depends({ query_minimize = true }) - - ath = s1:taboption("resource", Flag, "prefetch_root", translate("Prefetch Root:"), - translate("Obtain complete root zone files and install in auth-zone: clause")) - ath.rmempty = false - - eds = s1:taboption("resource", Value, "edns_size", translate("EDNS Size:"), - translate("Limit extended DNS packet size")) - eds.datatype = "and(uinteger,min(512),max(4096))" - eds.rmempty = false - - tlm = s1:taboption("resource", Value, "ttl_min", translate("TTL Minimum:"), - translate("Prevent excessively short cache periods")) - tlm.datatype = "and(uinteger,min(0),max(600))" - tlm.rmempty = false - - stt = s1:taboption("resource", Flag, "extended_stats", translate("Extended Statistics:"), - translate("Extended statistics are printed from unbound-control")) - stt.rmempty = false -end - - ---Trigger Tab, always unconditional -ag2 = s1:taboption("trigger", Value, "root_age", translate("Root DSKEY Age:"), - translate("Limit days between RFC5011 copies to reduce flash writes")) -ag2.datatype = "and(uinteger,min(1),max(99))" -ag2:value("3", "3") -ag2:value("9", "9 ("..translate("default")..")") -ag2:value("12", "12") -ag2:value("24", "24") -ag2:value("99", "99 ("..translate("never")..")") -tgr = s1:taboption("trigger", Value, "trigger_interface", translate("Trigger Networks:"), - translate("Networks that may trigger Unbound to reload (avoid wan6)")) -tgr.template = "cbi/network_netlist" -tgr.widget = "checkbox" -tgr.rmempty = true -tgr.cast = "string" -tgr.nocreate = true +if (valman == "0") then + -- Not in manual configuration mode; show UCI + --Basic Tab + lsv = s1:taboption("basic", Flag, "localservice", + translate("Local Service:"), + translate("Accept queries only from local subnets")) + lsv.rmempty = false + + vld = s1:taboption("basic", Flag, "validator", + translate("Enable DNSSEC:"), + translate("Enable the DNSSEC validator module")) + vld.rmempty = false + + nvd = s1:taboption("basic", Flag, "validator_ntp", + translate("DNSSEC NTP Fix:"), + translate("Break the loop where DNSSEC needs NTP and NTP needs DNS")) + nvd.rmempty = false + nvd:depends({ validator = true }) + + prt = s1:taboption("basic", Value, "listen_port", + translate("Listening Port:"), + translate("Choose Unbounds listening port")) + prt.datatype = "port" + prt.rmempty = false + + --Avanced Tab + rlh = s1:taboption("advanced", Flag, "rebind_localhost", + translate("Filter Localhost Rebind:"), + translate("Protect against upstream response of 127.0.0.0/8")) + rlh.rmempty = false + + rpv = s1:taboption("advanced", ListValue, "rebind_protection", + translate("Filter Private Rebind:"), + translate("Protect against upstream responses within local subnets")) + rpv:value("0", translate("No Filter")) + rpv:value("1", translate("Filter RFC1918/4193")) + rpv:value("2", translate("Filter Entire Subnet")) + rpv.rmempty = false + + d64 = s1:taboption("advanced", Flag, "dns64", translate("Enable DNS64:"), + translate("Enable the DNS64 module")) + d64.rmempty = false + + pfx = s1:taboption("advanced", Value, "dns64_prefix", + translate("DNS64 Prefix:"), + translate("Prefix for generated DNS64 addresses")) + pfx.datatype = "ip6addr" + pfx.placeholder = "64:ff9b::/96" + pfx.optional = true + pfx:depends({ dns64 = true }) + + din = s1:taboption("advanced", DynamicList, "domain_insecure", + translate("Domain Insecure:"), + translate("List domains to bypass checks of DNSSEC")) + din:depends({ validator = true }) + + ag2 = s1:taboption("advanced", Value, "root_age", + translate("Root DSKEY Age:"), + translate("Limit days between RFC5011 copies to reduce flash writes")) + ag2.datatype = "and(uinteger,min(1),max(99))" + ag2:value("3", "3") + ag2:value("9", "9 ("..translate("default")..")") + ag2:value("12", "12") + ag2:value("24", "24") + ag2:value("99", "99 ("..translate("never")..")") + + tgr = s1:taboption("advanced", Value, "trigger_interface", + translate("Trigger Networks:"), + translate("Networks that may trigger Unbound to reload (avoid wan6)")) + tgr.template = "cbi/network_netlist" + tgr.widget = "checkbox" + tgr.rmempty = true + tgr.cast = "string" + tgr.nocreate = true + + --DHCP Tab + dlk = s1:taboption("DHCP", ListValue, "dhcp_link", + translate("DHCP Link:"), + translate("Link to supported programs to load DHCP into DNS")) + dlk:value("none", translate("No Link")) + dlk:value("dnsmasq", "dnsmasq") + dlk:value("odhcpd", "odhcpd") + dlk.rmempty = false + + dp6 = s1:taboption("DHCP", Flag, "dhcp4_slaac6", + translate("DHCPv4 to SLAAC:"), + translate("Use DHCPv4 MAC to discover IP6 hosts SLAAC (EUI64)")) + dp6.rmempty = false + dp6:depends({ dhcp_link = "odhcpd" }) + + dom = s1:taboption("DHCP", Value, "domain", + translate("Local Domain:"), + translate("Domain suffix for this router and DHCP clients")) + dom.placeholder = "lan" + dom:depends({ dhcp_link = "none" }) + dom:depends({ dhcp_link = "odhcpd" }) + + dty = s1:taboption("DHCP", ListValue, "domain_type", + translate("Local Domain Type:"), + translate("How to treat queries of this local domain")) + dty:value("deny", translate("Denied (nxdomain)")) + dty:value("refuse", translate("Refused")) + dty:value("static", translate("Static (local only)")) + dty:value("transparent", translate("Transparent (local/global)")) + dty:depends({ dhcp_link = "none" }) + dty:depends({ dhcp_link = "odhcpd" }) + + lfq = s1:taboption("DHCP", ListValue, "add_local_fqdn", + translate("LAN DNS:"), + translate("How to enter the LAN or local network router in DNS")) + lfq:value("0", translate("No Entry")) + lfq:value("1", translate("Hostname, Primary Address")) + lfq:value("2", translate("Hostname, All Addresses")) + lfq:value("3", translate("Host FQDN, All Addresses")) + lfq:value("4", translate("Interface FQDN, All Addresses")) + lfq:depends({ dhcp_link = "none" }) + lfq:depends({ dhcp_link = "odhcpd" }) + + wfq = s1:taboption("DHCP", ListValue, "add_wan_fqdn", + translate("WAN DNS:"), + translate("Override the WAN side router entry in DNS")) + wfq:value("0", translate("Use Upstream")) + wfq:value("1", translate("Hostname, Primary Address")) + wfq:value("2", translate("Hostname, All Addresses")) + wfq:value("3", translate("Host FQDN, All Addresses")) + wfq:value("4", translate("Interface FQDN, All Addresses")) + wfq:depends({ dhcp_link = "none" }) + wfq:depends({ dhcp_link = "odhcpd" }) + + exa = s1:taboption("DHCP", ListValue, "add_extra_dns", + translate("Extra DNS:"), + translate("Use extra DNS entries found in /etc/config/dhcp")) + exa:value("0", translate("Ignore")) + exa:value("1", translate("Host Records")) + exa:value("2", translate("Host/MX/SRV RR")) + exa:value("3", translate("Host/MX/SRV/CNAME RR")) + exa:depends({ dhcp_link = "none" }) + exa:depends({ dhcp_link = "odhcpd" }) + + --TODO: dnsmasq needs to not reference resolve-file and get off port 53. + + --Resource Tuning Tab + ctl = s1:taboption("resource", ListValue, "unbound_control", + translate("Unbound Control App:"), + translate("Enable access for unbound-control")) + ctl.rmempty = false + ctl:value("0", translate("No Remote Control")) + ctl:value("1", translate("Local Host, No Encryption")) + ctl:value("2", translate("Local Host, Encrypted")) + ctl:value("3", translate("Local Subnet, Encrypted")) + ctl:value("4", translate("Local Subnet, Static Encryption")) + + pro = s1:taboption("resource", ListValue, "protocol", + translate("Recursion Protocol:"), + translate("Chose the protocol recursion queries leave on")) + pro:value("default", translate("Default")) + pro:value("ip4_only", translate("IP4 Only")) + pro:value("ip6_only", translate("IP6 Only")) + pro:value("ip6_prefer", translate("IP6 Preferred")) + pro:value("mixed", translate("IP4 and IP6")) + pro.rmempty = false + + rsc = s1:taboption("resource", ListValue, "resource", + translate("Memory Resource:"), + translate("Use menu System/Processes to observe any memory growth")) + rsc:value("default", translate("Default")) + rsc:value("tiny", translate("Tiny")) + rsc:value("small", translate("Small")) + rsc:value("medium", translate("Medium")) + rsc:value("large", translate("Large")) + rsc.rmempty = false + + rsn = s1:taboption("resource", ListValue, "recursion", + translate("Recursion Strength:"), + translate("Recursion activity affects memory growth and CPU load")) + rsn:value("default", translate("Default")) + rsn:value("passive", translate("Passive")) + rsn:value("aggressive", translate("Aggressive")) + rsn.rmempty = false + + qry = s1:taboption("resource", Flag, "query_minimize", + translate("Query Minimize:"), + translate("Break down query components for limited added privacy")) + qry.rmempty = false + qry:depends({ recursion = "passive" }) + qry:depends({ recursion = "aggressive" }) + + qrs = s1:taboption("resource", Flag, "query_min_strict", + translate("Strict Minimize:"), + translate("Strict version of 'query minimize' but it can break DNS")) + qrs.rmempty = false + qrs:depends({ query_minimize = true }) + + eds = s1:taboption("resource", Value, "edns_size", + translate("EDNS Size:"), + translate("Limit extended DNS packet size")) + eds.datatype = "and(uinteger,min(512),max(4096))" + eds.rmempty = false + + tlm = s1:taboption("resource", Value, "ttl_min", + translate("TTL Minimum:"), + translate("Prevent excessively short cache periods")) + tlm.datatype = "and(uinteger,min(0),max(600))" + tlm.rmempty = false + + stt = s1:taboption("resource", Flag, "extended_stats", + translate("Extended Statistics:"), + translate("Extended statistics are printed from unbound-control")) + stt.rmempty = false + +else + ag2 = s1:taboption("basic", Value, "root_age", + translate("Root DSKEY Age:"), + translate("Limit days between RFC5011 copies to reduce flash writes")) + ag2.datatype = "and(uinteger,min(1),max(99))" + ag2:value("3", "3") + ag2:value("9", "9 ("..translate("default")..")") + ag2:value("12", "12") + ag2:value("24", "24") + ag2:value("99", "99 ("..translate("never")..")") + + tgr = s1:taboption("basic", Value, "trigger_interface", + translate("Trigger Networks:"), + translate("Networks that may trigger Unbound to reload (avoid wan6)")) + tgr.template = "cbi/network_netlist" + tgr.widget = "checkbox" + tgr.rmempty = true + tgr.cast = "string" + tgr.nocreate = true +end function ena.cfgvalue(self, section) - return luci.sys.init.enabled("unbound") and self.enabled or self.disabled + return sy.init.enabled("unbound") and self.enabled or self.disabled end function ena.write(self, section, value) - if value == "1" then - luci.sys.init.enable("unbound") - luci.sys.call("/etc/init.d/unbound start >/dev/null") - else - luci.sys.call("/etc/init.d/unbound stop >/dev/null") - luci.sys.init.disable("unbound") - end - - return Flag.write(self, section, value) + if (value == "1") then + sy.init.enable("unbound") + sy.call("/etc/init.d/unbound start >/dev/null 2>&1") + + else + sy.call("/etc/init.d/unbound stop >/dev/null 2>&1") + sy.init.disable("unbound") + end + + + return Flag.write(self, section, value) end -function m1.on_apply(self) - function ena.validate(self, value) - if value ~= "0" then - luci.sys.call("/etc/init.d/unbound restart >/dev/null 2>&1") +function m1.on_commit(self) + if sy.init.enabled("unbound") then + -- Restart Unbound with configuration + sy.call("/etc/init.d/unbound restart >/dev/null 2>&1") + else - luci.sys.call("/etc/init.d/unbound stop >/dev/null 2>&1") + sy.call("/etc/init.d/unbound stop >/dev/null 2>&1") end - end +end - -- Restart Unbound with configuration and reload the page (some options hide) - luci.http.redirect(luci.dispatcher.build_url("admin", "services", "unbound")) +function m1.on_apply(self) + -- reload the page because some options hide + ht.redirect(ds.build_url("admin", "services", "unbound", "configure")) end diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/extended.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/extended.lua index 67d2ec6c6b..6c5e8c23ef 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/extended.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/extended.lua @@ -1,28 +1,31 @@ --- Copyright 2016 Eric Luehrsen +-- Copyright 2016 Eric Luehrsen -- Licensed to the public under the Apache License 2.0. local m4, s4, frm local filename = "/etc/unbound/unbound_ext.conf" -local description = translatef("Here you may edit 'forward:' and 'remote-control:' in an extended 'include:'") -description = description .. " (" .. filename .. ")" +local fs = require "nixio.fs" +local ut = require "luci.util" m4 = SimpleForm("editing", nil) m4:append(Template("unbound/css-editing")) m4.submit = translate("Save") m4.reset = false -s4 = m4:section(SimpleSection, "Unbound Extended Conf", description) +s4 = m4:section(SimpleSection, "", + translatef( + "Edit clauses such as 'forward-zone:' for 'include: " .. filename .. "'")) + frm = s4:option(TextValue, "data") frm.datatype = "string" frm.rows = 20 function frm.cfgvalue() - return nixio.fs.readfile(filename) or "" + return fs.readfile(filename) or "" end function frm.write(self, section, data) - return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n"))) + return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n"))) end diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/manual.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/manual.lua index 5cfb9c32c1..317c23fda0 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/manual.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/manual.lua @@ -1,28 +1,31 @@ --- Copyright 2016 Eric Luehrsen +-- Copyright 2016 Eric Luehrsen -- Licensed to the public under the Apache License 2.0. local m2, s2, frm local filename = "/etc/unbound/unbound.conf" -local description = translatef("Here you may edit raw 'unbound.conf' when you don't use UCI:") -description = description .. " (" .. filename .. ")" +local fs = require "nixio.fs" +local ut = require "luci.util" m2 = SimpleForm("editing", nil) m2:append(Template("unbound/css-editing")) m2.submit = translate("Save") m2.reset = false -s2 = m2:section(SimpleSection, "Unbound Conf", description) +s2 = m2:section(SimpleSection, "", + translatef( + "Edit '" .. filename .. "' when you do not use UCI.")) + frm = s2:option(TextValue, "data") frm.datatype = "string" frm.rows = 20 function frm.cfgvalue() - return nixio.fs.readfile(filename) or "" + return fs.readfile(filename) or "" end function frm.write(self, section, data) - return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n"))) + return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n"))) end diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/server.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/server.lua index d0ac407847..5cef2a67b0 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/server.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/server.lua @@ -1,28 +1,31 @@ --- Copyright 2016 Eric Luehrsen +-- Copyright 2016 Eric Luehrsen -- Licensed to the public under the Apache License 2.0. local m3, s3, frm local filename = "/etc/unbound/unbound_srv.conf" -local description = translatef("Here you may edit the 'server:' clause in an internal 'include:'") -description = description .. " (" .. filename .. ")" +local fs = require "nixio.fs" +local ut = require "luci.util" m3 = SimpleForm("editing", nil) m3:append(Template("unbound/css-editing")) m3.submit = translate("Save") m3.reset = false -s3 = m3:section(SimpleSection, "Unbound Server Conf", description) +s3 = m3:section(SimpleSection, "", + translatef( + "Edit 'server:' clause options for 'include: " .. filename .. "'")) + frm = s3:option(TextValue, "data") frm.datatype = "string" frm.rows = 20 function frm.cfgvalue() - return nixio.fs.readfile(filename) or "" + return fs.readfile(filename) or "" end function frm.write(self, section, data) - return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n"))) + return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n"))) end diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua new file mode 100644 index 0000000000..3aef189652 --- /dev/null +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua @@ -0,0 +1,37 @@ +-- Copyright 2016 Eric Luehrsen +-- Licensed to the public under the Apache License 2.0. + +local m6, s6, frm +local filename = "/etc/config/unbound" +local fs = require "nixio.fs" +local ut = require "luci.util" + +m6 = SimpleForm("editing", nil) +m6:append(Template("unbound/css-editing")) +m6.submit = translate("Save") +m6.reset = false +s6 = m6:section(SimpleSection, "", + translatef("Edit '" .. filename .. "' " + .. "and help can be found in OpenWrt " + .. "Guides " + .. "and Github.", + "https://openwrt.org/docs/guide-user/services/dns/unbound", + "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md")) + +frm = s6:option(TextValue, "data") +frm.datatype = "string" +frm.rows = 20 + + +function frm.cfgvalue() + return fs.readfile(filename) or "" +end + + +function frm.write(self, section, data) + return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n"))) +end + + +return m6 + diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua new file mode 100644 index 0000000000..bbc0e2335f --- /dev/null +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua @@ -0,0 +1,207 @@ +-- Copyright 2017 Eric Luehrsen +-- Licensed to the public under the Apache License 2.0. + +local m5, s5 +local ztype, zones, servers, fallback, enabled + +local fs = require "nixio.fs" +local ut = require "luci.util" +local sy = require "luci.sys" +local resolvfile = "/tmp/resolv.conf.auto" + +m5 = Map("unbound") +s5 = m5:section(TypedSection, "zone", "Zones", + translatef("This shows extended zones and more details can be " + .. "changed in Files tab and Edit:UCI subtab.", + "/cgi-bin/luci/admin/services/unbound/files" )) + +s5.addremove = false +s5.anonymous = true +s5.sortable = true +s5.template = "cbi/tblsection" + +ztype = s5:option(DummyValue, "DummyType", translate("Type")) +ztype.rawhtml = true + +zones = s5:option(DummyValue, "DummyZones", translate("Zones")) +zones.rawhtml = true + +servers = s5:option(DummyValue, "DummyServers", translate("Servers")) +servers.rawhtml = true + +fallback = s5:option(Flag, "fallback", translate("Fallback")) +fallback.rmempty = false + +enabled = s5:option(Flag, "enabled", translate("Enable")) +enabled.rmempty = false + + +function ztype.cfgvalue(self, s) + -- Format a meaninful tile for the Zone Type column + local itxt = self.map:get(s, "zone_type") + local itls = self.map:get(s, "tls_upstream") + + + if itxt and itxt:match("forward") then + if itls and (itls == "1") then + return translate("Forward TLS") + + else + return translate("Forward") + end + + elseif itxt and itxt:match("stub") then + return translate("Recurse") + + elseif itxt and itxt:match("auth") then + return translate("AXFR") + + else + return translate("Error") + end +end + + +function zones.cfgvalue(self, s) + -- Format a meaninful sentence for the Zones viewed column + local xtxt, otxt + local itxt = self.map:get(s, "zone_name") + local itype = self.map:get(s, "zone_type") + + + for xtxt in ut.imatch(itxt) do + if (xtxt == ".") then + -- zone_name lists + xtxt = translate("(root)") + end + + + if otxt and (#otxt > 0) then + otxt = otxt .. ", %s" % xtxt + + else + otxt = "%s" % xtxt + end + end + + + if itype and itype:match("forward") then + -- from zone_type create a readable hint for the action + otxt = translate("accept upstream results for ") .. otxt + + elseif itype and itype:match("stub") then + otxt = translate("select recursion for ") .. otxt + + elseif itype and itype:match("auth") then + otxt = translate("prefetch zone files for ") .. otxt + + else + otxt = translate("unknown action for ") .. otxt + end + + + if otxt and (#otxt > 0) then + return otxt + + else + return "(empty)" + end +end + + +function servers.cfgvalue(self, s) + -- Format a meaninful sentence for the Servers (and URL) column + local xtxt, otxt, rtxt, found + local itxt = self.map:get(s, "server") + local iurl = self.map:get(s, "url_dir") + local itype = self.map:get(s, "zone_type") + local itls = self.map:get(s, "tls_upstream") + local iidx = self.map:get(s, "tls_index") + local irslv = self.map:get(s, "resolv_conf") + + + for xtxt in ut.imatch(itxt) do + if otxt and (#otxt > 0) then + -- bundle and make pretty the server list + otxt = otxt .. ", %s" % xtxt + + else + otxt = "%s" % xtxt + end + end + + + if otxt and (#otxt > 0) + and itls and (itls == "1") + and iidx and (#iidx > 0) then + -- show TLS certificate name index if provided + otxt = translatef("use nameservers by %s at ", iidx) .. otxt + + elseif otxt and (#otxt > 0) then + otxt = translate("use nameservers ") .. otxt + end + + + if iurl and (#iurl > 0) and itype and itype:match("auth") then + if otxt and (#otxt > 0) then + -- include optional URL filed for auth-zone: type + otxt = otxt .. translatef(", and try %s", iurl) + + else + otxt = translatef("download from %s", iurl) + end + end + + + if irslv and (irslv == "1") and itype and itype:match("forward") then + for xtxt in ut.imatch(fs.readfile(resolvfile)) do + if xtxt:match("nameserver") then + found = true + + elseif (found == true) then + if rtxt and (#rtxt > 0) then + -- fetch name servers from resolv.conf + rtxt = rtxt .. ", %s" % xtxt + + else + rtxt = "%s" % xtxt + end + + + found = false + end + end + + + if otxt and (#otxt > 0) and rtxt and (#rtxt > 0) then + otxt = otxt + .. translatef(", and %s entries ", resolvfile) .. rtxt + + elseif rtxt and (#rtxt > 0) then + otxt = translatef("use %s nameservers ", resolvfile) .. rtxt + end + end + + + if otxt and (#otxt > 0) then + return otxt + + else + return "(empty)" + end +end + + +function m5.on_commit(self) + if sy.init.enabled("unbound") then + -- Restart Unbound with configuration + sy.call("/etc/init.d/unbound restart >/dev/null 2>&1") + + else + sy.call("/etc/init.d/unbound stop >/dev/null 2>&1") + end +end + + +return m5 + diff --git a/contrib/package/freifunk-common/files/usr/sbin/ff_olsr_watchdog b/contrib/package/freifunk-common/files/usr/sbin/ff_olsr_watchdog index 069f4c3217..8ac803d309 100755 --- a/contrib/package/freifunk-common/files/usr/sbin/ff_olsr_watchdog +++ b/contrib/package/freifunk-common/files/usr/sbin/ff_olsr_watchdog @@ -23,6 +23,15 @@ if fs.access("/var/run/olsrd.pid") or fs.access("/var/run/olsrd4.pid") then if not wdgtime or ( systime - wdgtime ) > ( intv * 2 ) then os.execute("logger -t 'OLSR watchdog' 'Process died - restarting!'") + local tnls = io.popen("ip tunnel show | cut -d : -f 1") + while true do + tnl = tnls:read("*line") + if tnl == nil then break end + if string.find(tnl, "tnl_") == 1 then + os.execute(string.format("logger -t 'OLSR watchdog' 'Deleting stale tunnel %s'", tnl)) + os.execute(string.format("ip link del %s", tnl)) + end + end os.execute("/etc/init.d/olsrd restart") end end diff --git a/luci.mk b/luci.mk index 6ece81c3d6..f9153819ee 100644 --- a/luci.mk +++ b/luci.mk @@ -153,7 +153,7 @@ LUCI_LIBRARYDIR = $(LUA_LIBRARYDIR)/luci define SrcDiet $(FIND) $(1) -type f -name '*.lua' | while read src; do \ - if luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \ + if LUA_PATH="$(STAGING_DIR_HOSTPKG)/lib/lua/5.1/?.lua" luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \ then mv "$$$$src.o" "$$$$src"; fi; \ done endef diff --git a/modules/luci-base/Makefile b/modules/luci-base/Makefile index 5c38d99c58..06ee7985eb 100644 --- a/modules/luci-base/Makefile +++ b/modules/luci-base/Makefile @@ -37,13 +37,14 @@ endef define Host/Compile $(MAKE) -C src/ clean po2lmo - $(MAKE) -C $(HOST_BUILD_DIR) bin/luasrcdiet endef define Host/Install $(INSTALL_DIR) $(1)/bin + $(INSTALL_DIR) $(1)/lib/lua/5.1 $(INSTALL_BIN) src/po2lmo $(1)/bin/po2lmo $(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/luasrcdiet $(1)/bin/luasrcdiet + $(CP) $(HOST_BUILD_DIR)/luasrcdiet $(1)/lib/lua/5.1/ endef $(eval $(call HostBuild)) diff --git a/modules/luci-base/htdocs/luci-static/resources/xhr.js b/modules/luci-base/htdocs/luci-static/resources/xhr.js index 62b525ebb0..25a90e7254 100644 --- a/modules/luci-base/htdocs/luci-static/resources/xhr.js +++ b/modules/luci-base/htdocs/luci-static/resources/xhr.js @@ -65,12 +65,8 @@ XHR = function() if (xhr.readyState == 4) { var json = null; if (xhr.getResponseHeader("Content-Type") == "application/json") { - try { - json = JSON.parse(xhr.responseText); - } - catch(e) { - json = null; - } + try { json = JSON.parse(xhr.responseText); } + catch(e) { json = null; } } callback(xhr, json, Date.now() - ts); @@ -90,8 +86,15 @@ XHR = function() xhr.onreadystatechange = function() { - if (xhr.readyState == 4) - callback(xhr, null, Date.now() - ts); + if (xhr.readyState == 4) { + var json = null; + if (xhr.getResponseHeader("Content-Type") == "application/json") { + try { json = JSON.parse(xhr.responseText); } + catch(e) { json = null; } + } + + callback(xhr, json, Date.now() - ts); + } } xhr.open('POST', url, true); diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index 6d5a8f4d3d..6cf2712eb4 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -893,8 +893,6 @@ local function _cbi(self, ...) local pageaction = true local parsechain = { } - local is_rollback, time_remaining = uci:rollback_pending() - for i, res in ipairs(maps) do if res.apply_needed and res.parsechain then local c @@ -921,8 +919,6 @@ local function _cbi(self, ...) for i, res in ipairs(maps) do res:render({ firstmap = (i == 1), - applymap = applymap, - confirmmap = (is_rollback and time_remaining or nil), redirect = redirect, messages = messages, pageaction = pageaction, @@ -932,11 +928,12 @@ local function _cbi(self, ...) if not config.nofooter then tpl.render("cbi/footer", { - flow = config, - pageaction = pageaction, - redirect = redirect, - state = state, - autoapply = config.autoapply + flow = config, + pageaction = pageaction, + redirect = redirect, + state = state, + autoapply = config.autoapply, + trigger_apply = applymap }) end end diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index 92c0d8f699..b2c1e463bf 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -147,19 +147,31 @@ function apply(self, rollback) local _, err if rollback then + local sys = require "luci.sys" local conf = require "luci.config" - local timeout = tonumber(conf and conf.apply and conf.apply.rollback or "") or 0 + local timeout = tonumber(conf and conf.apply and conf.apply.rollback or 30) or 0 _, err = call("apply", { - timeout = (timeout > 30) and timeout or 30, + timeout = (timeout > 30) and timeout or 30, rollback = true }) if not err then + local now = os.time() + local token = sys.uniqueid(16) + util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = os.time() + timeout } + ubus_rpc_session = "00000000000000000000000000000000", + values = { + rollback = { + token = token, + session = session_id, + timeout = now + timeout + } + } }) + + return token end else _, err = call("changes", {}) @@ -184,40 +196,72 @@ function apply(self, rollback) return (err == nil), ERRSTR[err] end -function confirm(self) - local _, err = call("confirm", {}) - if not err then - util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = 0 } +function confirm(self, token) + local is_pending, time_remaining, rollback_sid, rollback_token = self:rollback_pending() + + if is_pending then + if token ~= rollback_token then + return false, "Permission denied" + end + + local _, err = util.ubus("uci", "confirm", { + ubus_rpc_session = rollback_sid }) + + if not err then + util.ubus("session", "set", { + ubus_rpc_session = "00000000000000000000000000000000", + values = { rollback = {} } + }) + end + + return (err == nil), ERRSTR[err] end - return (err == nil), ERRSTR[err] + + return false, "No data" end function rollback(self) - local _, err = call("rollback", {}) - if not err then - util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = 0 } + local is_pending, time_remaining, rollback_sid = self:rollback_pending() + + if is_pending then + local _, err = util.ubus("uci", "rollback", { + ubus_rpc_session = rollback_sid }) + + if not err then + util.ubus("session", "set", { + ubus_rpc_session = "00000000000000000000000000000000", + values = { rollback = {} } + }) + end + + return (err == nil), ERRSTR[err] end - return (err == nil), ERRSTR[err] + + return false, "No data" end function rollback_pending(self) - local deadline, err = util.ubus("session", "get", { - ubus_rpc_session = session_id, + local rv, err = util.ubus("session", "get", { + ubus_rpc_session = "00000000000000000000000000000000", keys = { "rollback" } }) - if type(deadline) == "table" and - type(deadline.values) == "table" and - type(deadline.values.rollback) == "number" and - deadline.values.rollback > os.time() + local now = os.time() + + if type(rv) == "table" and + type(rv.values) == "table" and + type(rv.values.rollback) == "table" and + type(rv.values.rollback.token) == "string" and + type(rv.values.rollback.session) == "string" and + type(rv.values.rollback.timeout) == "number" and + rv.values.rollback.timeout > now then - return true, deadline.values.rollback - os.time() + return true, + rv.values.rollback.timeout - now, + rv.values.rollback.session, + rv.values.rollback.token end return false, ERRSTR[err] diff --git a/modules/luci-base/luasrc/util.lua b/modules/luci-base/luasrc/util.lua index 10428b0b35..f16b3afb2e 100644 --- a/modules/luci-base/luasrc/util.lua +++ b/modules/luci-base/luasrc/util.lua @@ -16,7 +16,7 @@ local _ubus = require "ubus" local _ubus_connection = nil local getmetatable, setmetatable = getmetatable, setmetatable -local rawget, rawset, unpack = rawget, rawset, unpack +local rawget, rawset, unpack, select = rawget, rawset, unpack, select local tostring, type, assert, error = tostring, type, assert, error local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring local require, pcall, xpcall = require, pcall, xpcall @@ -647,6 +647,17 @@ local ubus_codes = { "CONNECTION_FAILED" } +local function ubus_return(...) + if select('#', ...) == 2 then + local rv, err = select(1, ...), select(2, ...) + if rv == nil and type(err) == "number" then + return nil, err, ubus_codes[err] + end + end + + return ... +end + function ubus(object, method, data) if not _ubus_connection then _ubus_connection = _ubus.connect() @@ -657,8 +668,7 @@ function ubus(object, method, data) if type(data) ~= "table" then data = { } end - local rv, err = _ubus_connection:call(object, method, data) - return rv, err, ubus_codes[err] + return ubus_return(_ubus_connection:call(object, method, data)) elseif object then return _ubus_connection:signatures(object) else diff --git a/modules/luci-base/luasrc/view/cbi/apply_widget.htm b/modules/luci-base/luasrc/view/cbi/apply_widget.htm index f76846ee87..ce279edd40 100644 --- a/modules/luci-base/luasrc/view/cbi/apply_widget.htm +++ b/modules/luci-base/luasrc/view/cbi/apply_widget.htm @@ -1,4 +1,4 @@ -<% export("cbi_apply_widget", function(redirect_ok) -%> +<% export("cbi_apply_widget", function(redirect_ok, rollback_token) -%>