From 5eda3b6e853c9f1773dd8def54589e8f1ad2299e Mon Sep 17 00:00:00 2001 From: Fredrik Eriksson Date: Wed, 17 Apr 2019 08:50:26 +0200 Subject: [PATCH] fork and reboot instead of just reboot; hopefully will make sure a mail is sent from cron even if a reboot happens --- bin/sau | 125 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 84 insertions(+), 41 deletions(-) diff --git a/bin/sau b/bin/sau index 8990527..03c4523 100755 --- a/bin/sau +++ b/bin/sau @@ -11,47 +11,7 @@ import sau import sau.services import sau.platforms - -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.warning('Rebooting because of a system upgrade') - elif reboot_recommended: - log.warning('Rebooting because service restarts did not close all deleted files') - if reboot_required or reboot_recommended: - # sleep a little to make sure the above log-messages has reached - # syslog before we reboot - time.sleep(1) - os.system('/sbin/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__': +def init(): sau.config = configparser.SafeConfigParser() conf = sau.config @@ -82,4 +42,87 @@ if __name__ == '__main__': 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.warning('Rebooting because of a system upgrade') + elif reboot_recommended: + log.warning('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())