Beispiel #1
0
 def _on_start(self, persona, component_order, instances):
     LOG.info("Booting up your components.")
     LOG.debug("Starting environment settings:")
     utils.log_object(env.get(), logger=LOG, level=logging.DEBUG, item_max_len=64)
     self._establish_passwords(component_order, instances)
     self._verify_components(component_order, instances)
     self._warm_components(component_order, instances)
Beispiel #2
0
 def _on_start(self, persona, groups):
     LOG.info("Booting up your components.")
     LOG.debug("Starting environment settings:")
     utils.log_object(env.get(), logger=LOG, level=logging.DEBUG, item_max_len=64)
     sh.mkdirslist(self.phase_dir)
     self._verify_components(groups)
     self._warm_components(groups)
Beispiel #3
0
 def _on_finish(self, persona, groups):
     LOG.info("Tearing down your components.")
     LOG.debug("Final environment settings:")
     utils.log_object(env.get(),
                      logger=LOG,
                      level=logging.DEBUG,
                      item_max_len=64)
Beispiel #4
0
 def _on_start(self, persona, component_order, instances):
     LOG.info("Booting up your components.")
     LOG.debug("Starting environment settings:")
     utils.log_object(env.get(), logger=LOG, level=logging.DEBUG, item_max_len=64)
     sh.mkdirslist(self.phase_dir)
     self._establish_passwords(component_order, instances)
     self._verify_components(component_order, instances)
     self._warm_components(component_order, instances)
Beispiel #5
0
 def _on_finish(self, persona, component_order, instances):
     LOG.info("Tearing down your components.")
     LOG.debug("Final environment settings:")
     utils.log_object(env.get(),
                      logger=LOG,
                      level=logging.DEBUG,
                      item_max_len=64)
     exports_filename = "%s.rc" % (self.name)
     self._write_exports(component_order, instances,
                         sh.joinpths("/etc/anvil", exports_filename))
Beispiel #6
0
 def _on_finish(self, persona, component_order, instances):
     LOG.info("Tearing down your components.")
     LOG.debug("Final environment settings:")
     utils.log_object(env.get(), logger=LOG, level=logging.DEBUG, item_max_len=64)
Beispiel #7
0
def execute(cmd,
            process_input=None,
            check_exit_code=True,
            cwd=None,
            shell=False,
            env_overrides=None,
            stdout_fh=subprocess.PIPE,
            stderr_fh=subprocess.PIPE):
    """Helper method to execute a command through subprocess.

    :param cmd:             Command passed to subprocess.Popen.
    :param process_input:   Input send to opened process.
    :param check_exit_code: Specifies whether to check process return code.
                            If return code is other then `0` - exception will
                            be raised.
    :param cwd:             The child's current directory will be changed to
                            `cwd` before it is executed.
    :param shell:           Specifies whether to use the shell as the program
                            to execute.
    :param env_overrides:   Process environment parameters to override.
    :param stdout_fh:       Stdout file handler.
    :param stderr_fh:       Stderr file handler.
    :returns:               A tuple, (stdout, stderr) from the spawned process.
    :raises:                :class:`exceptions.ProcessExecutionError` when
                            process ends with other then `0` return code.
    """
    # Ensure all string args (i.e. for those that send ints, etc.).
    cmd = map(str, cmd)

    # NOTE(skudriashev): If shell is True, it is recommended to pass args as a
    # string rather than as a sequence.
    str_cmd = subprocess.list2cmdline(cmd)
    if shell:
        cmd = str_cmd
        LOG.debug('Running shell cmd: %r' % cmd)
    else:
        LOG.debug('Running cmd: %r' % cmd)

    if process_input is not None:
        process_input = str(process_input)
        LOG.debug('Process input: %s' % process_input)

    if cwd:
        LOG.debug('Process working directory: %r' % cwd)

    # Override process environment in needed.
    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for k, v in env_overrides.items():
            process_env[k] = str(v)

    # Run command process.
    exec_kwargs = {
        'stdin': subprocess.PIPE,
        'stdout': stdout_fh,
        'stderr': stderr_fh,
        'close_fds': True,
        'shell': shell,
        'cwd': cwd,
        'env': process_env,
    }
    result = ("", "")
    try:
        obj = subprocess.Popen(cmd, **exec_kwargs)
        result = obj.communicate(process_input)
    except OSError as e:
        raise excp.ProcessExecutionError(str_cmd,
                                         exec_kwargs=exec_kwargs,
                                         description="%s: [%s, %s]" %
                                         (e, e.errno, e.strerror))
    else:
        rc = obj.returncode

    # Handle process exit code.
    stdout = result[0] or ""
    stderr = result[1] or ""
    if rc != 0 and check_exit_code:
        # Raise exception if return code is not `0`.
        e = excp.ProcessExecutionError(str_cmd,
                                       exec_kwargs=exec_kwargs,
                                       stdout=stdout,
                                       stderr=stderr,
                                       exit_code=rc,
                                       where_output="debug log")
        LOG.debug("Stdout: %s", e.stdout)
        LOG.debug("Stderr: %s", e.stderr)
        raise e
    return stdout, stderr
Beispiel #8
0
def execute(
    cmd,
    process_input=None,
    check_exit_code=True,
    cwd=None,
    shell=False,
    env_overrides=None,
    stdout_fh=None,
    stderr_fh=None,
    stdout_fn=None,
    stderr_fn=None,
    trace_writer=None,
):
    """Helper method to execute command.

    :param cmd:             Passed to subprocess.Popen
    :param process_input:   Send to opened process
    :param check_exit_code: Single `bool`, `int`, or `list` of allowed exit
                            codes.  By default, only 0 exit code is allowed.
                            Raise :class:`exceptions.ProcessExecutionError`
                            unless program exits with one of these code

    :returns: a tuple, (stdout, stderr) from the spawned process, or None if
              the command fails
    """
    if isinstance(check_exit_code, (bool)):
        ignore_exit_code = not check_exit_code
        check_exit_code = [0]
    elif isinstance(check_exit_code, (int)):
        check_exit_code = [check_exit_code]

    # Ensure all string args (ie for those that send ints and such...)
    execute_cmd = [str(c) for c in cmd]

    # From the docs it seems a shell command must be a string??
    # TODO(harlowja) this might not really be needed?
    str_cmd = " ".join(shellquote(word) for word in cmd)

    if shell:
        execute_cmd = str_cmd

    if not shell:
        LOG.debug("Running cmd: %r" % (execute_cmd))
    else:
        LOG.debug("Running shell cmd: %r" % (execute_cmd))

    if process_input is not None:
        LOG.debug("With stdin: %s" % (process_input))
    if cwd:
        LOG.debug("In working directory: %r" % (cwd))

    if stdout_fn is not None and stdout_fh is not None:
        LOG.warn("Stdout file handles and stdout file names can not be used simultaneously!")
    if stderr_fn is not None and stderr_fh is not None:
        LOG.warn("Stderr file handles and stderr file names can not be used simultaneously!")

    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for (k, v) in env_overrides.items():
            process_env[k] = str(v)

    rc = None
    result = ("", "")
    if is_dry_run():
        rc = 0
    else:
        stdin_fh = subprocess.PIPE
        if stdout_fn or (stdout_fh is None):
            stdout_fh = subprocess.PIPE
        if stderr_fn or (stderr_fh is None):
            stderr_fh = subprocess.PIPE
        try:
            obj = subprocess.Popen(
                execute_cmd,
                stdin=stdin_fh,
                stdout=stdout_fh,
                stderr=stderr_fh,
                close_fds=True,
                cwd=cwd,
                shell=shell,
                env=process_env,
            )
            if process_input is not None:
                result = obj.communicate(str(process_input))
            else:
                result = obj.communicate()
        except OSError as e:
            raise excp.ProcessExecutionError(description="%s: [%s, %s]" % (e, e.errno, e.strerror), cmd=str_cmd)
        rc = obj.returncode

    if stdout_fh != subprocess.PIPE:
        stdout = "<redirected to %s>" % (stdout_fn or stdout_fh)
    else:
        stdout = result[0] or ""
    if stderr_fh != subprocess.PIPE:
        stderr = "<redirected to %s>" % (stderr_fn or stderr_fh)
    else:
        stderr = result[1] or ""

    if (not ignore_exit_code) and (rc not in check_exit_code):
        raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout, stderr=stderr, cmd=str_cmd)
    else:
        # Log it anyway
        if rc not in check_exit_code:
            LOG.debug(
                "A failure may of just happened when running command %r [%s] (%s, %s)", str_cmd, rc, stdout, stderr
            )
        # See if a requested storage place was given for stderr/stdout
        for name, handle in ((stdout_fn, stdout), (stderr_fn, stderr)):
            if name:
                write_file(name, handle)
                if trace_writer:
                    trace_writer.file_touched(name)
        return (stdout, stderr)
Beispiel #9
0
 def _on_finish(self, persona, component_order, instances):
     LOG.info("Tearing down your components.")
     LOG.debug("Final environment settings:")
     utils.log_object(env.get(), logger=LOG, level=logging.DEBUG, item_max_len=64)
     exports_filename = "%s.rc" % (self.name)
     self._write_exports(component_order, instances, sh.joinpths("/etc/anvil", exports_filename))
Beispiel #10
0
def execute(*cmd, **kwargs):
    process_input = kwargs.pop('process_input', None)
    check_exit_code = kwargs.pop('check_exit_code', [0])
    cwd = kwargs.pop('cwd', None)
    env_overrides = kwargs.pop('env_overrides', None)
    close_stdin = kwargs.pop('close_stdin', False)
    ignore_exit_code = kwargs.pop('ignore_exit_code', False)

    if isinstance(check_exit_code, bool):
        ignore_exit_code = not check_exit_code
        check_exit_code = [0]
    elif isinstance(check_exit_code, int):
        check_exit_code = [check_exit_code]

    run_as_root = kwargs.pop('run_as_root', False)
    shell = kwargs.pop('shell', False)

    # Ensure all string args
    execute_cmd = []
    for c in cmd:
        execute_cmd.append(str(c))

    # From the docs it seems a shell command must be a string??
    # TODO(harlowja) this might not really be needed?
    str_cmd = " ".join(execute_cmd)
    if shell:
        execute_cmd = str_cmd.strip()

    stdin_fh = subprocess.PIPE
    stdout_fh = subprocess.PIPE
    stderr_fh = subprocess.PIPE
    close_file_descriptors = True

    if 'stdout_fh' in kwargs.keys():
        stdout_fh = kwargs.get('stdout_fh')

    if 'stdin_fh' in kwargs.keys():
        stdin_fh = kwargs.get('stdin_fh')
        process_input = None

    if 'stderr_fh' in kwargs.keys():
        stderr_fh = kwargs.get('stderr_fh')

    if not shell:
        LOG.debug('Running cmd: %r' % (execute_cmd))
    else:
        LOG.debug('Running shell cmd: %r' % (execute_cmd))
    if process_input is not None:
        LOG.debug('With stdin: %s' % (process_input))
    if cwd:
        LOG.debug("In working directory: %r" % (cwd))

    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for (k, v) in env_overrides.items():
            process_env[k] = str(v)
    else:
        process_env = env.get()

    # LOG.debug("With environment %s", process_env)
    demoter = None

    def demoter_functor(user_uid, user_gid):
        def doit():
            os.setregid(user_gid, user_gid)
            os.setreuid(user_uid, user_uid)
        return doit

    if not run_as_root:
        (user_uid, user_gid) = get_suids()
        if user_uid is None or user_gid is None:
            pass
        else:
            demoter = demoter_functor(user_uid=user_uid, user_gid=user_gid)

    rc = None
    result = None
    with Rooted(run_as_root):
        if is_dry_run():
            rc = 0
            result = ('', '')
        else:
            try:
                obj = subprocess.Popen(execute_cmd, stdin=stdin_fh, stdout=stdout_fh, stderr=stderr_fh,
                                       close_fds=close_file_descriptors, cwd=cwd, shell=shell,
                                       preexec_fn=demoter, env=process_env)
                if process_input is not None:
                    result = obj.communicate(str(process_input))
                else:
                    result = obj.communicate()
            except OSError as e:
                raise excp.ProcessExecutionError(description="%s: [%s, %s]" % (e, e.errno, e.strerror),
                                                 cmd=str_cmd)
            if (stdin_fh != subprocess.PIPE and obj.stdin and close_stdin):
                obj.stdin.close()
            rc = obj.returncode

    if not result:
        result = ("", "")

    (stdout, stderr) = result
    if stdout is None:
        stdout = ''
    if stderr is None:
        stderr = ''

    if (not ignore_exit_code) and (rc not in check_exit_code):
        raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout,
                                         stderr=stderr, cmd=str_cmd)
    else:
        # Log it anyway
        if rc not in check_exit_code:
            LOG.debug("A failure may of just happened when running command %r [%s] (%s, %s)",
                      str_cmd, rc, stdout, stderr)
        # See if a requested storage place was given for stderr/stdout
        trace_writer = kwargs.get('trace_writer')
        stdout_fn = kwargs.get('stdout_fn')
        if stdout_fn:
            write_file(stdout_fn, stdout)
            if trace_writer:
                trace_writer.file_touched(stdout_fn)
        stderr_fn = kwargs.get('stderr_fn')
        if stderr_fn:
            write_file(stderr_fn, stderr)
            if trace_writer:
                trace_writer.file_touched(stderr_fn)
        return (stdout, stderr)
Beispiel #11
0
def execute(cmd,
            process_input=None,
            check_exit_code=True,
            cwd=None,
            shell=False,
            env_overrides=None,
            stdout_fh=subprocess.PIPE,
            stderr_fh=subprocess.PIPE):
    """Helper method to execute a command through subprocess.

    :param cmd:             Command passed to subprocess.Popen.
    :param process_input:   Input send to opened process.
    :param check_exit_code: Specifies whether to check process return code.
                            If return code is other then `0` - exception will
                            be raised.
    :param cwd:             The child's current directory will be changed to
                            `cwd` before it is executed.
    :param shell:           Specifies whether to use the shell as the program
                            to execute.
    :param env_overrides:   Process environment parameters to override.
    :param stdout_fh:       Stdout file handler.
    :param stderr_fh:       Stderr file handler.
    :returns:               A tuple, (stdout, stderr) from the spawned process.
    :raises:                :class:`exceptions.ProcessExecutionError` when
                            process ends with other then `0` return code.
    """
    # Ensure all string args (i.e. for those that send ints, etc.).
    cmd = map(str, cmd)

    # NOTE(skudriashev): If shell is True, it is recommended to pass args as a
    # string rather than as a sequence.
    str_cmd = subprocess.list2cmdline(cmd)
    if shell:
        cmd = str_cmd
        LOG.debug('Running shell cmd: %r' % cmd)
    else:
        LOG.debug('Running cmd: %r' % cmd)

    if process_input is not None:
        process_input = str(process_input)
        LOG.debug('Process input: %s' % process_input)

    if cwd:
        LOG.debug('Process working directory: %r' % cwd)

    # Override process environment in needed.
    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for k, v in env_overrides.items():
            LOG.debug("Using environment override '%s' => '%s'", k, v)
            process_env[k] = str(v)

    # Run command process.
    exec_kwargs = {
        'stdin': subprocess.PIPE,
        'stdout': stdout_fh,
        'stderr': stderr_fh,
        'close_fds': True,
        'shell': shell,
        'cwd': cwd,
        'env': process_env,
    }
    result = ("", "")
    try:
        obj = subprocess.Popen(cmd, **exec_kwargs)
        result = obj.communicate(process_input)
    except OSError as e:
        raise excp.ProcessExecutionError(
            str_cmd,
            exec_kwargs=exec_kwargs,
            description="%s: [%s, %s]" % (e, e.errno, e.strerror)
        )
    else:
        rc = obj.returncode

    # Handle process exit code.
    stdout = result[0] or ""
    stderr = result[1] or ""
    if rc != 0 and check_exit_code:
        # Raise exception if return code is not `0`.
        e = excp.ProcessExecutionError(str_cmd,
                                       exec_kwargs=exec_kwargs,
                                       stdout=stdout,
                                       stderr=stderr,
                                       exit_code=rc,
                                       where_output="debug log")
        LOG.debug("Stdout: %s", e.stdout)
        LOG.debug("Stderr: %s", e.stderr)
        raise e
    return stdout, stderr
Beispiel #12
0
def execute(cmd,
            process_input=None,
            check_exit_code=True,
            cwd=None,
            shell=False,
            env_overrides=None,
            stdout_fh=None,
            stderr_fh=None,
            stdout_fn=None,
            stderr_fn=None,
            trace_writer=None):
    """Helper method to execute command.

    :param cmd:             Passed to subprocess.Popen
    :param process_input:   Send to opened process
    :param check_exit_code: Single `bool`, `int`, or `list` of allowed exit
                            codes.  By default, only 0 exit code is allowed.
                            Raise :class:`exceptions.ProcessExecutionError`
                            unless program exits with one of these code

    :returns: a tuple, (stdout, stderr) from the spawned process, or None if
              the command fails
    """
    if isinstance(check_exit_code, (bool)):
        ignore_exit_code = not check_exit_code
        check_exit_code = [0]
    elif isinstance(check_exit_code, (int)):
        check_exit_code = [check_exit_code]

    # Ensure all string args (ie for those that send ints and such...)
    execute_cmd = [str(c) for c in cmd]

    # From the docs it seems a shell command must be a string??
    # TODO(harlowja) this might not really be needed?
    str_cmd = " ".join(shellquote(word) for word in cmd)

    if shell:
        execute_cmd = str_cmd

    if not shell:
        LOG.debug('Running cmd: %r' % (execute_cmd))
    else:
        LOG.debug('Running shell cmd: %r' % (execute_cmd))

    if process_input is not None:
        LOG.debug('With stdin: %s' % (process_input))
    if cwd:
        LOG.debug("In working directory: %r" % (cwd))

    if stdout_fn is not None and stdout_fh is not None:
        LOG.warn("Stdout file handles and stdout file names can not be used simultaneously!")
    if stderr_fn is not None and stderr_fh is not None:
        LOG.warn("Stderr file handles and stderr file names can not be used simultaneously!")

    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for (k, v) in env_overrides.items():
            process_env[k] = str(v)

    rc = None
    result = ("", "")
    if is_dry_run():
        rc = 0
    else:
        stdin_fh = subprocess.PIPE
        if stdout_fn or (stdout_fh is None):
            stdout_fh = subprocess.PIPE
        if stderr_fn or (stderr_fh is None):
            stderr_fh = subprocess.PIPE
        try:
            obj = subprocess.Popen(execute_cmd, stdin=stdin_fh, stdout=stdout_fh, stderr=stderr_fh,
                                   close_fds=True, cwd=cwd, shell=shell, env=process_env)
            if process_input is not None:
                result = obj.communicate(str(process_input))
            else:
                result = obj.communicate()
        except OSError as e:
            raise excp.ProcessExecutionError(description="%s: [%s, %s]" % (e, e.errno, e.strerror),
                                             cmd=str_cmd)
        rc = obj.returncode

    if stdout_fh != subprocess.PIPE:
        stdout = "<redirected to %s>" % (stdout_fn or stdout_fh)
    else:
        stdout = result[0] or ""
    if stderr_fh != subprocess.PIPE:
        stderr = "<redirected to %s>" % (stderr_fn or stderr_fh)
    else:
        stderr = result[1] or ""

    if (not ignore_exit_code) and (rc not in check_exit_code):
        raise excp.ProcessExecutionError(exit_code=rc, stdout=stdout,
                                         stderr=stderr, cmd=str_cmd)
    else:
        # Log it anyway
        if rc not in check_exit_code:
            LOG.debug("A failure may of just happened when running command %r [%s] (%s, %s)",
                      str_cmd, rc, stdout, stderr)
        # See if a requested storage place was given for stderr/stdout
        for name, handle in ((stdout_fn, stdout), (stderr_fn, stderr)):
            if name:
                write_file(name, handle)
                if trace_writer:
                    trace_writer.file_touched(name)
        return (stdout, stderr)
Beispiel #13
0
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import sys

import termcolor

from anvil import env
from anvil import type_utils as tu

COLORS = termcolor.COLORS.keys()

LOG_COLOR = True
if 'LOG_COLOR' in env.get():
    LOG_COLOR = tu.make_bool(env.get_key('LOG_COLOR'))
if not sys.stdout.isatty():
    LOG_COLOR = False


def color_enabled():
    return LOG_COLOR


def quote(data, quote_color='green', **kargs):
    if not color_enabled():
        return "'%s'" % (data)
    else:
        text = str(data)
        if len(text) == 0:
Beispiel #14
0
def execute(*cmd, **kwargs):
    process_input = kwargs.pop('process_input', None)
    check_exit_code = kwargs.pop('check_exit_code', [0])
    cwd = kwargs.pop('cwd', None)
    env_overrides = kwargs.pop('env_overrides', None)
    close_stdin = kwargs.pop('close_stdin', False)
    ignore_exit_code = kwargs.pop('ignore_exit_code', False)

    if isinstance(check_exit_code, bool):
        ignore_exit_code = not check_exit_code
        check_exit_code = [0]
    elif isinstance(check_exit_code, int):
        check_exit_code = [check_exit_code]

    run_as_root = kwargs.pop('run_as_root', False)
    shell = kwargs.pop('shell', False)

    # Ensure all string args
    execute_cmd = []
    for c in cmd:
        execute_cmd.append(str(c))

    # From the docs it seems a shell command must be a string??
    # TODO(harlowja) this might not really be needed?
    str_cmd = " ".join(execute_cmd)
    if shell:
        execute_cmd = str_cmd.strip()

    stdin_fh = subprocess.PIPE
    stdout_fh = subprocess.PIPE
    stderr_fh = subprocess.PIPE
    close_file_descriptors = True

    if 'stdout_fh' in kwargs.keys():
        stdout_fh = kwargs.get('stdout_fh')

    if 'stdin_fh' in kwargs.keys():
        stdin_fh = kwargs.get('stdin_fh')
        process_input = None

    if 'stderr_fh' in kwargs.keys():
        stderr_fh = kwargs.get('stderr_fh')

    if not shell:
        LOG.debug('Running cmd: %r' % (execute_cmd))
    else:
        LOG.debug('Running shell cmd: %r' % (execute_cmd))
    if process_input is not None:
        LOG.debug('With stdin: %s' % (process_input))
    if cwd:
        LOG.debug("In working directory: %r" % (cwd))

    process_env = None
    if env_overrides and len(env_overrides):
        process_env = env.get()
        for (k, v) in env_overrides.items():
            process_env[k] = str(v)
    else:
        process_env = env.get()

    # LOG.debug("With environment %s", process_env)
    demoter = None

    def demoter_functor(user_uid, user_gid):
        def doit():
            os.setregid(user_gid, user_gid)
            os.setreuid(user_uid, user_uid)

        return doit

    if not run_as_root:
        (user_uid, user_gid) = get_suids()
        if user_uid is None or user_gid is None:
            pass
        else:
            demoter = demoter_functor(user_uid=user_uid, user_gid=user_gid)

    rc = None
    result = None
    with Rooted(run_as_root):
        if is_dry_run():
            rc = 0
            result = ('', '')
        else:
            try:
                obj = subprocess.Popen(execute_cmd,
                                       stdin=stdin_fh,
                                       stdout=stdout_fh,
                                       stderr=stderr_fh,
                                       close_fds=close_file_descriptors,
                                       cwd=cwd,
                                       shell=shell,
                                       preexec_fn=demoter,
                                       env=process_env)
                if process_input is not None:
                    result = obj.communicate(str(process_input))
                else:
                    result = obj.communicate()
            except OSError as e:
                raise excp.ProcessExecutionError(description="%s: [%s, %s]" %
                                                 (e, e.errno, e.strerror),
                                                 cmd=str_cmd)
            if (stdin_fh != subprocess.PIPE and obj.stdin and close_stdin):
                obj.stdin.close()
            rc = obj.returncode

    if not result:
        result = ("", "")

    (stdout, stderr) = result
    if stdout is None:
        stdout = ''
    if stderr is None:
        stderr = ''

    if (not ignore_exit_code) and (rc not in check_exit_code):
        raise excp.ProcessExecutionError(exit_code=rc,
                                         stdout=stdout,
                                         stderr=stderr,
                                         cmd=str_cmd)
    else:
        # Log it anyway
        if rc not in check_exit_code:
            LOG.debug(
                "A failure may of just happened when running command %r [%s] (%s, %s)",
                str_cmd, rc, stdout, stderr)
        # See if a requested storage place was given for stderr/stdout
        trace_writer = kwargs.get('trace_writer')
        stdout_fn = kwargs.get('stdout_fn')
        if stdout_fn:
            write_file(stdout_fn, stdout)
            if trace_writer:
                trace_writer.file_touched(stdout_fn)
        stderr_fn = kwargs.get('stderr_fn')
        if stderr_fn:
            write_file(stderr_fn, stderr)
            if trace_writer:
                trace_writer.file_touched(stderr_fn)
        return (stdout, stderr)
def color_enabled():
    if 'LOG_COLOR' in env.get() and not tu.make_bool(env.get_key('LOG_COLOR')):
        return False
    if not sys.stdout.isatty():
        return False
    return True