rpmlint/InitScriptCheck.py

147 lines
5.5 KiB
Python

#---------------------------------------------------------------
# Project : Mandrake Linux
# Module : rpmlint
# File : InitScriptCheck.py
# Version : $Id$
# Author : Frederic Lepied
# Created On : Fri Aug 25 09:26:37 2000
# Purpose : check init scripts (files in /etc/rc.d/init.d)
#---------------------------------------------------------------
from Filter import *
import AbstractCheck
import re
import rpm
import Pkg
import string
rc_regex=re.compile('^/etc(/rc.d)?/init.d/')
chkconfig_content_regex=re.compile('# +chkconfig: +([-0-9]+) +[-0-9]+ +[-0-9]+', re.MULTILINE)
subsys_regex=re.compile('/var/lock/subsys/([^/\n ]+)', re.MULTILINE)
chkconfig_regex=re.compile('^[^#]*(chkconfig|add-service|del-service)', re.MULTILINE)
status_regex=re.compile('^[^#]*status', re.MULTILINE)
reload_regex=re.compile('^[^#]*reload', re.MULTILINE)
basename_regex=re.compile('([^/]+)$')
dot_in_name_regex=re.compile('.*\..*')
class InitScriptCheck(AbstractCheck.AbstractCheck):
def __init__(self):
AbstractCheck.AbstractCheck.__init__(self, 'InitScriptCheck')
def check(self, pkg):
# Check only binary package
if pkg.isSource():
return
list=[]
for f in pkg.files().keys():
if rc_regex.search(f):
basename=basename_regex.search(f).group(1)
list.append(basename)
if dot_in_name_regex.match(basename):
printError(pkg, 'init-script-name-with-dot', f)
# check chkconfig call in %post and %preun
postin=pkg[rpm.RPMTAG_POSTIN] or pkg[rpm.RPMTAG_POSTINPROG]
if not postin:
printError(pkg, 'init-script-without-chkconfig-postin', f)
else:
if not chkconfig_regex.search(postin):
printError(pkg, 'postin-without-chkconfig', f)
preun=pkg[rpm.RPMTAG_PREUN] or pkg[rpm.RPMTAG_PREUNPROG]
if not preun:
printError(pkg, 'init-script-without-chkconfig-preun', f)
else:
if not chkconfig_regex.search(preun):
printError(pkg, 'preun-without-chkconfig', f)
# check common error in file content
fd=open(pkg.dirName() + '/' + f, 'r')
content=fd.read(-1)
fd.close()
if not status_regex.search(content):
printError(pkg, 'no-status-entry', f)
if not reload_regex.search(content):
printWarning(pkg, 'no-reload-entry', f)
res=chkconfig_content_regex.search(content)
if not res:
printError(pkg, 'no-chkconfig-line', f)
else:
if res.group(1) == '-':
printWarning(pkg, 'no-default-runlevel')
res=subsys_regex.search(content)
if not res:
printError(pkg, 'subsys-not-used', f)
else:
name=res.group(1)
if name != basename:
error=1
if name[0] == '$':
value=Pkg.substitute_shell_vars(name, content)
if value == basename:
error=0
if error:
printError(pkg, 'incoherent-subsys', f, name)
if len(list) == 1 and string.lower(pkg[rpm.RPMTAG_NAME]) != list[0]:
printWarning(pkg, 'incoherent-init-script-name', list[0])
# Create an object to enable the auto registration of the test
check=InitScriptCheck()
if Config.info:
addDetails(
'init-script-without-chkconfig-postin',
'''The package contains an initscript but doesn't contain a %post with
a call to chkconfig.''',
'postin-without-chkconfig',
'''The package contains an initscript but doesn't call chkconfig in its %post.''',
'init-script-without-chkconfig-preun',
'''The package contains an initscript but doesn't contain a %preun with
a call to chkconfig.''',
'preun-without-chkconfig',
'''The package contains an initscript but doesn't call chkconfig in its %preun.''',
'no-status-entry',
'''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'status' entry, which is necessary for a good functionnality.''',
'no-reload-entry',
'''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'reload' entry, which is necessary for a good functionnality.''',
'no-chkconfig-line',
'''The initscript doesn't contain a chkconfig line to specify the runlevels at which
to start and stop it.''',
'no-default-runlevel',
'''The default runlevel isn't specified in the initscript.''',
'subsys-not-used',
'''While your program is running, you have to put a lock file in
/var/lock/subsys/. To see an example, look at this directory on your
machine.''',
'incoherent-subsys',
'''The filename of your lock file in /var/lock/subsys/ is incoherent
with your actual init script name. For example, if your script name
is httpd, you have to put a 'httpd' file in your subsys directory.''',
'incoherent-init-script-name',
'''The init script name should be the same as the package name in lower case.''',
'init-script-name-with-dot',
'''The init script name should not contains a dot in the name.
it would not be taken in account by chkconfig'''
)
# InitScriptCheck.py ends here