Example #1
0
def join_bg_jobs(bg_jobs, timeout=None):
    """
    Joins the bg_jobs with the current thread.
    Returns the same list of bg_jobs objects that was passed in.
    """
    ret, timeout_error = 0, False
    for bg_job in bg_jobs:
        bg_job.output_prepare(StringIO.StringIO(), StringIO.StringIO())

    try:
        # We are holding ends to stdin, stdout pipes
        # hence we need to be sure to close those fds no mater what
        start_time = time.time()
        timeout_error = _wait_for_commands(bg_jobs, start_time, timeout)

        for bg_job in bg_jobs:
            # Process stdout and stderr
            bg_job.process_output(stdout=True, final_read=True)
            bg_job.process_output(stdout=False, final_read=True)
    finally:
        # close our ends of the pipes to the sp no matter what
        for bg_job in bg_jobs:
            bg_job.cleanup()

    if timeout_error:
        # TODO: This needs to be fixed to better represent what happens when
        # running in parallel. However this is backwards compatible, so it will
        # do for the time being.
        raise error.CmdError(
            bg_jobs[0].command, bg_jobs[0].result,
            "Command(s) did not complete within %d seconds" % timeout)
    return bg_jobs
Example #2
0
def run(command,
        timeout=None,
        ignore_status=False,
        stdout_tee=None,
        stderr_tee=None,
        verbose=True,
        stdin=None,
        stderr_is_expected=None,
        args=()):
    """
    run a command on the host.
    :param stdout_tee: optional file-like object to which stdout data will be
                        written as it is generated (data will be stored in
                        result.stdout)
    :param stderr_tee: likewise for stderr
    :param verbose: if True, log the command being run
    :param args: sequence of strings of arguments to be given to the command
                    inside quotes after they have been escaped for that;
                    each element in the sequence will be given as a seperate
                    command argument
    :return: a CmdResult object
    :raise CmdError
    """
    if isinstance(args, basestring):
        raise TypeError('Got a string for the "args" keyword argument, "\
                        "need a sequence')

    for arg in args:
        command += '"%s"' % sh_escape(arg)
    if stderr_is_expected is None:
        stderr_is_expected = ignore_status

    bg_job = join_bg_jobs(
        (BgJob(command,
               stdout_tee,
               stderr_tee,
               verbose,
               stdin=stdin,
               stderr_level=get_stderr_level(stderr_is_expected)), ),
        timeout)[0]
    if not ignore_status and bg_job.result.exit_status:
        raise error.CmdError(command, bg_job.result,
                             "Command returned non-zero exit status")

    return bg_job.result