Пример #1
0
def call(command, **kw):
    """
    Similar to ``subprocess.Popen`` with the following changes:

    * returns stdout, stderr, and exit code (vs. just the exit code)
    * logs the full contents of stderr and stdout (separately) to the file log

    By default, no terminal output is given, not even the command that is going
    to run.

    Useful when system calls are needed to act on output, and that same output
    shouldn't get displayed on the terminal.

    :param terminal_verbose: Log command output to terminal, defaults to False, and
                             it is forcefully set to True if a return code is non-zero
    """
    terminal_verbose = kw.pop('terminal_verbose', False)
    show_command = kw.pop('show_command', False)
    command_msg = "Running command: %s" % ' '.join(command)
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    if show_command:
        terminal.write(command_msg)

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE,
        close_fds=True,
        **kw
    )
    if stdin:
        stdout_stream, stderr_stream = process.communicate(stdin)
    else:
        stdout_stream = process.stdout.read()
        stderr_stream = process.stderr.read()
    returncode = process.wait()
    if not isinstance(stdout_stream, str):
        stdout_stream = stdout_stream.decode('utf-8')
    if not isinstance(stderr_stream, str):
        stderr_stream = stderr_stream.decode('utf-8')
    stdout = stdout_stream.splitlines()
    stderr = stderr_stream.splitlines()

    if returncode != 0:
        # set to true so that we can log the stderr/stdout that callers would
        # do anyway
        terminal_verbose = True

    # the following can get a messed up order in the log if the system call
    # returns output with both stderr and stdout intermingled. This separates
    # that.
    for line in stdout:
        log_output('stdout', line, terminal_verbose)
    for line in stderr:
        log_output('stderr', line, terminal_verbose)
    return stdout, stderr, returncode
Пример #2
0
def call(command, **kw):
    """
    Similar to ``subprocess.Popen`` with the following changes:

    * returns stdout, stderr, and exit code (vs. just the exit code)
    * logs the full contents of stderr and stdout (separately) to the file log

    By default, no terminal output is given, not even the command that is going
    to run.

    Useful when system calls are needed to act on output, and that same output
    shouldn't get displayed on the terminal.

    :param terminal_verbose: Log command output to terminal, defaults to False, and
                             it is forcefully set to True if a return code is non-zero
    """
    terminal_verbose = kw.pop('terminal_verbose', False)
    show_command = kw.pop('show_command', False)
    command_msg = "Running command: %s" % ' '.join(command)
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    if show_command:
        terminal.write(command_msg)

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE,
        close_fds=True,
        **kw
    )
    if stdin:
        stdout_stream, stderr_stream = process.communicate(stdin)
    else:
        stdout_stream = process.stdout.read()
        stderr_stream = process.stderr.read()
    returncode = process.wait()
    if not isinstance(stdout_stream, str):
        stdout_stream = stdout_stream.decode('utf-8')
    if not isinstance(stderr_stream, str):
        stderr_stream = stderr_stream.decode('utf-8')
    stdout = stdout_stream.splitlines()
    stderr = stderr_stream.splitlines()

    if returncode != 0:
        # set to true so that we can log the stderr/stdout that callers would
        # do anyway
        terminal_verbose = True

    # the following can get a messed up order in the log if the system call
    # returns output with both stderr and stdout intermingled. This separates
    # that.
    for line in stdout:
        log_output('stdout', line, terminal_verbose)
    for line in stderr:
        log_output('stderr', line, terminal_verbose)
    return stdout, stderr, returncode
Пример #3
0
def run(command, run_on_host=False, **kw):
    """
    A real-time-logging implementation of a remote subprocess.Popen call where
    a command is just executed on the remote end and no other handling is done.

    :param command: The command to pass in to the remote subprocess.Popen as a list
    :param stop_on_error: If a nonzero exit status is return, it raises a ``RuntimeError``
    :param fail_msg: If a nonzero exit status is returned this message will be included in the log
    """
    executable = which(command.pop(0), run_on_host)
    command.insert(0, executable)
    if run_on_host and path.isdir(host_rootfs):
        command = run_host_cmd + command
    stop_on_error = kw.pop('stop_on_error', True)
    command_msg = obfuscate(command, kw.pop('obfuscate', None))
    fail_msg = kw.pop('fail_msg', None)
    logger.info(command_msg)
    terminal.write(command_msg)
    terminal_logging = kw.pop('terminal_logging', True)

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        close_fds=True,
        **kw
    )

    while True:
        reads, _, _ = select(
            [process.stdout.fileno(), process.stderr.fileno()],
            [], []
        )
        log_descriptors(reads, process, terminal_logging)

        if process.poll() is not None:
            # ensure we do not have anything pending in stdout or stderr
            log_descriptors(reads, process, terminal_logging)

            break

    returncode = process.wait()
    if returncode != 0:
        msg = "command returned non-zero exit status: %s" % returncode
        if fail_msg:
            logger.warning(fail_msg)
            if terminal_logging:
                terminal.warning(fail_msg)
        if stop_on_error:
            raise RuntimeError(msg)
        else:
            if terminal_logging:
                terminal.warning(msg)
            logger.warning(msg)
Пример #4
0
def run(command, **kw):
    """
    A real-time-logging implementation of a remote subprocess.Popen call where
    a command is just executed on the remote end and no other handling is done.

    :param command: The command to pass in to the remote subprocess.Popen as a list
    :param stop_on_error: If a nonzero exit status is return, it raises a ``RuntimeError``
    :param fail_msg: If a nonzero exit status is returned this message will be included in the log
    """
    executable = which(command.pop(0))
    command.insert(0, executable)
    stop_on_error = kw.pop('stop_on_error', True)
    command_msg = obfuscate(command, kw.pop('obfuscate', None))
    fail_msg = kw.pop('fail_msg', None)
    logger.info(command_msg)
    terminal.write(command_msg)
    terminal_logging = kw.pop('terminal_logging', True)

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        close_fds=True,
        **kw
    )

    while True:
        reads, _, _ = select(
            [process.stdout.fileno(), process.stderr.fileno()],
            [], []
        )
        log_descriptors(reads, process, terminal_logging)

        if process.poll() is not None:
            # ensure we do not have anything pending in stdout or stderr
            log_descriptors(reads, process, terminal_logging)

            break

    returncode = process.wait()
    if returncode != 0:
        msg = "command returned non-zero exit status: %s" % returncode
        if fail_msg:
            logger.warning(fail_msg)
            if terminal_logging:
                terminal.warning(fail_msg)
        if stop_on_error:
            raise RuntimeError(msg)
        else:
            if terminal_logging:
                terminal.warning(msg)
            logger.warning(msg)
Пример #5
0
def run(command, **kw):
    """
    A real-time-logging implementation of a remote subprocess.Popen call where
    a command is just executed on the remote end and no other handling is done.

    :param command: The command to pass in to the remote subprocess.Popen as a list
    :param stop_on_error: If a nonzero exit status is return, it raises a ``RuntimeError``
    """
    stop_on_error = kw.pop('stop_on_error', True)
    command_msg = "Running command: %s" % ' '.join(command)
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    terminal.write(command_msg)
    terminal_logging = kw.pop('terminal_logging', True)

    process = subprocess.Popen(
        command,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        close_fds=True,
        **kw
    )

    if stdin:
        process.communicate(stdin)
    while True:
        reads, _, _ = select(
            [process.stdout.fileno(), process.stderr.fileno()],
            [], []
        )
        log_descriptors(reads, process, terminal_logging)

        if process.poll() is not None:
            # ensure we do not have anything pending in stdout or stderr
            log_descriptors(reads, process, terminal_logging)

            break

    returncode = process.wait()
    if returncode != 0:
        msg = "command returned non-zero exit status: %s" % returncode
        if stop_on_error:
            raise RuntimeError(msg)
        else:
            if terminal_logging:
                terminal.warning(msg)
            logger.warning(msg)
Пример #6
0
def run(command, **kw):
    """
    A real-time-logging implementation of a remote subprocess.Popen call where
    a command is just executed on the remote end and no other handling is done.

    :param command: The command to pass in to the remote subprocess.Popen as a list
    :param stop_on_error: If a nonzero exit status is return, it raises a ``RuntimeError``
    """
    stop_on_error = kw.pop('stop_on_error', True)
    command_msg = obfuscate(command, kw.pop('obfuscate', None))
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    terminal.write(command_msg)
    terminal_logging = kw.pop('terminal_logging', True)

    process = subprocess.Popen(
        command,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        close_fds=True,
        **kw
    )

    if stdin:
        process.communicate(stdin)
    while True:
        reads, _, _ = select(
            [process.stdout.fileno(), process.stderr.fileno()],
            [], []
        )
        log_descriptors(reads, process, terminal_logging)

        if process.poll() is not None:
            # ensure we do not have anything pending in stdout or stderr
            log_descriptors(reads, process, terminal_logging)

            break

    returncode = process.wait()
    if returncode != 0:
        msg = "command returned non-zero exit status: %s" % returncode
        if stop_on_error:
            raise RuntimeError(msg)
        else:
            if terminal_logging:
                terminal.warning(msg)
            logger.warning(msg)
Пример #7
0
    def zap(self, args):
        device = args.device
        lv = api.get_lv_from_argument(device)
        if lv:
            # we are zapping a logical volume
            path = lv.lv_path
        else:
            # we are zapping a partition
            #TODO: ensure device is a partition
            path = device

        logger.info("Zapping: %s", path)
        terminal.write("Zapping: %s" % path)

        if args.destroy and not lv:
            # check if there was a pv created with the
            # name of device
            pv = api.PVolumes().get(pv_name=device)
            if pv:
                logger.info(
                    "Found a physical volume created from %s, will destroy all it's vgs and lvs",
                    device)
                vg_name = pv.vg_name
                logger.info(
                    "Destroying volume group %s because --destroy was given",
                    vg_name)
                terminal.write(
                    "Destroying volume group %s because --destroy was given" %
                    vg_name)
                api.remove_vg(vg_name)
                logger.info(
                    "Destroying physical volume %s because --destroy was given",
                    device)
                terminal.write(
                    "Destroying physical volume %s because --destroy was given"
                    % device)
                api.remove_pv(device)
            else:
                logger.info(
                    "Skipping --destroy because no associated physical volumes are found for %s",
                    device)
                terminal.write(
                    "Skipping --destroy because no associated physical volumes are found for %s"
                    % device)

        wipefs(path)
        zap_data(path)

        if lv:
            # remove all lvm metadata
            lv.clear_tags()

        terminal.success("Zapping successful for: %s" % path)
Пример #8
0
    def zap(self, args):
        device = args.device
        lv = api.get_lv_from_argument(device)
        if lv:
            # we are zapping a logical volume
            path = lv.lv_path
        else:
            # we are zapping a partition
            #TODO: ensure device is a partition
            path = device

        logger.info("Zapping: %s", path)
        terminal.write("Zapping: %s" % path)

        wipefs(path)
        zap_data(path)

        if lv:
            # remove all lvm metadata
            lv.clear_tags()

        terminal.success("Zapping successful for: %s" % path)
Пример #9
0
    def zap(self, args):
        device = args.device
        lv = api.get_lv_from_argument(device)
        if lv:
            # we are zapping a logical volume
            path = lv.lv_path
        else:
            # we are zapping a partition
            #TODO: ensure device is a partition
            path = device

        logger.info("Zapping: %s", path)
        terminal.write("Zapping: %s" % path)

        wipefs(path)
        zap_data(path)

        if lv:
            # remove all lvm metadata
            lv.clear_tags()

        terminal.success("Zapping successful for: %s" % path)
Пример #10
0
def call(command, **kw):
    """
    Similar to ``subprocess.Popen`` with the following changes:

    * returns stdout, stderr, and exit code (vs. just the exit code)
    * logs the full contents of stderr and stdout (separately) to the file log

    By default, no terminal output is given, not even the command that is going
    to run.

    Useful when system calls are needed to act on output, and that same output
    shouldn't get displayed on the terminal.

    Optionally, the command can be displayed on the terminal and the log file,
    and log file output can be turned off. This is useful to prevent sensitive
    output going to stderr/stdout and being captured on a log file.

    :param terminal_verbose: Log command output to terminal, defaults to False, and
                             it is forcefully set to True if a return code is non-zero
    :param logfile_verbose: Log stderr/stdout output to log file. Defaults to True
    :param verbose_on_failure: On a non-zero exit status, it will forcefully set logging ON for
                               the terminal. Defaults to True
    """
    executable = which(command.pop(0))
    command.insert(0, executable)
    terminal_verbose = kw.pop('terminal_verbose', False)
    logfile_verbose = kw.pop('logfile_verbose', True)
    verbose_on_failure = kw.pop('verbose_on_failure', True)
    show_command = kw.pop('show_command', False)
    command_msg = "Running command: %s" % ' '.join(command)
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    if show_command:
        terminal.write(command_msg)

    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               stdin=subprocess.PIPE,
                               close_fds=True,
                               **kw)

    if stdin:
        stdout_stream, stderr_stream = process.communicate(as_bytes(stdin))
    else:
        stdout_stream = process.stdout.read()
        stderr_stream = process.stderr.read()
    returncode = process.wait()
    if not isinstance(stdout_stream, str):
        stdout_stream = stdout_stream.decode('utf-8')
    if not isinstance(stderr_stream, str):
        stderr_stream = stderr_stream.decode('utf-8')
    stdout = stdout_stream.splitlines()
    stderr = stderr_stream.splitlines()

    if returncode != 0:
        # set to true so that we can log the stderr/stdout that callers would
        # do anyway as long as verbose_on_failure is set (defaults to True)
        if verbose_on_failure:
            terminal_verbose = True
        # logfiles aren't disruptive visually, unlike the terminal, so this
        # should always be on when there is a failure
        logfile_verbose = True

    # the following can get a messed up order in the log if the system call
    # returns output with both stderr and stdout intermingled. This separates
    # that.
    for line in stdout:
        log_output('stdout', line, terminal_verbose, logfile_verbose)
    for line in stderr:
        log_output('stderr', line, terminal_verbose, logfile_verbose)
    return stdout, stderr, returncode
Пример #11
0
def call(command, **kw):
    """
    Similar to ``subprocess.Popen`` with the following changes:

    * returns stdout, stderr, and exit code (vs. just the exit code)
    * logs the full contents of stderr and stdout (separately) to the file log

    By default, no terminal output is given, not even the command that is going
    to run.

    Useful when system calls are needed to act on output, and that same output
    shouldn't get displayed on the terminal.

    Optionally, the command can be displayed on the terminal and the log file,
    and log file output can be turned off. This is useful to prevent sensitive
    output going to stderr/stdout and being captured on a log file.

    :param terminal_verbose: Log command output to terminal, defaults to False, and
                             it is forcefully set to True if a return code is non-zero
    :param logfile_verbose: Log stderr/stdout output to log file. Defaults to True
    :param verbose_on_failure: On a non-zero exit status, it will forcefully set logging ON for
                               the terminal. Defaults to True
    """
    executable = which(command.pop(0))
    command.insert(0, executable)
    terminal_verbose = kw.pop('terminal_verbose', False)
    logfile_verbose = kw.pop('logfile_verbose', True)
    verbose_on_failure = kw.pop('verbose_on_failure', True)
    show_command = kw.pop('show_command', False)
    command_msg = "Running command: %s" % ' '.join(command)
    stdin = kw.pop('stdin', None)
    logger.info(command_msg)
    if show_command:
        terminal.write(command_msg)

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE,
        close_fds=True,
        **kw
    )
    if stdin:
        stdout_stream, stderr_stream = process.communicate(stdin)
    else:
        stdout_stream = process.stdout.read()
        stderr_stream = process.stderr.read()
    returncode = process.wait()
    if not isinstance(stdout_stream, str):
        stdout_stream = stdout_stream.decode('utf-8')
    if not isinstance(stderr_stream, str):
        stderr_stream = stderr_stream.decode('utf-8')
    stdout = stdout_stream.splitlines()
    stderr = stderr_stream.splitlines()

    if returncode != 0:
        # set to true so that we can log the stderr/stdout that callers would
        # do anyway as long as verbose_on_failure is set (defaults to True)
        if verbose_on_failure:
            terminal_verbose = True
        # logfiles aren't disruptive visually, unlike the terminal, so this
        # should always be on when there is a failure
        logfile_verbose = True

    # the following can get a messed up order in the log if the system call
    # returns output with both stderr and stdout intermingled. This separates
    # that.
    for line in stdout:
        log_output('stdout', line, terminal_verbose, logfile_verbose)
    for line in stderr:
        log_output('stderr', line, terminal_verbose, logfile_verbose)
    return stdout, stderr, returncode