Skip to content
Snippets Groups Projects
Select Git revision
  • 2a3b0f1bc037d6a95a82ab1569d503f4bc52cee3
  • experimental default protected
  • v2023.2.5-ffs
  • nrb/ex400-remove-wps
  • nrb/airmax-test
  • v2023.2.4-ffs
  • nrb/ar9344-reset-sequence
  • autinerd/experimental-openwrt-24.10
  • v2023.2.3-ffs
  • v2023.2.2-ffs
  • v2023.2-ffs
  • v2023.1-ffs
  • v2022.1.4-ffs
  • feature/addMikrotikwAP
  • v2022.1.3-ffs
  • v2021.1.2-ffs
  • v2022.1.1-ffs
  • master protected
  • v2021.1.1-ffs
  • nrb/gluon-master-cpe510
  • v2021.1-ffs
  • experimental-2025-07-12
  • experimental-2025-07-12-base
  • experimental-2025-07-04
  • experimental-2025-07-04-base
  • experimental-2025-07-01
  • experimental-2025-07-01-base
  • experimental-2025-06-25
  • experimental-2025-06-25-base
  • experimental-2025-06-24
  • experimental-2025-06-24-base
  • experimental-2025-06-22
  • experimental-2025-06-22-base
  • v2023.2.5-ffs0.1
  • experimental-2025-06-08
  • experimental-2025-06-08-base
  • experimental-2025-06-06
  • experimental-2025-06-06-base
  • experimental-2025-05-27
  • experimental-2025-05-27-base
  • experimental-2025-05-18
41 results

modules

Blame
  • status-page.html 6.07 KiB
    <%-
    	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')
    
    	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
    
    	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>
    	<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 %>
    					<% 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>
    					<%- end %>
    					<% 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 %>
    				</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>
    								<% 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>
    								<% end %>
    								<% if wireless then %>
    									<th class="row-signal">dBm</th>
    									<th class="row-distance"><%:Distance%></th>
    									<th class="row-inactive"><%:Last seen%></th>
    								<% end %>
    							</tr>
    						</table>
    					</div>
    				<%
    						end
    					end
    				%>
    			</div>
    		</div>
    		<script src="/static/status-page.js"></script>
    	</body>
    </html>