Newer
Older
<%-
local ubus = require 'ubus'
local unistd = require 'posix.unistd'
local util = require 'gluon.util'
local translations = {}
local function _(v)
translations[v] = translate(v)
end
-- i18n strings for JavaScript
_('.') -- decimal point
_('connected')
_('not connected')
_('1 day')
_('%s days')
_('%s used')
_('%s packets/s')

Matthias Schiffer
committed
local function get_mesh()
local f = loadfile('/lib/gluon/status-page/mesh.lua')
if f then
return f()
end
return {}
end
local mesh = get_mesh()
local function get_interfaces()
local uconn = ubus.connect()
if not uconn then
error('failed to connect to ubus')
end
local interfaces = util.get_mesh_devices(uconn)
ubus.close(uconn)
table.sort(interfaces)
return interfaces
end
local function is_wireless(iface)
while true do
local pattern = '/sys/class/net/' .. iface .. '/lower_*'
local lower = util.glob(pattern)[1]
if not lower then break end
iface = lower:sub(pattern:len())
end
return unistd.access('/sys/class/net/' .. iface .. '/wireless') ~= nil
end
local interfaces = get_interfaces()
local function sorted(t)
t = {unpack(t)}
table.sort(t)
return t
end
local function enabled(v)
return v and translate('enabled') or translate('disabled')
end
local function statistics(key, format)
return string.format('<span data-statistics="%s" data-format="%s"></span>', pcdata(key), pcdata(format or 'id'))
end
local function statisticsTraffic(key)
return string.format('%s<br />%s<br />%s',
statistics(key .. '/packets', 'packetsDiff'),
statistics(key .. '/bytes', 'bytesDiff'),
statistics(key .. '/bytes', 'bytes')
)
end
local wg_pubkey = util.readfile('/etc/parker/wg-pubkey')
http:prepare_content("application/xhtml+xml")
-%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title><%| nodeinfo.hostname %> - <%:Status%></title>
<link rel="stylesheet" href="/static/status-page.css" type="text/css" />
</head>

Matthias Schiffer
committed
<body data-node-address="<%| http:getenv('SERVER_ADDR') %>"<%=
attr('data-translations', translations) ..
attr('data-node-location', nodeinfo.location) ..
attr('data-mesh-provider', mesh.provider)
%>>
<header>
<h1><%| nodeinfo.hostname %></h1>
</header>
<div class="container">
<div class="frame">
<h2><%:Overview%></h2>
<dl>
<dt><%:Node name%></dt><dd><%| nodeinfo.hostname %></dd>
<% if nodeinfo.owner and nodeinfo.owner.contact then -%>
<dt><%:Contact%></dt><dd><%| nodeinfo.owner.contact %></dd>
<%- end %>

Martin Weinelt
committed
<% if nodeinfo.location then -%>
<dt><%:Location%></dt>
<dd><a href="geo:<%| nodeinfo.location.latitude %>,<%| nodeinfo.location.longitude %>">
<%| nodeinfo.location.latitude %>, <%| nodeinfo.location.longitude %>
</a></dd>
<%- end %>
<dt><%:Model%></dt><dd><%| nodeinfo.hardware.model %></dd>
<dt><%:Primary MAC address%></dt><dd><%| nodeinfo.network.mac %></dd>
<dt><%:IP address%></dt><dd><%= pcdata(table.concat(sorted(nodeinfo.network.addresses), '\n')):gsub('\n', '<br />') %></dd>
<dt><%:Firmware%></dt><dd><%| nodeinfo.software.firmware.release %></dd>
<% if nodeinfo.software.fastd then -%>
<dt><%:Mesh VPN%></dt><dd><%| enabled(nodeinfo.software.fastd.enabled) %></dd>
<%- end %>
<dt><%:Site%></dt><dd><%| site.site_name() %></dd>
<% if nodeinfo.system.domain_code then -%>
<dt><%:Domain%></dt>
<dd>
<%| site.domain_names[nodeinfo.system.domain_code]() %>
<% if nodeinfo.system.domain_code ~= nodeinfo.system.primary_domain_code then %>
(<%| site.domain_names[nodeinfo.system.primary_domain_code]() %>)
<%- end %>
</dd>
<% if nodeinfo.software.autoupdater then -%>
<dt><%:Automatic updates%></dt><dd><%| enabled(nodeinfo.software.autoupdater.enabled) %><%|
nodeinfo.software.autoupdater.enabled and
string.format(' (%s)', nodeinfo.software.autoupdater.branch)
%></dd>
<%- end %>
<% if wg_pubkey then -%>
<dt>Wireguard Key</dt>
<dd><%| wg_pubkey %></dd>
<%- end %>
</dl>
</div>
<div class="frame">
<h2><%:Monitoring%></h2>
<table>
<tr><th><%:Uptime%></th><td><%= statistics('uptime', 'time') %></td></tr>
<tr><th><%:Load average%></th><td><%= statistics('loadavg', 'decimal') %></td></tr>
<tr><th><%:RAM%></th><td><%= statistics('memory', 'memory') %></td></tr>
<tr><th><%:Filesystem%></th><td><%= statistics('rootfs_usage', 'percent') %></td></tr>
<tr><th><%:Gateway%></th><td><%= statistics('gateway') %><br /><%= statistics('gateway_nexthop', 'neighbour') %></td></tr>
<tr><th><%:Clients%></th><td><%= statistics('clients/total') %></td></tr>
</table>
<h3><%:Traffic%></h3>
<table>
<tr><th><%:Transmitted%></th><td><%= statisticsTraffic('traffic/tx') %></td></tr>
<tr><th><%:Received%></th><td><%= statisticsTraffic('traffic/rx') %></td></tr>
<tr><th><%:Forwarded%></th><td><%= statisticsTraffic('traffic/forward') %></td></tr>
</table>
<div id="mesh-vpn" style="display: none">
<h3><%:Mesh VPN%></h3>
<table id="mesh-vpn-peers">
</table>
</div>
</div>
<div class="frame frame-wide">
<h2><%:Neighbors%></h2>
<%
for _, iface in ipairs(interfaces) do
local wireless = is_wireless(iface)
local address = util.readfile('/sys/class/net/' .. iface .. '/address')
if address then
%>
<h3><%| iface %></h3>
<div data-interface="<%| iface %>" data-interface-address="<%| util.trim(address) %>"<%= attr('data-interface-wireless', wireless) %>>
<table class="datatable">
<tr>
<th><%:Node%></th>

Matthias Schiffer
committed
<% for i, v in ipairs(mesh.attrs or {}) do %>
<th<%= attr('class', 'row-' .. v[1] ) .. attr('data-key', v[1]) .. attr('data-suffix', v[3]) %>><%| v[2] %></th>

Matthias Schiffer
committed
<% end %>
<% if wireless then %>
<th class="row-signal">dBm</th>
<th class="row-distance"><%:Distance%></th>
<th class="row-inactive"><%:Last seen%></th>