From 572868c9e152a13b67112a3bbedc0583879e390a Mon Sep 17 00:00:00 2001 From: Michel Blanc Date: Thu, 3 May 2012 08:34:36 +0200 Subject: [PATCH] Adds support for Ubuntu style update-rc.d Checks if update-rc.d (Ubuntu) or chkconfig (RHEL) should be used. Adds basic bin path search for those binaries Adds 'enable' and 'disable' options for 'enable' command since it's the arguments that update-rc.d uses (this might be somewhat confusing to have a command line with 'enable=enable', but probably mkes sense for Ubuntu users). Allows use of mixed case for 'list' and 'state' commands. --- library/service | 86 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/library/service b/library/service index 38e5a0e3384..755cd5b2be6 100755 --- a/library/service +++ b/library/service @@ -24,14 +24,49 @@ except ImportError: import sys import shlex import subprocess +import os.path # TODO: switch to fail_json and other helper functions # like other modules are using # =========================================== -SERVICE = '/sbin/service' -CHKCONFIG = '/sbin/chkconfig' +SERVICE = None +CHKCONFIG = None + +def fail_json(d): + print json.dumps(d) + sys.exit(1) + +def _find_binaries(): + # list of possible paths for service/chkconfig binaries + # with the most probable first + paths = ['/sbin', '/usr/sbin', '/bin', '/usr/bin'] + binaries = [ 'service', 'chkconfig', 'update-rc.d' ] + location = dict() + + for binary in binaries: + location[binary] = None + + for path in paths: + for binary in binaries: + if os.path.exists(path + '/' + binary): + location[binary] = path + '/' + binary + break + + + + if location.get('chkconfig', None): + CHKCONFIG = location['chkconfig'] + elif location.get('update-rc.d', None): + CHKCONFIG = location['update-rc.d'] + else: + fail_json(dict(failed=True, msg='unable to find chkconfig or update-rc.d binary')) + + if location.get('service', None): + SERVICE = location['service'] + else: + fail_json(dict(failed=True, msg='unable to find service binary')) def _run(cmd): # returns (rc, stdout, stderr) from shell command @@ -41,10 +76,19 @@ def _run(cmd): def _do_enable(name, enable): - if enable.lower() in ['on', 'true', 'yes']: - rc, stdout, stderr = _run("%s %s on" % (CHKCONFIG, name)) - elif enable.lower() in ['off', 'false', 'no']: - rc, stdout, stderr = _run("%s %s off" % (CHKCONFIG, name)) + # we change argument depending on real binary used + # update-rc.d wants enable/disable while + # chkconfig wants on/off + valid_argument = dict({'on' : 'on', 'off' : 'off'}) + + if CHKCONFIG.endswith("update-rc.d"): + valid_argument['on'] = "enable" + valid_argument['off'] = "disable" + + if enable.lower() in ['on', 'true', 'yes', 'enable']: + rc, stdout, stderr = _run("%s %s %s" % (CHKCONFIG, name, valid_argument['on'])) + elif enable.lower() in ['off', 'false', 'no', 'disable']: + rc, stdout, stderr = _run("%s %s %s" % (CHKCONFIG, name, valid_argument['off'])) return rc, stdout, stderr @@ -53,37 +97,37 @@ args = open(argfile, 'r').read() items = shlex.split(args) if not len(items): - print json.dumps(dict(failed=True, msg='this module requires arguments (-a)')) - sys.exit(1) + fail_json(dict(failed=True, msg='this module requires arguments (-a)')) params = {} for arg in items: if "=" not in arg: - print json.dumps(dict(failed=True, msg='expected key=value format arguments')) - sys.exit(1) + fail_json(dict(failed=True, msg='expected key=value format arguments')) + (name, value) = arg.split("=") params[name] = value name = params.get('name', None) if name is None: - print json.dumps(dict(failed=True, msg='missing name')) - sys.exit(1) + fail_json(dict(failed=True, msg='missing name')) state = params.get('state', None) list_items = params.get('list', None) enable = params.get('enable', None) # running and started are the same -if state and state not in [ 'running', 'started', 'stopped', 'restarted' ]: - print json.dumps(dict(failed=True, msg='invalid value for state')) - sys.exit(1) -if list_items and list_items not in [ 'status' ]: - print json.dumps(dict(failed=True, msg='invalid value for list')) - sys.exit(1) -if enable and enable.lower() not in [ 'on', 'off', 'true', 'false', 'yes', 'no' ]: - print json.dumps(dict(failed=True, msg='invalid value for enable')) - sys.exit(1) +if state and state.lower() not in [ 'running', 'started', 'stopped', 'restarted' ]: + fail_json(dict(failed=True, msg='invalid value for state')) +if list_items and list_items.lower() not in [ 'status' ]: + fail_json(dict(failed=True, msg='invalid value for list')) +if enable and enable.lower() not in [ 'on', 'off', 'true', 'false', 'yes', 'no', 'enable', 'disable' ]: + fail_json(dict(failed=True, msg='invalid value for enable')) + + +# =========================================== +# find binaries locations on minion +_find_binaries() # ===========================================