From 9268aa0289349a17027290e8701ecbfcbdd2fbc6 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Tue, 30 Oct 2012 10:36:11 +0100 Subject: [PATCH 1/2] Use return codes > 255 for Ansible-specific errors. I had made and pushed this change after you already pulled the request. @dhozac indicated that it would probably be better to use return codes > 255 for anything related to Ansible itself. Which makes sens :) --- library/command | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/command b/library/command index 63f7cdc70b3..e1b5d0c240c 100755 --- a/library/command +++ b/library/command @@ -84,7 +84,7 @@ def main(): args = module.params['args'] if args.strip() == '': - module.fail_json(rc=255, msg="no command given") + module.fail_json(rc=256, msg="no command given") if chdir: os.chdir(os.path.expanduser(chdir)) @@ -99,7 +99,7 @@ def main(): except (OSError, IOError), e: module.fail_json(rc=e.errno, msg=str(e), cmd=args) except: - module.fail_json(rc=254, msg=traceback.format_exc(), cmd=args) + module.fail_json(rc=257, msg=traceback.format_exc(), cmd=args) endd = datetime.datetime.now() delta = endd - startd @@ -178,9 +178,9 @@ class CommandModule(AnsibleModule): elif m.group(2) == "chdir": v = os.path.expanduser(v) if not (os.path.exists(v) and os.path.isdir(v)): - self.fail_json(rc=253, msg="cannot change to directory '%s': path does not exist" % v) + self.fail_json(rc=258, msg="cannot change to directory '%s': path does not exist" % v) elif v[0] != '/': - self.fail_json(rc=252, msg="the path for 'chdir' argument must be fully qualified") + self.fail_json(rc=259, msg="the path for 'chdir' argument must be fully qualified") params['chdir'] = v args = r.sub("", args) params['args'] = args From 13f75e5a8ec6730cbe6f134d1bc6b4f48cc2bd7c Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 30 Oct 2012 22:06:11 -0400 Subject: [PATCH 2/2] Now can handle rc.conf and init.d/rc.d based systems Signed-off-by: Brian Coca --- library/service | 88 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/library/service b/library/service index 3426e9becad..43b86ef5a53 100755 --- a/library/service +++ b/library/service @@ -66,20 +66,29 @@ examples: ''' import platform +import os +import re SERVICE = None CHKCONFIG = None INITCTL = None +INITSCRIPT = None +RCCONF = None + PS_OPTIONS = 'auxww' -def _find_binaries(m): +def _find_binaries(m,name): # list of possible paths for service/chkconfig binaries # with the most probable first global SERVICE global CHKCONFIG global INITCTL + global INITSCRIPT + global RCCONF paths = ['/sbin', '/usr/sbin', '/bin', '/usr/bin'] binaries = [ 'service', 'chkconfig', 'update-rc.d', 'initctl', 'systemctl'] + initpaths = [ '/etc/init.d','/etc/rc.d','/usr/local/etc/rc.d' ] + rcpaths = [ '/etc/rc.conf','/usr/local/etc/rc.conf' ] location = dict() for binary in binaries: @@ -95,11 +104,20 @@ def _find_binaries(m): elif location.get('update-rc.d', None): CHKCONFIG = location['update-rc.d'] else: + for rcfile in rcpaths: + if os.path.isfile(rcfile): + RCCONF = rcfile + if not CHKCONFIG and not RCCONF: m.fail_json(msg='unable to find chkconfig or update-rc.d binary') if location.get('service', None): SERVICE = location['service'] else: - m.fail_json(msg='unable to find service binary') + for rcdir in initpaths: + initscript = "%s/%s" % (rcdir,name) + if os.path.isfile(initscript): + INITSCRIPT = initscript + if not SERVICE and not INITSCRIPT: + m.fail_json(msg='unable to find service binary nor initscript') if location.get('initctl', None): INITCTL = location['initctl'] else: @@ -196,19 +214,39 @@ def _do_enable(name, enable): if enable: on_off = "on" enable_disable = "enable" + rc = "YES" else: on_off = "off" enable_disable = "disable" - - if CHKCONFIG.endswith("update-rc.d"): - args = (CHKCONFIG, name, enable_disable) - elif CHKCONFIG.endswith("systemctl"): - args = (CHKCONFIG, enable_disable, name + ".service") + rc = "NO" + + if RCCONF: + entry = "%s_enable" % name + full_entry = '%s="%s"' % (entry,rc) + rc = open(RCCONF,"r+") + rctext = rc.read() + if re.search("^%s" % full_entry,rctext,re.M) is None: + if re.search("^%s" % entry,rctext,re.M) is None: + rctext += "\n%s" % full_entry + else: + rctext = re.sub("^%s.*" % entry,full_entry,rctext,1,re.M) + rc.truncate(0) + rc.seek(0) + rc.write(rctext) + rc.close() + + rc=0 + stderr=stdout='' else: - args = (CHKCONFIG, name, on_off) + if CHKCONFIG.endswith("update-rc.d"): + args = (CHKCONFIG, name, enable_disable) + elif CHKCONFIG.endswith("systemctl"): + args = (CHKCONFIG, enable_disable, name + ".service") + else: + args = (CHKCONFIG, name, on_off) - if enable is not None: - rc, stdout, stderr = _run("%s %s %s" % args) + if enable is not None: + rc, stdout, stderr = _run("%s %s %s" % args) return rc, stdout, stderr @@ -235,7 +273,7 @@ def main(): # =========================================== # find binaries locations on minion - _find_binaries(module) + _find_binaries(module,name) # =========================================== # get service status @@ -248,6 +286,12 @@ def main(): err = '' out = '' + # set command to run + if SERVICE: + svc_cmd = "%s %s" % (SERVICE, name) + elif INITSCRIPT: + svc_cmd = "%s" % INITSCRIPT + if module.params['enabled']: rc_enable, out_enable, err_enable = _do_enable(name, enable) rc += rc_enable @@ -273,15 +317,24 @@ def main(): # run change commands if we need to if changed: + if platform.system() == 'FreeBSD': + start = "onestart" + stop = "onestop" + reload = "onereload" + else: + start = "start" + stop = "stop" + reload = "reload" + if state in ['started', 'running']: - rc_state, stdout, stderr = _run("%s %s start" % (SERVICE, name)) + rc_state, stdout, stderr = _run("%s %s" % (svc_cmd,start)) elif state == 'stopped': - rc_state, stdout, stderr = _run("%s %s stop" % (SERVICE, name)) + rc_state, stdout, stderr = _run("%s %s" % (svc_cmd,stop)) elif state == 'reloaded': - rc_state, stdout, stderr = _run("%s %s reload" % (SERVICE, name)) + rc_state, stdout, stderr = _run("%s %s" % (svc_cmd,reload)) elif state == 'restarted': - rc1, stdout1, stderr1 = _run("%s %s stop" % (SERVICE, name)) - rc2, stdout2, stderr2 = _run("%s %s start" % (SERVICE, name)) + rc1, stdout1, stderr1 = _run("%s %s" % (svc_cmd,stop)) + rc2, stdout2, stderr2 = _run("%s %s" % (svc_cmd,start)) if rc1 != 0 and rc2 == 0: rc_state = rc + rc2 stdout = stdout2 @@ -303,7 +356,8 @@ def main(): result['enabled'] = module.params['enabled'] if state: result['state'] = state - rc, stdout, stderr = _run("%s %s status" % (SERVICE, name)) + + rc, stdout, stderr = _run("%s status" % (svc_cmd)) module.exit_json(**result) # this is magic, see lib/ansible/module_common.py