nicer syntax checks in dbuscrontab utility
[dbuscron] / dbuscrontab.py
1 #!/usr/bin/python
2
3 import os, sys, shutil, signal, tempfile, pipes
4 conffile = '/etc/dbuscrontab'
5 pidfile = '/var/run/dbuscron.pid'
6
7 from dbuscron.parser import CrontabParser, CrontabParserError
8
9 def create_temp_file(orig_file):
10     try:
11         temp_file = tempfile.mktemp(prefix=os.path.basename(orig_file))
12         shutil.copy(orig_file, temp_file)
13         return temp_file
14     except:
15         raise SystemError('Unable to make copy of dbuscrontab file.')
16
17 def run_system_editor(filename):
18     editor = pipes.quote(os.environ.get('EDITOR', '/usr/bin/vim'))
19     if os.system(editor + ' ' + pipes.quote(filename)) != 0:
20         raise SystemError('Editor returned non-zero status value.')
21
22 def get_dbuscron_pid():
23     try:
24         f = os.popen('initctl status dbuscron', 'r')
25         status = f.readline()
26         f.close()
27         return int(status.strip().split(' ').pop())
28     except:
29         raise SystemError('Unable to get PID of dbuscron job.')
30
31 def check_syntax(filename):
32     parser = CrontabParser(filename)
33     for rule, command in parser:
34         pass
35
36 if __name__ == '__main__':
37
38     try:
39         action = sys.argv[1]
40     except IndexError:
41         action = None
42
43     if action == '-e':
44         # 1. create temporary config file copy
45         temp_file = create_temp_file(conffile)
46         mod_time = os.path.getmtime(temp_file)
47
48         # 2. run system editor on this file
49         run_system_editor(temp_file)
50
51         # 3. check if this file is changed
52         if os.path.getmtime(temp_file) <= mod_time:
53             print 'File was not changed.'
54             sys.exit(2)
55
56         # TODO: 4. check this file's syntax
57         try:
58             check_syntax(temp_file)
59         except CrontabParserError, e:
60             print e.message
61             print 'File has syntax errors, aborting.'
62             sys.exit(3)
63
64         # 5. replace system wide config file with new one
65         shutil.move(temp_file, conffile)
66
67         # 6. send sighup to dbuscron daemon
68         pid = get_dbuscron_pid()
69         os.kill(pid, signal.SIGHUP)
70         print "Everything's OK, SIGHUP to dbuscron is sent."
71
72     elif action == '-l':
73         f = open(conffile, 'r')
74         for l in f:
75             print l.strip()
76         f.close()
77
78     elif action == '-k':
79         try:
80             check_syntax(conffile)
81         except CrontabParserError, e:
82             print e.message
83             sys.exit(3)
84
85     else:
86         print """
87 Usage:
88     %(myname)s { -e | -l }
89
90     -e      edit %(conffile)s file
91     -l      list contents of %(conffile)s file
92     -k      check %(conffile)s's syntax
93
94 """ % dict(myname=os.path.basename(sys.argv[0]), conffile=conffile)
95