diff options
Diffstat (limited to '')
| -rwxr-xr-x | apt-panopticon-report-email-web.lua | 201 |
1 files changed, 165 insertions, 36 deletions
diff --git a/apt-panopticon-report-email-web.lua b/apt-panopticon-report-email-web.lua index 9faf476..23608d3 100755 --- a/apt-panopticon-report-email-web.lua +++ b/apt-panopticon-report-email-web.lua | |||
| @@ -12,11 +12,12 @@ local arg, sendArgs = APT.parseArgs({...}) | |||
| 12 | 12 | ||
| 13 | local results = {} | 13 | local results = {} |
| 14 | APT.mirrors = loadfile("results/mirrors.lua")() | 14 | APT.mirrors = loadfile("results/mirrors.lua")() |
| 15 | APT.debians = loadfile("results/debians.lua")() | ||
| 15 | 16 | ||
| 16 | local revDNS = function(dom, IP) | 17 | local revDNS = function(hosts, dom, IP) |
| 17 | if "deb.devuan.org" ~= dom then | 18 | if "deb.devuan.org" ~= dom then |
| 18 | if nil ~= APT.mirrors["deb.devuan.org"] then | 19 | if nil ~= hosts["deb.devuan.org"] then |
| 19 | if nil ~= APT.mirrors["deb.devuan.org"].IPs["deb.roundr.devuan.org"][IP] then | 20 | if nil ~= hosts["deb.devuan.org"].IPs["deb.roundr.devuan.org"][IP] then |
| 20 | if APT.html then | 21 | if APT.html then |
| 21 | return "<font color='purple'><b>DNS-RR</b></font>" | 22 | return "<font color='purple'><b>DNS-RR</b></font>" |
| 22 | else | 23 | else |
| @@ -25,7 +26,7 @@ local revDNS = function(dom, IP) | |||
| 25 | end | 26 | end |
| 26 | end | 27 | end |
| 27 | else | 28 | else |
| 28 | for k, v in pairs(APT.mirrors) do | 29 | for k, v in pairs(hosts) do |
| 29 | if "deb.devuan.org" ~= k then | 30 | if "deb.devuan.org" ~= k then |
| 30 | local IPs = v.IPs | 31 | local IPs = v.IPs |
| 31 | for i, u in pairs(IPs) do | 32 | for i, u in pairs(IPs) do |
| @@ -44,12 +45,12 @@ local revDNS = function(dom, IP) | |||
| 44 | end | 45 | end |
| 45 | 46 | ||
| 46 | local faulty = "" | 47 | local faulty = "" |
| 47 | local status = function(host, results, typ) | 48 | local status = function(hosts, host, results, typ) |
| 48 | local result = "" | 49 | local result = "" |
| 49 | local e = 0 | 50 | local e = 0 |
| 50 | local w = 0 | 51 | local w = 0 |
| 51 | local t = 0 | 52 | local t = 0 |
| 52 | local s = nil ~= APT.mirrors[host].Protocols[typ] | 53 | local s = nil ~= hosts[host].Protocols[typ] |
| 53 | local to = results.timeout | 54 | local to = results.timeout |
| 54 | if not APT.search(APT.protocols, typ) then s = true end | 55 | if not APT.search(APT.protocols, typ) then s = true end |
| 55 | if nil ~= results[typ] then | 56 | if nil ~= results[typ] then |
| @@ -57,7 +58,7 @@ local status = function(host, results, typ) | |||
| 57 | w = results[typ].warnings | 58 | w = results[typ].warnings |
| 58 | t = results[typ].timeouts | 59 | t = results[typ].timeouts |
| 59 | for k, v in pairs(results[typ]) do | 60 | for k, v in pairs(results[typ]) do |
| 60 | if "table" == type(v) then | 61 | if ("table" == type(v)) and ('redirects' ~= k) then |
| 61 | if 0 <= v.errors then e = e + v.errors else to = true end | 62 | if 0 <= v.errors then e = e + v.errors else to = true end |
| 62 | if 0 <= v.warnings then w = w + v.warnings else to = true end | 63 | if 0 <= v.warnings then w = w + v.warnings else to = true end |
| 63 | if 0 <= v.timeouts then t = t + v.timeouts else to = true end | 64 | if 0 <= v.timeouts then t = t + v.timeouts else to = true end |
| @@ -139,31 +140,49 @@ local logCount = function(domain, ip) | |||
| 139 | local nm = "LOG_" .. domain | 140 | local nm = "LOG_" .. domain |
| 140 | local log = "" | 141 | local log = "" |
| 141 | local extra = "" | 142 | local extra = "" |
| 143 | local errors = 0 | ||
| 144 | local warnings = 0 | ||
| 145 | local timeouts = 0 | ||
| 142 | if nil ~= ip then nm = nm .. "_" .. ip end | 146 | if nil ~= ip then nm = nm .. "_" .. ip end |
| 143 | nm = nm .. ".html" | 147 | nm = nm .. ".html" |
| 144 | local rfile, e = io.open("results/" .. nm, "r") | 148 | local rfile, e = io.open("results/" .. nm, "r") |
| 145 | if nil ~= rfile then | 149 | if nil ~= rfile then |
| 146 | local errors = 0 | ||
| 147 | local warnings = 0 | ||
| 148 | local timeouts = 0 | ||
| 149 | for l in rfile:lines() do | 150 | for l in rfile:lines() do |
| 150 | if nil ~= l:match("><b>ERROR ") then errors = errors + 1 end | 151 | if nil ~= l:match("><b>ERROR ") then errors = errors + 1 end |
| 151 | if nil ~= l:match("><b>WARNING ") then warnings = warnings + 1 end | 152 | if nil ~= l:match("><b>WARNING ") then warnings = warnings + 1 end |
| 152 | if nil ~= l:match("><b>TIMEOUT ") then timeouts = timeouts + 1 end | 153 | if nil ~= l:match("><b>TIMEOUT ") then timeouts = timeouts + 1 end |
| 153 | end | 154 | end |
| 154 | rfile:close() | 155 | rfile:close() |
| 155 | if APT.html then | 156 | end |
| 156 | if nil == ip then | 157 | if APT.html then |
| 157 | log = "<a href='" .. nm .. "'>" .. domain .. "</a>" | 158 | if nil == ip then |
| 158 | else | 159 | log = "<a href='" .. nm .. "'>" .. domain .. "</a>" |
| 159 | log = "<a href='" .. nm .. "'>" .. ip .. "</a>" | 160 | else |
| 160 | end | 161 | log = "<a href='" .. nm .. "'>" .. ip .. "</a>" |
| 161 | end | 162 | end |
| 162 | log = log .. APT.plurals(errors, warnings, timeouts) | ||
| 163 | end | 163 | end |
| 164 | log = log .. APT.plurals(errors, warnings, timeouts) | ||
| 164 | return log | 165 | return log |
| 165 | end | 166 | end |
| 166 | 167 | ||
| 168 | local redirs = function(hosts, host) | ||
| 169 | local results = APT.collateAll(hosts, 'results', host) | ||
| 170 | local rdr = {} | ||
| 171 | local redirs = '' | ||
| 172 | for p, pt in pairs(APT.protocols) do | ||
| 173 | if 0 ~= #(results[pt].redirects) then | ||
| 174 | table.sort(results[pt].redirects) | ||
| 175 | for r, rd in pairs(results[pt].redirects) do | ||
| 176 | rdr[rd] = rd | ||
| 177 | end | ||
| 178 | end | ||
| 179 | end | ||
| 180 | for r, rd in pairs(rdr) do | ||
| 181 | redirs = redirs .. ',   ' .. rd | ||
| 182 | end | ||
| 183 | if '' ~= redirs then redirs = '<br>\n (Redirects some packages to - ' .. redirs:sub(3) .. ')' end | ||
| 184 | return redirs | ||
| 185 | end | ||
| 167 | 186 | ||
| 168 | APT.html = false | 187 | APT.html = false |
| 169 | local email, e = io.open("results/Report-email.txt", "w+") | 188 | local email, e = io.open("results/Report-email.txt", "w+") |
| @@ -183,16 +202,16 @@ if nil == email then C("opening mirrors file - " .. e) else | |||
| 183 | "[skip] means that the test hasn't been written yet.\n\n") | 202 | "[skip] means that the test hasn't been written yet.\n\n") |
| 184 | for k, v in APT.orderedPairs(APT.mirrors) do | 203 | for k, v in APT.orderedPairs(APT.mirrors) do |
| 185 | email:write(k .. "....\n") | 204 | email:write(k .. "....\n") |
| 186 | local results = APT.collateAll('results', k) | 205 | local results = APT.collateAll(APT.mirrors, 'results', k) |
| 187 | local ftp = "[skip]" | 206 | local ftp = "[skip]" |
| 188 | local http = status(k, results, "http") | 207 | local http = status(APT.mirrors, k, results, "http") |
| 189 | local https = status(k, results, "https") | 208 | local https = status(APT.mirrors, k, results, "https") |
| 190 | local rsync = "[skip]" | 209 | local rsync = "[skip]" |
| 191 | local dns = "" | 210 | local dns = "" |
| 192 | local protocol = status(k, results, "Protocol") | 211 | local protocol = status(APT.mirrors, k, results, "Protocol") |
| 193 | local sanity = status(k, results, "URLSanity") | 212 | local sanity = status(APT.mirrors, k, results, "URLSanity") |
| 194 | local integrity = status(k, results, "Integrity") | 213 | local integrity = status(APT.mirrors, k, results, "Integrity") |
| 195 | local updated = status(k, results, "Updated") | 214 | local updated = status(APT.mirrors, k, results, "Updated") |
| 196 | 215 | ||
| 197 | -- DNS-RR test. | 216 | -- DNS-RR test. |
| 198 | if ("deb.devuan.org" ~= k) and (nil ~= APT.mirrors["deb.devuan.org"]) then | 217 | if ("deb.devuan.org" ~= k) and (nil ~= APT.mirrors["deb.devuan.org"]) then |
| @@ -347,7 +366,7 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 347 | "<th>Protocol</th><th>URL sanity</th><th>Integrity</th><th>Updated</th><th colspan='2'>Speed range</th></tr>\n" | 366 | "<th>Protocol</th><th>URL sanity</th><th>Integrity</th><th>Updated</th><th colspan='2'>Speed range</th></tr>\n" |
| 348 | ) | 367 | ) |
| 349 | for k, v in APT.orderedPairs(APT.mirrors) do | 368 | for k, v in APT.orderedPairs(APT.mirrors) do |
| 350 | local results = APT.collateAll('results', k) | 369 | local results = APT.collateAll(APT.mirrors, 'results', k) |
| 351 | local active = "" | 370 | local active = "" |
| 352 | if "yes" == v.Active then | 371 | if "yes" == v.Active then |
| 353 | web:write(" <tr><th>" .. k .. "</th> ") | 372 | web:write(" <tr><th>" .. k .. "</th> ") |
| @@ -356,14 +375,14 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 356 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") | 375 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") |
| 357 | end | 376 | end |
| 358 | local ftp = "[<font color='grey'><b>skip</b></font>]" | 377 | local ftp = "[<font color='grey'><b>skip</b></font>]" |
| 359 | local http = status(k, results, "http") | 378 | local http = status(APT.mirrors, k, results, "http") |
| 360 | local https = status(k, results, "https") | 379 | local https = status(APT.mirrors, k, results, "https") |
| 361 | local rsync = "[<font color='grey'><b>skip</b></font>]" | 380 | local rsync = "[<font color='grey'><b>skip</b></font>]" |
| 362 | local dns = "" | 381 | local dns = "" |
| 363 | local protocol = status(k, results, "Protocol") | 382 | local protocol = status(APT.mirrors, k, results, "Protocol") |
| 364 | local sanity = status(k, results, "URLSanity") | 383 | local sanity = status(APT.mirrors, k, results, "URLSanity") |
| 365 | local integrity = status(k, results, "Integrity") | 384 | local integrity = status(APT.mirrors, k, results, "Integrity") |
| 366 | local updated = status(k, results, "Updated") | 385 | local updated = status(APT.mirrors, k, results, "Updated") |
| 367 | local rate = v.Rate | 386 | local rate = v.Rate |
| 368 | if nil ~= rate then updated = updated .. ' ' .. rate end | 387 | if nil ~= rate then updated = updated .. ' ' .. rate end |
| 369 | local min = tonumber(results.speed.min) | 388 | local min = tonumber(results.speed.min) |
| @@ -434,14 +453,14 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 434 | n[l] = {} | 453 | n[l] = {} |
| 435 | for i, u in pairs(w) do | 454 | for i, u in pairs(w) do |
| 436 | local log = logCount(k, i) | 455 | local log = logCount(k, i) |
| 437 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(k, i)] = u end | 456 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(APT.mirrors, k, i)] = u end |
| 438 | end | 457 | end |
| 439 | else | 458 | else |
| 440 | local log = logCount(k, l) | 459 | local log = logCount(k, l) |
| 441 | if "" == log then n[l] = w else n[log .. " " .. revDNS(k, l)] = w end | 460 | if "" == log then n[l] = w else n[log .. " " .. revDNS(APT.mirrors, k, l)] = w end |
| 442 | end | 461 | end |
| 443 | end | 462 | end |
| 444 | m[log .. " DNS entries -"] = n | 463 | m[log .. " DNS entries -" .. redirs(APT.mirrors, k)] = n |
| 445 | end | 464 | end |
| 446 | web:write( "<p>This lists each mirror, and the DNS entries for that mirror. " .. | 465 | web:write( "<p>This lists each mirror, and the DNS entries for that mirror. " .. |
| 447 | "The links point to the testing log files for " .. logCount("apt-panopticon") .. " for each domain name / IP combination that was tested. " .. | 466 | "The links point to the testing log files for " .. logCount("apt-panopticon") .. " for each domain name / IP combination that was tested. " .. |
| @@ -453,8 +472,118 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 453 | ) | 472 | ) |
| 454 | web:write(APT.dumpTableHTML(m, "", "")) | 473 | web:write(APT.dumpTableHTML(m, "", "")) |
| 455 | web:write( "\n<br>\n<br>\n<h2>==== graphs: ====</h2>\n" .. | 474 | web:write( "\n<br>\n<br>\n<h2>==== graphs: ====</h2>\n" .. |
| 456 | "<img src='speed.png'>\n<br>\n<p><a href='../apt-panopticon_cgp/'>More graphs.</a> with greater detail.</p><hr>\n\n" .. | 475 | "<img src='speed.png'>\n<br>\n<p><a href='../apt-panopticon_cgp/'>More graphs.</a> with greater detail.</p><hr>\n\n") |
| 457 | "<p>The <a href='Report-email.txt'>email report</a>. " .. | 476 | |
| 477 | results = {} | ||
| 478 | m = {} | ||
| 479 | faulty = "" | ||
| 480 | web:write( "<hr>\n<h2>==== Debian mirror status ====</h2>\n" .. | ||
| 481 | "<p>NOTE - This is not fully probing the Debian mirrors, we just collect some data from any redirects to other servers. " .. | ||
| 482 | "So this isn't a full set of tests.</p>\n" .. | ||
| 483 | "<p><font style='background-color:red; color:black'>EXPERIMENTAL CODE - this is even more experimental than the rest.</font></p>\n" .. | ||
| 484 | "<table>\n<tr><th></th><th>FTP</th><th>HTTP</th><th>HTTPS</th><th>RSYNC</th><th>DNS round robin</th>" .. | ||
| 485 | "<th>Protocol</th><th>URL sanity</th><th>Integrity</th><th>Updated</th><th colspan='2'>Speed range</th></tr>\n") | ||
| 486 | for k, v in APT.orderedPairs(APT.debians) do | ||
| 487 | local results = APT.collateAll(APT.debians, 'results', k) | ||
| 488 | local active = "" | ||
| 489 | if "yes" == v.Active then | ||
| 490 | web:write(" <tr><th>" .. k .. "</th> ") | ||
| 491 | else | ||
| 492 | if nil == v.Active then active = 'nil' else active = v.Active end | ||
| 493 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") | ||
| 494 | end | ||
| 495 | local ftp = "[<font color='grey'><b>skip</b></font>]" | ||
| 496 | local http = status(APT.debians, k, results, "http") | ||
| 497 | local https = status(APT.debians, k, results, "https") | ||
| 498 | local rsync = "[<font color='grey'><b>skip</b></font>]" | ||
| 499 | local dns = "" | ||
| 500 | local protocol = status(APT.debians, k, results, "Protocol") | ||
| 501 | local sanity = status(APT.debians, k, results, "URLSanity") | ||
| 502 | local integrity = status(APT.debians, k, results, "Integrity") | ||
| 503 | local updated = status(APT.debians, k, results, "Updated") | ||
| 504 | local rate = v.Rate | ||
| 505 | if nil ~= rate then updated = updated .. ' ' .. rate end | ||
| 506 | local min = tonumber(results.speed.min) | ||
| 507 | local max = tonumber(results.speed.max) | ||
| 508 | local spd = '' | ||
| 509 | |||
| 510 | -- DNS-RR test. | ||
| 511 | if ("deb.devuan.org" ~= k) and (nil ~= APT.debians["deb.devuan.org"]) then | ||
| 512 | for l, w in pairs(APT.debians[k].IPs) do | ||
| 513 | if type(w) == "table" then | ||
| 514 | for i, u in pairs(w) do | ||
| 515 | if nil ~= APT.debians["deb.devuan.org"].IPs["deb.roundr.devuan.org"][i] then | ||
| 516 | local log = logCount("deb.devuan.org", i) | ||
| 517 | if "" ~= log then | ||
| 518 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 519 | dns = dns .. logCount("deb.devuan.org", i) | ||
| 520 | else | ||
| 521 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 522 | dns = dns .. "<font color='maroon'><b>" .. i .. "</b></font>" | ||
| 523 | end | ||
| 524 | end | ||
| 525 | end | ||
| 526 | else | ||
| 527 | if nil ~= APT.debians["deb.devuan.org"].IPs["deb.roundr.devuan.org"][l] then | ||
| 528 | local log = logCount("deb.devuan.org", l) | ||
| 529 | if "" ~= log then | ||
| 530 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 531 | dns = dns .. log | ||
| 532 | else | ||
| 533 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 534 | dns = dns .. "<font color='maroon'><b>" .. l .. "</b></font>" | ||
| 535 | end | ||
| 536 | end | ||
| 537 | end | ||
| 538 | end | ||
| 539 | if "" == dns then dns = "[<font color='grey'><b>no</b></font>]" end | ||
| 540 | |||
| 541 | if 0 == max then | ||
| 542 | spd = '<td></td><td></td>' | ||
| 543 | else | ||
| 544 | spd = string.format('<td align="right">%d -></td><td align="right">%d</td>', min, max) | ||
| 545 | end | ||
| 546 | end | ||
| 547 | |||
| 548 | web:write("<td>" .. ftp .. " </td><td>" .. http .. " </td><td>" .. https .. " </td><td>" .. rsync .. " </td><td>" .. dns .. | ||
| 549 | " </td><td>" .. protocol .. " </td><td>" .. sanity .. | ||
| 550 | " </td><td>" .. integrity .. " </td><td>" .. updated .. " </td>" .. spd .. "</tr>\n") | ||
| 551 | if "" ~= active then | ||
| 552 | web:write("<tr><td style='background-color:dimgrey'>" .. active .. "</td></tr>\n") | ||
| 553 | end | ||
| 554 | end | ||
| 555 | web:write( "</table>\n<br>\n\n") | ||
| 556 | |||
| 557 | web:write( "<br>\n<br>\n<h2>==== Debian DNS and logs: ====</h2>\n") | ||
| 558 | |||
| 559 | for k, v in pairs(APT.debians) do | ||
| 560 | local log = k | ||
| 561 | local n = {} | ||
| 562 | log = logCount(k) | ||
| 563 | APT.debians[k].Protocols = nil | ||
| 564 | APT.debians[k].FQDN = nil | ||
| 565 | APT.debians[k].Active = nil | ||
| 566 | APT.debians[k].Rate = nil | ||
| 567 | APT.debians[k].BaseURL = nil | ||
| 568 | APT.debians[k].Country = nil | ||
| 569 | APT.debians[k].Bandwidth = nil | ||
| 570 | for l, w in pairs(APT.debians[k].IPs) do | ||
| 571 | if type(w) == "table" then | ||
| 572 | n[l] = {} | ||
| 573 | for i, u in pairs(w) do | ||
| 574 | local log = logCount(k, i) | ||
| 575 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(APT.debians, k, i)] = u end | ||
| 576 | end | ||
| 577 | else | ||
| 578 | local log = logCount(k, l) | ||
| 579 | if "" == log then n[l] = w else n[log .. " " .. revDNS(APT.debians, k, l)] = w end | ||
| 580 | end | ||
| 581 | end | ||
| 582 | m[log .. " DNS entries -" .. redirs(APT.mirrors, k)] = n | ||
| 583 | end | ||
| 584 | web:write(APT.dumpTableHTML(m, "", "")) | ||
| 585 | |||
| 586 | web:write( "<hr>\n<hr>\n<p>The <a href='Report-email.txt'>email report</a>. " .. | ||
| 458 | "All <a href='../results'>the logs and other output</a>. " .. | 587 | "All <a href='../results'>the logs and other output</a>. " .. |
| 459 | "You can get the <a href='https://sledjhamr.org/cgit/apt-panopticon/about/'>source code here</a>.</p>\n") | 588 | "You can get the <a href='https://sledjhamr.org/cgit/apt-panopticon/about/'>source code here</a>.</p>\n") |
| 460 | local status, whn = APT.execute('TZ="GMT" ls -l1 --time-style="+%s" results/stamp | cut -d " " -f 6-6') | 589 | local status, whn = APT.execute('TZ="GMT" ls -l1 --time-style="+%s" results/stamp | cut -d " " -f 6-6') |
