diff --git a/ChangeLog b/ChangeLog index 489d1cf40e73c71c6390618aef8fa9eb3a6421c6..9ede1027474d87ac7881430726b7ed3d01c64ce1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,55 @@ 2007-06-14 Per Cederqvist <ceder@shafan.lysator.liu.se> + New options --continue and --only-clone. Better remote watching + of the status. + + * backup-one-task: Handle --only-clone. Adjusted to the new CLI + of lysrdiff-set-status. + + * lysrdiff-set-status.py (open_socket): New function. + (sendmsg): Use it to simplify code. + (completion): New function. + (Top level): New mandatory first argument: --status, --ok, + --warning or --fail. + + * backup-all: Added --continue and --only-clone. + + * lysrdiff-monitord.py (now): New function. + (Client.__init__): New API: use sock and peer arguments instead of + accept_retval. Renamed the input buffer from __readbuf to + _readbuf so that derived classes can use it. + (Client.read_event): Fixed misnamed errno name. Track name change + of _readbuf. + (Client.got_eof): Track name change of _readbuf. + (Client.write_event): Handle EAGAIN, ETIMEDOUT and EHOSTUNREACH + errors. + (Client.parse): Track name change of _readbuf. + (Client.handle_cmd): New command: completed. + (Client.dispatcher): New method. + (Server.read_event): Track API change of Client. Set the new + client socket nonblocking. + (Vt100Client.__init__): Negotiate telnet to get a raw byte channel + using WILL ECHO, WILL SuppressGoahead, DO SuppressGoahead. Use + vt100 escape sequences to disable line wrap and query the screen + size. Don't register with the dispatcher. + (Vt100Client.parse): New method. Register with the dispatcher + once the screen size report has arrived from the client. + (Dispatcher.toploop): Write the curren time to vt100 clients every + second. + (Dispatcher.register_vt100): Position the cursor at the command + line position. + (Dispatcher.write_monitor_status): Format the status separately + for each client, as their screen sizes may vary. + (Dispatcher.format_monitor_status): New argument: client. + Position the cursor properly. + (Dispatcher.set_status): Use now() to simplify code. Don't crash + if a client connection is found to be broken. Format the status + separately for each client, as their screen sizes may vary. + (Dispatcher.format_status_vt100): New argument: client. Truncate + the status to the line length reported by the client. Position + the cursor at the command line position. + (Dispatcher.completed): New method. + More categories. * fetch-backup-work: New categories: quota1, shafan and vesuvius. diff --git a/backup-all b/backup-all index 4057a8128efecc4aeba91e985600decb59477485..5a2e3d341bc8b0f3e80cf936036a8cde913005e7 100755 --- a/backup-all +++ b/backup-all @@ -5,12 +5,16 @@ usage () { echo ' --failed Only run backup jobs that failed.' >&2 echo ' --retry Only run backup jobs that produced warnings.' >&2 echo ' --new Only run backup jobs that have never completed.' >&2 + echo ' --continue Resume last run.' >&2 + echo ' --only-clone Only clone the jobs.' >&2 } failed= retry= new= only_prune= +only_clone= +cont=0 while true do @@ -27,6 +31,12 @@ do x--only-prune) shift only_prune=--only-prune;; + x--only-clone) + shift + only_clone=--only-clone;; + x--continue) + shift + cont=1;; x--*) usage exit 1;; @@ -66,7 +76,10 @@ do fi done -/opt/LYSrdiff/bin/distribute-tasks $PARTS +if [ $cont = 0 ] +then + /opt/LYSrdiff/bin/distribute-tasks $PARTS +fi total=0 for lysrdiffpart in $PARTS @@ -81,6 +94,13 @@ for lysrdiffpart in $PARTS do disk=`echo $lysrdiffpart|sed sx/.*xx` part=`echo $lysrdiffpart|sed sx.*/xx` + if [ $cont = 1 ] + then + skipuntil=`cat /opt/LYSrdiff/var/running-task-$disk-$part` + else + skipuntil=0 + fi + while read category subcategory server serverpath do @@ -100,10 +120,18 @@ do echo Hold file disappeared. Continuing. >&2 fi - /opt/LYSrdiff/bin/backup-one-task \ - $failed $retry $new $only_prune \ - $disk $part "$category" "$subcategory" "$server" "$serverpath" \ - "$ctr/$total $disk/$part $category $subcategory" + if [ $ctr -lt $skipuntil ] + then + echo Skipping $ctr/$total $category $subcategory + else + /opt/LYSrdiff/bin/backup-one-task \ + $failed $retry $new $only_prune $only_clone \ + $disk $part "$category" "$subcategory" "$server" "$serverpath" \ + "$ctr/$total $disk/$part $category $subcategory" + + echo $ctr > /opt/LYSrdiff/var/running-task-$disk-$part + + fi ctr=`expr $ctr + 1` done < /lysrdiff/$disk/perm/$part/lysrdiff/tasks done diff --git a/backup-one-task b/backup-one-task index 438bc51dcc70e2b1c06b79e77994576b712e6ee1..d865571df21f5014f1eb839fa1aec42e84995d94 100755 --- a/backup-one-task +++ b/backup-one-task @@ -8,6 +8,7 @@ usage () { echo ' --retry Only run backups with output from rdiff-backup' >&2 echo ' --new Only run backups that never completed' >&2 echo ' --only-prune Only prune old increments' >&2 + echo ' --only-clone Only clone to copy disks' >&2 echo 'Backups are always performed to the "perm" disk.' >&2 echo 'Once the backup is finished, it is cloned to all mounted copies.' >&2 } @@ -16,6 +17,7 @@ failed=0 retry=0 new=0 only_prune=0 +only_clone=0 ss=/opt/LYSrdiff/bin/lysrdiff-set-status.py @@ -34,6 +36,9 @@ do x--only-prune) shift only_prune=1;; + x--only-clone) + shift + only_clone=1;; x--*) usage exit 1;; @@ -122,152 +127,163 @@ unset SSH_ASKPASS unset SSH_AUTH_SOCK CLR='\e[2K\r' - AGE=120D -echo -ne "${CLR}${msg}: removing increments older than $AGE" -$ss $disk $part "${msg}: removing increments older than $AGE" +if [ $only_clone = 0 ] +then + + echo -ne "${CLR}${msg}: removing increments older than $AGE" + $ss --status $disk $part "${msg}: removing increments older than $AGE" -/opt/LYSrdiff/bin/rdiff-backup \ - --remove-older-than $AGE \ - --null-separator \ - --force \ - -v \ - "$files" > "$rdifflogfile" 2>&1 + /opt/LYSrdiff/bin/rdiff-backup \ + --remove-older-than $AGE \ + --null-separator \ + --force \ + -v \ + "$files" > "$rdifflogfile" 2>&1 +fi if [ $only_prune = 1 ] then rmdir "$lockdir" - $ss $disk $part "" + $ss --status $disk $part "" exit 0 fi -echo -ne "${CLR}${msg}: fetching exclude file" -$ss $disk $part "${msg}: fetching exclude file" - -# Fetch an up-to-date exclude file. -rm -f "$exclude" -scp -B -q -i /root/.ssh/backupkey \ - "$server":"$serverpath"/.lysrdiff-exclude "$exclude" >/dev/null 2>&1 -# Create an emtpy exclude file if non existed on the server. -touch "$exclude" - -sed < "$exclude" \ - -e 's%^\([-+] \|\)\([^/]\)%\1'"$serverpath"'/\2%' \ - -e 's%^\([-+] \|\)//%\1/%' \ -| tr '\n' '\0' > "$excl_abs" - - -# See how long time the previous backup took. -if [ -f "$statebase"--start ] && [ -f "$statebase"--end ] +if [ $only_clone = 0 ] then - startdec="`stat --format '%Y' \"$statebase\"--start`" - enddec="`stat --format '%Y' \"$statebase\"--end`" - seconds=`expr $enddec - $startdec` - ETA=`date +' (ETA: %H:%M:%S)' -d "$seconds seconds"` -else - ETA="" -fi - -touch "$base"/backup-attempt-start -touch "$statebase"--attempt - -echo -ne "${CLR}${msg}: running rdiff-backup$ETA" -$ss $disk $part "${msg}: rdiff-backup$ETA" + echo -ne "${CLR}${msg}: fetching exclude file" + $ss --status $disk $part "${msg}: fetching exclude file" -schema="ssh -o BatchMode=yes -o ServerAliveInterval=120" -schema="$schema -a -k -x -i /root/.ssh/backupkey" -schema="$schema %s $remoterdiff --server" + # Fetch an up-to-date exclude file. + rm -f "$exclude" + scp -B -q -i /root/.ssh/backupkey \ + "$server":"$serverpath"/.lysrdiff-exclude "$exclude" >/dev/null 2>&1 + # Create an emtpy exclude file if non existed on the server. + touch "$exclude" -/opt/LYSrdiff/bin/rdiff-backup \ - --exclude-other-filesystems --null-separator \ - --include-globbing-filelist "$excl_abs" \ - --remote-schema "$schema" \ - --force \ - "$server"::"$serverpath" "$files" > "$rdifflogfile" 2>&1 -exit=$? + sed < "$exclude" \ + -e 's%^\([-+] \|\)\([^/]\)%\1'"$serverpath"'/\2%' \ + -e 's%^\([-+] \|\)//%\1/%' \ + | tr '\n' '\0' > "$excl_abs" -echo -ne "${CLR}" -$ss $disk $part "${msg}: updating status files" -if [ $exit = 0 ] -then - touch "$base"/last-good-backup - mv "$base"/backup-attempt-start "$base"/last-good-start - touch "$statebase"--end - mv "$statebase"--attempt "$statebase"--start - - starttime="`stat --format '%y' \"$statebase\"--start|sed 's/\..*//'`" - endtime="`stat --format '%y' \"$statebase\"--end|sed 's/\..*//'`" - startdec="`stat --format '%Y' \"$statebase\"--start`" - enddec="`stat --format '%Y' \"$statebase\"--end`" + # See how long time the previous backup took. + if [ -f "$statebase"--start ] && [ -f "$statebase"--end ] + then + startdec="`stat --format '%Y' \"$statebase\"--start`" + enddec="`stat --format '%Y' \"$statebase\"--end`" + seconds=`expr $enddec - $startdec` + ETA=`date +' (ETA: %H:%M:%S)' -d "$seconds seconds"` + else + ETA="" + fi - echo -ne "${CLR}${msg}: running du" - $ss $disk $part "${msg}: running du" + touch "$base"/backup-attempt-start + touch "$statebase"--attempt - sizes="" + echo -ne "${CLR}${msg}: running rdiff-backup$ETA" + $ss --status $disk $part "${msg}: rdiff-backup$ETA" - if [ -d "$files" ] - then - totalsize=`du -ks "$files" | awk '{print $1}'` - sizes="$sizes totalsize=$totalsize" - echo $totalsize > "$base"/totalsize - fi + schema="ssh -o BatchMode=yes -o ServerAliveInterval=120" + schema="$schema -a -k -x -i /root/.ssh/backupkey" + schema="$schema %s $remoterdiff --server" - if [ -d "$rdiffdir" ] - then - metasize=`du -ks "$rdiffdir" --exclude increments | awk '{print $1}'` - sizes="$sizes metasize=$metasize" - echo $metasize > "$base"/metasize - fi - - if [ -d "$incrementsdir" ] - then - incrementsize=`du -ks "$incrementsdir" | awk '{print $1}'` - sizes="$sizes incrementsize=$incrementsize" - echo $incrementsize > "$base"/incrementsize - fi + /opt/LYSrdiff/bin/rdiff-backup \ + --exclude-other-filesystems --null-separator \ + --include-globbing-filelist "$excl_abs" \ + --remote-schema "$schema" \ + --force \ + "$server"::"$serverpath" "$files" > "$rdifflogfile" 2>&1 + exit=$? echo -ne "${CLR}" - $ss $disk $part "${msg}: updating log file" - - time=`expr $enddec - $startdec` - echo $time > "$base"/time - echo $starttime $endtime time=$time"$sizes" \ - >> "$summaryfile" + $ss --status $disk $part "${msg}: updating status files" - rm -f "$base"/last-failure - rm -f "$statebase"--fail - if [ `wc -c < "$rdifflogfile"` = 0 ] + if [ $exit = 0 ] then - touch "$statebase"--nowarn - touch "$base"/last-nowarn-backup - rm -f "$statebase"--neverwarnfree - rm -f "$statebase"--warn - logger -p local5.info -t LYSrdiff "$lysrdiffpart $category $subcategory: OK" + touch "$base"/last-good-backup + mv "$base"/backup-attempt-start "$base"/last-good-start + touch "$statebase"--end + mv "$statebase"--attempt "$statebase"--start + + starttime="`stat --format '%y' \"$statebase\"--start|sed 's/\..*//'`" + endtime="`stat --format '%y' \"$statebase\"--end|sed 's/\..*//'`" + startdec="`stat --format '%Y' \"$statebase\"--start`" + enddec="`stat --format '%Y' \"$statebase\"--end`" + + echo -ne "${CLR}${msg}: running du" + $ss --status $disk $part "${msg}: running du" + + sizes="" + + if [ -d "$files" ] + then + totalsize=`du -ks "$files" | awk '{print $1}'` + sizes="$sizes totalsize=$totalsize" + echo $totalsize > "$base"/totalsize + fi + + if [ -d "$rdiffdir" ] + then + metasize=`du -ks "$rdiffdir" --exclude increments | awk '{print $1}'` + sizes="$sizes metasize=$metasize" + echo $metasize > "$base"/metasize + fi + + if [ -d "$incrementsdir" ] + then + incrementsize=`du -ks "$incrementsdir" | awk '{print $1}'` + sizes="$sizes incrementsize=$incrementsize" + echo $incrementsize > "$base"/incrementsize + fi + + echo -ne "${CLR}" + $ss --status $disk $part "${msg}: updating log file" + + time=`expr $enddec - $startdec` + echo $time > "$base"/time + echo $starttime $endtime time=$time"$sizes" \ + >> "$summaryfile" + + rm -f "$base"/last-failure + rm -f "$statebase"--fail + if [ `wc -c < "$rdifflogfile"` = 0 ] + then + touch "$statebase"--nowarn + touch "$base"/last-nowarn-backup + rm -f "$statebase"--neverwarnfree + rm -f "$statebase"--warn + logger -p local5.info -t LYSrdiff "$lysrdiffpart $category $subcategory: OK" + $ss --ok $disk $part "$category" "$subcategory" + else + echo ${msg}: WARNING: output from rdiff-backup: + echo + sed 's/^/ /' "$rdifflogfile" + echo + if [ ! -f "$statebase"--warn ] + then + touch "$statebase"--warn + fi + if [ ! -f "$statebase"--nowarn ] && [ ! -f "$statebase"--neverwarnfree ] + then + touch "$statebase"--neverwarnfree + fi + logger -p local5.info -t LYSrdiff \ + "$lysrdiffpart $category $subcategory: OK with warnings" + $ss --warn $disk $part "$category" "$subcategory" + fi else - echo ${msg}: WARNING: output from rdiff-backup: - echo - sed 's/^/ /' "$rdifflogfile" - echo - if [ ! -f "$statebase"--warn ] - then - touch "$statebase"--warn - fi - if [ ! -f "$statebase"--nowarn ] && [ ! -f "$statebase"--neverwarnfree ] - then - touch "$statebase"--neverwarnfree - fi - logger -p local5.info -t LYSrdiff "$lysrdiffpart $category $subcategory: OK with warnings" + mv "$base"/backup-attempt-start "$base"/last-failure + mv "$statebase"--attempt "$statebase"--fail + echo ${msg}: FAIL: + echo + sed 's/^/ /' "$rdifflogfile" + echo + logger -p local5.info -t LYSrdiff \ + "$lysrdiffpart $category $subcategory: FAIL" + $ss --fail $disk $part "$category" "$subcategory" fi -else - mv "$base"/backup-attempt-start "$base"/last-failure - mv "$statebase"--attempt "$statebase"--fail - echo ${msg}: FAIL: - echo - sed 's/^/ /' "$rdifflogfile" - echo - logger -p local5.info -t LYSrdiff "$lysrdiffpart $category $subcategory: FAIL" fi for copy in A B @@ -292,7 +308,7 @@ do if mkdir "$copybase"/lock then echo -ne "${CLR}${msg}: copying to $copy" - $ss $disk $part "${msg}: copying to $copy" + $ss --status $disk $part "${msg}: copying to $copy" rsync -a --delete "$base"/ "$copybase" rm -f "$copystatebase"--* || true @@ -306,6 +322,6 @@ do fi done -$ss $disk $part "" +$ss --status $disk $part "" rmdir "$lockdir" diff --git a/lysrdiff-monitord.py b/lysrdiff-monitord.py index 34207d2ec9cdd99dedd402f688001482c07f95da..49523d8a79965fa77389ac05809a621e61e70e46 100755 --- a/lysrdiff-monitord.py +++ b/lysrdiff-monitord.py @@ -1,18 +1,23 @@ #!/usr/bin/env python +import re import socket +import errno import select import sys import time +def now(): + return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) + class Client(object): - def __init__(self, accept_retval, dispatcher): - self.__s, peer = accept_retval + def __init__(self, sock, peer, dispatcher): + self.__s = sock self.__peer_ip = peer[0] self.__peer_port = peer[1] dispatcher.register(self) self.__writebuf = "" - self.__readbuf = "" + self._readbuf = "" self.__got_eof = False self.__dispatcher = dispatcher @@ -35,7 +40,7 @@ class Client(object): try: bytes = self.__s.recv(100) except socket.error, e: - if e[0] == errno.ECONNTIMEOUT: + if e[0] == errno.ETIMEDOUT: self.got_eof(True) return raise @@ -43,32 +48,43 @@ class Client(object): self.got_eof() return - self.__readbuf += bytes + self._readbuf += bytes self.parse() def got_eof(self, error=False): self.__got_eof = True if not error: self.parse() - if len(self.__readbuf) > 0: + if len(self._readbuf) > 0: sys.stderr.write("EOF with %d bytes pending from client.\n" % ( - len(self.__readbuf))) + len(self._readbuf))) if len(self.__writebuf) == 0 or error: self.__dispatcher.unregister(self) self.__s.close() del self def write_event(self): - rv = self.__s.send(self.__writebuf) + try: + rv = self.__s.send(self.__writebuf) + except socket.error, e: + if e[0] == errno.EAGAIN: + rv = 0 + # Give the rest of the system a chance to recover. + time.sleep(0.05) + elif e[0] in [errno.ETIMEDOUT, errno.EHOSTUNREACH]: + self.got_eof(True) + return + else: + raise if rv > 0: self.__writebuf = self.__writebuf[rv:] def parse(self): - ix = self.__readbuf.find("\n") + ix = self._readbuf.find("\n") if ix < 0: return - cmd = self.__readbuf[:ix] - self.__readbuf = self.__readbuf[ix+1:] + cmd = self._readbuf[:ix] + self._readbuf = self._readbuf[ix+1:] self.handle_cmd(cmd) def handle_cmd(self, cmd): @@ -83,6 +99,11 @@ class Client(object): cmd, disk, part, status = split dispatcher.set_status(int(disk), int(part), status) + elif cmd.startswith("completed "): + cmd, disk, part, category, subcategory, outcome = cmd.split() + dispatcher.completed(int(disk), int(part), category, subcategory, + outcome) + else: sys.stderr.write("Unknown command received from client.\n") @@ -90,6 +111,10 @@ class Client(object): self.__writebuf += buf self.write_event() + def dispatcher(self): + return self.__dispatcher + + class Server(object): IP = '127.0.0.1' PORT = 9933 @@ -114,16 +139,47 @@ class Server(object): return self.__s.fileno() def read_event(self): - self.CLIENT(self.__s.accept(), self.__dispatcher) + sock, peer = self.__s.accept() + sock.setblocking(False) + self.CLIENT(sock, peer, self.__dispatcher) class Vt100Client(Client): - def handle_cmd(self, cmd): - pass + def __init__(self, sock, peer, dispatcher): + Client.__init__(self, sock, peer, dispatcher) + self.write("\377\373\001") # IAC WILL ECHO + self.write("\377\373\003") # IAC WILL SuppressGoahead + self.write("\377\375\003") # IAC DO SuppressGoahead + self.write("\033[7l") # Disable line wrap. + self.write("\033[r") # Scroll entire screen. + self.write("\033[999;999H") # Move to row 999, col 999. + self.write("\033[6n") # Report cursor position. + self.rows = None + self.cols = None + + def parse(self): + print "Got data", repr(self._readbuf) + while True: + ix = self._readbuf.find("\033") + if ix < 0: + print "Discarding" + self._readbuf = "" + return + m = re.match("\033\\[(?P<row>\\d+);(?P<col>\\d+)R", + self._readbuf[ix:]) + if m is None: + print "ESC at", ix, "but discarding it" + self._readbuf = self._readbuf[ix+1:] + else: + break + print "Got something nice" + self.rows = int(m.group("row")) + self.cols = int(m.group("col")) + self._readbuf = self._readbuf[ix+1:] + print "Got", self.rows, "rows and", self.cols, "cols" + sys.stdout.flush() + self.dispatcher().register_vt100(self) - def __init__(self, accept_retval, dispatcher): - Client.__init__(self, accept_retval, dispatcher) - dispatcher.register_vt100(self) class Vt100Server(Server): IP = '' @@ -147,6 +203,7 @@ class Dispatcher(object): self.write_monitor_status() def toploop(self): + prev_ts = now() while True: r = [] w = [] @@ -156,7 +213,14 @@ class Dispatcher(object): r += c.want_read() w += c.want_write() - r, w, e = select.select(r, w, [], None) + t = time.time() + maxwait = 1 - (t - int(t)) + 0.05 + if maxwait < 0: + maxwait = 0 + + r, w, e = select.select(r, w, [], maxwait) + + ts = now() for c in w: if self.__break: @@ -168,54 +232,65 @@ class Dispatcher(object): break c.read_event() + if ts != prev_ts: + for c in list(self.__vt100): + c.write("\033[1;%dH%s\033[%d;1H" % ( + c.cols - len(ts), ts, c.rows - 1)) + def register_vt100(self, client): self.__vt100.add(client) msg = "\033[2J\033[HLYSrdiff status\r\n===============" for disk in self.__status.keys(): for part in self.__status[disk].keys(): - msg += self.format_status_vt100(disk, part) + msg += self.format_status_vt100(disk, part, client) + msg += "\033[%d;%dr" % (9, client.rows - 2) client.write(msg) self.write_monitor_status() def write_monitor_status(self): - msg = self.format_monitor_status() - for c in self.__vt100: + for c in list(self.__vt100): + msg = self.format_monitor_status(c) c.write(msg) - def format_monitor_status(self): - msg = "\033[9;1H" + def format_monitor_status(self, client): + msg = "\033[%d;1H" % client.rows msg += "%d clients" % len(self.__vt100) msg += "\033[K" - msg += "\033[H" + msg += "\033[%d;1H" % (client.rows - 1) return msg def set_status(self, disk, part, status): if disk not in self.__status: self.__status[disk] = {} - timestamp = time.strftime("%Y-%m-%d %H:%M:%S", - time.localtime(time.time())) + timestamp = now() self.__status[disk][part] = (timestamp, status) - msg = self.format_status_vt100(disk, part) - for c in self.__vt100: + for c in list(self.__vt100): + msg = self.format_status_vt100(disk, part, c) c.write(msg) print timestamp, "%d/%d" % (disk, part), status - def format_status_vt100(self, disk, part): + def format_status_vt100(self, disk, part, client): timestamp, status = self.__status[disk][part] msg = "\033[%d;1H" % (2 + 2 * disk + part) - msg += timestamp - msg += " " - msg += status + msg += (timestamp + " " + status)[:client.cols] msg += "\033[K" - msg += "\033[H" + msg += "\033[%d;1H" % (client.rows - 1) return msg + def completed(self, disk, part, category, subcategory, outcome): + msg = "%s %d/%d %s %s %s" % (now(), disk, part, outcome, + category, subcategory) + for c in list(self.__vt100): + c.write("\033[%d;1H\r\n%s\033[%d;1H" % (c.rows - 2, + msg, + c.rows - 1)) + if __name__ == '__main__': dispatcher = Dispatcher() Server(dispatcher) diff --git a/lysrdiff-set-status.py b/lysrdiff-set-status.py index c88e9d1b37fd983175f48996eb78da4bdd521fa7..c94e509824d64ea23b37b248740c9126e6dd01b8 100755 --- a/lysrdiff-set-status.py +++ b/lysrdiff-set-status.py @@ -4,16 +4,41 @@ import sys import errno import socket -def sendmsg(disk, part, msg): +def open_socket(): s = socket.socket() try: s.connect(("127.0.0.1", 9933)) except socket.error, e: if e[0] == errno.ECONNREFUSED: - return + return None raise + return s + +def sendmsg(disk, part, msg): + s = open_socket() + if s is None: + return s.send("set-status %d %d %s\n" % (disk, part, msg)) s.close() +def completion(disk, part, category, subcategory, outcome): + s = open_socket() + if s is None: + return + s.send("completed %d %d %s %s %s\n" % (disk, part, + category, subcategory, + outcome)) + s.close() + if __name__ == '__main__': - sendmsg(int(sys.argv[1]), int(sys.argv[2]), sys.argv[3]) + if sys.argv[1] == "--status": + sendmsg(int(sys.argv[2]), int(sys.argv[3]), sys.argv[4]) + if sys.argv[1] == "--ok": + completion(int(sys.argv[2]), int(sys.argv[3]), + sys.argv[4], sys.argv[5], "OK") + if sys.argv[1] == "--warning": + completion(int(sys.argv[2]), int(sys.argv[3]), + sys.argv[4], sys.argv[5], "WARN") + if sys.argv[1] == "--fail": + completion(int(sys.argv[2]), int(sys.argv[3]), + sys.argv[4], sys.argv[5], "FAIL")