Univention Bugzilla – Attachment 5166 Details for
Bug 31030
service_info.py broken
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Fixes, cleanup
cleanup.diff (text/plain), 7.47 KB, created by
Philipp Hahn
on 2013-04-11 15:05 CEST
(
hide
)
Description:
Fixes, cleanup
Filename:
MIME Type:
Creator:
Philipp Hahn
Created:
2013-04-11 15:05 CEST
Size:
7.47 KB
patch
obsolete
>diff --git a/branches/ucs-3.1/ucs-3.1-2/base/univention-config-registry/python/univention/service_info.py b/branches/ucs-3.1/ucs-3.1-2/base/univention-config-registry/python/univention/service_info.py >index d3542ae..316cf78 100644 >--- a/branches/ucs-3.1/ucs-3.1-2/base/univention-config-registry/python/univention/service_info.py >+++ b/branches/ucs-3.1/ucs-3.1-2/base/univention-config-registry/python/univention/service_info.py >@@ -31,64 +31,58 @@ > # /usr/share/common-licenses/AGPL-3; if not, see > # <http://www.gnu.org/licenses/>. > >-import locale > import os > import re >-import string > import shlex > > import univention.info_tools as uit > >-class Service( uit.LocalizedDictionary ): >- def __init__( self ): >- uit.LocalizedDictionary.__init__( self ) >+class Service(uit.LocalizedDictionary): >+ def __init__(self): >+ uit.LocalizedDictionary.__init__(self) > self.start_runlevel = [] > self.stop_runlevel = [] > self.start_code = 0 > self.stop_code = 0 > self.running = False > >- def check( self ): >+ def check(self): > """Check service entry for validity, returning list of incomplete entries.""" > incomplete = [] >- for key in ( 'description', 'programs' ): >- if not self.get( key, None ): >+ for key in ('description', 'programs'): >+ if not self.get(key, None): > incomplete.append(key) > return incomplete > >-def pidof( name ): >- result = [] >- for file in os.listdir( '/proc' ): >- dir = os.path.join( '/proc', file ) >- if not os.path.isdir( dir ): >- continue >- if not os.path.isfile( os.path.join( dir, 'stat' ) ): >- continue >- cmdline = os.path.join( dir, 'cmdline' ) >- if not os.path.isfile( cmdline ): >+ >+def pidof(name): >+ """ >+ Return list of process IDs matching name. >+ >>> import os,sys;str(os.getpid()) in pidof(sys.executable) >+ True >+ """ >+ cmd = shlex.split(name) >+ for proc in os.listdir('/proc'): >+ cmdline = os.path.join('/proc', proc, 'cmdline') >+ try: >+ with open(cmdline, 'r') as fd: >+ commandline = fd.read() >+ except EnvironmentError: > continue >- fd = open( cmdline ) >- cmd = fd.readline() > # kernel thread >- if not cmd: >+ if not commandline: > continue >- if '\x00' in cmd: >- args = cmd.split( '\x00' ) >+ if '\x00' in commandline: >+ args = commandline.split('\x00') > else: >- args = cmd.split(' ') >- cmd = shlex.split( name ) >+ args = commandline.split(' ') > if cmd[0] in args: >- if len( cmd ) > 1 and len( args ) >= len( cmd ): >- for i in range( 1, len( cmd ) ): >- print cmd[ i ], args[ i ] >- if cmd[ i ] != args[ i ]: >- break >- else: >- result.append( file ) >+ if len(args) >= len(cmd) > 1: >+ if all(a == c for a, c in zip(args, cmd)): >+ yield proc > else: >- result.append( file ) >+ yield proc > >- return result > > class ServiceInfo( object ): > BASE_DIR = '/etc/univention/service.info' >@@ -96,8 +90,8 @@ class ServiceInfo( object ): > CUSTOMIZED = '_customized' > FILE_SUFFIX = '.cfg' > >- RUNLEVELS = map(str, range(7)) + ['S'] >- INIT_SCRIPT_REGEX = re.compile( '(?P<action>[SK])(?P<code>[0-9]+)(?P<name>.*)' ) >+ RUNLEVELS = "0123456S" >+ INIT_SCRIPT_REGEX = re.compile('(?P<action>[SK])(?P<code>[0-9]{2})(?P<name>.+)') > > def __init__( self, install_mode = False ): > self.services = {} >@@ -106,38 +100,38 @@ class ServiceInfo( object ): > self.update_services() > > def sysv_infos( self ): >- global _runlevels, _init_link >- >- for level in _runlevels: >- for link in os.listdir( '/etc/rc%s.d/' % level ): >+ """Read start/stop levels of services.""" >+ for level in ServiceInfo.RUNLEVELS: >+ for link in os.listdir('/etc/rc%s.d/' % (level,)): > if not os.path.islink( link ): > continue >- matches = _init_link.match( link ) >- if not matches: >+ match = ServiceInfo.INIT_SCRIPT_REGEX.match(link) >+ if not match: > continue >- grp = matches.groupdict() >- >- name = grp.get( 'name', '' ) >- if not name or not name in self.services.keys(): >+ action, code, name = match.groups() >+ try: >+ service = self.service[name] >+ except LookupError: > continue >- if grp.get( 'action', '' ) == 'S': >- self.services[ name ].start_runlevels.append( level ) >- self.services[ name ].start_code = int( grp[ 'code' ] ) >- elif grp.get( 'action', '' ) == 'K': >- self.services[ name ].start_runlevels.append( level ) >- self.services[ name ].start_code = int( grp[ 'code' ] ) >- >- def __update_status( self, name, service ): >- for prog in service[ 'programs' ].split( ',' ): >- if prog and not pidof( prog.strip() ): >+ if action == 'S': >+ service.start_runlevels.append(level) >+ service.start_code = int(code) >+ elif action == 'K': >+ service.stop_runlevels.append(level) >+ service.stop_code = int(code) >+ >+ def __update_status(self, name, service): >+ for prog in service['programs'].split(','): >+ if prog and not pidof(prog.strip()): > service.running = False > break > else: > service.running = True > > def update_services( self ): >+ """Update the run state of all services.""" > for name, serv in self.services.items(): >- self.__update_status( name, serv ) >+ self.__update_status(name, serv) > > def check_services( self ): > """Return dictionary of incomplete service descriptions.""" >@@ -149,11 +143,12 @@ class ServiceInfo( object ): > return incomplete > > def write_customized( self ): >+ """Save service cusomization.""" > filename = os.path.join( ServiceInfo.BASE_DIR, ServiceInfo.SERVICES, > ServiceInfo.CUSTOMIZED ) > try: >- fd = open( filename, 'w' ) >- except: >+ fd = open(filename, 'w') >+ except IOError: > return False > > cfg = uit.UnicodeConfig() >@@ -176,14 +171,14 @@ class ServiceInfo( object ): > filename = os.path.join( ServiceInfo.BASE_DIR, ServiceInfo.SERVICES, > package + ServiceInfo.FILE_SUFFIX ) > cfg = uit.UnicodeConfig() >- cfg.read( filename ) >+ cfg.read(filename) > for sec in cfg.sections(): > # service already known? >- if not override and sec in self.services.keys(): >+ if not override and sec in self.services: > continue > srv = Service() >- for name, value in cfg.items( sec ): >- srv[ name ] = value >+ for name, value in cfg.items(sec): >+ srv[name] = value > for path in srv.get('programs', '').split(','): > # "programs" defines the "/proc/self/cmdline" of the service, > # not the executable, therefore we test for a leading "/": >@@ -191,9 +186,10 @@ class ServiceInfo( object ): > if path.startswith('/') and not os.path.exists(path.split(' ', 1)[0]): > break # ==> do not execute else > else: >- self.services[ sec ] = srv >+ self.services[sec] = srv > > def __load_services( self ): >+ """Load definition of all defined services.""" > path = os.path.join( ServiceInfo.BASE_DIR, ServiceInfo.SERVICES ) > for entry in os.listdir( path ): > # customized service descrptions are read afterwards >@@ -206,6 +202,7 @@ class ServiceInfo( object ): > self.read_customized() > > def read_customized( self ): >+ """Read service cusomization.""" > custom = os.path.join( ServiceInfo.BASE_DIR, ServiceInfo.SERVICES, > ServiceInfo.CUSTOMIZED ) > self.read_services( custom, override = True ) >@@ -217,10 +214,15 @@ class ServiceInfo( object ): > def get_service( self, name ): > '''returns a service object associated with the given name or > None if it does not exist''' >- self.services.get( name, None ) >+ return self.services.get( name, None ) > > def add_service( self, name, service ): > '''this methods adds a new service object or overrides an old > entry''' > if not service.check(): > self.services[ name ] = service >+ >+ >+if __name__ == '__main__': >+ import doctest >+ doctest.testmod()
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 31030
: 5166