The service module made some assumptions about how a service should be managed based on what was installed on the system in terms of service

management tools, which meant upstart services on CentOS6 were not startable.  This tweak allows things like vmware-tools to be controlled
via the service module.  More testing on other distributions (particularly with systemd) is presumably needed.
This commit is contained in:
Michael DeHaan 2013-02-23 20:31:29 -05:00
parent 362d91004f
commit f7f4743746

71
service
View file

@ -345,39 +345,45 @@ class LinuxService(Service):
distribution = None distribution = None
def get_service_tools(self): def get_service_tools(self):
paths = [ '/sbin', '/usr/sbin', '/bin', '/usr/bin' ] paths = [ '/sbin', '/usr/sbin', '/bin', '/usr/bin' ]
binaries = [ 'service', 'chkconfig', 'update-rc.d', 'initctl', 'systemctl' ] binaries = [ 'service', 'chkconfig', 'update-rc.d', 'initctl', 'systemctl', 'start', 'stop', 'restart' ]
initpaths = [ '/etc/init.d' ] initpaths = [ '/etc/init.d' ]
location = dict() location = dict()
for binary in binaries: for binary in binaries:
location[binary] = None location[binary] = None
for binary in binaries: for binary in binaries:
location[binary] = self.module.get_bin_path(binary) location[binary] = self.module.get_bin_path(binary)
# Locate a tool for enable options # Locate a tool for enable options
if location.get('systemctl', None): if location.get('chkconfig', None) and os.path.exists("/etc/init.d/%s" % self.name):
self.enable_cmd = location['systemctl'] # we are using a standard SysV service
elif location.get('chkconfig', None):
self.enable_cmd = location['chkconfig'] self.enable_cmd = location['chkconfig']
elif location.get('update-rc.d', None): elif location.get('update-rc.d', None) and os.path.exists("/etc/init/%s.conf" % self.name):
# service is managed by upstart
self.enable_cmd = location['update-rc.d'] self.enable_cmd = location['update-rc.d']
elif location.get('systemctl', None):
if self.enable_cmd is None: # service is managed by systemd
self.module.fail_json(msg='unable to find enable binary') self.enable_cmd = location['systemctl']
# Locate a tool for runtime service management (start, stop etc.) # Locate a tool for runtime service management (start, stop etc.)
if location.get('service', None): self.svc_cmd = ''
if location.get('service', None) and os.path.exists("/etc/init.d/%s" % self.name):
# SysV init script
self.svc_cmd = location['service'] self.svc_cmd = location['service']
elif location.get('start', None) and os.path.exists("/etc/init/%s.conf" % self.name):
# upstart -- rather than being managed by one command, start/stop/restart are actual commands
self.svc_cmd = ''
else: else:
# still a SysV init script, but /sbin/service isn't installed
for initdir in initpaths: for initdir in initpaths:
initscript = "%s/%s" % (initdir,self.name) initscript = "%s/%s" % (initdir,self.name)
if os.path.isfile(initscript): if os.path.isfile(initscript):
self.svc_initscript = initscript self.svc_initscript = initscript
if not self.svc_cmd and not self.svc_initscript: if self.svc_cmd is None and not self.svc_initscript:
self.module.fail_json(msg='unable to find service binary nor initscript') self.module.fail_json(msg='cannot find \'service\' binary or init script for service, aborting')
if location.get('initctl', None): if location.get('initctl', None):
self.svc_initctl = location['initctl'] self.svc_initctl = location['initctl']
@ -386,7 +392,7 @@ class LinuxService(Service):
self.action = "status" self.action = "status"
rc, status_stdout, status_stderr = self.service_control() rc, status_stdout, status_stderr = self.service_control()
# Check if we have upstart on the system and then the job state # if we have decided the service is managed by upstart, we check for some additional output...
if self.svc_initctl and self.running is None: if self.svc_initctl and self.running is None:
# check the job status by upstart response # check the job status by upstart response
initctl_rc, initctl_status_stdout, initctl_status_stderr = self.execute_command("%s status %s" % (self.svc_initctl, self.name)) initctl_rc, initctl_status_stdout, initctl_status_stderr = self.execute_command("%s status %s" % (self.svc_initctl, self.name))
@ -434,10 +440,14 @@ class LinuxService(Service):
def service_enable(self): def service_enable(self):
if self.enable_cmd is None:
self.module.fail_json(msg='unable to find enable binary')
# we change argument depending on real binary used # we change argument depending on real binary used
# update-rc.d wants enable/disable while # update-rc.d wants enable/disable while
# chkconfig wants on/off # chkconfig wants on/off
# also, systemctl needs the arguments reversed # also, systemctl needs the argument order reversed
if self.enable: if self.enable:
on_off = "on" on_off = "on"
enable_disable = "enable" enable_disable = "enable"
@ -463,19 +473,42 @@ class LinuxService(Service):
if self.enable is not None and changed: if self.enable is not None and changed:
return self.execute_command("%s %s %s" % args) return self.execute_command("%s %s %s" % args)
def service_control(self): def service_control(self):
# Decide what command to run # Decide what command to run
svc_cmd = ''
if self.svc_cmd: if self.svc_cmd:
# SysV or systemd
svc_cmd = "%s %s" % (self.svc_cmd, self.name) svc_cmd = "%s %s" % (self.svc_cmd, self.name)
elif self.svc_initscript: elif self.svc_initscript:
# upstart
svc_cmd = "%s" % self.svc_initscript svc_cmd = "%s" % self.svc_initscript
if self.action is not "restart": if self.action is not "restart":
rc_state, stdout, stderr = self.execute_command("%s %s %s" % (svc_cmd, self.action, self.arguments), daemonize=True) if svc_cmd != '':
# upstart
rc_state, stdout, stderr = self.execute_command("%s %s %s" % (svc_cmd, self.action, self.arguments), daemonize=True)
else:
# SysV or systemd
rc_state, stdout, stderr = self.execute_command("%s %s %s" % (self.action, self.name, self.arguments), daemonize=True)
else: else:
rc1, stdout1, stderr1 = self.execute_command("%s %s %s" % (svc_cmd, 'stop', self.arguments), daemonize=True) # not all services support restart. Do it the hard way.
rc2, stdout2, stderr2 = self.execute_command("%s %s %s" % (svc_cmd, 'start', self.arguments), daemonize=True) if svc_cmd != '':
# upstart
rc1, stdout1, stderr1 = self.execute_command("%s %s %s" % (svc_cmd, 'stop', self.arguments), daemonize=True)
else:
# SysV or systemd
rc1, stdout1, stderr1 = self.execute_command("%s %s %s" % ('stop', self.name, self.arguments), daemonize=True)
if svc_cmd != '':
# upstart
rc2, stdout2, stderr2 = self.execute_command("%s %s %s" % (svc_cmd, 'start', self.arguments), daemonize=True)
else:
# SysV or systemd
rc2, stdout2, stderr2 = self.execute_command("%s %s %s" % ('start', self.name, self.arguments), daemonize=True)
# merge return information
if rc1 != 0 and rc2 == 0: if rc1 != 0 and rc2 == 0:
rc_state = rc2 rc_state = rc2
stdout = stdout2 stdout = stdout2