diff options
Diffstat (limited to 'apt-panopticommon.lua')
| -rw-r--r-- | apt-panopticommon.lua | 105 |
1 files changed, 88 insertions, 17 deletions
diff --git a/apt-panopticommon.lua b/apt-panopticommon.lua index 0862b77..22d294a 100644 --- a/apt-panopticommon.lua +++ b/apt-panopticommon.lua | |||
| @@ -3,14 +3,19 @@ local APT = {} | |||
| 3 | -- https://oss.oetiker.ch/rrdtool/prog/rrdlua.en.html | 3 | -- https://oss.oetiker.ch/rrdtool/prog/rrdlua.en.html |
| 4 | APT.rrd = require 'rrd' | 4 | APT.rrd = require 'rrd' |
| 5 | 5 | ||
| 6 | APT.version = '0.3 alpha' | ||
| 7 | |||
| 6 | APT.protocols = {"ftp", "http", "https", "rsync"} | 8 | APT.protocols = {"ftp", "http", "https", "rsync"} |
| 7 | APT.tests = {'raw', 'Integrity', 'Protocol', 'Redirects', 'Updated', 'URLSanity', 'Speed'} | 9 | APT.tests = {'raw', 'Integrity', 'Protocol', 'Redirects', 'Updated', 'URLSanity', 'Speed'} |
| 8 | APT.releases = {"ascii", "beowulf", "chimaera", "ceres"} | 10 | --APT.releases = {"jessie", "ascii", "beowulf", "chimaera", "daedalus", "ceres"} |
| 11 | APT.releases = {"chimaera", "daedalus", "excalibur", "freia", "ceres"} | ||
| 9 | APT.subRels = {'backports', 'proposed-updates', 'security', 'updates'} | 12 | APT.subRels = {'backports', 'proposed-updates', 'security', 'updates'} |
| 10 | APT.notExist = | 13 | APT.notExist = |
| 11 | { | 14 | { |
| 12 | 'chimaera-backports', | 15 | 'chimaera-backports', |
| 13 | 'chimaera-security', | 16 | 'freia-backports', |
| 17 | 'freia-security', | ||
| 18 | 'freia-updates', | ||
| 14 | 'ceres-backports', -- These will never exist, it's our code name for the testing suite. | 19 | 'ceres-backports', -- These will never exist, it's our code name for the testing suite. |
| 15 | 'ceres-proposed-updates', | 20 | 'ceres-proposed-updates', |
| 16 | 'ceres-updates', | 21 | 'ceres-updates', |
| @@ -50,6 +55,12 @@ APT.options = | |||
| 50 | help = "The round robin DNS name.", | 55 | help = "The round robin DNS name.", |
| 51 | value = "deb.devuan.org", | 56 | value = "deb.devuan.org", |
| 52 | }, | 57 | }, |
| 58 | roundRobinCname = | ||
| 59 | { | ||
| 60 | typ = "string", | ||
| 61 | help = "The round robin DNS name.", | ||
| 62 | value = "deb.rr.devuan.org", | ||
| 63 | }, | ||
| 53 | tests = | 64 | tests = |
| 54 | { | 65 | { |
| 55 | typ = "table", | 66 | typ = "table", |
| @@ -74,13 +85,13 @@ APT.options = | |||
| 74 | { | 85 | { |
| 75 | typ = "number", | 86 | typ = "number", |
| 76 | help = "", | 87 | help = "", |
| 77 | value = 240, | 88 | value = 180, |
| 78 | }, | 89 | }, |
| 79 | timeout = | 90 | timeout = |
| 80 | { | 91 | { |
| 81 | typ = "number", | 92 | typ = "number", |
| 82 | help = "", | 93 | help = "", |
| 83 | value = 5, | 94 | value = 42, |
| 84 | }, | 95 | }, |
| 85 | timeouts = | 96 | timeouts = |
| 86 | { | 97 | { |
| @@ -125,7 +136,7 @@ APT.parseArgs = function(args) | |||
| 125 | local arg = {} | 136 | local arg = {} |
| 126 | local sendArgs = "" | 137 | local sendArgs = "" |
| 127 | -- A special test to disable IPv6 tests if IPv6 isn't available. | 138 | -- A special test to disable IPv6 tests if IPv6 isn't available. |
| 128 | if 1 == APT.exe('ip -6 addr | grep inet6 | grep " global"'):Do().status then | 139 | if 1 == APT.exe('ip -6 addr | grep inet6 | grep " global"'):timeout():Do().status then |
| 129 | table.insert(args, '--tests=-IPv6') | 140 | table.insert(args, '--tests=-IPv6') |
| 130 | end | 141 | end |
| 131 | if 0 ~= #(args) then | 142 | if 0 ~= #(args) then |
| @@ -139,7 +150,7 @@ APT.parseArgs = function(args) | |||
| 139 | end | 150 | end |
| 140 | os.exit() | 151 | os.exit() |
| 141 | elseif "--version" == a then | 152 | elseif "--version" == a then |
| 142 | print("apt-panopticon version 0.2 alpha") | 153 | print("apt-panopticon version " .. APT.version) |
| 143 | os.exit() | 154 | os.exit() |
| 144 | elseif "-v" == a then | 155 | elseif "-v" == a then |
| 145 | APT.verbosity = APT.verbosity + 1 | 156 | APT.verbosity = APT.verbosity + 1 |
| @@ -398,7 +409,7 @@ APT.logOpen = function(host, a2, a3) | |||
| 398 | local name = APT.logName(host, a2, a3)[1] | 409 | local name = APT.logName(host, a2, a3)[1] |
| 399 | if APT.checkFile(name) then return false end | 410 | if APT.checkFile(name) then return false end |
| 400 | APT.logFile, e = io.open(name, "a+") | 411 | APT.logFile, e = io.open(name, "a+") |
| 401 | if nil == APT.logFile then C('opening log file (' .. name .. ') - ' .. e); return false end | 412 | if nil == APT.logFile then print('CRITICAL - opening log file (' .. name .. ') - ' .. e); return false end |
| 402 | if nil ~= APT.logFile then | 413 | if nil ~= APT.logFile then |
| 403 | APT.logFile:write("<html><head>\n") | 414 | APT.logFile:write("<html><head>\n") |
| 404 | APT.logFile:write("</head><body bgcolor='black' text='white' alink='red' link='aqua' vlink='fuchsia'>\n") | 415 | APT.logFile:write("</head><body bgcolor='black' text='white' alink='red' link='aqua' vlink='fuchsia'>\n") |
| @@ -415,6 +426,7 @@ APT.logPost = function() | |||
| 415 | if nil ~= APT.logFile then | 426 | if nil ~= APT.logFile then |
| 416 | APT.logFile:write("</body></html> \n") | 427 | APT.logFile:write("</body></html> \n") |
| 417 | APT.logFile:close() | 428 | APT.logFile:close() |
| 429 | APT.logFile = nil | ||
| 418 | end | 430 | end |
| 419 | end | 431 | end |
| 420 | 432 | ||
| @@ -455,7 +467,7 @@ local log = function(v, t, s, prot, test, host) | |||
| 455 | if nil ~= APT.logFile then | 467 | if nil ~= APT.logFile then |
| 456 | if APT.html then | 468 | if APT.html then |
| 457 | local colour = "white" | 469 | local colour = "white" |
| 458 | if -1 == v then colour = "fuchsia" end -- CRITICAL | 470 | if -1 == v then colour = "fuchsia"; print(t .. " " .. s) end -- CRITICAL |
| 459 | if 0 == v then colour = "red " end -- ERROR | 471 | if 0 == v then colour = "red " end -- ERROR |
| 460 | if 1 == v then colour = "yellow " end -- WARNING | 472 | if 1 == v then colour = "yellow " end -- WARNING |
| 461 | if 2 == v then colour = "blue " end -- TIMEOUT | 473 | if 2 == v then colour = "blue " end -- TIMEOUT |
| @@ -482,6 +494,19 @@ local E = APT.E | |||
| 482 | local C = APT.C | 494 | local C = APT.C |
| 483 | 495 | ||
| 484 | 496 | ||
| 497 | APT.readCmd = function(cmd) | ||
| 498 | local result = {} | ||
| 499 | local output = io.popen(cmd) | ||
| 500 | if nil ~= output then | ||
| 501 | for l in output:lines() do | ||
| 502 | table.insert(result, l) | ||
| 503 | end | ||
| 504 | end | ||
| 505 | -- While this does return the same things as os.execute(), it's just as useless. | ||
| 506 | output:close() | ||
| 507 | return result | ||
| 508 | end | ||
| 509 | |||
| 485 | APT.debians = {} | 510 | APT.debians = {} |
| 486 | APT.mirrors = {} | 511 | APT.mirrors = {} |
| 487 | 512 | ||
| @@ -508,7 +533,7 @@ APT.tested = function(prot, test, host) | |||
| 508 | end | 533 | end |
| 509 | 534 | ||
| 510 | APT.exe = function(c) | 535 | APT.exe = function(c) |
| 511 | local exe = {status = 0, result = '', log = true, cmd = c .. ' '} | 536 | local exe = {status = 0, result = '', log = true, cmd = c .. ' ', command = c} |
| 512 | 537 | ||
| 513 | function exe:log() | 538 | function exe:log() |
| 514 | self.log = true | 539 | self.log = true |
| @@ -522,6 +547,16 @@ APT.exe = function(c) | |||
| 522 | end | 547 | end |
| 523 | return self | 548 | return self |
| 524 | end | 549 | end |
| 550 | function exe:timeout(c) | ||
| 551 | -- timeout returns a status of - command status if --preserve-status; "128+9" (actually 137) if --kill-after ends up being done; 124 if it had to TERM; command status if all went well. | ||
| 552 | -- --kill-after means "send KILL after TERM fails. | ||
| 553 | if nil == c then | ||
| 554 | self.cmd = 'timeout --kill-after=10.0s --foreground 42.0s ' .. self.cmd | ||
| 555 | else | ||
| 556 | self.cmd = 'timeout --kill-after=10.0s --foreground ' .. c .. ' ' .. self.cmd | ||
| 557 | end | ||
| 558 | return self | ||
| 559 | end | ||
| 525 | function exe:also(c) | 560 | function exe:also(c) |
| 526 | if nil == c then c = '' else c = ' ' .. c end | 561 | if nil == c then c = '' else c = ' ' .. c end |
| 527 | self.cmd = self.cmd .. ';' .. c .. ' ' | 562 | self.cmd = self.cmd .. ';' .. c .. ' ' |
| @@ -558,17 +593,51 @@ APT.exe = function(c) | |||
| 558 | I'm getting 7168 or 0. No idea what the fuck that is. | 593 | I'm getting 7168 or 0. No idea what the fuck that is. |
| 559 | local ok, rslt, status = os.execute(s) | 594 | local ok, rslt, status = os.execute(s) |
| 560 | ]] | 595 | ]] |
| 561 | local f = io.popen(self.cmd .. ' ; echo "$?"', 'r') | 596 | |
| 562 | -- The last line will be the command's returned status, collect everything else in result. | 597 | local f = APT.readCmd(self.cmd, 'r') |
| 598 | -- The last line will be the command's returned status, collect everything else in result. | ||
| 563 | self.status = '' -- Otherwise the result starts with 0. | 599 | self.status = '' -- Otherwise the result starts with 0. |
| 564 | for l in f:lines() do | 600 | self.result = '\n' |
| 565 | self.result = self.result .. self.status .. "\n" | 601 | for i,l in ipairs(f) do |
| 566 | self.status = l | 602 | self.result = self.result .. l .. "\n" |
| 603 | end | ||
| 604 | f = APT.readCmd('echo "$?"', 'r') | ||
| 605 | for i,l in ipairs(f) do | ||
| 606 | self.status = tonumber(l) | ||
| 607 | if (137 == self.status) or (124 == self.status) then | ||
| 608 | print("timeout killed " .. self.status .. ' ' .. self.command) | ||
| 609 | E("timeout killed " .. self.status .. ' ' .. self.command) | ||
| 610 | elseif (0 ~= self.status) then | ||
| 611 | print("status |" .. self.status .. '| ' .. self.command) | ||
| 612 | E("status |" .. self.status .. '| ' .. self.command) | ||
| 613 | end | ||
| 614 | end | ||
| 615 | |||
| 616 | --[[ While this is more reliable, it breaks stuff that's likely making assumptions that match the old way. | ||
| 617 | TODO - fix it later. | ||
| 618 | local f = APT.readCmd(self.cmd .. '; echo "$?"', 'r') | ||
| 619 | -- The last line will be the command's returned status, collect everything else in result. | ||
| 620 | self.status = tonumber(f[#f]) | ||
| 621 | f[#f] = nil | ||
| 622 | self.result = '\n' | ||
| 623 | for i,l in ipairs(f) do | ||
| 624 | self.result = self.result .. l .. "\n" | ||
| 625 | end | ||
| 626 | if (137 == self.status) or (124 == self.status) then | ||
| 627 | print("timeout killed " .. self.status .. ' ' .. self.command) | ||
| 628 | print('ERROR ' .. "timeout killed " .. self.status .. ' ' .. self.command) | ||
| 629 | elseif (nil == self.status) then | ||
| 630 | print("status |" .. "NIL" .. '| ' .. self.command) | ||
| 631 | E("status |" .. "NIL" .. '| ' .. self.command) | ||
| 632 | elseif (0 ~= self.status) then | ||
| 633 | -- print("status |" .. self.status .. '| ' .. self.command) | ||
| 634 | E("status |" .. self.status .. '| ' .. self.command) | ||
| 567 | end | 635 | end |
| 568 | self.status = tonumber(self.status) | 636 | ]] |
| 569 | return self | 637 | return self |
| 570 | end | 638 | end |
| 571 | function exe:fork() | 639 | function exe:fork(host) |
| 640 | if nil ~= host then self.cmd = self.cmd .. '; r=$?; if [ $r -ge 124 ]; then echo "$r ' .. host .. ' failed forked command ' .. string.gsub(self.cmd, '"', "'") .. '"; fi' end | ||
| 572 | self.cmd = '{ ' .. self.cmd .. '; } &' | 641 | self.cmd = '{ ' .. self.cmd .. '; } &' |
| 573 | if true == self.log then D(" forking - <code>" .. self.cmd .. "</code>") end | 642 | if true == self.log then D(" forking - <code>" .. self.cmd .. "</code>") end |
| 574 | os.execute(self.cmd) | 643 | os.execute(self.cmd) |
| @@ -578,7 +647,9 @@ APT.exe = function(c) | |||
| 578 | end | 647 | end |
| 579 | 648 | ||
| 580 | APT.checkExes = function (exe) | 649 | APT.checkExes = function (exe) |
| 581 | local count = io.popen('ps x | grep "' .. exe .. '" | grep -v " grep " | grep -v "flock -n apt-panopticon.lock " | wc -l'):read("*l") | 650 | local count = 0 |
| 651 | local ps = io.popen('ps x | grep "' .. exe .. '" | grep -v " grep " | grep -v "flock -n apt-panopticon.lock " | wc -l') | ||
| 652 | if nil ~= ps then count = ps:read("*l") end | ||
| 582 | D(count .. " " .. exe .. " commands still running.") | 653 | D(count .. " " .. exe .. " commands still running.") |
| 583 | return tonumber(count) | 654 | return tonumber(count) |
| 584 | end | 655 | end |
