Source code for emop.lib.utilities

import collections
import errno
import logging
import os
import shlex
import signal
import subprocess32

logger = logging.getLogger('emop')


[docs]def get_temp_dir(): """Gets the temp directory based on environment variables Currently searched environment variables: * TMPDIR Returns: str: Path to temp directory. """ env_vars = [ 'TMPDIR', ] tmp_dir = None for env_var in env_vars: if os.environ.get(env_var): tmp_dir = os.environ.get(env_var) logger.debug("Using temp directory %s" % tmp_dir) return tmp_dir if not tmp_dir: logger.error("Temporary directory could not be found.") return tmp_dir
[docs]def mkdirs_exists_ok(path): """Wrapper for os.makedirs This function is needed to avoid race conditions when the directory exists when attempting to use os.makedirs. This emulates the behavior of Python 3.x os.makedirs exist_ok argument. Args: path (str): Path of directory to create """ try: os.makedirs(path) except OSError as exception: if exception.errno != errno.EEXIST: raise
[docs]def exec_cmd(cmd, log_level="info", timeout=-1): """Executes a command This is the method used by this application to execute shell commands. If the cmd argument can be a 2D list but only one level deep. The command's stdout, stderr and exitcode are turned as a namedtuple. Args: cmd (str or list): Command to execute log_level (str, optional): log level when printing information about the command being executed. timeout (int, optional): The time in seconds the command should be allowed to run before timing out. Returns: tuple: (stdout, stderr, exitcode) """ # REF: http://stackoverflow.com/a/3326559 Proc = collections.namedtuple('Proc', ['stdout', 'stderr', 'exitcode']) if timeout == -1: timeout = None if isinstance(cmd, str): cmd_str = cmd cmd = shlex.split(cmd) elif isinstance(cmd, list): cmd_flat = [] for i in cmd: if isinstance(i, list): for j in i: cmd_flat.append(j) else: cmd_flat.append(i) cmd = cmd_flat cmd_str = " ".join(cmd) getattr(logger, log_level)("Executing: '%s'" % cmd_str) try: # TODO Eventually may just need to redirect all stderr to stdout for simplicity # process = subprocess32.Popen(cmd, stdout=subprocess32.PIPE, stderr=subprocess32.STDOUT, env=os.environ) process = subprocess32.Popen(cmd, stdout=subprocess32.PIPE, stderr=subprocess32.PIPE, env=os.environ) out, err = process.communicate(timeout=timeout) retval = process.returncode return Proc(stdout=out, stderr=err, exitcode=retval) except subprocess32.TimeoutExpired: process.kill() timeout_msg = "Command timed out" return Proc(stdout=timeout_msg, stderr=timeout_msg, exitcode=1) except OSError as e: if e.errno == os.errno.ENOENT: error_msg = "File not found for command: %s" % e return Proc(stdout=error_msg, stderr=error_msg, exitcode=1) else: raise