#!/usr/bin/lua debugdata = "" ATH9K_DEBUGFS_DIR="/sys/kernel/debug/ieee80211/phy0/ath9k" PATH_DBG_REPORT='/tmp/debug-report.txt' local nixio = require('nixio'), require('nixio.util') local util = require("luci.util") local fs = require("nixio.fs") local ltn12 = require 'luci.ltn12' local sys = require("luci.sys") local json = require("luci.jsonc") local platform_info = require("platform_info") local site = require 'gluon.site_config' local ip = require 'luci.ip' local uci = require('luci.model.uci').cursor() -- some usefull functions local hostname = sys.hostname() local model = platform_info.get_model() local release = util.trim(fs.readfile("/lib/gluon/release") or "") local version = util.trim(fs.readfile("/lib/gluon/gluon-version") or "") local primary_mac = require('gluon.sysconfig').primary_mac local contact = uci:get_first('gluon-node-info', 'owner', 'contact', '') if contact == '' then contact = "none" end local autoupdater = uci:get('autoupdater', 'settings', 'branch') if uci:get_bool('autoupdater', 'settings', 'enabled') == false then autoupdater = "disabled (" .. autoupdater .. ")" end local addresses = "" for line in io.lines('/proc/net/if_inet6') do local matches = { line:match('^' .. string.rep('(%x%x%x%x)', 8) .. string.rep(' %x%x', 4) .. '%s+([^%s]+)$') } if matches[9] == 'br-client' then addresses = addresses .. " " .. ip.IPv6(string.format('%s:%s:%s:%s:%s:%s:%s:%s', unpack(matches))):string():lower() .. "\n" end end local data = io.open('/proc/meminfo'):read('*a') local fields = {} for k, v in data:gmatch('([^\n:]+):%s*(%d+) kB') do fields[k] = tonumber(v) end local function location() local text = 'none' local locationid = uci:get_first('gluon-node-info', 'location') if locationid then local location = uci:get_all('gluon-node-info', locationid) if uci:get_bool('gluon-node-info', locationid, 'share_location') and location.latitude and location.longitude then text = location.latitude .. ', ' .. location.longitude end end return text end local function ip_proto(address) if address:match("%.") then return "IPv4" end if address:match(":") then return "IPv6" end return "???" end -- wrapper for calling systemcommands local function cmd(_command) local f = io.popen(_command) local l = f:read("*a") f:close() return "# " .. _command .. ": \n" .. l .. "\n" end -- read contents of a given file local function readFile(_file) local f = io.open(_file, "r") if f~=nil then local l = f:read("*a") f:close() return "--- Content of file " .. _file .. " ---\n" .. l .. "\n\n" else return "" end end -- Should we enter local mode? localMode = false if arg[1] == '-l' then localMode = true end -- search for existing debug report local oldReport = nixio.open(PATH_DBG_REPORT, "r") if oldReport==nil then -- no existing debugreport, let's generate a new one -- inform the User ;) print('-- Hello, Mr. Dillinger. Thank you for coming back early.') print('-- Sit right there; make yourself comfortable. Remember the time we spent play chess together?') -- first of all, collect some generic information about the system debugdata = debugdata .. "---- BEGIN SYSTEM INFORMATION ----\n" debugdata = debugdata .. "Hostname: " .. hostname .. "\n" debugdata = debugdata .. "Community: " .. site.site_name .. "\n" debugdata = debugdata .. "Model: " .. model .. "\n" debugdata = debugdata .. "Firmware: " .. release .. " / " .. version .. "\n" debugdata = debugdata .. "MAC: " .. primary_mac .. "\n" debugdata = debugdata .. "Contact: " .. contact .. "\n" debugdata = debugdata .. "Uptime: " .. util.trim(sys.exec("uptime | sed 's/^ \+//'")) .. "\n" debugdata = debugdata .. "Autoupdater: " .. autoupdater .. "\n" debugdata = debugdata .. "Location: " .. location() .. "\n" debugdata = debugdata .. "IPs: " .. util.trim(addresses) .. "\n" debugdata = debugdata .. "Memory: " .. string.format("%.1f %% used, %.1f %% free\n",(fields.MemTotal-fields.MemFree)/fields.MemTotal*100,fields.MemFree/fields.MemTotal*100) debugdata = debugdata .. cmd("ps w") debugdata = debugdata .. "---- END SYSTEM INFORMATION ----\n\n" -- show uci variables debugdata = debugdata .. "---- BEGIN UCI VARIABLES ----\n" debugdata = debugdata .. cmd("uci show | grep -v '\.key' | grep -v '\.secret'") debugdata = debugdata .. "---- END UCI VARIABLES ----\n\n" -- show cron jobs debugdata = debugdata .. "---- BEGIN CRON JOBS ----\n" debugdata = debugdata .. cmd("grep -r \"\" /usr/lib/micron.d/ | sed -e \"s/:/:\\n/\"") debugdata = debugdata .. "---- END CRON JOBS ----\n\n" -- now get some information about the network status debugdata = debugdata .. "---- BEGIN IP AND ROUTUNG INFORMATION ----\n" debugdata = debugdata .. cmd("ip addr show") debugdata = debugdata .. cmd("ip route show") debugdata = debugdata .. cmd("ip -6 route show") debugdata = debugdata .. "---- BEGIN IP AND ROUTUNG INFORMATION ----\n\n" -- get wireless status debugdata = debugdata .. "---- BEGIN WIRELESS INFORMATION ----\n" debugdata = debugdata .. cmd("iwinfo ibss0 info 2>&1") debugdata = debugdata .. cmd("iwinfo client0 info 2>&1") debugdata = debugdata .. cmd("iwinfo ibss1 info 2>&1") debugdata = debugdata .. cmd("iwinfo client1 info 2>&1") debugdata = debugdata .. cmd("iwinfo ibss0 assoclist 2>&1") debugdata = debugdata .. cmd("iwinfo ibss1 assoclist 2>&1") debugdata = debugdata .. "---- END WIRELESS INFORMATION ----\n\n" -- get batman status debugdata = debugdata .. "---- BEGIN BATMAN STATUS ----\n" debugdata = debugdata .. cmd("batctl gwl") debugdata = debugdata .. cmd("batctl tl") debugdata = debugdata .. "---- END BATMAN STATUS ----\n\n" -- get fastd status debugdata = debugdata .. "---- BEGIN FASTD STATUS ----\n" if string.len(util.exec("ip -f inet address show dev br-wan | grep global")) >= 2 then debugdata = debugdata .. "IPv4 configured\n" else debugdata = debugdata .. "IPv4 not configured\n" end if string.len(util.exec("ip -f inet6 address show dev br-wan | grep global")) >= 2 then debugdata = debugdata .. "IPv6 configured\n" else debugdata = debugdata .. "IPv6 not configured\n" end local stat, fastd_status = pcall( function() local fastd_sock = nixio.socket('unix', 'stream') assert(fastd_sock:connect('/var/run/fastd.mesh_vpn.socket')) decoder = json.new() ltn12.pump.all(ltn12.source.file(fastd_sock), decoder:sink()) return decoder:get() end ) if stat then debugdata = debugdata .. string.format("fastd running for %.3f seconds\n", fastd_status.uptime/1000) local peers = 0 local connections = 0 for key, peer in pairs(fastd_status.peers) do peers = peers+1 if peer.connection then connections = connections+1 end end debugdata = debugdata .. string.format("There are %i peers configured, of which %i are connected:\n", peers, connections) for key, peer in pairs(fastd_status.peers) do debugdata = debugdata .. peer.name .. ": " if peer.connection then debugdata = debugdata .. string.format("connected for %.3f seconds via %s\n", peer.connection.established/1000, ip_proto(peer.address)) else debugdata = debugdata .. "not connected\n" end end else debugdata = debugdata .. "fastd not running\n" end debugdata = debugdata .. "---- END FASTD STATUS ----\n\n" -- get log debugdata = debugdata .. "---- BEGIN LOGREAD ----\n" debugdata = debugdata .. cmd("logread") debugdata = debugdata .. "---- END LOGREAD ----\n\n" debugdata = debugdata .. "---- BEGIN DMESG KERNEL LOG ----\n" debugdata = debugdata .. cmd("dmesg") debugdata = debugdata .. "---- END DMESG KERNEL LOG ----\n\n" else print('Orphaned debug-report file found.') print('-- You wouldn\'t want me to dig up Flynn\'s file and read it up on a VDT at The Times, would you?') debugdata = oldReport:readall() oldReport:close() end -- if local mode is requested print the report, otherwise send it to the admin team siteConfig = require("gluon.site_config") if localMode then print('Omitting to send the report data to a report-server') print('-- Sark! All of my functions are now yours. Take them!:') print(debugdata) nixio.fs.unlink(PATH_DBG_REPORT) else local nixio = require('nixio'), require('nixio.util') print('-- My User has information that could... that could make this a free system again!') local sent = 0 local reportname = nil local port = siteConfig.debugserver.port for host in ipairs(siteConfig.debugserver.host) do print('Trying to deliver debug-report to: ' .. host) local sock = nixio.connect(host, port, "inet6", "stream") if sock then sock:setopt('socket', 'sndtimeo', 30.0) sock:setopt('socket', 'rcvtimeo', 30.0) sent = sock:writeall(debugdata) if sent == debugdata:len() then -- half-side close to indicate the end of our transmission sock:shutdown('wr') print('Transmission succeeded. Waiting for report-name.') reportname = sock:readall(256) end sock:close() if reportname ~= nil then break end end end if reportname ~= nil then print('\nYour report has been stored at the debug-server with the name: ' .. reportname) print('-- With the information I can access, I can run things 900 to 1200 times better than any human.') else print('Sorry, I couldn\'t send the report.') print('-- If you are a User, then everything you\'ve done so far has been according to a plan, right?') print('-- I will try it again the next time you run me. See you soon ...') local f = nixio.open(PATH_DBG_REPORT, 'w') f:writeall(debugdata) f:close() end end print("-- You've almost reached your decision gate, and I cannot spare you any more time. End of Line.") os.exit(0)