Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 0x4A6F-master
  • 0x4A6F-rpi4
  • autinerd/experimental-openwrt-24.10
  • experimental
  • feature/addMikrotikwAP
  • master
  • nrb/airmax-test
  • nrb/ar9344-reset-sequence
  • nrb/ex400-remove-wps
  • nrb/gluon-master-cpe510
  • nrb/test-radv-filter
  • nrbffs/fastd-remove-delay
  • nrbffs/netgear-ex6120
  • v2018.2.2-ffs
  • v2018.2.3-ffs
  • v2019.1-ffs
  • v2019.1.1-ffs
  • v2019.1.2-ffs
  • v2020.1-ffs
  • v2020.1.1-ffs
  • v2020.1.3-ffs
  • v2020.2-ffs
  • v2020.2.1-ffs
  • v2020.2.2-ffs
  • v2020.2.3-ffs
  • v2021.1-ffs
  • v2021.1.1-ffs
  • v2021.1.2-ffs
  • v2022.1.1-ffs
  • v2022.1.3-ffs
  • v2022.1.4-ffs
  • v2023.1-ffs
  • v2023.2-ffs
  • v2023.2.2-ffs
  • v2023.2.3-ffs
  • v2023.2.4-ffs
  • v2023.2.5-ffs
  • experimental-2022-09-24
  • experimental-2022-09-24-base
  • experimental-2023-03-11
  • experimental-2023-03-11-base
  • experimental-2023-03-12
  • experimental-2023-03-12-base
  • experimental-2023-03-16
  • experimental-2023-03-16-base
  • experimental-2023-03-20
  • experimental-2023-03-20-base
  • experimental-2023-03-23
  • experimental-2023-03-23-base
  • experimental-2023-03-25
  • experimental-2023-03-25-base
  • experimental-2023-03-26
  • experimental-2023-03-26-base
  • experimental-2023-03-30
  • experimental-2023-03-30-base
  • experimental-2023-03-31
  • experimental-2023-03-31-base
  • experimental-2023-04-01
  • experimental-2023-04-01-base
  • experimental-2023-04-08
  • experimental-2023-04-08-base
  • experimental-2023-04-10
  • experimental-2023-04-10-base
  • experimental-2023-04-13
  • experimental-2023-04-13-base
  • experimental-2023-04-15
  • experimental-2023-04-15-base
  • experimental-2023-04-16
  • experimental-2023-04-16-base
  • experimental-2023-04-18
  • experimental-2023-04-18-base
  • experimental-2023-04-20
  • experimental-2023-04-20-base
  • experimental-2023-04-26
  • experimental-2023-04-26-base
  • experimental-2023-04-28
  • experimental-2023-04-28-base
  • experimental-2023-04-30
  • experimental-2023-04-30-base
  • experimental-2023-05-02
  • experimental-2023-05-02-base
  • experimental-2023-05-03
  • experimental-2023-05-03-base
  • experimental-2023-05-12
  • experimental-2023-05-12-base
  • experimental-2023-05-21
  • experimental-2023-05-21-base
  • experimental-2023-05-25
  • experimental-2023-05-25-base
  • experimental-2023-07-02
  • experimental-2023-07-02-base
  • experimental-2023-07-04
  • experimental-2023-07-04-base
  • experimental-2023-07-12
  • experimental-2023-07-12-base
  • experimental-2023-07-16
  • experimental-2023-07-16-base
  • experimental-2023-08-04
  • experimental-2023-08-04-base
  • experimental-2023-08-10
  • experimental-2023-08-10-base
  • experimental-2023-09-08
  • experimental-2023-09-08-base
  • experimental-2023-09-09
  • experimental-2023-09-09-base
  • experimental-2023-09-10
  • experimental-2023-09-10-base
  • experimental-2023-09-11
  • experimental-2023-09-11-base
  • experimental-2023-09-12
  • experimental-2023-09-12-base
  • experimental-2023-09-13
  • experimental-2023-09-13-base
  • experimental-2023-09-15
  • experimental-2023-09-15-base
  • experimental-2023-09-16
  • experimental-2023-09-16-base
  • experimental-2023-09-18
  • experimental-2023-09-18-base
  • experimental-2023-09-20
  • experimental-2023-09-20-base
  • experimental-2023-09-27
  • experimental-2023-09-27-base
  • experimental-2023-09-28
  • experimental-2023-09-28-base
  • experimental-2023-09-29
  • experimental-2023-09-29-base
  • experimental-2023-10-02
  • experimental-2023-10-02-base
  • experimental-2023-10-13
  • experimental-2023-10-13-base
  • experimental-2023-10-14
  • experimental-2023-10-14-base
  • experimental-2023-10-16
  • experimental-2023-10-16-base
  • experimental-2023-10-23
  • experimental-2023-10-23-base
137 results

Target

Select target project
  • firmware/gluon
  • 0x4A6F/gluon
  • patrick/gluon
3 results
Select Git revision
  • 0x4A6F-master
  • 0x4A6F-rpi4
  • 2014.3.x
  • 2014.4.x
  • babel
  • experimental
  • hoodselector
  • master
  • nrb/gluon-master-cpe510
  • nrb/test-radv-filter
  • nrbffs/fastd-remove-delay
  • nrbffs/netgear-ex6120
  • radv-filterd
  • v2015.1.x
  • v2016.1.x
  • v2016.2.4-batmanbug
  • v2016.2.x
  • v2018.2.2-ffs
  • v2018.2.3-ffs
  • v2018.2.x
  • v2019.1-ffs
  • v2019.1.1-ffs
  • v2019.1.2-ffs
  • v2020.1-ffs
  • v2020.1.1-ffs
  • v2020.1.3-ffs
  • v2020.2-ffs
  • v2020.2.1-ffs
  • v2020.2.2-ffs
  • v2020.2.3-ffs
  • v2020.2.x
  • v2021.1-ffs
  • v2021.1.1-ffs
  • v2021.1.2-ffs
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.3.1
  • v2014.4
  • v2015.1
  • v2015.1.1
  • v2015.1.2
  • v2016.1
  • v2016.1.1
  • v2016.1.2
  • v2016.1.3
  • v2016.1.4
  • v2016.1.5
  • v2016.1.6
  • v2016.2
  • v2016.2.1
  • v2016.2.2
  • v2016.2.3
  • v2016.2.4
  • v2016.2.5
  • v2016.2.6
  • v2016.2.7
  • v2017.1
  • v2017.1.1
  • v2017.1.2
  • v2017.1.3
  • v2017.1.4
  • v2017.1.5
  • v2017.1.6
  • v2017.1.7
  • v2017.1.8
  • v2018.1
  • v2018.1.1
  • v2018.1.2
  • v2018.1.3
  • v2018.1.4
  • v2018.2
  • v2018.2-ffs0.1
  • v2018.2.1
  • v2018.2.1-ffs0.1
  • v2018.2.2-ffs0.1
  • v2018.2.3-ffs0.1
  • v2019.1-ffs0.1
  • v2019.1.1-ffs0.1
  • v2019.1.2-ffs0.1
  • v2020.1-ffs0.1
  • v2020.1.1-ffs0.1
  • v2020.1.3-ffs0.1
  • v2020.2
  • v2020.2-ffs0.1
  • v2020.2.1-ffs0.1
  • v2020.2.2-ffs0.1
  • v2020.2.3-ffs0.1
  • v2020.2.3-ffs0.2
  • v2020.2.3-ffs0.3
  • v2020.2.x-ffs0.1
  • v2021.1-ffs0.1
  • v2021.1.1-ffs0.1
  • v2021.1.1-ffs0.2
  • v2021.1.1-ffs0.3
  • v2021.1.1-ffs0.4
  • v2021.1.2-ffs0.1
  • v2021.1.2-ffs0.2
98 results
Show changes
Showing
with 384 additions and 210 deletions
Draft for french translation, taken from gluon-config-mode-mesh-vpn
msgid ""
msgstr ""
msgid "downstream"
msgstr "débit déscendant"
msgid "upstream"
msgstr "débit ascendant"
......@@ -19,16 +19,25 @@ msgstr ""
msgid "Automatic updates"
msgstr ""
msgid "Bandwidth limit"
msgstr ""
msgid "Channel %u"
msgstr ""
msgid "Clients"
msgstr ""
msgid "Contact"
msgstr ""
msgid "Location"
msgid "Distance"
msgstr ""
msgid "Distance"
msgid "Domain"
msgstr ""
msgid "downstream"
msgstr ""
msgid "Error"
......@@ -55,6 +64,12 @@ msgstr ""
msgid "Load average"
msgstr ""
msgid "Location"
msgstr ""
msgid "Mesh protocol"
msgstr ""
msgid "Mesh VPN"
msgstr ""
......@@ -79,24 +94,45 @@ msgstr ""
msgid "Primary MAC address"
msgstr ""
msgid "Radios"
msgstr ""
msgid "RAM"
msgstr ""
msgid "Received"
msgstr ""
msgid "Role"
msgstr ""
msgid "Site"
msgstr ""
msgid "Status"
msgstr ""
msgid "Total"
msgstr ""
msgid "Traffic"
msgstr ""
msgid "Transmitted"
msgstr ""
msgid "upstream"
msgstr ""
msgid "Uptime"
msgstr ""
msgid "Wireless 2.4 GHz"
msgstr ""
msgid "Wireless 5 GHz"
msgstr ""
msgid "connected"
msgstr ""
......
THe previous version of the status page had a Russian translation;
if we ever add Russion to gluon-web, the following strings can be reused:
if we ever add Russian to gluon-web, the following strings can be reused:
"Node": "Узел",
"Distance": "Дальность",
......@@ -10,14 +10,17 @@ if we ever add Russion to gluon-web, the following strings can be reused:
"Primary MAC": "Основной MAC",
"IP Address": "IP Адрес",
"Automatic updates": "Автоматические обновления",
"Bandwidth limit": "Ограничение пропускной способности",
"Overview": "Обзор",
"used": "используется",
"Uptime": "Время работы",
"Load average": "Загрузка системы",
"Gateway": "Шлюз",
"Channel": "Канал",
"Clients": "Клиенты",
"Transmitted": "Передано",
"Received": "Получено",
"Role": "Роль",
"Forwarded": "Переправленно",
"Day": "День",
"Days": "Дней",
......@@ -26,6 +29,7 @@ if we ever add Russion to gluon-web, the following strings can be reused:
"Packets/s": "Пакетов/c",
"Statistic": "Статистика",
"Traffic": "Трафик",
"Mesh protocol": "Ячеистый протокол"
"Neighbors": "Соседи",
"Firmware": "Прошивка",
"Branch": "Ветка"
/*
Build using:
uglifyjs javascript/status-page.js -o files/lib/gluon/status-page/www/static/status-page.js -c -m
uglifyjs javascript/status-page.js -o javascript/status-page.min.js -c -m
*/
'use strict';
......@@ -112,6 +112,31 @@
'bytes': function(bytes) {
return prettyBytes(bytes);
},
'neighbour': function(addr) {
if (!addr)
return '';
for (var i in interfaces) {
var iface = interfaces[i];
var neigh = iface.lookup_neigh(addr);
if (!neigh)
continue;
var span = document.createElement('span');
span.appendChild(document.createTextNode('via '));
var a = document.createElement('a');
a.href = 'http://[' + neigh.get_addr() + ']/';
a.textContent = neigh.get_hostname();
span.appendChild(a);
span.appendChild(document.createTextNode(' (' + i + ')'));
return span;
}
return 'via ' + addr + ' (unknown iface)';
},
'tq': function(value) {
return formatNumber(100/255 * value, 1) + '%';
}
}
......@@ -169,9 +194,9 @@
}
div.style.display = '';
var table = document.getElementById('mesh-vpn-peers');
while (table.lastChild)
table.removeChild(table.lastChild);
var tbody = document.getElementById('mesh-vpn-peers');
while (tbody.lastChild)
tbody.removeChild(tbody.lastChild);
var peers = add_group([], data);
peers.sort();
......@@ -184,13 +209,15 @@
tr.appendChild(th);
var td = document.createElement('td');
if (peer[1])
td.textContent = _['connected'] + ' (' + formats.time(peer[1].established) + ')';
else
if (peer[1] && peer[1].established != null) {
var method = peer[1].method ? ', ' + peer[1].method : '';
td.textContent = _['connected'] + ' (' + formats.time(peer[1].established) + method + ')';
} else {
td.textContent = _['not connected'];
}
tr.appendChild(td);
table.appendChild(tr);
tbody.appendChild(tr);
});
}
......@@ -206,9 +233,16 @@
var valuePrev = resolve_key(dataPrev, stat);
var value = resolve_key(data, stat);
try {
var text = formats[format](value, valuePrev, diff);
if (text !== undefined)
elem.textContent = text;
var format_result = formats[format](value, valuePrev, diff);
switch (typeof format_result) {
case "object":
if (elem.lastChild)
elem.removeChild(elem.lastChild);
elem.appendChild(format_result);
break;
default:
elem.textContent = format_result;
}
} catch (e) {
console.error(e);
}
......@@ -256,7 +290,7 @@
'resize': function(w, h) {
var lastImage;
try {
ctx.getImageData(0, 0, w, h);
lastImage = ctx.getImageData(0, 0, w, h);
} catch (e) {}
canvas.width = w;
canvas.height = h;
......@@ -415,10 +449,11 @@
}
function Neighbour(iface, addr, color, destroy) {
var th = iface.table.firstElementChild;
var el = iface.table.insertRow();
var th = iface.tbody.querySelector('tr');
var el = iface.tbody.insertRow();
var tdHostname = el.insertCell();
tdHostname.setAttribute('data-label', th.children[0].textContent);
if (iface.wireless) {
var marker = document.createElement("span");
......@@ -428,6 +463,7 @@
}
var hostname = document.createElement("span");
var addr;
hostname.textContent = addr;
tdHostname.appendChild(hostname);
......@@ -442,6 +478,7 @@
var td = el.insertCell();
td.textContent = '-';
td.setAttribute('data-label', attr.textContent);
meshAttrs[key] = {
'td': td,
......@@ -460,10 +497,24 @@
if (iface.wireless) {
tdSignal = el.insertCell();
tdSignal.textContent = '-';
tdSignal.setAttribute(
'data-label',
th.children[Object.keys(meshAttrs).length + 1].textContent
);
tdDistance = el.insertCell();
tdDistance.textContent = '-';
tdDistance.setAttribute(
'data-label',
th.children[Object.keys(meshAttrs).length + 2].textContent
);
tdInactive = el.insertCell();
tdInactive.textContent = '-';
tdInactive.setAttribute(
'data-label',
th.children[Object.keys(meshAttrs).length + 3].textContent
);
signal = Signal(color);
iface.signalgraph.addSignal(signal);
......@@ -473,13 +524,13 @@
el.classList.add("highlight");
if (signal)
signal.highlight = true;
}
};
el.onmouseleave = function () {
el.classList.remove("highlight")
el.classList.remove("highlight");
if (signal)
signal.highlight = false;
}
};
var timeout;
......@@ -507,7 +558,8 @@
var n = parts.length;
var groups = [];
parts.forEach(function(part, i) {
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part === '') {
while (n++ <= 8)
groups.push(0);
......@@ -517,7 +569,7 @@
groups.push(parseInt(part, 16));
}
});
};
return groups;
}
......@@ -582,8 +634,14 @@
}
return {
'get_hostname': function() {
return hostname.textContent;
},
'get_addr': function() {
return addr;
},
'update_nodeinfo': function(nodeinfo) {
var addr = choose_address(nodeinfo.network.addresses);
addr = choose_address(nodeinfo.network.addresses);
if (addr) {
if (hostname.nodeName.toLowerCase() === 'span') {
var oldHostname = hostname;
......@@ -639,7 +697,7 @@
}
var info = {
'table': el.firstElementChild,
'tbody': el.querySelector('tbody'),
'signalgraph': signalgraph,
'ifname': ifname,
'wireless': wireless,
......@@ -711,6 +769,9 @@
}
}
function lookup_neigh(addr) {
return neighs[addr];
}
function get_neigh(addr) {
var neigh = neighs[addr];
......@@ -738,6 +799,7 @@
return {
'get_neigh': get_neigh,
'lookup_neigh': lookup_neigh
};
}
......
"use strict";!function(){var o=JSON.parse(document.body.getAttribute("data-translations"));function i(t,e){return t.toFixed(e).replace(/\./,o["."])}function a(t,e){e--;for(var n=t;10<=n&&0<e;n/=10)e--;return i(t,e)}function r(t){var e=["","K","M","G","T"],n=1024,i=t,r=0;if(void 0===i)return"- ";for(;n<i&&r<e.length-1;)i/=n,r++;return(i=a(i,3))+" "+e[r]}String.prototype.sprintf=function(){var t=0,e=arguments;return this.replace(/%s/g,function(){return e[t++]})};var u={id:function(t){return t},decimal:function(t){return i(t,2)},percent:function(t){return o["%s used"].sprintf(a(100*t,3)+"%")},memory:function(t){t=1-t.available/t.total;return u.percent(t)},time:function(t){var t=Math.round(t/60),e=Math.floor(t/1440),n=Math.floor(t%1440/60),t=Math.floor(t%60),i="";return 1===e?i+=o["1 day"]+", ":1<e&&(i+=o["%s days"].sprintf(e)+", "),i+=n+":",t<10&&(i+="0"),i+=t},packetsDiff:function(t,e,n){if(0<n)return t=(t-e)/n,o["%s packets/s"].sprintf(i(t,0))},bytesDiff:function(t,e,n){if(0<n)return r(8*((t-e)/n))+"bps"},bytes:function(t){return r(t)+"B"},neighbour:function(t){if(!t)return"";for(var e in c){var n,i,r=c[e].lookup_neigh(t);if(r)return(n=document.createElement("span")).appendChild(document.createTextNode("via ")),(i=document.createElement("a")).href="http://["+r.get_addr()+"]/",i.textContent=r.get_hostname(),n.appendChild(i),n.appendChild(document.createTextNode(" ("+e+")")),n}return"via "+t+" (unknown iface)"},tq:function(t){return a(100/255*t,1)+"%"}};function s(e,t){return t.split("/").forEach(function(t){e=e&&e[t]}),e}function d(t,e){var n=new EventSource(t),i={};n.onmessage=function(t){t=JSON.parse(t.data);e(t,i),i=t},n.onerror=function(){n.close(),window.setTimeout(function(){d(t,e)},3e3)}}var E,k=document.body.getAttribute("data-node-address");try{E=JSON.parse(document.body.getAttribute("data-node-location"))}catch(t){}function t(t){var e=document.getElementById("mesh-vpn");if(t){e.style.display="";for(var r=document.getElementById("mesh-vpn-peers");r.lastChild;)r.removeChild(r.lastChild);t=function e(n,i){return Object.keys(i.peers||{}).forEach(function(t){n.push([t,i.peers[t]])}),Object.keys(i.groups||{}).forEach(function(t){e(n,i.groups[t])}),n}([],t);t.sort(),t.forEach(function(t){var e,n=document.createElement("tr"),i=document.createElement("th"),i=(i.textContent=t[0],n.appendChild(i),document.createElement("td"));t[1]&&null!=t[1].established?(e=t[1].method?", "+t[1].method:"",i.textContent=o.connected+" ("+u.time(t[1].established)+e+")"):i.textContent=o["not connected"],n.appendChild(i),r.appendChild(n)})}else e.style.display="none"}var e=document.querySelectorAll("[data-statistics]");d("/cgi-bin/dyn/statistics",function(o,a){var c=o.uptime-a.uptime;e.forEach(function(t){var e=t.getAttribute("data-statistics"),n=t.getAttribute("data-format"),i=s(a,e),e=s(o,e);try{var r=u[n](e,i,c);"object"==typeof r?(t.lastChild&&t.removeChild(t.lastChild),t.appendChild(r)):t.textContent=r}catch(t){console.error(t)}});try{t(o.mesh_vpn)}catch(t){console.error(t)}});var c={};function A(n){var i=document.createElement("canvas"),r=i.getContext("2d"),o=null;return{canvas:i,highlight:!1,resize:function(t,e){var n;try{n=r.getImageData(0,0,t,e)}catch(t){}i.width=t,i.height=e,n&&r.putImageData(n,0,0)},draw:function(t,e){var e=e(o);r.clearRect(t,0,5,i.height),e&&(t=t,e=e,r.beginPath(),r.fillStyle=n,r.arc(t,e,1.2,0,2*Math.PI,!1),r.closePath(),r.fill())},set:function(t){o=t}}}function h(){var o=-100,a=0,c=0,u=[],s=document.createElement("canvas"),l=(s.className="signalgraph",s.height=200,s.getContext("2d"));function d(){s.width=s.clientWidth,u.forEach(function(t){t.resize(s.width,s.height)})}function n(){if(0!==s.clientWidth){s.width!==s.clientWidth&&d(),l.clearRect(0,0,s.width,s.height);var e=!1,t=(u.forEach(function(t){t.highlight&&(e=!0)}),l.save(),u.forEach(function(t){e&&(l.globalAlpha=.2),t.highlight&&(l.globalAlpha=1),t.draw(c,function(t){return e=s.height,(1-(t-o)/(a-o))*e;var e}),l.drawImage(t.canvas,0,0)}),l.restore(),l.save(),l.beginPath(),l.strokeStyle="rgba(255, 180, 0, 0.15)",l.lineWidth=5,l.moveTo(c+2.5,0),l.lineTo(c+2.5,s.height),l.stroke(),Math.floor(s.height/40));l.save(),l.lineWidth=.5,l.strokeStyle="rgba(0, 0, 0, 0.25)",l.fillStyle="rgba(0, 0, 0, 0.5)",l.textAlign="end",l.textBaseline="bottom",l.beginPath();for(var n=0;n<t;n++){var i=s.height-40*n,r=(l.moveTo(0,i-.5),l.lineTo(s.width,i-.5),Math.round((r=s.height,(o*i+a*(r-i))/r))+" dBm");l.save(),l.strokeStyle="rgba(255, 255, 255, 0.9)",l.lineWidth=4,l.miterLimit=2,l.strokeText(r,s.width-5,i-2.5),l.fillText(r,s.width-5,i-2.5),l.restore()}l.stroke(),l.strokeStyle="rgba(0, 0, 0, 0.83)",l.lineWidth=1.5,l.strokeRect(.5,.5,s.width-1,s.height-1),l.restore()}}d(),window.addEventListener("resize",n);var i=0;return window.requestAnimationFrame(function t(e){40<e-i&&(n(),c=(c+1)%s.width,i=e),window.requestAnimationFrame(t)}),{el:s,addSignal:function(t){u.push(t),t.resize(s.width,s.height)},removeSignal:function(t){u.splice(u.indexOf(t),1)}}}function f(t,a,e,n){var i,r=t.tbody.querySelector("tr"),o=t.tbody.insertRow(),c=o.insertCell(),u=(c.setAttribute("data-label",r.children[0].textContent),t.wireless&&((i=document.createElement("span")).textContent="",i.style.color=e,c.appendChild(i)),document.createElement("span")),s=(u.textContent=a,c.appendChild(u),{});for(var l,d,h,f,g,p,m,v,b,C=0;C<r.children.length;C++)l=r.children[C],f=h=d=void 0,(f=l.getAttribute("data-key"))&&(d=l.getAttribute("data-suffix")||"",(h=o.insertCell()).textContent="-",h.setAttribute("data-label",l.textContent),s[f]={td:h,suffix:d});function y(){b&&window.clearTimeout(b),b=window.setTimeout(function(){v&&t.signalgraph.removeSignal(v),o.parentNode.removeChild(o),n()},6e4)}function w(t){var e,t=function(t){"::"==(t="::"==t.slice(0,2)?"0"+t:t).slice(-2)&&(t+="0");for(var e=t.split(":"),n=e.length,i=[],r=0;r<e.length;r++){var o=e[r];if(""===o)for(;n++<=8;)i.push(0);else{if(!/^[a-f0-9]{1,4}$/i.test(o))return;i.push(parseInt(o,16))}}return i}(t);if(t)return e="",t.forEach(function(t){e+=("0000000000000000"+t.toString(2)).slice(-16)}),e}function x(t){var i=w(k);if(t&&t[0])return(t=t.map(function(t){var e,n=w(t);return n?(e=0,[e=i?function(t,e){for(var n=0;n<t.length&&n<e.length&&t[n]===e[n];n++);return n}(i,n):e,n,t]):[-1]})).sort(function(t,e){return t[0]<e[0]?1:t[0]>e[0]||t[1]<e[1]?-1:t[1]>e[1]?1:0}),(t=t[0][2])&&!/^fe80:/i.test(t)?t:void 0}return t.wireless&&((g=o.insertCell()).textContent="-",g.setAttribute("data-label",r.children[Object.keys(s).length+1].textContent),(p=o.insertCell()).textContent="-",p.setAttribute("data-label",r.children[Object.keys(s).length+2].textContent),(m=o.insertCell()).textContent="-",m.setAttribute("data-label",r.children[Object.keys(s).length+3].textContent),v=A(e),t.signalgraph.addSignal(v)),o.onmouseenter=function(){o.classList.add("highlight"),v&&(v.highlight=!0)},o.onmouseleave=function(){o.classList.remove("highlight"),v&&(v.highlight=!1)},y(),{get_hostname:function(){return u.textContent},get_addr:function(){return a},update_nodeinfo:function(t){var e,n,i,r,o;(a=x(t.network.addresses))&&("span"===u.nodeName.toLowerCase()&&(e=u,u=document.createElement("a"),e.parentNode.replaceChild(u,e)),u.href="http://["+a+"]/"),u.textContent=t.hostname,E&&t.location&&(e=E.latitude,n=E.longitude,i=t.location.latitude,t=t.location.longitude,r=Math.PI/180,o=(i*=r)-(e*=r),t=(t*=r)-(n*=r),r=Math.sin(o/2)*Math.sin(o/2)+Math.sin(t/2)*Math.sin(t/2)*Math.cos(e)*Math.cos(i),n=6372.8*(2*Math.asin(Math.sqrt(r))),p.textContent=Math.round(1e3*n)+" m"),y()},update_mesh:function(n){Object.keys(s).forEach(function(t){var e=s[t];e.td.textContent=n[t]+e.suffix}),y()},update_wifi:function(t){g.textContent=t.signal,m.textContent=Math.round(t.inactive/1e3)+" s",o.classList.toggle("inactive",200<t.inactive),v.set(200<t.inactive?null:t.signal),y()}}}function l(t,e,n){var i,o={},r=(n&&(i=h(),t.appendChild(i.el)),{tbody:t.querySelector("tbody"),signalgraph:i,ifname:e,wireless:n}),a=!1,c={},u=[];function s(){var t;a||(a=!0,(t=new EventSource("/cgi-bin/dyn/neighbours-nodeinfo?"+encodeURIComponent(e))).addEventListener("neighbour",function(t){try{var n=JSON.parse(t.data);i=[],r=n.network.mesh,Object.keys(r).forEach(function(t){var e=r[t].interfaces;Object.keys(e).forEach(function(t){e[t].forEach(function(t){i.push(t)})})}),i.forEach(function(t){var e=o[t];if(e){delete c[t];try{e.update_nodeinfo(n)}catch(t){console.error(t)}}})}catch(t){console.error(t)}var i,r},!1),t.onerror=function(){t.close(),a=!1,Object.keys(c).forEach(function(t){0<c[t]&&(c[t]--,s())})})}function l(t){var e=o[t];return e||(c[t]=3,e=o[t]=f(r,t,(u=u[0]?u:["#396AB1","#DA7C30","#3E9651","#CC2529","#535154","#6B4C9A","#922428","#948B3D"]).shift(),function(){delete c[t],delete o[t]}),s()),e}return n&&d("/cgi-bin/dyn/stations?"+encodeURIComponent(e),function(n){Object.keys(n).forEach(function(t){var e=n[t];l(t).update_wifi(e)})}),{get_neigh:l,lookup_neigh:function(t){return o[t]}}}document.querySelectorAll("[data-interface]").forEach(function(t){var e=t.getAttribute("data-interface"),n=(t.getAttribute("data-interface-address"),!!t.getAttribute("data-interface-wireless"));c[e]=l(t,e,n)});var n=document.body.getAttribute("data-mesh-provider");n&&d(n,function(i){Object.keys(i).forEach(function(t){var e=i[t],n=c[e.ifname];n&&n.get_neigh(t).update_mesh(e)})})}();
\ No newline at end of file
......@@ -61,7 +61,7 @@ local function match(a, b, n)
end
entry({}, call(function(http, renderer)
local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 1 -c 1 -r nodeinfo'))
local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 3 -c 1 -r nodeinfo'))
local node_ip = parse_ip(http:getenv('SERVER_ADDR'))
if node_ip and (
......@@ -82,5 +82,5 @@ entry({}, call(function(http, renderer)
end
renderer.render('status-page', { nodeinfo = nodeinfo }, 'gluon-status-page')
renderer.render('status-page', { nodeinfo = nodeinfo, site = site }, 'gluon-status-page')
end))
#!/usr/bin/lua
local uci = require('simple-uci').cursor()
local util = require 'gluon.util'
local function get_mem_total()
for line in io.lines('/proc/meminfo') do
local match = line:match('^MemTotal:%s+(%d+)')
if match then
return tonumber(match)
end
end
end
local max_requests = 32
if get_mem_total() < 48*1024 then
if util.get_mem_total() < 48*1024 then
max_requests = 16
end
......@@ -27,7 +19,7 @@ uci:section('uhttpd', 'uhttpd', 'main', {
uci:save('uhttpd')
for _, zone in ipairs({'mesh', 'local_client'}) do
for _, zone in ipairs({'mesh', 'loc_client'}) do
uci:section('firewall', 'rule', zone .. '_http', {
src = zone,
dest_port = '80',
......@@ -35,4 +27,5 @@ for _, zone in ipairs({'mesh', 'local_client'}) do
target = 'ACCEPT',
})
end
uci:save('firewall')
......@@ -6,7 +6,7 @@
sass --sourcemap=none -C -t compressed sass/status-page.scss files/lib/gluon/status-page/www/static/status-page.css
When commiting changes to this file make sure to commit the respective
When committing changes to this file make sure to commit the respective
changes to the compiled version within the same commit!
*/
......@@ -109,10 +109,14 @@ header {
& + .frame {
border-width: 0 0 0 1px;
}
&-wide {
flex: 2;
}
}
}
dt, th {
dt, th, td::before {
font-weight: bold;
color: rgba(0, 0, 0, 0.87);
}
......@@ -146,13 +150,30 @@ table {
&.datatable {
width: 100%;
table-layout: fixed;
th, td {
font-size: 1em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&:last-child {
width: 100%;
th {
&.row-tq {
width: 45px;
}
&.row-signal {
width: 36px;
}
&.row-distance {
width: 90px;
}
&.row-inactive {
width: 130px;
}
}
......@@ -182,6 +203,34 @@ canvas.signalgraph {
z-index: 1;
position: fixed;
}
.datatable {
tr {
display: block;
margin-bottom: 15px;
&:first-child {
margin-bottom: 0;
}
}
th {
display: none;
}
td {
display: block;
position: relative;
padding-left: 150px;
max-width: calc(100% - 150px);
&::before {
position: absolute;
left: 5px;
content: attr(data-label)
}
}
}
}
@media only screen and (max-width: 700px) {
......
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-tls
include ../gluon.mk
define Package/gluon-tls
DEPENDS:=+libustream-mbedtls +ca-bundle
TITLE:=Enable TLS support
endef
define Package/gluon-tls/install
$(INSTALL_DIR) $(1)/lib/gluon/features
touch $(1)/lib/gluon/features/tls
endef
$(eval $(call BuildPackageGluon,gluon-tls))
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-wan-dnsmasq
PKG_VERSION:=1
include ../gluon.mk
define Package/gluon-wan-dnsmasq
TITLE:=Support for a secondary DNS server using the WAN interface
DEPENDS:=+gluon-core +libubus-lua +dnsmasq +libpacketmark
DEPENDS:=+gluon-core +libubus-lua +dnsmasq-full +libpacketmark
endef
define Package/gluon-wan-dnsmasq/description
Gluon community wifi mesh firmware framework: Support for a secondary DNS server using the WAN interface
endef
define Package/gluon-wan-dnsmasq/conffiles
/etc/config/gluon-wan-dnsmasq
endef
$(eval $(call BuildPackageGluon,gluon-wan-dnsmasq))
if [ "$INTERFACE" = 'wan' -o "$INTERFACE" = 'wan6' ]; then
if [ "$INTERFACE" = 'wan' -o "$INTERFACE" = 'wan6' -o "$INTERFACE" = 'cellular_4' -o "$INTERFACE" = 'cellular_6' ]; then
/lib/gluon/wan-dnsmasq/update.lua
fi
......@@ -2,28 +2,35 @@
START=60
SERVICE_NAME=gluon-wan-dnsmasq
SERVICE_USE_PID=1
SERVICE_PID_FILE=/var/run/gluon-wan-dnsmasq.pid
PORT=54
PACKET_MARK=1
USE_PROCD=1
RESOLV_CONF_DIR=/var/gluon/wan-dnsmasq
RESOLV_CONF=$RESOLV_CONF_DIR/resolv.conf
start() {
start_service() {
mkdir -p /var/run/dnsmasq/
mkdir -p $RESOLV_CONF_DIR
/lib/gluon/wan-dnsmasq/update.lua
export LD_PRELOAD=libpacketmark.so
export LIBPACKETMARK_MARK=$PACKET_MARK
service_start /usr/sbin/dnsmasq -x $SERVICE_PID_FILE -u root -i lo -p $PORT -h -r $RESOLV_CONF
}
stop() {
service_stop /usr/sbin/dnsmasq
touch "$RESOLV_CONF"
procd_open_instance
procd_set_param command /usr/sbin/dnsmasq \
--user=dnsmasq \
--group=dnsmasq \
--interface=lo \
--port=54 \
--no-hosts \
--keep-in-foreground \
--pid-file=/var/run/dnsmasq/gluon-wan-dnsmasq.pid \
--cache-size=0 \
--resolv-file=$RESOLV_CONF
procd_set_param env LD_PRELOAD=libpacketmark.so LIBPACKETMARK_MARK=1
procd_set_param respawn 60 5 5
procd_add_jail dnsmasq log
procd_add_jail_mount $RESOLV_CONF_DIR
procd_add_jail_mount /usr/lib/libpacketmark.so
procd_add_jail_mount /etc/passwd /etc/group /etc/TZ
procd_add_jail_mount_rw /var/run/dnsmasq/
procd_close_instance
}
#!/bin/sh
/etc/init.d/gluon-wan-dnsmasq stop
#!/bin/sh
/etc/init.d/gluon-wan-dnsmasq start
wan6
wan
cellular_4
cellular_6
......@@ -16,6 +16,19 @@ local function append_server(server)
end
local function handled_interfaces()
local interfaces = {}
for _, path in ipairs(util.glob('/lib/gluon/wan-dnsmasq/interface.d/*')) do
for interface in io.lines(path) do
table.insert(interfaces, interface)
end
end
return interfaces
end
local function handle_interface(status)
local ifname = status.device
local servers = status.inactive['dns-server']
......@@ -41,8 +54,9 @@ if type(static) == 'table' and #static > 0 then
append_server(server)
end
else
pcall(append_interface_servers, 'wan6')
pcall(append_interface_servers, 'wan')
for _, interface in ipairs(handled_interfaces()) do
pcall(append_interface_servers, interface)
end
end
......
......@@ -4,8 +4,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-web-admin
PKG_VERSION:=1
PKG_RELEASE:=1
include ../gluon.mk
......
<%-
local uci = require('simple-uci').cursor()
local pretty_hostname = require 'pretty_hostname'
local info = require 'gluon.info'
local site = require 'gluon.site'
local sysconfig = require 'gluon.sysconfig'
local platform = require 'gluon.platform'
local util = require "gluon.util"
local _ = translate
local pubkey
local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
if meshvpn_enabled then
pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
if pubkey == '' then
pubkey = nil
end
end
local values = {
{ _('Hostname'), pretty_hostname.get(uci) },
{ _('MAC address'), sysconfig.primary_mac },
{ _('Hardware model'), platform.get_model() },
{ _('Gluon version') .. " / " .. _('Site version'), util.trim(util.readfile('/lib/gluon/gluon-version'))
.. " / " .. util.trim(util.readfile('/lib/gluon/site-version')) },
{ _('Firmware release'), util.trim(util.readfile('/lib/gluon/release')) },
{ _('Site'), site.site_name() },
{ _('Public VPN key'), pubkey },
}
local values = info.get_info_pretty(i18n)
-%>
<h2><%:Information%></h2>
<% for _, v in ipairs(values) do %>
......
......@@ -26,7 +26,7 @@ $Id$
<%:Firmware image%>
</label>
<div class="gluon-value-field">
<input class="gluon-input-file" type="file" name="image" />
<input type="file" name="image">
</div>
</div>
......@@ -36,15 +36,14 @@ $Id$
</label>
<div class="gluon-value-field">
<input id="keepcfg" class="gluon-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" />
<input id="keepcfg" type="checkbox" name="keepcfg" value="1" checked="checked">
<label for="keepcfg"></label>
</div>
</div>
</div>
<div class="gluon-page-actions right">
<input type="hidden" name="step" value="2" />
<input type="hidden" name="token" value="<%=token%>" />
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>" />
<div class="gluon-page-actions">
<input type="hidden" name="step" value="2">
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>">
</div>
</form>