mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
498 lines
13 KiB
Python
498 lines
13 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
Service support for RHEL-based systems, including support for both upstart and sysvinit
|
|
'''
|
|
|
|
# Import python libs
|
|
import glob
|
|
import logging
|
|
import os
|
|
import stat
|
|
|
|
# Import salt libs
|
|
import salt.utils
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
__func_alias__ = {
|
|
'reload_': 'reload'
|
|
}
|
|
|
|
# Define the module's virtual name
|
|
__virtualname__ = 'service'
|
|
|
|
# Import upstart module if needed
|
|
HAS_UPSTART = False
|
|
if salt.utils.which('initctl'):
|
|
try:
|
|
# Don't re-invent the wheel, import the helper functions from the
|
|
# upstart module.
|
|
from salt.modules.upstart \
|
|
import _upstart_enable, _upstart_disable, _upstart_is_enabled
|
|
except Exception as exc:
|
|
log.error('Unable to import helper functions from '
|
|
'salt.modules.upstart: {0}'.format(exc))
|
|
else:
|
|
HAS_UPSTART = True
|
|
|
|
|
|
def __virtual__():
|
|
'''
|
|
Only work on select distros which still use Red Hat's /usr/bin/service for
|
|
management of either sysvinit or a hybrid sysvinit/upstart init system.
|
|
'''
|
|
# Enable on these platforms only.
|
|
enable = set((
|
|
'RedHat',
|
|
'CentOS',
|
|
'ScientificLinux',
|
|
'CloudLinux',
|
|
'Amazon',
|
|
'Fedora',
|
|
'ALT',
|
|
'OEL',
|
|
'SUSE Enterprise Server',
|
|
'SUSE',
|
|
'McAfee OS Server'
|
|
))
|
|
if __grains__['os'] in enable:
|
|
if __grains__['os'] == 'SUSE':
|
|
if __grains__['osrelease'].startswith('11'):
|
|
return __virtualname__
|
|
else:
|
|
return False
|
|
try:
|
|
osrelease = float(__grains__.get('osrelease', 0))
|
|
except ValueError:
|
|
return False
|
|
if __grains__['os'] == 'Fedora':
|
|
if osrelease > 15:
|
|
return False
|
|
if __grains__['os'] in ('RedHat', 'CentOS', 'ScientificLinux'):
|
|
if osrelease >= 7:
|
|
return False
|
|
return __virtualname__
|
|
return False
|
|
|
|
|
|
def _runlevel():
|
|
'''
|
|
Return the current runlevel
|
|
'''
|
|
out = __salt__['cmd.run']('/sbin/runlevel')
|
|
# unknown will be returned while inside a kickstart environment, since
|
|
# this is usually a server deployment it should be safe to assume runlevel
|
|
# 3. If not all service related states will throw an out of range
|
|
# exception here which will cause other functions to fail.
|
|
if 'unknown' in out:
|
|
return '3'
|
|
else:
|
|
return out.split()[1]
|
|
|
|
|
|
def _chkconfig_add(name):
|
|
'''
|
|
Run 'chkconfig --add' for a service whose script is installed in
|
|
/etc/init.d. The service is initially configured to be disabled at all
|
|
run-levels.
|
|
'''
|
|
cmd = '/sbin/chkconfig --add {0}'.format(name)
|
|
if __salt__['cmd.retcode'](cmd) == 0:
|
|
log.info('Added initscript "{0}" to chkconfig'.format(name))
|
|
return True
|
|
else:
|
|
log.error('Unable to add initscript "{0}" to chkconfig'.format(name))
|
|
return False
|
|
|
|
|
|
def _service_is_upstart(name):
|
|
'''
|
|
Return True if the service is an upstart service, otherwise return False.
|
|
'''
|
|
return HAS_UPSTART and os.path.exists('/etc/init/{0}.conf'.format(name))
|
|
|
|
|
|
def _service_is_sysv(name):
|
|
'''
|
|
Return True if the service is a System V service (includes those managed by
|
|
chkconfig); otherwise return False.
|
|
'''
|
|
try:
|
|
# Look for user-execute bit in file mode.
|
|
return bool(os.stat(
|
|
os.path.join('/etc/init.d', name)).st_mode & stat.S_IXUSR)
|
|
except OSError:
|
|
return False
|
|
|
|
|
|
def _service_is_chkconfig(name):
|
|
'''
|
|
Return True if the service is managed by chkconfig.
|
|
'''
|
|
cmdline = '/sbin/chkconfig --list {0}'.format(name)
|
|
return __salt__['cmd.retcode'](cmdline, ignore_retcode=True) == 0
|
|
|
|
|
|
def _sysv_is_enabled(name, runlevel=None):
|
|
'''
|
|
Return True if the sysv (or chkconfig) service is enabled for the specified
|
|
runlevel; otherwise return False. If `runlevel` is None, then use the
|
|
current runlevel.
|
|
'''
|
|
# Try chkconfig first.
|
|
result = _chkconfig_is_enabled(name, runlevel)
|
|
if result:
|
|
return True
|
|
|
|
if runlevel is None:
|
|
runlevel = _runlevel()
|
|
return (
|
|
len(glob.glob('/etc/rc.d/rc{0}.d/S??{1}'.format(runlevel, name))) > 0)
|
|
|
|
|
|
def _chkconfig_is_enabled(name, runlevel=None):
|
|
'''
|
|
Return True if the service is enabled according to chkconfig; otherwise
|
|
return False. If `runlevel` is None, then use the current runlevel.
|
|
'''
|
|
cmdline = '/sbin/chkconfig --list {0}'.format(name)
|
|
result = __salt__['cmd.run_all'](cmdline)
|
|
if result['retcode'] == 0:
|
|
cols = result['stdout'].splitlines()[0].split()
|
|
try:
|
|
if cols[0].strip(':') == name:
|
|
if runlevel is None:
|
|
runlevel = _runlevel()
|
|
if len(cols) > 3 and '{0}:on'.format(runlevel) in cols:
|
|
return True
|
|
elif len(cols) < 3 and cols[1] and cols[1] == 'on':
|
|
return True
|
|
except IndexError:
|
|
pass
|
|
return False
|
|
|
|
|
|
def _sysv_enable(name):
|
|
'''
|
|
Enable the named sysv service to start at boot. The service will be enabled
|
|
using chkconfig with default run-levels if the service is chkconfig
|
|
compatible. If chkconfig is not available, then this will fail.
|
|
'''
|
|
if not _service_is_chkconfig(name) and not _chkconfig_add(name):
|
|
return False
|
|
cmd = '/sbin/chkconfig {0} on'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def _sysv_disable(name):
|
|
'''
|
|
Disable the named sysv service from starting at boot. The service will be
|
|
disabled using chkconfig with default run-levels if the service is chkconfig
|
|
compatible; otherwise, the service will be disabled for the current
|
|
run-level only.
|
|
'''
|
|
if not _service_is_chkconfig(name) and not _chkconfig_add(name):
|
|
return False
|
|
cmd = '/sbin/chkconfig {0} off'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def _upstart_services():
|
|
'''
|
|
Return list of upstart services.
|
|
'''
|
|
if HAS_UPSTART:
|
|
return [os.path.basename(name)[:-5]
|
|
for name in glob.glob('/etc/init/*.conf')]
|
|
else:
|
|
return []
|
|
|
|
|
|
def _sysv_services():
|
|
'''
|
|
Return list of sysv services.
|
|
'''
|
|
ret = []
|
|
return [name for name in os.listdir('/etc/init.d')
|
|
if _service_is_sysv(name)]
|
|
|
|
|
|
def get_enabled(limit=''):
|
|
'''
|
|
Return the enabled services. Use the ``limit`` param to restrict results
|
|
to services of that type.
|
|
|
|
CLI Examples:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.get_enabled
|
|
salt '*' service.get_enabled limit=upstart
|
|
salt '*' service.get_enabled limit=sysvinit
|
|
'''
|
|
limit = limit.lower()
|
|
if limit == 'upstart':
|
|
return sorted(name for name in _upstart_services()
|
|
if _upstart_is_enabled(name))
|
|
elif limit == 'sysvinit':
|
|
runlevel = _runlevel()
|
|
return sorted(name for name in _sysv_services()
|
|
if _sysv_is_enabled(name, runlevel))
|
|
else:
|
|
runlevel = _runlevel()
|
|
return sorted(
|
|
[name for name in _upstart_services()
|
|
if _upstart_is_enabled(name)]
|
|
+ [name for name in _sysv_services()
|
|
if _sysv_is_enabled(name, runlevel)])
|
|
|
|
|
|
def get_disabled(limit=''):
|
|
'''
|
|
Return the disabled services. Use the ``limit`` param to restrict results
|
|
to services of that type.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.get_disabled
|
|
salt '*' service.get_disabled limit=upstart
|
|
salt '*' service.get_disabled limit=sysvinit
|
|
'''
|
|
limit = limit.lower()
|
|
if limit == 'upstart':
|
|
return sorted(name for name in _upstart_services()
|
|
if not _upstart_is_enabled(name))
|
|
elif limit == 'sysvinit':
|
|
runlevel = _runlevel()
|
|
return sorted(name for name in _sysv_services()
|
|
if not _sysv_is_enabled(name, runlevel))
|
|
else:
|
|
runlevel = _runlevel()
|
|
return sorted(
|
|
[name for name in _upstart_services()
|
|
if not _upstart_is_enabled(name)]
|
|
+ [name for name in _sysv_services()
|
|
if not _sysv_is_enabled(name, runlevel)])
|
|
|
|
|
|
def get_all(limit=''):
|
|
'''
|
|
Return all installed services. Use the ``limit`` param to restrict results
|
|
to services of that type.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.get_all
|
|
salt '*' service.get_all limit=upstart
|
|
salt '*' service.get_all limit=sysvinit
|
|
'''
|
|
limit = limit.lower()
|
|
if limit == 'upstart':
|
|
return sorted(_upstart_services())
|
|
elif limit == 'sysvinit':
|
|
return sorted(_sysv_services())
|
|
else:
|
|
return sorted(_sysv_services() + _upstart_services())
|
|
|
|
|
|
def available(name, limit=''):
|
|
'''
|
|
Return True if the named service is available. Use the ``limit`` param to
|
|
restrict results to services of that type.
|
|
|
|
CLI Examples:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.available sshd
|
|
salt '*' service.available sshd limit=upstart
|
|
salt '*' service.available sshd limit=sysvinit
|
|
'''
|
|
if limit == 'upstart':
|
|
return _service_is_upstart(name)
|
|
elif limit == 'sysvinit':
|
|
return _service_is_sysv(name)
|
|
else:
|
|
return _service_is_upstart(name) or _service_is_sysv(name) or _service_is_chkconfig(name)
|
|
|
|
|
|
def missing(name, limit=''):
|
|
'''
|
|
The inverse of service.available.
|
|
Return True if the named service is not available. Use the ``limit`` param to
|
|
restrict results to services of that type.
|
|
|
|
CLI Examples:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.missing sshd
|
|
salt '*' service.missing sshd limit=upstart
|
|
salt '*' service.missing sshd limit=sysvinit
|
|
'''
|
|
if limit == 'upstart':
|
|
return not _service_is_upstart(name)
|
|
elif limit == 'sysvinit':
|
|
return not _service_is_sysv(name)
|
|
else:
|
|
if _service_is_upstart(name) or _service_is_sysv(name):
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
|
|
def start(name):
|
|
'''
|
|
Start the specified service
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.start <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
cmd = 'start {0}'.format(name)
|
|
else:
|
|
cmd = '/sbin/service {0} start'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def stop(name):
|
|
'''
|
|
Stop the specified service
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.stop <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
cmd = 'stop {0}'.format(name)
|
|
else:
|
|
cmd = '/sbin/service {0} stop'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def restart(name):
|
|
'''
|
|
Restart the named service
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.restart <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
cmd = 'restart {0}'.format(name)
|
|
else:
|
|
cmd = '/sbin/service {0} restart'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def reload_(name):
|
|
'''
|
|
Reload the named service
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.reload <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
cmd = 'reload {0}'.format(name)
|
|
else:
|
|
cmd = '/sbin/service {0} reload'.format(name)
|
|
return not __salt__['cmd.retcode'](cmd)
|
|
|
|
|
|
def status(name, sig=None):
|
|
'''
|
|
Return the status for a service, returns a bool whether the service is
|
|
running.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.status <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
cmd = 'status {0}'.format(name)
|
|
return 'start/running' in __salt__['cmd.run'](cmd)
|
|
if sig:
|
|
return bool(__salt__['status.pid'](sig))
|
|
cmd = '/sbin/service {0} status'.format(name)
|
|
return __salt__['cmd.retcode'](cmd, ignore_retcode=True) == 0
|
|
|
|
|
|
def enable(name, **kwargs):
|
|
'''
|
|
Enable the named service to start at boot
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.enable <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
return _upstart_enable(name)
|
|
else:
|
|
return _sysv_enable(name)
|
|
|
|
|
|
def disable(name, **kwargs):
|
|
'''
|
|
Disable the named service to start at boot
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.disable <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
return _upstart_disable(name)
|
|
else:
|
|
return _sysv_disable(name)
|
|
|
|
|
|
def enabled(name):
|
|
'''
|
|
Check to see if the named service is enabled to start on boot
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.enabled <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
return _upstart_is_enabled(name)
|
|
else:
|
|
return _sysv_is_enabled(name)
|
|
|
|
|
|
def disabled(name):
|
|
'''
|
|
Check to see if the named service is disabled to start on boot
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt '*' service.disabled <service name>
|
|
'''
|
|
if _service_is_upstart(name):
|
|
return not _upstart_is_enabled(name)
|
|
else:
|
|
return not _sysv_is_enabled(name)
|