diff options
15 files changed, 340 insertions, 248 deletions
diff --git a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm index 273675cd3..82168712a 100644 --- a/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm +++ b/applications/luci-app-firewall/luasrc/view/firewall/cbi_addrule.htm @@ -1,11 +1,9 @@ <% local fw = require "luci.model.firewall".init() - local wz = fw:get_zone("wan") - local lz = fw:get_zone("lan") local zones = fw:get_zones() %> -<% if wz then %> +<% if #zones > 0 then %> <h4><%:Open ports on router%></h4> <div class="table"> <div class="tr cbi-section-table-titles"> @@ -71,7 +69,7 @@ <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> <% end %> -<% if wz then %> +<% if #zones > 0 then %> <script type="text/javascript">//<![CDATA[ cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))'); cbi_bind(document.getElementById('_newopen.extport'), 'blur', diff --git a/applications/luci-app-unbound/luasrc/controller/unbound.lua b/applications/luci-app-unbound/luasrc/controller/unbound.lua index ea3d26b91..771385b79 100644 --- a/applications/luci-app-unbound/luasrc/controller/unbound.lua +++ b/applications/luci-app-unbound/luasrc/controller/unbound.lua @@ -28,7 +28,8 @@ function index() if (valman == "0") then entry({"admin", "services", "unbound", "zones"}, - cbi("unbound/zones"), _("Zones"), 15) + arcombine(cbi("unbound/zones"), cbi("unbound/zone-details")), + _("Zones"), 15).leaf = true end @@ -106,7 +107,7 @@ end function QuerySysLog() - local lcldata = luci.util.exec("logread | grep -i unbound") + local lcldata = luci.util.exec("logread -e 'unbound'") local lcldesc = luci.i18n.translate( "This shows syslog filtered for events involving Unbound.") 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 f665a2c9d..8170f3d2b 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/configure.lua @@ -19,10 +19,12 @@ 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"), +s1 = m1:section(TypedSection, "unbound", translate("Recursive DNS"), translatef("Unbound <a href=\"%s\" target=\"_blank\">(NLnet Labs)</a>" - .. " is a validating, recursive, and caching DNS resolver.", - "https://www.unbound.net/")) + .. " is a validating, recursive, and caching DNS resolver" + .. " <a href=\"%s\" target=\"_blank\">(help)</a>.", + "https://www.unbound.net/", + "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md")) s1.addremove = false s1.anonymous = true @@ -40,11 +42,11 @@ end --Basic Tab, unconditional pieces -ena = s1:taboption("basic", Flag, "enabled", translate("Enable Unbound:"), +ena = s1:taboption("basic", Flag, "enabled", translate("Enable Unbound"), translate("Enable the initialization scripts for Unbound")) ena.rmempty = false -mcf = s1:taboption("basic", Flag, "manual_conf", translate("Manual Conf:"), +mcf = s1:taboption("basic", Flag, "manual_conf", translate("Manual Conf"), translate("Skip UCI and use /etc/unbound/unbound.conf")) mcf.rmempty = false @@ -53,60 +55,60 @@ if (valman == "0") then -- Not in manual configuration mode; show UCI --Basic Tab lsv = s1:taboption("basic", Flag, "localservice", - translate("Local Service:"), + translate("Local Service"), translate("Accept queries only from local subnets")) lsv.rmempty = false vld = s1:taboption("basic", Flag, "validator", - translate("Enable DNSSEC:"), + translate("Enable DNSSEC"), translate("Enable the DNSSEC validator module")) vld.rmempty = false nvd = s1:taboption("basic", Flag, "validator_ntp", - translate("DNSSEC NTP Fix:"), + translate("DNSSEC NTP Fix"), translate("Break the loop where DNSSEC needs NTP and NTP needs DNS")) - nvd.rmempty = false - nvd:depends({ validator = true }) + nvd.optional = true + nvd:depends("validator", true) prt = s1:taboption("basic", Value, "listen_port", - translate("Listening Port:"), + translate("Listening Port"), translate("Choose Unbounds listening port")) prt.datatype = "port" - prt.rmempty = false + prt.placeholder = "53" --Avanced Tab rlh = s1:taboption("advanced", Flag, "rebind_localhost", - translate("Filter Localhost Rebind:"), + 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("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("1", translate("Filter Private Address")) rpv:value("2", translate("Filter Entire Subnet")) rpv.rmempty = false - d64 = s1:taboption("advanced", Flag, "dns64", translate("Enable DNS64:"), + 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("DNS64 Prefix"), translate("Prefix for generated DNS64 addresses")) pfx.datatype = "ip6addr" pfx.placeholder = "64:ff9b::/96" pfx.optional = true - pfx:depends({ dns64 = true }) + pfx:depends("dns64", true) din = s1:taboption("advanced", DynamicList, "domain_insecure", - translate("Domain Insecure:"), + translate("Domain Insecure"), translate("List domains to bypass checks of DNSSEC")) - din:depends({ validator = true }) + din:depends("validator", true) ag2 = s1:taboption("advanced", Value, "root_age", - translate("Root DSKEY 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") @@ -116,7 +118,7 @@ if (valman == "0") then ag2:value("99", "99 ("..translate("never")..")") tgr = s1:taboption("advanced", Value, "trigger_interface", - translate("Trigger Networks:"), + translate("Trigger Networks"), translate("Networks that may trigger Unbound to reload (avoid wan6)")) tgr.template = "cbi/network_netlist" tgr.widget = "checkbox" @@ -126,7 +128,7 @@ if (valman == "0") then --DHCP Tab dlk = s1:taboption("DHCP", ListValue, "dhcp_link", - translate("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") @@ -134,65 +136,70 @@ if (valman == "0") then dlk.rmempty = false dp6 = s1:taboption("DHCP", Flag, "dhcp4_slaac6", - translate("DHCPv4 to SLAAC:"), + translate("DHCPv4 to SLAAC"), translate("Use DHCPv4 MAC to discover IP6 hosts SLAAC (EUI64)")) - dp6.rmempty = false - dp6:depends({ dhcp_link = "odhcpd" }) + dp6.optional = true + dp6:depends("dhcp_link", "odhcpd") dom = s1:taboption("DHCP", Value, "domain", - translate("Local 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" }) + dom.optional = true + dom:depends("dhcp_link", "none") + dom:depends("dhcp_link", "odhcpd") dty = s1:taboption("DHCP", ListValue, "domain_type", - translate("Local Domain Type:"), + translate("Local Domain Type"), translate("How to treat queries of this local domain")) + dty.optional = true 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" }) + dty:depends("dhcp_link", "none") + dty:depends("dhcp_link", "odhcpd") lfq = s1:taboption("DHCP", ListValue, "add_local_fqdn", - translate("LAN DNS:"), + translate("LAN DNS"), translate("How to enter the LAN or local network router in DNS")) + lfq.optional = true 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" }) + lfq:depends("dhcp_link", "none") + lfq:depends("dhcp_link", "odhcpd") wfq = s1:taboption("DHCP", ListValue, "add_wan_fqdn", - translate("WAN DNS:"), + translate("WAN DNS"), translate("Override the WAN side router entry in DNS")) + wfq.optional = true 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" }) + wfq:depends("dhcp_link", "none") + wfq:depends("dhcp_link", "odhcpd") exa = s1:taboption("DHCP", ListValue, "add_extra_dns", - translate("Extra DNS:"), + translate("Extra DNS"), translate("Use extra DNS entries found in /etc/config/dhcp")) + exa.optional = true 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" }) + 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("Unbound Control App"), translate("Enable access for unbound-control")) ctl.rmempty = false ctl:value("0", translate("No Remote Control")) @@ -202,7 +209,7 @@ if (valman == "0") then ctl:value("4", translate("Local Subnet, Static Encryption")) pro = s1:taboption("resource", ListValue, "protocol", - translate("Recursion Protocol:"), + translate("Recursion Protocol"), translate("Chose the protocol recursion queries leave on")) pro:value("default", translate("Default")) pro:value("ip4_only", translate("IP4 Only")) @@ -212,7 +219,7 @@ if (valman == "0") then pro.rmempty = false rsc = s1:taboption("resource", ListValue, "resource", - translate("Memory Resource:"), + translate("Memory Resource"), translate("Use menu System/Processes to observe any memory growth")) rsc:value("default", translate("Default")) rsc:value("tiny", translate("Tiny")) @@ -222,7 +229,7 @@ if (valman == "0") then rsc.rmempty = false rsn = s1:taboption("resource", ListValue, "recursion", - translate("Recursion Strength:"), + translate("Recursion Strength"), translate("Recursion activity affects memory growth and CPU load")) rsn:value("default", translate("Default")) rsn:value("passive", translate("Passive")) @@ -230,38 +237,38 @@ if (valman == "0") then rsn.rmempty = false qry = s1:taboption("resource", Flag, "query_minimize", - translate("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" }) + qry.optional = true + qry:depends("recursion", "passive") + qry:depends("recursion", "aggressive") qrs = s1:taboption("resource", Flag, "query_min_strict", - translate("Strict Minimize:"), + translate("Strict Minimize"), translate("Strict version of 'query minimize' but it can break DNS")) - qrs.rmempty = false - qrs:depends({ query_minimize = true }) + qrs.optional = true + 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 + eds.placeholder = "1280" tlm = s1:taboption("resource", Value, "ttl_min", - translate("TTL Minimum:"), + translate("TTL Minimum"), translate("Prevent excessively short cache periods")) - tlm.datatype = "and(uinteger,min(0),max(600))" - tlm.rmempty = false + tlm.datatype = "and(uinteger,min(0),max(1200))" + tlm.placeholder = "120" stt = s1:taboption("resource", Flag, "extended_stats", - translate("Extended Statistics:"), + 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("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") @@ -271,7 +278,7 @@ else ag2:value("99", "99 ("..translate("never")..")") tgr = s1:taboption("basic", Value, "trigger_interface", - translate("Trigger Networks:"), + translate("Trigger Networks"), translate("Networks that may trigger Unbound to reload (avoid wan6)")) tgr.template = "cbi/network_netlist" tgr.widget = "checkbox" diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua index 3aef18965..f1e1d842a 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/uciedit.lua @@ -12,7 +12,7 @@ m6.submit = translate("Save") m6.reset = false s6 = m6:section(SimpleSection, "", translatef("Edit '" .. filename .. "' " - .. "and help can be found in OpenWrt " + .. "and recipes can be found in OpenWrt " .. "<a href=\"%s\" target=\"_blank\">Guides</a> " .. "and <a href=\"%s\" target=\"_blank\">Github</a>.", "https://openwrt.org/docs/guide-user/services/dns/unbound", diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/zone-details.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zone-details.lua new file mode 100644 index 000000000..dcaa877fd --- /dev/null +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zone-details.lua @@ -0,0 +1,95 @@ +-- Copyright 2018 Eric Luehrsen <ericluehrsen@gmail.com> +-- Licensed to the public under the Apache License 2.0. + +local sy = require "luci.sys" +local ds = require "luci.dispatcher" +local hp = require "luci.http" +local m7, s7 +local ena, flb, zty, znm, srv, rlv, tlu +local prt, tlp, tli, url + +arg[1] = arg[1] or "" +m7 = Map("unbound") +m7.redirect = ds.build_url("admin/services/unbound/zones") + + +if (arg[1] == "") then + hp.redirect(m7.redirect) + return + +else + s7 = m7:section(NamedSection, arg[1], "zone", + translatef("Directed Zone"), + translatef("Edit a forward, stub, or zone-file-cache zone " + .. "for Unbound to use instead of recursion.")) + + s7.anonymous = true + s7.addremove = false + + ena = s7:option(Flag, "enabled", translate("Enabled"), + translate("Enable this directed zone")) + ena.rmempty = false + + flb = s7:option(Flag, "fallback", translate("Fall Back"), + translate("Allow open recursion when record not in zone")) + flb.rmempty = false + + zty = s7:option(ListValue, "zone_type", translate("Zone Type")) + zty:value("auth_zone", translate("Authoritative (zone file)")) + zty:value("stub_zone", translate("Stub (forced recursion)")) + zty:value("forward_zone", translate("Forward (simple handoff)")) + zty.rmempty = false + + znm = s7:option(DynamicList, "zone_name", translate("Zone Names"), + translate("Zone (Domain) names included in this zone combination")) + znm.placeholder="new.example.net." + + srv = s7:option(DynamicList, "server", translate("Servers"), + translate("Servers for this zone; see README.md for optional form")) + srv.placeholder="192.0.2.53" + + rlv = s7:option(Flag, "resolv_conf", translate("Use 'resolv.conf.auto'"), + translate("Forward to upstream nameservers (ISP)")) + rlv:depends("zone_type", "forward_zone") + + tlu = s7:option(Flag, "tls_upstream", translate("DNS over TLS"), + translate("Connect to servers using TLS")) + tlu:depends("zone_type", "forward_zone") + + prt = s7:option(Value, "port", translate("Server Port"), + translate("Port servers will receive queries on")) + prt:depends("tls_upstream", false) + prt.datatype = "port" + prt.placeholder="53" + + tlp = s7:option(Value, "tls_port", translate("Server TLS Port"), + translate("Port servers will receive queries on")) + tlp:depends("tls_upstream", true) + tlp.datatype = "port" + tlp.placeholder="853" + + tli = s7:option(Value, "tls_index", translate("TLS Name Index"), + translate("Domain name to verify TLS certificate")) + tli:depends("tls_upstream", true) + tli.placeholder="dns.example.net" + + url = s7:option(Value, "url_dir", translate("Zone Download URL"), + translate("Directory only part of URL")) + url:depends("zone_type", "auth_zone") + url.placeholder="https://www.example.net/dl/zones/" +end + + +function m7.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 m7 + diff --git a/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua index bbc0e2335..798ca6a45 100644 --- a/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua +++ b/applications/luci-app-unbound/luasrc/model/cbi/unbound/zones.lua @@ -1,4 +1,4 @@ --- Copyright 2017 Eric Luehrsen <ericluehrsen@gmail.com> +-- Copyright 2018 Eric Luehrsen <ericluehrsen@gmail.com> -- Licensed to the public under the Apache License 2.0. local m5, s5 @@ -7,18 +7,22 @@ local ztype, zones, servers, fallback, enabled local fs = require "nixio.fs" local ut = require "luci.util" local sy = require "luci.sys" +local ds = require "luci.dispatcher" local resolvfile = "/tmp/resolv.conf.auto" +local logerr = ut.exec("logread -e 'unbound.*error.*ssl library'") m5 = Map("unbound") s5 = m5:section(TypedSection, "zone", "Zones", - translatef("This shows extended zones and more details can be " - .. "changed in Files tab and <a href=\"%s\">Edit:UCI</a> subtab.", - "/cgi-bin/luci/admin/services/unbound/files" )) + translatef("Organize directed forward, stub, and authoritative zones" + .. " <a href=\"%s\" target=\"_blank\">(help)</a>.", + "https://www.unbound.net/", + "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md")) -s5.addremove = false +s5.addremove = true s5.anonymous = true s5.sortable = true s5.template = "cbi/tblsection" +s5.extedit = ds.build_url("admin/services/unbound/zones/%s") ztype = s5:option(DummyValue, "DummyType", translate("Type")) ztype.rawhtml = true @@ -36,6 +40,23 @@ enabled = s5:option(Flag, "enabled", translate("Enable")) enabled.rmempty = false +if logerr and (#logerr > 0) then + logerr = logerr:sub((1 + #logerr - math.min(#logerr, 250)), #logerr) + m5.message = translatef( "Note: SSL/TLS library is missing an API. " + .. "Please review syslog. >> logread ... " .. logerr ) +end + + +function s5.create(self, section) + created = TypedSection.create(self, section) +end + + +function s5.parse(self, ...) + TypedSection.parse(self, ...) +end + + function ztype.cfgvalue(self, s) -- Format a meaninful tile for the Zone Type column local itxt = self.map:get(s, "zone_type") @@ -57,7 +78,7 @@ function ztype.cfgvalue(self, s) return translate("AXFR") else - return translate("Error") + return translate("Undefined") end end @@ -85,22 +106,22 @@ function zones.cfgvalue(self, s) 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 + if otxt and (#otxt > 0) then + 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("stub") then + otxt = translate("select recursion for ") .. otxt - elseif itype and itype:match("auth") then - otxt = translate("prefetch zone files for ") .. otxt + elseif itype and itype:match("auth") then + otxt = translate("prefetch zone files for ") .. otxt - else - otxt = translate("unknown action for ") .. otxt - end + else + otxt = translate("unknown action for ") .. otxt + end - if otxt and (#otxt > 0) then return otxt else @@ -131,14 +152,17 @@ function servers.cfgvalue(self, s) end + if otxt and (#otxt > 0) then + otxt = translate("use nameservers ") .. otxt + 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 <var>%s</var> at ", iidx) .. otxt - - elseif otxt and (#otxt > 0) then - otxt = translate("use nameservers ") .. otxt + otxt = otxt .. translatef( + " with default certificate for <var>%s</var>", iidx) end @@ -174,11 +198,12 @@ function servers.cfgvalue(self, s) if otxt and (#otxt > 0) and rtxt and (#rtxt > 0) then - otxt = otxt - .. translatef(", and <var>%s</var> entries ", resolvfile) .. rtxt + otxt = otxt .. translatef( + ", and <var>%s</var> entries ", resolvfile) .. rtxt elseif rtxt and (#rtxt > 0) then - otxt = translatef("use <var>%s</var> nameservers ", resolvfile) .. rtxt + otxt = translatef( + "use <var>%s</var> nameservers ", resolvfile) .. rtxt end end diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index b2c1e463b..2119a210b 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -95,41 +95,15 @@ end function changes(self, config) - local rv = call("changes", { config = config }) - local res = {} + local rv, err = call("changes", { config = config }) if type(rv) == "table" and type(rv.changes) == "table" then - local package, changes - for package, changes in pairs(rv.changes) do - res[package] = {} - - local _, change - for _, change in ipairs(changes) do - local operation, section, option, value = unpack(change) - if option and operation ~= "add" then - res[package][section] = res[package][section] or { } - - if operation == "list-add" then - local v = res[package][section][option] - if type(v) == "table" then - v[#v+1] = value or "" - elseif v ~= nil then - res[package][section][option] = { v, value } - else - res[package][section][option] = { value } - end - else - res[package][section][option] = value or "" - end - else - res[package][section] = res[package][section] or {} - res[package][section][".type"] = option or "" - end - end - end + return rv.changes + elseif err then + return nil, ERRSTR[err] + else + return { } end - - return res end diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_system/applyreboot.htm b/modules/luci-mod-admin-full/luasrc/view/admin_system/applyreboot.htm index 66b80896e..e235bd467 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_system/applyreboot.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_system/applyreboot.htm @@ -16,6 +16,7 @@ img.onload = function() { window.clearInterval(interval); + window.location.replace(target); }; img.src = target + '<%=resource%>/icons/loading.gif?' + Math.random(); diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm index e05ccdece..8a162c88b 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changelog.htm @@ -1,5 +1,5 @@ <%# - Copyright 2010 Jo-Philipp Wich <jow@openwrt.org> + Copyright 2010 Jo-Philipp Wich <jo@mein.io> Licensed to the public under the Apache License 2.0. -%> @@ -17,65 +17,50 @@ <div class="uci-change-list"><% local util = luci.util - local ret = { } + local tpl = { + ["add-3"] = "<ins>uci add %0 <strong>%3</strong> # =%2</ins>", + ["set-3"] = "<ins>uci set %0.<strong>%2</strong></ins>=%3", + ["set-4"] = "<var><ins>uci set %0.%2.%3=<strong>%4</strong></ins></var>", + ["remove-2"] = "<del>uci del %0.<strong>%2</strong></del>", + ["remove-3"] = "<var><del>uci del %0.%2.<strong>%3</strong></del></var>", + ["order-3"] = "<var>uci reorder %0.%2=<strong>%3</strong></var>", + ["list-add-4"] = "<var><ins>uci add_list %0.%2.%3=<strong>%4</strong></ins></var>", + ["list-del-4"] = "<var><del>uci del_list %0.%2.%3=<strong>%4</strong></del></var>", + ["rename-3"] = "<var>uci rename %0.%2=<strong>%3</strong></var>", + ["rename-4"] = "<var>uci rename %0.%2.%3=<strong>%4</strong></var>" + } - for r, tbl in pairs(changes) do - for s, os in pairs(tbl) do - -- section add - if os['.type'] and os['.type'] ~= "" then - ret[#ret+1] = "<ins>%s.%s=<strong>%s</strong>" %{ r, s, os['.type'] } - for o, v in util.kspairs(os) do - if o:sub(1,1) ~= "." then - if type(v) == "table" then - local i - for i = 1, #v do - ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>" - %{ r, s, o, util.pcdata(v[i]) } - end - elseif v ~= "" then - ret[#ret+1] = "<br />%s.%s.%s=<strong>%s</strong>" - %{ r, s, o, util.pcdata(v) } - else - ret[#ret+1] = "<br /><del>%s.%s.<strong>%s</strong></del>" %{ r, s, o } - end - end - end - ret[#ret+1] = "</ins><br />" - - -- section delete - elseif os['.type'] and os['.type'] == "" then - ret[#ret+1] = "<del>%s.<strong>%s</strong></del><br />" %{ r, s } + local conf, deltas + for conf, deltas in util.kspairs(changes) do + write("<h3># /etc/config/%s</h3>" % conf) - -- modifications - else - ret[#ret+1] = "<var>%s.%s<br />" %{ r, s } - for o, v in util.kspairs(os) do - if o:sub(1,1) ~= "." then - if v and #v > 0 then - ret[#ret+1] = "<ins>" - if type(v) == "table" then - local i - for i = 1, #v do - ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />" - %{ r, s, o, util.pcdata(v[i]) } - end + local _, delta, added + for _, delta in pairs(deltas) do + local t = tpl["%s-%d" %{ delta[1], #delta }] - else - ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />" - %{ r, s, o, util.pcdata(v) } - end - ret[#ret+1] = "</ins>" - else - ret[#ret+1] = "<del>%s.%s.<strong>%s</strong><br /></del>" %{ r, s, o } - end + write(t:gsub("%%(%d)", function(n) + if n == "0" then + return conf + elseif n == "2" then + if added and delta[2] == added[1] then + return "@%s[-1]" % added[2] + else + return delta[2] end + elseif n == "4" then + return util.shellquote(delta[4]) + else + return delta[tonumber(n)] end - ret[#ret+1] = "</var><br />" + end)) + + if delta[1] == "add" then + added = { delta[2], delta[3] } end end - end - write(table.concat(ret)) + write("<br />") + end %></div> </div> <%- end) %> diff --git a/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua b/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua index b258dfc59..318db7e77 100644 --- a/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua +++ b/protocols/luci-proto-ncm/luasrc/model/cbi/admin_network/proto_ncm.lua @@ -19,16 +19,13 @@ local ipv6, delay, defaultroute, metric, peerdns, dns device = section:taboption("general", Value, "device", translate("Modem device")) device.rmempty = false -local device_suggestions = nixio.fs.glob("/dev/cdc-wdm*") - or nixio.fs.glob("/dev/ttyUSB*") - -if device_suggestions then - local node - for node in device_suggestions do - device:value(node) - end +local dev +for dev in nixio.fs.glob("/dev/ttyUSB*") do + device:value(dev) +end +for dev in nixio.fs.glob("/dev/cdc-wdm*") do + device:value(dev) end - mode = section:taboption("general", Value, "mode", translate("Service Type")) mode:value("", translate("Modem default")) diff --git a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css index 644a47fee..260f5e31c 100644 --- a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css +++ b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css @@ -23,7 +23,7 @@ body { padding: 5px; } -h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, q, s, +h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, ins, q, s, small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset, form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td, .table, .tbody, .tfoot, .thead, .tr, .th, .td { @@ -1956,47 +1956,51 @@ div.cbi-value var, } .uci-change-list { - font-family: monospace; + line-height: 170%; + white-space: pre; } +.uci-change-list del, .uci-change-list ins, -.uci-change-legend-label ins { +.uci-change-list var, +.uci-change-legend-label del, +.uci-change-legend-label ins, +.uci-change-legend-label var { text-decoration: none; - border: 1px solid #0f0; - background-color: #cfc; - display: block; + font-family: monospace; + font-style: normal; + border: 1px solid #ccc; + background: #eee; padding: 2px; + display: block; + line-height: 15px; + margin-bottom: 1px; +} + +.uci-change-list ins, +.uci-change-legend-label ins { + border-color: #0f0; + background: #cfc; } .uci-change-list del, .uci-change-legend-label del { - text-decoration: none; - border: 1px solid #f00; - background-color: #fcc; - display: block; - font-style: normal; - padding: 2px; + border-color: #f00; + background: #fcc; } .uci-change-list var, .uci-change-legend-label var { - text-decoration: none; - border: 1px solid #ccc; - background-color: #eee; - display: block; - font-style: normal; - padding: 2px; - line-height: 19px; - white-space: pre; + border-color: #ccc; + background: #eee; } .uci-change-list var ins, .uci-change-list var del { - display: inline; - /*border: none;*/ - white-space: pre; - font-style: normal; - padding: 0px; + display: inline-block; + border: none; + width: 100%; + padding: 0; } .uci-change-legend { @@ -2016,12 +2020,17 @@ div.cbi-value var, width: 10px; height: 10px; display: block; + position: relative; } .uci-change-legend-label var ins, .uci-change-legend-label var del { - line-height: 6px; border: none; + position: absolute; + top: 2px; + left: 2px; + right: 2px; + bottom: 2px; } html body.apply-overlay-active { diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm index 6ad32efb4..4347f133a 100644 --- a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm +++ b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm @@ -136,12 +136,9 @@ if tree.nodes[category] and tree.nodes[category].ucidata then local ucichanges = 0 + local i, j for i, j in pairs(require("luci.model.uci").cursor():changes()) do - for k, l in pairs(j) do - for m, n in pairs(l) do - ucichanges = ucichanges + 1; - end - end + ucichanges = ucichanges + #j end if ucichanges > 0 then diff --git a/themes/luci-theme-material/luasrc/view/themes/material/header.htm b/themes/luci-theme-material/luasrc/view/themes/material/header.htm index e6047614f..c070b1a61 100644 --- a/themes/luci-theme-material/luasrc/view/themes/material/header.htm +++ b/themes/luci-theme-material/luasrc/view/themes/material/header.htm @@ -160,13 +160,9 @@ -- calculate the number of unsaved changes if tree.nodes[category] and tree.nodes[category].ucidata then local ucichanges = 0 - + local i, j for i, j in pairs(require("luci.model.uci").cursor():changes()) do - for k, l in pairs(j) do - for m, n in pairs(l) do - ucichanges = ucichanges + 1; - end - end + ucichanges = ucichanges + #j end if ucichanges > 0 then diff --git a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css index e7952338e..5becfc5ba 100644 --- a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css +++ b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css @@ -1397,44 +1397,49 @@ select + .cbi-button { .uci-change-list { font-family: monospace; + white-space: pre; } +.uci-change-list del, .uci-change-list ins, -.uci-change-legend-label ins { +.uci-change-list var, +.uci-change-legend-label del, +.uci-change-legend-label ins, +.uci-change-legend-label var { text-decoration: none; - border: 1px solid #00FF00; - background-color: #CCFFCC; - display: block; + font-style: normal; + border: 1px solid #ccc; + background: #eee; padding: 2px; + display: block; + line-height: 15px; + margin-bottom: 1px; +} + +.uci-change-list ins, +.uci-change-legend-label ins { + border-color: #0f0; + background: #cfc; } .uci-change-list del, .uci-change-legend-label del { - text-decoration: none; - border: 1px solid #FF0000; - background-color: #FFCCCC; - display: block; - font-style: normal; - padding: 2px; + border-color: #f00; + background: #fcc; } .uci-change-list var, .uci-change-legend-label var { - text-decoration: none; - border: 1px solid #CCCCCC; - background-color: #EEEEEE; - display: block; - font-style: normal; - padding: 2px; + border-color: #ccc; + background: #eee; } .uci-change-list var ins, .uci-change-list var del { - /*display: inline;*/ + display: inline-block; border: none; - white-space: pre; - font-style: normal; - padding: 0px; + width: 100%; + padding: 0; } .uci-change-legend { @@ -1452,15 +1457,20 @@ select + .cbi-button { .uci-change-legend-label>var { float: left; margin-right: 4px; - width: 10px; - height: 10px; + width: 12px; + height: 12px; display: block; + position: relative; } .uci-change-legend-label var ins, .uci-change-legend-label var del { - line-height: 6px; border: none; + position: absolute; + top: 1px; + left: 1px; + right: 1px; + bottom: 1px; } diff --git a/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm b/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm index e77f9a4bf..6fc657ddc 100644 --- a/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm +++ b/themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm @@ -129,12 +129,9 @@ local function render_changes() if tree.nodes[category] and tree.nodes[category].ucidata then local ucic = 0 + local i, j for i, j in pairs(require("luci.model.uci").cursor():changes()) do - for k, l in pairs(j) do - for m, n in pairs(l) do - ucic = ucic + 1; - end - end + ucic = ucic + #j end if ucic > 0 then |