#!/usr/bin/env python3.7 import configparser import logging import logging.handlers import os import platform import sys import time import sau import sau.services import sau.platforms def init(): sau.config = configparser.ConfigParser() conf = sau.config if platform.system() == 'FreeBSD': syslog_socket = '/var/run/log' conf_file = '/usr/local/etc/sau.cfg' else: syslog_socket = '/dev/log' conf_file = '/etc/sau.cfg' if os.path.isfile(conf_file): conf.read(conf_file) log = logging.getLogger(sau.LOGNAME) log.setLevel(logging.DEBUG) conf_level = _conf_level_to_logging_level(conf.get('default', 'stderr_loglevel', fallback="debug")) handler = logging.StreamHandler() formatter = logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s') handler.setFormatter(formatter) handler.setLevel(conf_level) log.addHandler(handler) conf_level = _conf_level_to_logging_level(conf.get('default', 'syslog_loglevel', fallback="debug")) handler = logging.handlers.SysLogHandler(address=syslog_socket) formatter = logging.Formatter(fmt='{}[%(process)s] %(message)s'.format(sau.LOGNAME)) handler.setFormatter(formatter) handler.setLevel(conf_level) log.addHandler(handler) def fork_and_reboot(): log = logging.getLogger(sau.LOGNAME) try: pid = os.fork() if pid != 0: sys.exit(0) except OSError as err: log.error("Fork #1 failed when going for reboot: {}".format(err)) sys.exit(1) os.chdir('/') os.setsid() os.umask(0) try: pid = os.fork() if pid != 0: sys.exit(0) except OSError as err: log.error("Fork #2 failed when going for reboot: {}".format(err)) sys.exit(1) sys.stdout.flush() sys.stderr.flush() stdin = open(os.devnull, 'r') stdout = open(os.devnull, 'a+') stderr = open(os.devnull, 'a+') os.dup2(stdin.fileno(), sys.stdin.fileno()) os.dup2(stdout.fileno(), sys.stdout.fileno()) os.dup2(stderr.fileno(), sys.stderr.fileno()) log.warning("New fork!") # sleep for a short while to give parent time to exit time.sleep(30) try: #log.error('would reboot now') os.execv('/sbin/reboot', ['/sbin/reboot']) except OSError as err: log.error('Could not reboot: {}'.format(err)) sys.exit(1) def main(): conf = sau.config log = logging.getLogger(sau.LOGNAME) platform = sau.platforms.get_platform() reboot_required = False reboot_recommended = False if conf.getboolean('default', 'do_system_upgrade', fallback=True): reboot_required = platform.system_upgrade() if conf.getboolean('default', 'do_package_upgrade', fallback=True): platform.pkg_upgrade() if conf.getboolean('default', 'do_service_restart', fallback=True): reboot_recommended = sau.services.restart_services() if conf.getboolean('default', 'do_reboot', fallback=False): if reboot_required: log.info('Rebooting because of a system upgrade') elif reboot_recommended: log.info('Rebooting because service restarts did not close all deleted files') if reboot_required or reboot_recommended: fork_and_reboot() def _conf_level_to_logging_level(conf_level): if conf_level.lower() == 'debug': return logging.DEBUG if conf_level.lower() == 'info': return logging.INFO if conf_level.lower() == 'warning': return logging.WARNING if conf_level.lower() == 'error': return logging.error return logging.DEBUG if __name__ == '__main__': init() sys.exit(main())