aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/apt-panopticommon.lua
diff options
context:
space:
mode:
Diffstat (limited to 'apt-panopticommon.lua')
-rw-r--r--apt-panopticommon.lua105
1 files changed, 88 insertions, 17 deletions
diff --git a/apt-panopticommon.lua b/apt-panopticommon.lua
index 0862b77..1507ae9 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
4APT.rrd = require 'rrd' 4APT.rrd = require 'rrd'
5 5
6APT.version = '0.3 alpha'
7
6APT.protocols = {"ftp", "http", "https", "rsync"} 8APT.protocols = {"ftp", "http", "https", "rsync"}
7APT.tests = {'raw', 'Integrity', 'Protocol', 'Redirects', 'Updated', 'URLSanity', 'Speed'} 9APT.tests = {'raw', 'Integrity', 'Protocol', 'Redirects', 'Updated', 'URLSanity', 'Speed'}
8APT.releases = {"ascii", "beowulf", "chimaera", "ceres"} 10--APT.releases = {"jessie", "ascii", "beowulf", "chimaera", "daedalus", "ceres"}
11APT.releases = {"chimaera", "daedalus", "excalibur", "freia", "ceres"}
9APT.subRels = {'backports', 'proposed-updates', 'security', 'updates'} 12APT.subRels = {'backports', 'proposed-updates', 'security', 'updates'}
10APT.notExist = 13APT.notExist =
11{ 14{
12 'chimaera-backports', 15 'chimaera-backports',
13 'chimaera-security', 16-- 'excalibur-backports',
17-- 'excalibur-security',
18-- 'excalibur-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
419end 431end
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
482local C = APT.C 494local C = APT.C
483 495
484 496
497APT.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
508end
509
485APT.debians = {} 510APT.debians = {}
486APT.mirrors = {} 511APT.mirrors = {}
487 512
@@ -508,7 +533,7 @@ APT.tested = function(prot, test, host)
508end 533end
509 534
510APT.exe = function(c) 535APT.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.
617TODO - 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 - &nbsp; <code>" .. self.cmd .. "</code>") end 642 if true == self.log then D(" forking - &nbsp; <code>" .. self.cmd .. "</code>") end
574 os.execute(self.cmd) 643 os.execute(self.cmd)
@@ -578,7 +647,9 @@ APT.exe = function(c)
578end 647end
579 648
580APT.checkExes = function (exe) 649APT.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)
584end 655end