Blame | Last modification | View Log | RSS feed
def ConfigureService(serviceName, description, lsbStartDep, lsbStopDep, lsbStartBefore,lsbStopAfter, chkcfgStartLevel, chkcfgStopLevel):"""Configure a service using the program appropriate for the current system.Right now we support insserv, chkconfig, and update-rc.d******** READ ME ... IMPORTANT!**************** This function expects the component using it to have the initinfo scripts in******** initinfo/initinfo.*. They shouldn't be installed, they should just be included******** in the component. Without them, it will fail.********@param serviceName: The service name, matches the script name@param description: Text description of the service. Single-line only@param lsbStartDep: Space separated list of services that must be started *before* this service.@param lsbStopDep: Space separated list of services that must be stopped *after* this service.@param lsbStartBefore: Space separated list of reverse deps. This package must start before these.@param lsbStopAfter: Space separated list of reverse deps. This package must stop after these.@param chkcfgStartLevel: The start number for chkconfig or update-rc.d scripts@param chkcfgStopLevel: The stop number for chkconfig or update-rc.d scripts"""scriptFile = INITSCRIPTDIR/serviceNameif not INITSCRIPTDIR or not scriptFile.exists():# TODO: Raise a dialog informing the user that we are unable to add init script links.# TODO: This can take the place of Workstation's current message for Gentoo and Arch# TODO: systems.returnscript = scriptFile.text()(initType, initProgram) = InitConfigProgram()if not initType:# We can't use a program to do it for us, lay down the links ourselves.if not INITDIR:# TODO: Raise a dialog informing the user that we are unable to add init script links.# TODO: This can take the place of Workstation's current message for Gentoo and Arch# TODO: systems.log.Warn('INITDIR has not been set. No rc?.d style dirs ''to populate.')returnscript = INITSCRIPTDIR/serviceNamepattern = 'rc%(runlevel)d.d/%(letter)s%(priority)02d%(name)s'for runlevel in (2, 3, 5):# Build symlinks for this runlevelstartLink = path(INITDIR/(pattern % {'runlevel': runlevel, 'letter': 'S','priority': chkcfgStartLevel, 'name': serviceName}))stopLink = path(INITDIR/(pattern % {'runlevel': runlevel, 'letter': 'K','priority': chkcfgStopLevel, 'name': serviceName}))try:script.symlink(startLink)except OSError as e:pass # Okay if it already existstry:script.symlink(stopLink)except OSError as e:pass # Okay if it already exists# Register files with the installer. It will clean them up on uninstall.inst.RegisterFile(startLink)inst.RegisterFile(stopLink)if initType == 'insserv':# Add the insserv style header and add our serviceinitheader = inst.GetFileText('initinfo/initinfo.lsb')initheader = re.sub('@@SERVICE_NAME@@', serviceName, initheader)initheader = re.sub('@@LSB_SERVICE_START_DEP@@', lsbStartDep, initheader)initheader = re.sub('@@LSB_SERVICE_STOP_DEP@@', lsbStopDep, initheader)initheader = re.sub('@@LSB_SERVICE_START_BEFORE_DEP@@', lsbStartBefore, initheader)initheader = re.sub('@@LSB_SERVICE_STOP_AFTER_DEP@@', lsbStopAfter, initheader)initheader = re.sub('@@SERVICE_DESCRIPTION@@', description, initheader)txt = re.sub('# VMWARE_INIT_INFO', initheader, script, re.DOTALL)scriptFile.write_text(txt)inst.RunCommand('/bin/sh', '-c', '%s -f %s >/dev/null 2>&1' % (initProgram, serviceName), ignoreErrors=True)if initType == 'chkconfig':# Add the chkconfig style header and add our serviceinitheader = inst.GetFileText('initinfo/initinfo.chkconfig')initheader = re.sub('@@CHKCFG_START_LEVEL@@', str(chkcfgStartLevel), initheader)initheader = re.sub('@@CHKCFG_STOP_LEVEL@@', str(chkcfgStopLevel), initheader)initheader = re.sub('@@SERVICE_DESCRIPTION@@', description, initheader)txt = re.sub('# VMWARE_INIT_INFO', initheader, script, re.DOTALL)scriptFile.write_text(txt)inst.RunCommand(initProgram, '--add', serviceName, ignoreErrors=True)if initType == 'update-rc.d':# Add the insserv style header and add our serviceinitheader = inst.GetFileText('initinfo/initinfo.updaterc')initheader = re.sub('@@SERVICE_NAME@@', serviceName, initheader)initheader = re.sub('@@LSB_SERVICE_START_DEP@@', lsbStartDep, initheader)initheader = re.sub('@@LSB_SERVICE_STOP_DEP@@', lsbStopDep, initheader)initheader = re.sub('@@LSB_SERVICE_START_BEFORE_DEP@@', lsbStartBefore, initheader)initheader = re.sub('@@LSB_SERVICE_STOP_AFTER_DEP@@', lsbStopAfter, initheader)initheader = re.sub('@@SERVICE_DESCRIPTION@@', description, initheader)txt = re.sub('# VMWARE_INIT_INFO', initheader, script, re.DOTALL)scriptFile.write_text(txt)inst.RunCommand(initProgram, serviceName,'start', chkcfgStartLevel, '2', '3', '4', '.','stop', chkcfgStopLevel, '0', '6', '.', ignoreErrors=True)log.Info('Installed Service: %s' % serviceName)def DeconfigureService(serviceName):(initType, initProgram) = InitConfigProgram()if not initType:# The links have been registered with the installer. It will remove them on# uninstall.passif initType == 'insserv':inst.RunCommand('/bin/sh', '-c', '%s -f -r %s >/dev/null 2>&1' % (initProgram, serviceName), ignoreErrors=True)if initType == 'chkconfig':inst.RunCommand(initProgram, '--del', serviceName, ignoreErrors=True)if initType == 'update-rc.d':inst.RunCommand(initProgram, '-f', serviceName, 'remove', ignoreErrors=True)log.Info('Uninstalled Service: %s' % serviceName)def InitConfigProgram():"""Scan the system to try and guess the program that sets up the init script links.On RHEL, it's chkconfig, on SuSE it's insserv, and on Ubuntu it's update-rc.d.NOTE: Don't use insserv on Ubuntu per bug 776485. Ubuntu so very wisely shipsit but expects developers not to use it."""# First, check for update-rc.d b/c we want to use it instead# of insserv on Ubuntu and Debian systems.if path('/usr/sbin/update-rc.d').isexe():return ('update-rc.d', '/usr/sbin/update-rc.d')elif path('/sbin/update-rc.d').isexe():return ('update-rc.d', '/sbin/update-rc.d')elif (_which('update-rc.d')):return ('update-rc.d', _which('update-rc.d'))if path('/sbin/insserv').isexe():return ('insserv', '/sbin/insserv')elif _which('insserv'):return ('insserv', _which('insserv'))if path('/sbin/chkconfig').isexe():return ('chkconfig', '/sbin/chkconfig')elif (_which('chkconfig')):return ('chkconfig', _which('chkconfig'))# XXX: Add support for upstart in the future.return (None, None)def _which(program):"""Gets the PATH environment variable and checks for programin order.@param program: Executable to search for@returns: Full path if found and executable, None otherwise"""# XXX: Borrowed from util/shell.py. This should be broken into a# utility file to be used by both components and the main code.systemPath = ENV['PATH']paths = systemPath.split(':')for p in paths:fullPath = path(p)/programif fullPath.isexe():return str(fullPath) # Return a string, not a path objectreturn None