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