aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2014-04-06 17:15:15 +0100
committerBryn M. Reeves <bmr@redhat.com>2014-04-06 17:15:15 +0100
commit57cacaf8bcf3a91f2719ad628463f032e6c1bacc (patch)
treecb363775e725f0dfcc7f98dc4e372a629253c513
parente517935bb7ddd230d885bc7c3f076fb82ad908c2 (diff)
downloadsos-57cacaf8bcf3a91f2719ad628463f032e6c1bacc.tar.gz
Add 'runat' parameter to command output interfaces
Add a new 'runat' parameter sos_get_command_output() to specify a directory for the child to switch to before executing the given command and propagate this through the various command output collection interfaces. Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
-rw-r--r--sos/plugins/__init__.py34
-rw-r--r--sos/utilities.py16
2 files changed, 36 insertions, 14 deletions
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
index f5042b41..052725d0 100644
--- a/sos/plugins/__init__.py
+++ b/sos/plugins/__init__.py
@@ -441,8 +441,8 @@ class Plugin(object):
self.copy_paths.update(copy_paths)
self.log_debug("added copyspec '%s'" % copyspec)
- def get_command_output(self, prog, timeout=300):
- result = sos_get_command_output(prog, timeout)
+ def get_command_output(self, prog, timeout=300, runat=None):
+ result = sos_get_command_output(prog, timeout, runat)
if result['status'] == 124:
self.log_warn("command '%s' timed out after %ds"
% (prog, timeout))
@@ -450,12 +450,12 @@ class Plugin(object):
self.log_debug("could not run '%s': command not found" % prog)
return result
- def call_ext_prog(self, prog, timeout=300):
+ def call_ext_prog(self, prog, timeout=300, runat=None):
"""Execute a command independantly of the output gathering part of
sosreport.
"""
# pylint: disable-msg = W0612
- return self.get_command_output(prog, timeout)
+ return self.get_command_output(prog, timeout, runat)
def check_ext_prog(self, prog):
"""Execute a command independently of the output gathering part of
@@ -465,9 +465,17 @@ class Plugin(object):
return (self.call_ext_prog(prog)['status'] == 0)
- def add_cmd_output(self, exe, suggest_filename=None, root_symlink=None, timeout=300):
+ def add_cmd_output(
+ self, exe,
+ suggest_filename=None,
+ root_symlink=None,
+ timeout=300,
+ runat=None
+ ):
"""Run a program and collect the output"""
- self.collect_cmds.append( (exe, suggest_filename, root_symlink, timeout) )
+ self.collect_cmds.append((
+ exe, suggest_filename, root_symlink, timeout, runat
+ ))
self.log_debug("added cmd output '%s'" % exe)
def get_cmd_output_path(self, name=None, make=True):
@@ -515,12 +523,18 @@ class Plugin(object):
self.copy_strings.append((content, filename))
self.log_debug("added string '%s' as '%s'" % (content,filename))
- def get_cmd_output_now(self, exe, suggest_filename=None, root_symlink=False, timeout=300):
+ def get_cmd_output_now(
+ self, exe,
+ suggest_filename=None,
+ root_symlink=False,
+ timeout=300,
+ runat=None
+ ):
"""Execute a command and save the output to a file for inclusion in the
report.
"""
# pylint: disable-msg = W0612
- result = self.get_command_output(exe, timeout=timeout)
+ result = self.get_command_output(exe, timeout, runat)
if (result['status'] == 127):
return None
@@ -567,11 +581,11 @@ class Plugin(object):
def collect_cmd_output(self):
for progs in zip(self.collect_cmds):
- prog, suggest_filename, root_symlink, timeout = progs[0]
+ prog, suggest_filename, root_symlink, timeout, runat = progs[0]
self.log_info("collecting output of '%s'" % prog)
try:
self.get_cmd_output_now(prog, suggest_filename,
- root_symlink, timeout)
+ root_symlink, timeout, runat)
except Exception as e:
self.log_debug("could not collect output of '%s': %s"
% (prog, e))
diff --git a/sos/utilities.py b/sos/utilities.py
index e65df349..1bc54879 100644
--- a/sos/utilities.py
+++ b/sos/utilities.py
@@ -127,9 +127,16 @@ def is_executable(command):
candidates = [command] + [os.path.join(p, command) for p in paths]
return any(os.access(path, os.X_OK) for path in candidates)
-def sos_get_command_output(command, timeout=300):
+def sos_get_command_output(command, timeout=300, runat=None):
"""Execute a command through the system shell. First checks to see if the
requested command is executable. Returns (returncode, stdout, 0)"""
+ def _child_chdir():
+ if(runat):
+ try:
+ os.chdir(runat)
+ except:
+ self.log_error("failed to chdir to '%s'" % runat)
+
cmd_env = os.environ
# ensure consistent locale for collected command output
cmd_env['LC_ALL'] = 'C'
@@ -138,7 +145,8 @@ def sos_get_command_output(command, timeout=300):
command = "timeout %ds %s" % (timeout, command)
p = Popen(command, shell=True, stdout=PIPE, stderr=STDOUT,
- bufsize=-1, env = cmd_env, close_fds = True)
+ bufsize=-1, env = cmd_env, close_fds = True,
+ preexec_fn=_child_chdir)
stdout, stderr = p.communicate()
@@ -164,11 +172,11 @@ def import_module(module_fqname, superclasses=None):
return modules
-def shell_out(cmd):
+def shell_out(cmd, runat=None):
"""Shell out to an external command and return the output or the empty
string in case of error.
"""
- return sos_get_command_output(cmd)['output']
+ return sos_get_command_output(cmd, runat=runat)['output']
class ImporterHelper(object):
"""Provides a list of modules that can be imported in a package.