4f61a3f6a91525f7da3f6576322ed5ac40a8a880
[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     try:
34         for rule, command in parser:
35             pass
36     except CrontabParserError, e:
37         print e.message
38         raise SystemError("File %s has syntax errors." % (filename))
39
40 if __name__ == '__main__':
41
42     try:
43         action = sys.argv[1]
44     except IndexError:
45         action = None
46
47     try:
48         if action == '-e':
49
50             # 1. create temporary config file copy
51             temp_file = create_temp_file(conffile)
52             mod_time = os.path.getmtime(temp_file)
53
54             try:
55                 # 2. run system editor on this file
56                 run_system_editor(temp_file)
57
58                 # 3. check if this file is changed
59                 if os.path.getmtime(temp_file) <= mod_time:
60                     print 'File was not changed.'
61                     sys.exit(2)
62
63                 # 4. check this file's syntax
64                 check_syntax(temp_file)
65
66                 # 5. replace system wide config file with new one
67                 shutil.move(temp_file, conffile)
68
69             finally:
70                 try:
71                     os.unlink(temp_file)
72                 except OSError:
73                     pass
74
75             # 6. send sighup to dbuscron daemon
76             pid = get_dbuscron_pid()
77             os.kill(pid, signal.SIGHUP)
78
79             print "Everything's OK, SIGHUP to dbuscron is sent."
80
81         elif action == '-l':
82             f = open(conffile, 'r')
83             for l in f:
84                 print l.strip()
85             f.close()
86
87         elif action == '-k':
88             check_syntax(conffile)
89             print "File %s has no syntax errors." % (conffile)
90
91         else:
92             print """
93 Usage:
94     %(myname)s { -e | -l }
95
96     -e      edit %(conffile)s file
97     -l      list contents of %(conffile)s file
98     -k      check %(conffile)s's syntax
99
100 """ % dict(myname=os.path.basename(sys.argv[0]), conffile=conffile)
101
102     except SystemError, e:
103         print e.message
104         sys.exit(1)
105