diff options
| author | onefang | 2019-12-29 17:30:51 +1000 |
|---|---|---|
| committer | onefang | 2019-12-29 17:30:51 +1000 |
| commit | 12f7868ef4a315893e65123d0fc3f60aaf0720ab (patch) | |
| tree | ed759a0a41c9c863a8b976e62bf0f1baf1134fad | |
| parent | Whitespace. (diff) | |
| download | apt-panopticon-12f7868ef4a315893e65123d0fc3f60aaf0720ab.zip apt-panopticon-12f7868ef4a315893e65123d0fc3f60aaf0720ab.tar.gz apt-panopticon-12f7868ef4a315893e65123d0fc3f60aaf0720ab.tar.bz2 apt-panopticon-12f7868ef4a315893e65123d0fc3f60aaf0720ab.tar.xz | |
Big refactor of the email / web report.
| -rwxr-xr-x | apt-panopticon-report-email-web.lua | 440 |
1 files changed, 181 insertions, 259 deletions
diff --git a/apt-panopticon-report-email-web.lua b/apt-panopticon-report-email-web.lua index a08b901..97f7cef 100755 --- a/apt-panopticon-report-email-web.lua +++ b/apt-panopticon-report-email-web.lua | |||
| @@ -14,10 +14,16 @@ local results = {} | |||
| 14 | APT.mirrors = loadfile("results/mirrors.lua")() | 14 | APT.mirrors = loadfile("results/mirrors.lua")() |
| 15 | APT.debians = loadfile("results/debians.lua")() | 15 | APT.debians = loadfile("results/debians.lua")() |
| 16 | 16 | ||
| 17 | |||
| 18 | local lnk = function(name, link) | ||
| 19 | if nil == link then link = name end | ||
| 20 | return name .. " <a href='explanations.html#" .. link .. "'>*</a>" | ||
| 21 | end | ||
| 22 | |||
| 17 | local revDNS = function(hosts, dom, IP) | 23 | local revDNS = function(hosts, dom, IP) |
| 18 | if "deb.devuan.org" ~= dom then | 24 | if APT.options.roundRobin.value ~= dom then |
| 19 | if nil ~= hosts["deb.devuan.org"] then | 25 | if nil ~= hosts[APT.options.roundRobin.value] then |
| 20 | if nil ~= hosts["deb.devuan.org"].IPs["deb.roundr.devuan.org"][IP] then | 26 | if nil ~= hosts[APT.options.roundRobin.value].IPs["deb.roundr.devuan.org"][IP] then |
| 21 | if APT.html then | 27 | if APT.html then |
| 22 | return "<font color='purple'><b>DNS-RR</b></font>" | 28 | return "<font color='purple'><b>DNS-RR</b></font>" |
| 23 | else | 29 | else |
| @@ -27,7 +33,7 @@ local revDNS = function(hosts, dom, IP) | |||
| 27 | end | 33 | end |
| 28 | else | 34 | else |
| 29 | for k, v in pairs(hosts) do | 35 | for k, v in pairs(hosts) do |
| 30 | if "deb.devuan.org" ~= k then | 36 | if APT.options.roundRobin.value ~= k then |
| 31 | local IPs = v.IPs | 37 | local IPs = v.IPs |
| 32 | for i, u in pairs(IPs) do | 38 | for i, u in pairs(IPs) do |
| 33 | if "table" == type(u) then | 39 | if "table" == type(u) then |
| @@ -174,6 +180,162 @@ local redirs = function(hosts, host) | |||
| 174 | return redirs | 180 | return redirs |
| 175 | end | 181 | end |
| 176 | 182 | ||
| 183 | |||
| 184 | local DNSrrTest = function(hosts, k) | ||
| 185 | local dns = '' | ||
| 186 | local space = ' ' | ||
| 187 | local no = 'no' | ||
| 188 | if APT.html then | ||
| 189 | space = ' ' | ||
| 190 | no = "<font color='grey'><b>no</b></font>" | ||
| 191 | end | ||
| 192 | if (APT.options.roundRobin.value ~= k) and (nil ~= hosts[APT.options.roundRobin.value]) then | ||
| 193 | APT.allpairs(hosts[k].IPs, | ||
| 194 | function(i, w, k, v) | ||
| 195 | if nil ~= hosts[APT.options.roundRobin.value].IPs["deb.roundr.devuan.org"][i] then | ||
| 196 | local log = logCount(APT.options.roundRobin.value, i) | ||
| 197 | if "" ~= log then | ||
| 198 | if "" == dns then dns = " " else dns = dns .. space end | ||
| 199 | dns = dns .. logCount(APT.options.roundRobin.value, i) | ||
| 200 | else | ||
| 201 | if "" == dns then dns = " " else dns = dns .. space end | ||
| 202 | if APT.html then i = "<font color='maroon'><b>" .. i .. "</b></font>" end | ||
| 203 | dns = dns .. i | ||
| 204 | end | ||
| 205 | end | ||
| 206 | end | ||
| 207 | ) | ||
| 208 | if "" == dns then dns = no end | ||
| 209 | end | ||
| 210 | return dns | ||
| 211 | end | ||
| 212 | |||
| 213 | local makeTable = function(web, hosts) | ||
| 214 | web:write("<table>\n<tr><th></th><th>" .. lnk('FTP') .. "</th><th>" .. lnk('HTTP') .. "</th><th>" .. lnk('HTTPS') .. "</th><th>" .. lnk('RSYNC') .. "</th>" .. | ||
| 215 | "<th>" .. lnk('DNS round robin', 'DNS-RR') .. "</th><th>" .. lnk('Protocol') .. "</th><th>" .. lnk('URL sanity', 'URL-Sanity') .. "</th><th>" .. lnk('Integrity') .. "</th>" .. | ||
| 216 | "<th>" .. lnk('Updated') .. "</th><th colspan='2'>" .. lnk('Speed range', 'Speed') .. "</th>" .. | ||
| 217 | "<th colspan='2'>" .. lnk('Weekly statistics', 'Weekly') .. "</th><th>" .. lnk('Graphs') .. "</th></tr>\n") | ||
| 218 | local bg = '' | ||
| 219 | for k, v in APT.orderedPairs(hosts) do | ||
| 220 | if '' == bg then bg = " style='background-color:#111111'" else bg = '' end | ||
| 221 | local results = APT.collateAll(hosts, 'results', k) | ||
| 222 | local active = "" | ||
| 223 | if "yes" == v.Active then | ||
| 224 | web:write(" <tr" .. bg .. "><th>" .. k .. "</th> ") | ||
| 225 | else | ||
| 226 | if nil == v.Active then active = 'nil' else active = v.Active end | ||
| 227 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") | ||
| 228 | end | ||
| 229 | local ftp = "<font color='grey'><b>skip</b></font>" | ||
| 230 | local http = status(hosts, k, results, "http") | ||
| 231 | local https = status(hosts, k, results, "https") | ||
| 232 | local rsync = "<font color='grey'><b>skip</b></font>" | ||
| 233 | local dns = DNSrrTest(hosts, k) | ||
| 234 | local protocol = status(hosts, k, results, "Protocol") | ||
| 235 | local sanity = status(hosts, k, results, "URLSanity") | ||
| 236 | local integrity = status(hosts, k, results, "Integrity") | ||
| 237 | local updated = status(hosts, k, results, "Updated") | ||
| 238 | local rate = v.Rate | ||
| 239 | if nil ~= rate then updated = updated .. ' ' .. rate end | ||
| 240 | local min = tonumber(results.speed.min) | ||
| 241 | local max = tonumber(results.speed.max) | ||
| 242 | local spd = '<td></td><td></td>' | ||
| 243 | local week = '<td></td><td></td>' | ||
| 244 | local graph = '<a href="../apt-panopticon_cgp/host.php?h=' .. k .. '">graphs</a>' | ||
| 245 | |||
| 246 | -- DNS-RR test. | ||
| 247 | if (APT.options.roundRobin.value ~= k) and (nil ~= hosts[APT.options.roundRobin.value]) then | ||
| 248 | if 0 == max then | ||
| 249 | spd = '<td></td><td></td>' | ||
| 250 | else | ||
| 251 | spd = string.format('<td align="right">%d -</td><td align="right">%d</td>', min, max) | ||
| 252 | end | ||
| 253 | end | ||
| 254 | |||
| 255 | if (APT.options.roundRobin.value ~= k) then | ||
| 256 | local percentUp = '??' | ||
| 257 | local percentUpdated = '??' | ||
| 258 | if APT.checkFile('rrd/' .. k .. '/Speed/Speed.rrd') then | ||
| 259 | local start, step, names, data = APT.rrd.fetch('rrd/' .. k .. '/Speed/Speed.rrd', 'LAST', '-a', '-r', '10m', '-s', '-1w') | ||
| 260 | local count, up, down, unknown = 0, 0, 0, 0 | ||
| 261 | for i, dp in ipairs(data) do | ||
| 262 | for j,v in ipairs(dp) do | ||
| 263 | if 'max' == names[j] then | ||
| 264 | if 'nan' == tostring(v) then | ||
| 265 | unknown = unknown + 1 | ||
| 266 | else | ||
| 267 | count = count + 1 | ||
| 268 | if 0 == v then down = down + 1 else up = up + 1 end | ||
| 269 | end | ||
| 270 | end | ||
| 271 | end | ||
| 272 | end | ||
| 273 | percentUp = string.format('%.2f', up / count * 100) | ||
| 274 | end | ||
| 275 | if APT.checkFile('rrd/' .. k .. '/HTTP/Tests.rrd') then | ||
| 276 | local start, step, names, data = APT.rrd.fetch('rrd/' .. k .. '/HTTP/Tests.rrd', 'LAST', '-a', '-r', '10m', '-s', '-1w') | ||
| 277 | local count, up, down, unknown = 0, 0, 0, 0 | ||
| 278 | for i,dp in ipairs(data) do | ||
| 279 | for j,v in ipairs(dp) do | ||
| 280 | if 'UpdatedErrors' == names[j] then | ||
| 281 | if 'nan' == tostring(v) then | ||
| 282 | unknown = unknown + 1 | ||
| 283 | else | ||
| 284 | count = count + 1 | ||
| 285 | if 0 == v then down = down + 1 else up = up + 1 end | ||
| 286 | end | ||
| 287 | end | ||
| 288 | end | ||
| 289 | end | ||
| 290 | percentUpdated = string.format('%.2f', (down / count * 100)) | ||
| 291 | if '0.00' == percentUp then percentUpdated = '??' end -- We are counting errors, and you can't get an error if you can't check anything. | ||
| 292 | -- TODO - try to account for this better, this is just a quick hack. | ||
| 293 | end | ||
| 294 | week = '<td>' .. percentUp .. '% up</td><td>' .. percentUpdated .. '% updated</td>' | ||
| 295 | end | ||
| 296 | |||
| 297 | web:write("<td>" .. ftp .. " </td><td>" .. http .. " </td><td>" .. https .. " </td><td>" .. rsync .. " </td><td>" .. dns .. | ||
| 298 | " </td><td>" .. protocol .. " </td><td>" .. sanity .. " </td><td>" .. integrity .. " </td><td>" .. updated .. | ||
| 299 | " " .. spd .. " " .. week .." <td>" .. graph .. "</td></tr>\n") | ||
| 300 | if "" ~= active then | ||
| 301 | web:write("<tr><td style='background-color:dimgrey'>" .. active .. "</td></tr>\n") | ||
| 302 | end | ||
| 303 | end | ||
| 304 | web:write( "</table>\n<br>\n") | ||
| 305 | end | ||
| 306 | |||
| 307 | local makeIPlist = function(hosts) | ||
| 308 | local m = {} | ||
| 309 | for k, v in pairs(hosts) do | ||
| 310 | local log = k | ||
| 311 | local n = {} | ||
| 312 | log = logCount(k) | ||
| 313 | hosts[k].Protocols = nil | ||
| 314 | hosts[k].FQDN = nil | ||
| 315 | hosts[k].Active = nil | ||
| 316 | hosts[k].Rate = nil | ||
| 317 | hosts[k].BaseURL = nil | ||
| 318 | hosts[k].Country = nil | ||
| 319 | hosts[k].Bandwidth = nil | ||
| 320 | |||
| 321 | for l, w in pairs(hosts[k].IPs) do | ||
| 322 | if type(w) == "table" then | ||
| 323 | n[l] = {} | ||
| 324 | for i, u in pairs(w) do | ||
| 325 | local log = logCount(k, i) | ||
| 326 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(hosts, k, i)] = u end | ||
| 327 | end | ||
| 328 | else | ||
| 329 | local log = logCount(k, l) | ||
| 330 | if "" == log then n[l] = w else n[log .. " " .. revDNS(hosts, k, l)] = w end | ||
| 331 | end | ||
| 332 | end | ||
| 333 | m[log .. " DNS entries -" .. redirs(hosts, k)] = n | ||
| 334 | end | ||
| 335 | return m | ||
| 336 | end | ||
| 337 | |||
| 338 | |||
| 177 | APT.html = false | 339 | APT.html = false |
| 178 | local email, e = io.open("results/Report-email.txt", "w+") | 340 | local email, e = io.open("results/Report-email.txt", "w+") |
| 179 | if nil == email then C("opening mirrors file - " .. e) else | 341 | if nil == email then C("opening mirrors file - " .. e) else |
| @@ -197,29 +359,14 @@ if nil == email then C("opening mirrors file - " .. e) else | |||
| 197 | local http = status(APT.mirrors, k, results, "http") | 359 | local http = status(APT.mirrors, k, results, "http") |
| 198 | local https = status(APT.mirrors, k, results, "https") | 360 | local https = status(APT.mirrors, k, results, "https") |
| 199 | local rsync = "[skip]" | 361 | local rsync = "[skip]" |
| 200 | local dns = "" | 362 | local dns = DNSrrTest(APT.mirrors, k) |
| 201 | local protocol = status(APT.mirrors, k, results, "Protocol") | 363 | local protocol = status(APT.mirrors, k, results, "Protocol") |
| 202 | local sanity = status(APT.mirrors, k, results, "URLSanity") | 364 | local sanity = status(APT.mirrors, k, results, "URLSanity") |
| 203 | local integrity = status(APT.mirrors, k, results, "Integrity") | 365 | local integrity = status(APT.mirrors, k, results, "Integrity") |
| 204 | local updated = status(APT.mirrors, k, results, "Updated") | 366 | local updated = status(APT.mirrors, k, results, "Updated") |
| 205 | 367 | ||
| 206 | -- DNS-RR test. | 368 | -- DNS-RR test. |
| 207 | if ("deb.devuan.org" ~= k) and (nil ~= APT.mirrors["deb.devuan.org"]) then | 369 | if (APT.options.roundRobin.value ~= k) and (nil ~= APT.mirrors[APT.options.roundRobin.value]) then |
| 208 | APT.allpairs(APT.mirrors[k].IPs, | ||
| 209 | function(i, w, k, v) | ||
| 210 | if nil ~= APT.mirrors["deb.devuan.org"].IPs["deb.roundr.devuan.org"][i] then | ||
| 211 | local log = logCount("deb.devuan.org", i) | ||
| 212 | if "" ~= log then | ||
| 213 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 214 | dns = dns .. logCount("deb.devuan.org", i) | ||
| 215 | else | ||
| 216 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 217 | dns = dns .. i | ||
| 218 | end | ||
| 219 | end | ||
| 220 | end | ||
| 221 | ) | ||
| 222 | if "" == dns then dns = "[no]" end | ||
| 223 | dns = " DNS-RR: " .. dns | 370 | dns = " DNS-RR: " .. dns |
| 224 | end | 371 | end |
| 225 | 372 | ||
| @@ -241,11 +388,6 @@ if nil == email then C("opening mirrors file - " .. e) else | |||
| 241 | email:close() | 388 | email:close() |
| 242 | end | 389 | end |
| 243 | 390 | ||
| 244 | local lnk = function(name, link) | ||
| 245 | if nil == link then link = name end | ||
| 246 | return name .. " <a href='explanations.html#" .. link .. "'>*</a>" | ||
| 247 | end | ||
| 248 | |||
| 249 | 391 | ||
| 250 | local colours = | 392 | local colours = |
| 251 | { | 393 | { |
| @@ -275,17 +417,17 @@ local colours = | |||
| 275 | local g = {} | 417 | local g = {} |
| 276 | local count = 0 | 418 | local count = 0 |
| 277 | for k, v in APT.orderedPairs(mirrors) do | 419 | for k, v in APT.orderedPairs(mirrors) do |
| 278 | if 'pkgmaster.devuan.org' ~= k then count = count + 1 end | 420 | if APT.options.referenceSite.value ~= k then count = count + 1 end |
| 279 | end | 421 | end |
| 280 | for i = 1, count do | 422 | for i = 1, count do |
| 281 | end | 423 | end |
| 282 | 424 | ||
| 283 | count = 1 | 425 | count = 1 |
| 284 | for k, v in APT.orderedPairs(mirrors) do | 426 | for k, v in APT.orderedPairs(mirrors) do |
| 285 | if 'deb.devuan.org' ~= k then | 427 | if APT.options.roundRobin.value ~= k then |
| 286 | local c = colours[count] | 428 | local c = colours[count] |
| 287 | local name = string.format('%32s', k) | 429 | local name = string.format('%32s', k) |
| 288 | if 'pkgmaster.devuan.org' == k then c = 'ffffff' end | 430 | if APT.options.referenceSite.value == k then c = 'ffffff' end |
| 289 | table.insert(g, 'DEF:speedn' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:MIN') | 431 | table.insert(g, 'DEF:speedn' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:MIN') |
| 290 | table.insert(g, 'DEF:speedx' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:MAX') | 432 | table.insert(g, 'DEF:speedx' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:MAX') |
| 291 | table.insert(g, 'DEF:speeda' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:AVERAGE') | 433 | table.insert(g, 'DEF:speeda' .. count .. '=rrd/' .. k .. '/Speed/Speed.rrd:max:AVERAGE') |
| @@ -343,153 +485,23 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 343 | "<p>NOTE: timeouts may be due to a problem on the testing computer.</p>" .. | 485 | "<p>NOTE: timeouts may be due to a problem on the testing computer.</p>" .. |
| 344 | "<p>The DNS round robin (DNS-RR) column shows the IPs for that mirror, or <font color='grey'><b>no</b></font> if it isn't part of the DNS-RR. " .. | 486 | "<p>The DNS round robin (DNS-RR) column shows the IPs for that mirror, or <font color='grey'><b>no</b></font> if it isn't part of the DNS-RR. " .. |
| 345 | "The IPs link to the testing log for that IP accessed via the DNS-RR. " .. | 487 | "The IPs link to the testing log for that IP accessed via the DNS-RR. " .. |
| 346 | "deb.devuan.org is the DNS-RR itself, so it doesn't get tested directly.</p>\n" .. | 488 | APT.options.roundRobin.value .. " is the DNS-RR itself, so it doesn't get tested directly.</p>\n" .. |
| 347 | "<p>The time in the Updated column is how often the mirror updates itself.</p>" .. | 489 | "<p>The time in the Updated column is how often the mirror updates itself.</p>" .. |
| 348 | "<p>Mirrors with a <font style='background-color:dimgrey'>grey background</font> are not active (though may be usable as part of the DNS-RR).</p>\n" .. | 490 | "<p>Mirrors with a <font style='background-color:dimgrey'>grey background</font> are not active (though may be usable as part of the DNS-RR).</p>\n" .. |
| 349 | "<p><font color='grey'><b>skip</b></font> means that the test hasn't been written yet.</p>\n" .. | 491 | "<p><font color='grey'><b>skip</b></font> means that the test hasn't been written yet.</p>\n" |
| 350 | "<table>\n<tr><th></th><th>" .. lnk('FTP') .. "</th><th>" .. lnk('HTTP') .. "</th><th>" .. lnk('HTTPS') .. "</th><th>" .. lnk('RSYNC') .. "</th>" .. | ||
| 351 | "<th>" .. lnk('DNS round robin', 'DNS-RR') .. "</th><th>" .. lnk('Protocol') .. "</th><th>" .. lnk('URL sanity', 'URL-Sanity') .. "</th><th>" .. lnk('Integrity') .. "</th>" .. | ||
| 352 | "<th>" .. lnk('Updated') .. "</th><th colspan='2'>" .. lnk('Speed range', 'Speed') .. "</th>" .. | ||
| 353 | "<th colspan='2'>" .. lnk('Weekly statistics', 'Weekly') .. "</th><th>" .. lnk('Graphs') .. "</th></tr>\n" | ||
| 354 | ) | 492 | ) |
| 355 | 493 | ||
| 356 | local bg = '' | 494 | makeTable(web, APT.mirrors) |
| 357 | for k, v in APT.orderedPairs(APT.mirrors) do | 495 | web:write( "<h2>==== faulty mirrors: ====</h2>\n" .. faulty) |
| 358 | local results = APT.collateAll(APT.mirrors, 'results', k) | ||
| 359 | if '' == bg then bg = " style='background-color:#111111'" else bg = '' end | ||
| 360 | local active = "" | ||
| 361 | if "yes" == v.Active then | ||
| 362 | web:write(" <tr" .. bg .. "><th>" .. k .. "</th> ") | ||
| 363 | else | ||
| 364 | if nil == v.Active then active = 'nil' else active = v.Active end | ||
| 365 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") | ||
| 366 | end | ||
| 367 | local ftp = "<font color='grey'><b>skip</b></font>" | ||
| 368 | local http = status(APT.mirrors, k, results, "http") | ||
| 369 | local https = status(APT.mirrors, k, results, "https") | ||
| 370 | local rsync = "<font color='grey'><b>skip</b></font>" | ||
| 371 | local dns = "" | ||
| 372 | local protocol = status(APT.mirrors, k, results, "Protocol") | ||
| 373 | local sanity = status(APT.mirrors, k, results, "URLSanity") | ||
| 374 | local integrity = status(APT.mirrors, k, results, "Integrity") | ||
| 375 | local updated = status(APT.mirrors, k, results, "Updated") | ||
| 376 | local rate = v.Rate | ||
| 377 | if nil ~= rate then updated = updated .. ' ' .. rate end | ||
| 378 | local min = tonumber(results.speed.min) | ||
| 379 | local max = tonumber(results.speed.max) | ||
| 380 | local spd = '<td></td><td></td>' | ||
| 381 | local week = '<td></td><td></td>' | ||
| 382 | local graph = '<a href="../apt-panopticon_cgp/host.php?h=' .. k .. '">graphs</a>' | ||
| 383 | |||
| 384 | -- DNS-RR test. | ||
| 385 | if ("deb.devuan.org" ~= k) and (nil ~= APT.mirrors["deb.devuan.org"]) then | ||
| 386 | APT.allpairs(APT.mirrors[k].IPs, | ||
| 387 | function(i, w, k, v) | ||
| 388 | if nil ~= APT.mirrors["deb.devuan.org"].IPs["deb.roundr.devuan.org"][i] then | ||
| 389 | local log = logCount("deb.devuan.org", i) | ||
| 390 | if "" ~= log then | ||
| 391 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 392 | dns = dns .. logCount("deb.devuan.org", i) | ||
| 393 | else | ||
| 394 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 395 | dns = dns .. "<font color='maroon'><b>" .. i .. "</b></font>" | ||
| 396 | end | ||
| 397 | end | ||
| 398 | end | ||
| 399 | ) | ||
| 400 | if "" == dns then dns = "<font color='grey'><b>no</b></font>" end | ||
| 401 | |||
| 402 | if 0 == max then | ||
| 403 | spd = '<td></td><td></td>' | ||
| 404 | else | ||
| 405 | spd = string.format('<td align="right">%d -</td><td align="right">%d</td>', min, max) | ||
| 406 | end | ||
| 407 | end | ||
| 408 | |||
| 409 | if ("deb.devuan.org" ~= k) then | ||
| 410 | local percentUp = '???' | ||
| 411 | local percentUpdated = '???' | ||
| 412 | if APT.checkFile('rrd/' .. k .. '/Speed/Speed.rrd') then | ||
| 413 | local start, step, names, data = APT.rrd.fetch('rrd/' .. k .. '/Speed/Speed.rrd', 'LAST', '-a', '-r', '10m', '-s', '-1w') | ||
| 414 | local count, up, down, unknown = 0, 0, 0, 0 | ||
| 415 | for i, dp in ipairs(data) do | ||
| 416 | for j,v in ipairs(dp) do | ||
| 417 | if 'max' == names[j] then | ||
| 418 | if 'nan' == tostring(v) then | ||
| 419 | unknown = unknown + 1 | ||
| 420 | else | ||
| 421 | count = count + 1 | ||
| 422 | if 0 == v then down = down + 1 else up = up + 1 end | ||
| 423 | end | ||
| 424 | end | ||
| 425 | end | ||
| 426 | end | ||
| 427 | percentUp = string.format('%.2f', up / count * 100) | ||
| 428 | end | ||
| 429 | if APT.checkFile('rrd/' .. k .. '/HTTP/Tests.rrd') then | ||
| 430 | local start, step, names, data = APT.rrd.fetch('rrd/' .. k .. '/HTTP/Tests.rrd', 'LAST', '-a', '-r', '10m', '-s', '-1w') | ||
| 431 | local count, up, down, unknown = 0, 0, 0, 0 | ||
| 432 | for i,dp in ipairs(data) do | ||
| 433 | for j,v in ipairs(dp) do | ||
| 434 | if 'UpdatedErrors' == names[j] then | ||
| 435 | if 'nan' == tostring(v) then | ||
| 436 | unknown = unknown + 1 | ||
| 437 | else | ||
| 438 | count = count + 1 | ||
| 439 | if 0 == v then down = down + 1 else up = up + 1 end | ||
| 440 | end | ||
| 441 | end | ||
| 442 | end | ||
| 443 | end | ||
| 444 | percentUpdated = string.format('%.2f', (down / count * 100)) | ||
| 445 | if '0.00' == percentUp then percentUpdated = '??' end -- We are counting errors, and you can't get an error if you can't check anything. | ||
| 446 | -- TODO - try to account for this better, this is just a quick hack. | ||
| 447 | end | ||
| 448 | week = '<td>' .. percentUp .. '% up</td><td>' .. percentUpdated .. '% updated</td>' | ||
| 449 | end | ||
| 450 | |||
| 451 | web:write("<td>" .. ftp .. " </td><td>" .. http .. " </td><td>" .. https .. " </td><td>" .. rsync .. " </td><td>" .. dns .. | ||
| 452 | " </td><td>" .. protocol .. " </td><td>" .. sanity .. " </td><td>" .. integrity .. " </td><td>" .. updated .. | ||
| 453 | " " .. spd .. " " .. week .." <td>" .. graph .. "</td></tr>\n") | ||
| 454 | if "" ~= active then | ||
| 455 | web:write("<tr><td style='background-color:dimgrey'>" .. active .. "</td></tr>\n") | ||
| 456 | end | ||
| 457 | end | ||
| 458 | web:write( "</table>\n<br>\n<h2>==== faulty mirrors: ====</h2>\n" .. faulty) | ||
| 459 | web:write( "<br>\n<br>\n<h2>==== DNS and logs: ====</h2>\n") | 496 | web:write( "<br>\n<br>\n<h2>==== DNS and logs: ====</h2>\n") |
| 460 | 497 | ||
| 461 | for k, v in pairs(APT.mirrors) do | 498 | m = makeIPlist(APT.mirrors) |
| 462 | local log = k | ||
| 463 | local n = {} | ||
| 464 | log = logCount(k) | ||
| 465 | APT.mirrors[k].Protocols = nil | ||
| 466 | APT.mirrors[k].FQDN = nil | ||
| 467 | APT.mirrors[k].Active = nil | ||
| 468 | APT.mirrors[k].Rate = nil | ||
| 469 | APT.mirrors[k].BaseURL = nil | ||
| 470 | APT.mirrors[k].Country = nil | ||
| 471 | APT.mirrors[k].Bandwidth = nil | ||
| 472 | |||
| 473 | for l, w in pairs(APT.mirrors[k].IPs) do | ||
| 474 | if type(w) == "table" then | ||
| 475 | n[l] = {} | ||
| 476 | for i, u in pairs(w) do | ||
| 477 | local log = logCount(k, i) | ||
| 478 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(APT.mirrors, k, i)] = u end | ||
| 479 | end | ||
| 480 | else | ||
| 481 | local log = logCount(k, l) | ||
| 482 | if "" == log then n[l] = w else n[log .. " " .. revDNS(APT.mirrors, k, l)] = w end | ||
| 483 | end | ||
| 484 | end | ||
| 485 | m[log .. " DNS entries -" .. redirs(APT.mirrors, k)] = n | ||
| 486 | end | ||
| 487 | web:write( "<p>This lists each mirror, and the DNS entries for that mirror. " .. | 499 | web:write( "<p>This lists each mirror, and the DNS entries for that mirror. " .. |
| 488 | "The links point to the testing log files for " .. logCount("apt-panopticon") .. " for each domain name / IP combination that was tested. " .. | 500 | "The links point to the testing log files for " .. logCount("apt-panopticon") .. " for each domain name / IP combination that was tested. " .. |
| 489 | "If a mirror has a CNAME, that CNAME is listed along with that CNAMEs DNS entries. " .. | 501 | "If a mirror has a CNAME, that CNAME is listed along with that CNAMEs DNS entries. " .. |
| 490 | "deb.devuan.org is the DNS round robin, which points to the mirrors that are part of the DNS-RR. " .. | 502 | APT.options.roundRobin.value .. " is the DNS round robin, which points to the mirrors that are part of the DNS-RR. " .. |
| 491 | "If an IP is part of the DNS-RR, it is marked with '<font color='purple'><b>DNS-RR</b></font>' " .. | 503 | "If an IP is part of the DNS-RR, it is marked with '<font color='purple'><b>DNS-RR</b></font>' " .. |
| 492 | "pkgmaster.devuan.org is the master mirror, all the others sync to it. " .. | 504 | APT.options.referenceSite.value .. " is the master mirror, all the others sync to it. " .. |
| 493 | "</p>\n" | 505 | "</p>\n" |
| 494 | ) | 506 | ) |
| 495 | web:write(APT.dumpTableHTML(m, "")) | 507 | web:write(APT.dumpTableHTML(m, "")) |
| @@ -499,106 +511,16 @@ if nil == web then C("opening mirrors file - " .. e) else | |||
| 499 | results = {} | 511 | results = {} |
| 500 | m = {} | 512 | m = {} |
| 501 | faulty = "" | 513 | faulty = "" |
| 502 | bg = '' | ||
| 503 | web:write( "<hr>\n<h2>==== Debian mirror status ====</h2>\n" .. | 514 | web:write( "<hr>\n<h2>==== Debian mirror status ====</h2>\n" .. |
| 504 | "<p>NOTE - This is not fully probing the Debian mirrors, we just collect some data from any redirects to other servers. " .. | 515 | "<p>NOTE - This is not fully probing the Debian mirrors, we just collect some data from any redirects to other servers. " .. |
| 505 | "So this isn't a full set of tests.   Basically we don't know the shape of the Debian mirror infrastructure.</p>\n" .. | 516 | "So this isn't a full set of tests.   Basically we don't know the shape of the Debian mirror infrastructure.</p>\n" .. |
| 506 | "<p><font style='background-color:red; color:black'>EXPERIMENTAL CODE - this is even more experimental than the rest.</font></p>\n" .. | 517 | "<p><font style='background-color:red; color:black'>EXPERIMENTAL CODE - this is even more experimental than the rest.</font></p>\n" |
| 507 | |||
| 508 | "<table>\n<tr><th></th><th>" .. lnk('FTP') .. "</a></th><th>" .. lnk('HTTP') .. "</th><th>" .. lnk('HTTPS') .. "</th><th>" .. lnk('RSYNC') .. "</th>" .. | ||
| 509 | "<th>" .. lnk('DNS round robin', 'DNS-RR') .. "</th><th>" .. lnk('Protocol') .. "</th><th>" .. lnk('URL sanity', 'URL-Sanity') .. "</th><th>" .. lnk('Integrity') .. "</th>" .. | ||
| 510 | "<th>" .. lnk('Updated') .. "</th><th colspan='2'>" .. lnk('Speed range', 'Speed') .. "</th>" .. | ||
| 511 | "<th colspan='2'>" .. lnk('Weekly statistics', 'Weekly') .. "</th><th>" .. lnk('Graphs') .. "</th></tr>\n" | ||
| 512 | ) | 518 | ) |
| 513 | for k, v in APT.orderedPairs(APT.debians) do | ||
| 514 | if '' == bg then bg = " style='background-color:#111111'" else bg = '' end | ||
| 515 | local results = APT.collateAll(APT.debians, 'results', k) | ||
| 516 | local active = "" | ||
| 517 | if "yes" == v.Active then | ||
| 518 | web:write(" <tr " .. bg .. "><th>" .. k .. "</th> ") | ||
| 519 | else | ||
| 520 | if nil == v.Active then active = 'nil' else active = v.Active end | ||
| 521 | web:write(" <tr style='background-color:dimgrey'><th>" .. k .. "</th> ") | ||
| 522 | end | ||
| 523 | local ftp = "<font color='grey'><b>skip</b></font>" | ||
| 524 | local http = status(APT.debians, k, results, "http") | ||
| 525 | local https = status(APT.debians, k, results, "https") | ||
| 526 | local rsync = "<font color='grey'><b>skip</b></font>" | ||
| 527 | local dns = "" | ||
| 528 | local protocol = status(APT.debians, k, results, "Protocol") | ||
| 529 | local sanity = status(APT.debians, k, results, "URLSanity") | ||
| 530 | local integrity = status(APT.debians, k, results, "Integrity") | ||
| 531 | local updated = status(APT.debians, k, results, "Updated") | ||
| 532 | local rate = v.Rate | ||
| 533 | if nil ~= rate then updated = updated .. ' ' .. rate end | ||
| 534 | local min = tonumber(results.speed.min) | ||
| 535 | local max = tonumber(results.speed.max) | ||
| 536 | local spd = '<td></td><td></td>' | ||
| 537 | local week = '<td>??% up</td><td>??% updated</td>' | ||
| 538 | local graph = '<a href="../apt-panopticon_cgp/host.php?h=' .. k .. '">graphs</a>' | ||
| 539 | |||
| 540 | -- DNS-RR test. | ||
| 541 | if ("deb.devuan.org" ~= k) and (nil ~= APT.debians["deb.devuan.org"]) then | ||
| 542 | APT.allpairs(APT.debians[k].IPs, | ||
| 543 | function(i, w, k, v) | ||
| 544 | if nil ~= APT.mirrors["deb.devuan.org"].IPs["deb.roundr.devuan.org"][i] then | ||
| 545 | local log = logCount("deb.devuan.org", i) | ||
| 546 | if "" ~= log then | ||
| 547 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 548 | dns = dns .. logCount("deb.devuan.org", i) | ||
| 549 | else | ||
| 550 | if "" == dns then dns = " " else dns = dns .. " " end | ||
| 551 | dns = dns .. "<font color='maroon'><b>" .. i .. "</b></font>" | ||
| 552 | end | ||
| 553 | end | ||
| 554 | end | ||
| 555 | ) | ||
| 556 | if "" == dns then dns = "<font color='grey'><b>no</b></font>" end | ||
| 557 | |||
| 558 | if 0 == max then | ||
| 559 | spd = '<td></td><td></td>' | ||
| 560 | else | ||
| 561 | spd = string.format('<td align="right">%d -</td><td align="right">%d</td>', min, max) | ||
| 562 | end | ||
| 563 | end | ||
| 564 | |||
| 565 | web:write("<td>" .. ftp .. " </td><td>" .. http .. " </td><td>" .. https .. " </td><td>" .. rsync .. " </td><td>" .. dns .. | ||
| 566 | " </td><td>" .. protocol .. " </td><td>" .. sanity .. " </td><td>" .. integrity .. " </td><td>" .. updated .. | ||
| 567 | " </td>" .. spd .. " " .. week .." <td>" .. graph .. "</td></tr>\n") | ||
| 568 | if "" ~= active then | ||
| 569 | web:write("<tr><td style='background-color:dimgrey'>" .. active .. "</td></tr>\n") | ||
| 570 | end | ||
| 571 | end | ||
| 572 | web:write( "</table>\n<br>\n\n") | ||
| 573 | 519 | ||
| 520 | makeTable(web, APT.debians) | ||
| 574 | web:write( "<br>\n<br>\n<h2>==== Debian DNS and logs: ====</h2>\n") | 521 | web:write( "<br>\n<br>\n<h2>==== Debian DNS and logs: ====</h2>\n") |
| 575 | 522 | ||
| 576 | for k, v in pairs(APT.debians) do | 523 | m = makeIPlist(APT.debians) |
| 577 | local log = k | ||
| 578 | local n = {} | ||
| 579 | log = logCount(k) | ||
| 580 | APT.debians[k].Protocols = nil | ||
| 581 | APT.debians[k].FQDN = nil | ||
| 582 | APT.debians[k].Active = nil | ||
| 583 | APT.debians[k].Rate = nil | ||
| 584 | APT.debians[k].BaseURL = nil | ||
| 585 | APT.debians[k].Country = nil | ||
| 586 | APT.debians[k].Bandwidth = nil | ||
| 587 | for l, w in pairs(APT.debians[k].IPs) do | ||
| 588 | if type(w) == "table" then | ||
| 589 | n[l] = {} | ||
| 590 | for i, u in pairs(w) do | ||
| 591 | local log = logCount(k, i) | ||
| 592 | if "" == log then n[l][i] = u else n[l][log .. " " .. revDNS(APT.debians, k, i)] = u end | ||
| 593 | end | ||
| 594 | else | ||
| 595 | local log = logCount(k, l) | ||
| 596 | if "" == log then n[l] = w else n[log .. " " .. revDNS(APT.debians, k, l)] = w end | ||
| 597 | end | ||
| 598 | end | ||
| 599 | |||
| 600 | m[log .. " DNS entries -" .. redirs(APT.mirrors, k)] = n | ||
| 601 | end | ||
| 602 | web:write(APT.dumpTableHTML(m, "")) | 524 | web:write(APT.dumpTableHTML(m, "")) |
| 603 | 525 | ||
| 604 | web:write( "<hr>\n<hr>\n<p>The <a href='Report-email.txt'>email report</a>. " .. | 526 | web:write( "<hr>\n<hr>\n<p>The <a href='Report-email.txt'>email report</a>. " .. |
