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 |
|