|
1 |
#!/usr/share/ucs-test/runner python |
1 |
#!/usr/share/ucs-test/runner python |
2 |
## desc: Logrotation should trigger UMC components to reopen their logfiles |
2 |
## desc: Logrotation should trigger UMC components to reopen their logfiles |
3 |
## roles: |
|
|
4 |
## - domaincontroller_master |
5 |
## packages: |
3 |
## packages: |
6 |
## - univention-management-console |
4 |
## - univention-management-console |
7 |
## - univention-management-console-frontend |
5 |
## - univention-management-console-frontend |
Lines 14-19
from subprocess import call, Popen, PIPE
|
Link Here
|
---|
|
14 |
|
12 |
|
15 |
from univention.testing.utils import fail |
13 |
from univention.testing.utils import fail |
16 |
|
14 |
|
|
|
15 |
|
17 |
class LogrotateError(Exception): |
16 |
class LogrotateError(Exception): |
18 |
pass |
17 |
pass |
19 |
|
18 |
|
Lines 22-33
class LogrotateService(object):
|
Link Here
|
---|
|
22 |
def __init__(self, service, logfile_pattern): |
21 |
def __init__(self, service, logfile_pattern): |
23 |
self.service = service |
22 |
self.service = service |
24 |
self.logfile_pattern = logfile_pattern |
23 |
self.logfile_pattern = logfile_pattern |
|
|
24 |
self.old_stat = None |
25 |
|
25 |
|
26 |
@property |
26 |
@property |
27 |
def pgrep_pattern(self): |
27 |
def pgrep_pattern(self): |
28 |
return r'^/usr/bin/python.*%s.*' % (self.service,) |
28 |
return r'^/usr/bin/python.*%s.*' % (self.service,) |
29 |
|
29 |
|
30 |
@property |
|
|
31 |
def pid(self): |
30 |
def pid(self): |
32 |
process = Popen(['pgrep', '-x', '-f', self.pgrep_pattern], stdout=PIPE) |
31 |
process = Popen(['pgrep', '-x', '-f', self.pgrep_pattern], stdout=PIPE) |
33 |
stdout, stderr = process.communicate() |
32 |
stdout, stderr = process.communicate() |
Lines 40-98
class LogrotateService(object):
|
Link Here
|
---|
|
40 |
raise LogrotateError('multiple services of %s are started: pids=%s' % (self.service, pids)) |
39 |
raise LogrotateError('multiple services of %s are started: pids=%s' % (self.service, pids)) |
41 |
return pids[0] |
40 |
return pids[0] |
42 |
|
41 |
|
43 |
@property |
|
|
44 |
def logfile(self): |
42 |
def logfile(self): |
45 |
pid = self.pid |
43 |
pid = self.pid() |
46 |
logfile = None |
|
|
47 |
for file_ in os.listdir('/proc/%d/fd/' % (pid,)): |
44 |
for file_ in os.listdir('/proc/%d/fd/' % (pid,)): |
48 |
file_ = os.path.join('/proc/%d/fd/' % (pid,), file_) |
45 |
file_ = os.path.join('/proc/%d/fd/' % (pid,), file_) |
49 |
if os.path.islink(file_) and os.readlink(file_).startswith(self.logfile_pattern): |
46 |
if os.path.islink(file_) and os.readlink(file_).startswith(self.logfile_pattern): |
50 |
logfile = file_ |
47 |
return file_ |
51 |
break |
48 |
|
52 |
return logfile |
49 |
def stat(self): |
|
|
50 |
logfile = self.logfile() |
51 |
if not logfile: |
52 |
raise LogrotateError('No logfile for service %s found.' % (self.service,)) |
53 |
try: |
54 |
stat = os.stat(logfile) |
55 |
print logfile, stat |
56 |
except OSError: |
57 |
raise LogrotateError('%s does not exists (service=%s)' % (logfile, self.service)) |
58 |
return stat |
53 |
|
59 |
|
54 |
def service_restart(self): |
60 |
def service_restart(self): |
55 |
call(['invoke-rc.d', os.path.basename(self.service), 'restart']) |
61 |
call(['invoke-rc.d', os.path.basename(self.service), 'restart']) |
56 |
sleep(1) # give time to restart |
62 |
sleep(1) # give time to restart |
57 |
|
63 |
|
58 |
def logrotate(self): |
64 |
def pre(self): |
59 |
if call(['logrotate', '-f', '/etc/logrotate.d/univention-management-console']): |
|
|
60 |
raise LogrotateError('logrotate failed') |
61 |
|
62 |
def main(self): |
63 |
self.service_restart() |
65 |
self.service_restart() |
|
|
66 |
self.old_stat = self.stat() |
64 |
|
67 |
|
65 |
logfile = self.logfile |
68 |
def post(self): |
66 |
if not logfile: |
69 |
for i in xrange(10): |
67 |
raise LogrotateError('No logfile for service %s found.' % (self.service,)) |
70 |
if i: |
68 |
if not os.path.exists(os.readlink(logfile)): # readlink -> "/var/log/univention/management-console-server.log" |
71 |
sleep(1) |
69 |
raise LogrotateError('%s does not exists (before logrotating) (service=%s)' % (logfile, self.service)) |
72 |
new_stat = self.stat() |
70 |
|
73 |
if not os.path.samestat(self.old_stat, new_stat): |
71 |
self.logrotate() |
74 |
return |
72 |
|
75 |
raise LogrotateError('Logrotate was executed, the service %s did not reopen the logfile %s.' % ( |
73 |
if not os.path.exists(os.readlink(logfile)): # readlink -> "/var/log/univention/management-console-server.log (deleted)" |
76 |
self.service, logfile)) |
74 |
raise LogrotateError('Logrotate was executed, the service %s did not reopen the logfile.' % (self.service,)) |
|
|
75 |
|
76 |
|
77 |
class UmcServer(LogrotateService): |
78 |
|
77 |
|
79 |
def __init__(self): |
|
|
80 |
super(UmcServer, self).__init__('/usr/sbin/univention-management-console-server', '/var/log/univention/management-console-server.log') |
81 |
|
78 |
|
82 |
|
79 |
def logrotate(): |
83 |
class UmcWebServer(LogrotateService): |
80 |
cmd = ('logrotate', '-v', '-f', '/etc/logrotate.d/univention-management-console') |
84 |
|
81 |
if call(cmd): |
85 |
def __init__(self): |
82 |
raise LogrotateError('logrotate failed: %r' % (cmd,)) |
86 |
super(UmcWebServer, self).__init__('/usr/sbin/univention-management-console-web-server', '/var/log/univention/management-console-web-server.log') |
|
|
87 |
|
83 |
|
88 |
|
84 |
|
89 |
def main(): |
85 |
def main(): |
90 |
for ServiceClass in (UmcServer, UmcWebServer): |
86 |
services = [ |
91 |
service = ServiceClass() |
87 |
LogrotateService('/usr/sbin/univention-management-console-server', '/var/log/univention/management-console-server.log'), |
92 |
try: |
88 |
LogrotateService('/usr/sbin/univention-management-console-web-server', '/var/log/univention/management-console-web-server.log'), |
93 |
service.main() |
89 |
] |
94 |
except LogrotateError as exc: |
90 |
try: |
95 |
fail('ERROR: %s' % (exc,)) |
91 |
for service in services: |
|
|
92 |
service.pre() |
93 |
logrotate() |
94 |
for service in services: |
95 |
service.post() |
96 |
except LogrotateError as exc: |
97 |
fail('ERROR: %s' % (exc,)) |
98 |
|
96 |
|
99 |
|
97 |
if __name__ == '__main__': |
100 |
if __name__ == '__main__': |
98 |
main() |
101 |
main() |