From c6db4e8fa36ec7b02a7ae994643678219a02ad3b Mon Sep 17 00:00:00 2001 From: John Kleint Date: Fri, 27 Apr 2012 13:35:24 -0400 Subject: [PATCH] Get service module working with sudo, add list=status, better error messages. When running the service module via sudo, `$PATH` didn't contain `/sbin`, so the service binary couldn't be found. This just runs `/sbin/service` directly. Output is spewed to stderr on error. Added `list=status` to include the output of `service status`. --- library/service | 53 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/library/service b/library/service index c1aaf13272..27fd79a048 100755 --- a/library/service +++ b/library/service @@ -21,13 +21,22 @@ try: import json except ImportError: import simplejson as json -import os import sys import shlex import subprocess # =========================================== +SERVICE = '/sbin/service' + +def _run(cmd): + ''' :Return: A tuple of ``(returncode, stdout, stderr)`` resulting from executing + `cmd` with the shell. ''' + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + stdout, stderr = process.communicate() + return (process.returncode, stdout, stderr) + + argfile = sys.argv[1] args = open(argfile, 'r').read() items = shlex.split(args) @@ -46,26 +55,31 @@ for arg in items: name = params['name'] state = params.get('state','unknown') +list_ = params.get('list') # running and started are the same if state not in [ 'running', 'started', 'stopped', 'restarted' ]: print json.dumps(dict(failed=True, msg='invalid state')) sys.exit(1) +if list_ and list_ not in ('status',): + print json.dumps(dict(failed=True, msg='invalid argument to list')) + sys.exit(1) + # =========================================== # get service status -status = os.popen("service %s status" % name).read() +rc, stdout, stderr = _run("%s %s status" % (SERVICE, name)) # =========================================== # determine if we are going to change anything running = False -if status.find("not running") != -1: +if stdout.find("not running") != -1: running = False -elif status.find("running") != -1: +elif stdout.find("running") != -1: running = True -elif name == 'iptables' and status.find("ACCEPT") != -1: +elif name == 'iptables' and stdout.find("ACCEPT") != -1: # iptables status command output is lame # TODO: lookup if we can use a return code for this instead? running = True @@ -81,32 +95,37 @@ elif state == "restarted": # =========================================== # run change commands if we need to -def _run(cmd): - return subprocess.call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) rc = 0 if changed: if state in ('started', 'running'): - rc = _run("service %s start" % name) + rc, stdout, stderr = _run("%s %s start" % (SERVICE, name)) elif state == 'stopped': - rc = _run("service %s stop" % name) + rc, stdout, stderr = _run("%s %s stop" % (SERVICE, name)) elif state == 'restarted': - rc1 = _run("service %s stop" % name) - rc2 = _run("service %s start" % name) - rc = rc1 and rc2 + rc1, stdout1, stderr1 = _run("%s %s stop" % (SERVICE, name)) + rc2, stdout2, stderr2 = _run("%s %s start" % (SERVICE, name)) + rc = rc1 and rc2 + stdout = stdout1 + stdout2 + stderr = stderr1 + stderr2 if rc != 0: - # yeah, should probably include output of failure... print json.dumps({ "failed" : 1, - "rc" : rc + "rc" : rc, }) + print >> sys.stderr, stdout + stderr sys.exit(1) + # =============================================== # success -print json.dumps({ - "changed" : changed -}) +result = {"changed": changed} + +if list_ == 'status': + rc, stdout, stderr = _run("%s %s status" % (SERVICE, name)) + result['status'] = stdout + +print json.dumps(result)