X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fceph-volume%2Fceph_volume%2Fprocess.py;fp=src%2Fceph%2Fsrc%2Fceph-volume%2Fceph_volume%2Fprocess.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=4b6a9c284741f50d5cb22644214a0293d19c266f;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/ceph-volume/ceph_volume/process.py b/src/ceph/src/ceph-volume/ceph_volume/process.py deleted file mode 100644 index 4b6a9c2..0000000 --- a/src/ceph/src/ceph-volume/ceph_volume/process.py +++ /dev/null @@ -1,199 +0,0 @@ -from fcntl import fcntl, F_GETFL, F_SETFL -from os import O_NONBLOCK, read -import subprocess -from select import select -from ceph_volume import terminal - -import logging - -logger = logging.getLogger(__name__) - - -def log_output(descriptor, message, terminal_logging): - """ - log output to both the logger and the terminal if terminal_logging is - enabled - """ - if not message: - return - message = message.strip() - line = '%s %s' % (descriptor, message) - if terminal_logging: - getattr(terminal, descriptor)(message) - logger.info(line) - - -def log_descriptors(reads, process, terminal_logging): - """ - Helper to send output to the terminal while polling the subprocess - """ - # these fcntl are set to O_NONBLOCK for the filedescriptors coming from - # subprocess so that the logging does not block. Without these a prompt in - # a subprocess output would hang and nothing would get printed. Note how - # these are just set when logging subprocess, not globally. - stdout_flags = fcntl(process.stdout, F_GETFL) # get current p.stdout flags - stderr_flags = fcntl(process.stderr, F_GETFL) # get current p.stderr flags - fcntl(process.stdout, F_SETFL, stdout_flags | O_NONBLOCK) - fcntl(process.stderr, F_SETFL, stderr_flags | O_NONBLOCK) - descriptor_names = { - process.stdout.fileno(): 'stdout', - process.stderr.fileno(): 'stderr' - } - for descriptor in reads: - descriptor_name = descriptor_names[descriptor] - try: - log_output(descriptor_name, read(descriptor, 1024), terminal_logging) - except (IOError, OSError): - # nothing else to log - pass - - -def obfuscate(command_, on=None): - """ - Certain commands that are useful to log might contain information that - should be replaced by '*' like when creating OSDs and the keyryings are - being passed, which should not be logged. - - :param on: A string (will match a flag) or an integer (will match an index) - - If matching on a flag (when ``on`` is a string) it will obfuscate on the - value for that flag. That is a command like ['ls', '-l', '/'] that calls - `obfuscate(command, on='-l')` will obfustace '/' which is the value for - `-l`. - - The reason for `on` to allow either a string or an integer, altering - behavior for both is because it is easier for ``run`` and ``call`` to just - pop a value to obfuscate (vs. allowing an index or a flag) - """ - command = command_[:] - msg = "Running command: %s" % ' '.join(command) - if on in [None, False]: - return msg - - if isinstance(on, int): - index = on - - else: - try: - index = command.index(on) + 1 - except ValueError: - # if the flag just doesn't exist then it doesn't matter just return - # the base msg - return msg - - try: - command[index] = '*' * len(command[index]) - except IndexError: # the index was completely out of range - return msg - - return "Running command: %s" % ' '.join(command) - - -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) - - -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