def call_lvm(command, debug=False): """ Call an executable and return a tuple of exitcode, stdout, stderr :param command: Command to execute :param debug: Dump debug to stdout """ # print 'STACK:' # for line in traceback.format_stack(): # print line.strip() # Prepend the full lvm executable so that we can run different versions # in different locations on the same box command.insert(0, cfg.LVM_CMD) command = add_no_notify(command) process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True, env=os.environ) out = process.communicate() stdout_text = bytes(out[0]).decode("utf-8") stderr_text = bytes(out[1]).decode("utf-8") if debug or process.returncode != 0: _debug_c(command, process.returncode, (stdout_text, stderr_text)) return process.returncode, stdout_text, stderr_text
def call_lvm(self, argv, debug=False): rc = 1 error_msg = "" if self.lvm_shell.poll(): raise Exception( self.lvm_shell.returncode, "Underlying lvm shell process is not present!") argv = add_no_notify(argv) # create the command string cmd = " ".join(_quote_arg(arg) for arg in argv) cmd += "\n" # run the command by writing it to the shell's STDIN self._write_cmd(cmd) # read everything from the STDOUT to the next prompt stdout, report_json, stderr = self._read_until_prompt() # Parse the report to see what happened if 'log' in report_json: if report_json['log'][-1:][0]['log_ret_code'] == '1': rc = 0 else: error_msg = self.get_error_msg() if debug or rc != 0: log_error(('CMD: %s' % cmd)) log_error(("EC = %d" % rc)) log_error(("ERROR_MSG=\n %s\n" % error_msg)) return rc, report_json, error_msg
def call_lvm(command, debug=False, line_cb=None, cb_data=None): """ Call an executable and return a tuple of exitcode, stdout, stderr :param command: Command to execute :param debug: Dump debug to stdout :param line_cb: Call the supplied function for each line read from stdin, CALL MUST EXECUTE QUICKLY and not *block* otherwise call_lvm function will fail to read stdin/stdout. Return value of call back is ignored :param cb_data: Supplied to callback to allow caller access to its own data # Callback signature def my_callback(my_context, line_read_stdin) pass """ # Prepend the full lvm executable so that we can run different versions # in different locations on the same box command.insert(0, cfg.LVM_CMD) command = add_no_notify(command) process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True, env=os.environ) stdout_text = "" stderr_text = "" stdout_index = 0 make_non_block(process.stdout) make_non_block(process.stderr) while True: try: rd_fd = [process.stdout.fileno(), process.stderr.fileno()] ready = select.select(rd_fd, [], [], 2) for r in ready[0]: if r == process.stdout.fileno(): stdout_text += read_decoded(process.stdout) elif r == process.stderr.fileno(): stderr_text += read_decoded(process.stderr) if line_cb is not None: # Process the callback for each line read! while True: i = stdout_text.find("\n", stdout_index) if i != -1: try: line_cb(cb_data, stdout_text[stdout_index:i]) except: st = traceback.format_exc() log_error("call_lvm: line_cb exception: \n %s" % st) stdout_index = i + 1 else: break # Check to see if process has terminated, None when running if process.poll() is not None: break except IOError as ioe: log_debug("call_lvm:" + str(ioe)) pass if debug or process.returncode != 0: _debug_c(command, process.returncode, (stdout_text, stderr_text)) return process.returncode, stdout_text, stderr_text