dbuscrontab: config file argument is accepted by all actions
[dbuscron] / dbuscron / shell / edit.py
1
2 import os, sys, shutil, signal, tempfile, pipes
3 pidfile = '/var/run/dbuscron.pid'
4
5 from dbuscron.parser import CrontabParser, CrontabParserError
6
7 def create_temp_file(orig_file):
8     try:
9         temp_file = tempfile.mktemp(prefix=os.path.basename(orig_file))
10         shutil.copy(orig_file, temp_file)
11         return temp_file
12     except:
13         raise SystemError('Unable to make copy of dbuscrontab file.')
14
15 def run_system_editor(filename):
16     editor = pipes.quote(os.environ.get('EDITOR', '/usr/bin/vim'))
17     if os.system(editor + ' ' + pipes.quote(filename)) != 0:
18         raise SystemError('Editor returned non-zero status value.')
19
20 def get_dbuscron_pid_from_upstart():
21     f = os.popen('initctl status dbuscron', 'r')
22     status = f.readline()
23     f.close()
24     return int(status.strip().split(' ').pop())
25
26 def get_dbuscron_pid_from_pidfile():
27     f = open(pidfile, 'r')
28     pid = f.readline()
29     f.close()
30     return int(pid)
31
32 def get_dbuscron_pid():
33     try:
34         return get_dbuscron_pid_from_upstart()
35     except:
36         try:
37             return get_dbuscron_pid_from_pidfile()
38         except:
39             raise SystemError('Unable to get PID of dbuscron job.')
40
41 def check_syntax(filename):
42     parser = CrontabParser(filename)
43     try:
44         for rule, command in parser:
45             pass
46     except CrontabParserError, e:
47         print e.message
48         raise SystemError("File %s has syntax errors." % (filename))
49
50 def run():
51
52     try:
53         action = sys.argv[1]
54     except IndexError:
55         action = None
56
57     try:
58         conffile = sys.argv[2]
59     except IndexError:
60         conffile = '/etc/dbuscrontab'
61
62     try:
63         if action == '-e':
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