dbuscrontab: ability to pass config file to edit for -e action
[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             # 0. get custom config file to edit
62             if len(sys.argv) > 2:
63                 conffile = sys.argv[2]
64
65             # 1. create temporary config file copy
66             temp_file = create_temp_file(conffile)
67             mod_time = os.path.getmtime(temp_file)
68
69             try:
70                 # 2. run system editor on this file
71                 run_system_editor(temp_file)
72
73                 # 3. check if this file is changed
74                 if os.path.getmtime(temp_file) <= mod_time:
75                     print 'File was not changed.'
76                     sys.exit(2)
77
78                 # 4. check this file's syntax
79                 check_syntax(temp_file)
80
81                 # 5. replace system wide config file with new one
82                 shutil.move(temp_file, conffile)
83
84             finally:
85                 try:
86                     os.unlink(temp_file)
87                 except OSError:
88                     pass
89
90             # 6. send sighup to dbuscron daemon
91             pid = get_dbuscron_pid()
92             os.kill(pid, signal.SIGHUP)
93
94             print "Everything's OK, SIGHUP to dbuscron is sent."
95
96         elif action == '-l':
97             f = open(conffile, 'r')
98             for l in f:
99                 print l.strip()
100             f.close()
101
102         elif action == '-k':
103             check_syntax(conffile)
104             print "File %s has no syntax errors." % (conffile)
105
106         else:
107             print """
108 Usage:
109     %(myname)s { -e | -l | -k } [config-file]
110
111     -e      edit config file
112     -l      list contents of config file
113     -k      check config file's syntax
114
115     Default for config-file is %(conffile)s
116 """ % dict(myname=os.path.basename(sys.argv[0]), conffile=conffile)
117
118     except SystemError, e:
119         print e.message
120         sys.exit(1)
121