| 1 #!/usr/local/bin/python3 |
|
| 2 # |
|
| 3 # Borgend by Tuomo Valkonen, 2018 |
|
| 4 # |
|
| 5 |
|
| 6 # Common modules |
|
| 7 import os |
|
| 8 import sys |
|
| 9 import argparse |
|
| 10 import platform |
|
| 11 import logging |
|
| 12 # Own modules needed at this stage |
|
| 13 import borgend.branding as branding |
|
| 14 import borgend.locations as locations |
|
| 15 |
|
| 16 # |
|
| 17 # Argument processing |
|
| 18 # |
|
| 19 |
|
| 20 epilog_format=""" |
|
| 21 Configuration file location: |
|
| 22 |
|
| 23 %s |
|
| 24 |
|
| 25 Log directory: |
|
| 26 |
|
| 27 %s/ |
|
| 28 """ |
|
| 29 |
|
| 30 parser=argparse.ArgumentParser( |
|
| 31 description=branding.appname_stylised + ": BorgBackup scheduler, queue, and tray icon.", |
|
| 32 epilog=epilog_format % (locations.cfgfile, locations.logs_dir), |
|
| 33 formatter_class=argparse.RawDescriptionHelpFormatter) |
|
| 34 |
|
| 35 parser.add_argument( |
|
| 36 '--no-tray', |
|
| 37 dest='notray', |
|
| 38 action='store_true', |
|
| 39 help='Do not show the tray icon') |
|
| 40 |
|
| 41 parser.add_argument( |
|
| 42 '--debug', |
|
| 43 dest='debug', |
|
| 44 action='store_true', |
|
| 45 help='Set logging level to debug') |
|
| 46 |
|
| 47 args=parser.parse_args() |
|
| 48 |
|
| 49 # |
|
| 50 # Done parsing args, import our own modules, and launch everything |
|
| 51 # |
|
| 52 |
|
| 53 import borgend.config as config |
|
| 54 import borgend.dreamtime as dreamtime |
|
| 55 import borgend.loggers as loggers |
|
| 56 from borgend.scheduler import Scheduler |
|
| 57 from borgend.repository import Repository |
|
| 58 from borgend.backup import Backup |
|
| 59 |
|
| 60 logger=loggers.mainlogger |
|
| 61 |
|
| 62 if args.debug: |
|
| 63 logger.setLevel(logging.DEBUG) |
|
| 64 |
|
| 65 tray = None |
|
| 66 repos=[] |
|
| 67 backups=[] |
|
| 68 |
|
| 69 try: |
|
| 70 dreamtime.start_monitoring() |
|
| 71 |
|
| 72 scheduler = Scheduler() |
|
| 73 scheduler.start() |
|
| 74 |
|
| 75 repoconfigs=config.settings['repositories'] |
|
| 76 |
|
| 77 logger.info('Initialising repositories') |
|
| 78 for i in range(len(repoconfigs)): |
|
| 79 r=Repository(i, repoconfigs[i]) |
|
| 80 repos.append(r) |
|
| 81 |
|
| 82 backupconfigs=config.settings['backups'] |
|
| 83 |
|
| 84 logger.info('Initialising backups') |
|
| 85 for i in range(len(backupconfigs)): |
|
| 86 b=Backup(i, backupconfigs[i], scheduler) |
|
| 87 backups.append(b) |
|
| 88 |
|
| 89 if args.notray or platform.system()!='Darwin': |
|
| 90 # Wait for scheduler to finish |
|
| 91 run=scheduler.join |
|
| 92 else: |
|
| 93 # This is needed for Ctrl+C to work. |
|
| 94 # TODO: proper exit handler, which seems to require |
|
| 95 # ditching/forking/extending rumps to extend the NSApp class |
|
| 96 from PyObjCTools.AppHelper import installMachInterrupt |
|
| 97 installMachInterrupt() |
|
| 98 # Start UI, and let it handle exit control |
|
| 99 from borgend.ui import BorgendTray |
|
| 100 tray=BorgendTray(backups); |
|
| 101 run=tray.run |
|
| 102 |
|
| 103 for r in repos: |
|
| 104 r.start() |
|
| 105 |
|
| 106 for b in backups: |
|
| 107 b.start() |
|
| 108 |
|
| 109 run() |
|
| 110 |
|
| 111 except Exception as err: |
|
| 112 # TODO: Should write errors here to stderr; |
|
| 113 # perhaps add an extra stderr logger for error level messages |
|
| 114 logger.exception("Exception fell through: exiting") |
|
| 115 |
|
| 116 finally: |
|
| 117 logger.debug("Exiting") |
|
| 118 |
|
| 119 for b in backups: |
|
| 120 b.terminate() |
|
| 121 |
|
| 122 for r in repos: |
|
| 123 r.terminate() |
|
| 124 |
|
| 125 if tray: |
|
| 126 tray.quit() |
|
| 127 else: |
|
| 128 logging.shutdown() |
|
| 129 |
|