Muehlenhoff has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/366573 )
Change subject: Add debdeploy client to detect library restarts (WIP) ...................................................................... Add debdeploy client to detect library restarts (WIP) Change-Id: I62d0b5d1e2fad2834fdb3572e45cde1d94f33210 --- A clients/debdeploy-restarts 1 file changed, 142 insertions(+), 0 deletions(-) Approvals: Muehlenhoff: Looks good to me, approved jenkins-bot: Verified diff --git a/clients/debdeploy-restarts b/clients/debdeploy-restarts new file mode 100755 index 0000000..50706e2 --- /dev/null +++ b/clients/debdeploy-restarts @@ -0,0 +1,142 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- +''' +Module for listing necessary service restarts after library updates +''' + +import logging +import pickle +import subprocess +import os +import re +import platform +import sys +import argparse +import json +import ConfigParser +from logging.handlers import RotatingFileHandler +from debian import deb822 + +logger = logging.getLogger('debdeploy') + + +def parse_args(): + p = argparse.ArgumentParser( + description='debdeploy-deploy - Deploy a software update') + p.add_argument('--console', action='store_true', default=False, + help='Enable additional console output') + p.add_argument('--json', action='store_true', default=False, + help='Return results as JSON') + p.add_argument('--soname', action='store', nargs='+', required=True) + + args = p.parse_args(sys.argv[1:]) + + return args + + +def setup_logger(verbose=False, console_output=False): + log_file = "/var/log/debdeploy/updates.log" + + log_path = os.path.dirname(log_file) + if not os.path.exists(log_path): + os.makedirs(log_path, 0770) + + log_formatter = logging.Formatter(fmt='%(asctime)s (%(levelname)s) %(message)s') + log_handler = RotatingFileHandler(log_file, maxBytes=(5 * (1024**2)), backupCount=30) + log_handler.setFormatter(log_formatter) + logger.addHandler(log_handler) + logger.raiseExceptions = False + + if console_output: + console = logging.StreamHandler() + logging.getLogger('debdeploy').addHandler(console) + + if verbose: + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.INFO) + + +def get_deleted_files(): + ''' + This function returns a list open file handles, which have a reference to deleted + files, this usually occurs after library upgrades. The original code in debdepoy + was parsing /proc itself, but we now rely on parsing the lsof which is much more + robust since it allows to directly query deleted filed + ''' + + deleted_files = [] + false_positives = ['/dev/zero'] + + try: + del_files = subprocess.check_output(["lsof", "+c", "15", "-nXd", "DEL"]) + except subprocess.CalledProcessError as e: + logger.info("Could not determine host architecture", e.returncode) + sys.exit(1) + + for line in del_files.splitlines(): + cols = line.split() + try: + if len(cols) == 8: + command, pid, filename = [cols[x] for x in (0, 1, 7)] + if filename not in false_positives: + deleted_files.append((command, pid, filename)) + except ValueError: + continue + + return deleted_files + + +def result(status, restarts_needed, json_output): + ''' + Generates a data set to return to Cumin. + status: OK | ERROR: foo + restarts_needed: dictionary of process names with a dictionary + of PIDs with a list of file references + ''' + + if json_output: + return json.dumps([status, restarts_needed]) + else: + return [status, restarts_needed] + + +def main(): + ''' + Updates all installed binary packages of the source package + to the specified version. + ''' + args = parse_args() + + setup_logger(False, args.console) + + deleted_files = get_deleted_files() + restarts_needed = {} + + for i in deleted_files: + procname, pid, fname = (i) + for soname in args.soname: + if fname.find(soname) != -1: + if not restarts_needed.get(procname, None): + restarts_needed[procname] = {} + + if not restarts_needed[procname].get(pid, None): + restarts_needed[procname][pid] = [] + + restarts_needed[procname][pid].append(fname) + + if len(restarts_needed) == 0: + return result("OK", "No service needs a restart", args.json) + else: + logger.info("These services need a restart:") + for i in restarts_needed: + logger.info(i + " (" + str(len(restarts_needed[i].keys())) + " processes)") + return result("OK", restarts_needed, args.json) + + +if __name__ == '__main__': + print main() + +# Local variables: +# mode: python +# End: -- To view, visit https://gerrit.wikimedia.org/r/366573 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I62d0b5d1e2fad2834fdb3572e45cde1d94f33210 Gerrit-PatchSet: 1 Gerrit-Project: operations/debs/debdeploy Gerrit-Branch: master Gerrit-Owner: Muehlenhoff <mmuhlenh...@wikimedia.org> Gerrit-Reviewer: Muehlenhoff <mmuhlenh...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits