def __connect_sftp(self): """SFTP connection opener""" with self.lock: try: self.__sftp = self.__ssh.open_sftp() except paramiko.SSHException: logger.warning('SFTP enable failed! SSH only is accessible.')
def __init__(self): warn( 'devops.helpers.KeyPolicy is deprecated ' 'and will be removed soon', DeprecationWarning) logger.warning('devops.helpers.KeyPolicy is deprecated ' 'and will be removed soon') super(KeyPolicy, self).__init__()
def nat_interface(self): msg = ( 'Environment.nat_interface is deprecated.' ) logger.warning(msg) warnings.warn(msg, DeprecationWarning) return ''
def _get_file_size(*args, **kwargs): logger.warning( '_get_file_size has been deprecated in favor of get_file_size') warn( '_get_file_size has been deprecated in favor of get_file_size', DeprecationWarning) return get_file_size(*args, **kwargs)
def _underscored(*args): logger.warning( '_underscored has been deprecated in favor of underscored') warn( '_underscored has been deprecated in favor of underscored', DeprecationWarning) return underscored(*args)
def sync_node_time(env, node_name='admin', cmd=None): if cmd is None: cmd = "hwclock -s && NTPD=$(find /etc/init.d/ -regex " cmd += "'/etc/init.d/ntp.?'); $NTPD stop; killall ntpd;" cmd += " ntpd -qg && $NTPD start" if node_name == 'admin': try: # If public NTP servers aren't accessible ntpdate will fail and # ntpd daemon shouldn't be restarted to avoid 'Server has gone # too long without sync' error while syncing time from slaves remote = get_admin_remote(env) remote.execute("ntpdate -d $(awk '/^server/{print" " $2}' /etc/ntp.conf)") except AssertionError as e: logger.warning('Error occurred while synchronizing time on master' ': {0}'.format(e)) else: remote = get_admin_remote(env) remote.execute('service ntpd stop && ntpd -qg && ' 'service ntpd start') else: remote = get_node_remote(env, node_name) remote.execute(cmd) remote.execute('hwclock -w') remote_date = remote.execute('date')['stdout'] logger.info("Node time: {0}".format(remote_date))
def admin_net2(self): msg = ( 'Environment.admin_net2 is deprecated. ' 'Replace by string "admin2".' ) logger.warning(msg) warnings.warn(msg, DeprecationWarning) return 'admin2'
def _sftp(self): if self.__sftp is not None: return self.__sftp logger.warning('SFTP is not connected, try to reconnect') self._connect_sftp() if self.__sftp is not None: return self.__sftp raise paramiko.SSHException('SFTP connection failed')
def interface_by_network_name(self, network_name): logger.warning('interface_by_network_name is deprecated in favor of ' 'get_interface_by_network_name') warnings.warn( "'Node.interface_by_network_name' is deprecated. " "Use 'Node.get_interface_by_network_name' instead.", DeprecationWarning) return self.get_interface_by_network_name(network_name=network_name)
def interface_by_network_name(self, network_name): logger.warning('interface_by_network_name is deprecated in favor of ' 'get_interface_by_network_name') warnings.warn( "'Node.interface_by_network_name' is deprecated. " "Use 'Node.get_interface_by_network_name' instead.", DeprecationWarning ) return self.get_interface_by_network_name(network_name=network_name)
def __init__(self): warn( 'devops.helpers.KeyPolicy is deprecated ' 'and will be removed soon', DeprecationWarning) logger.warning( 'devops.helpers.KeyPolicy is deprecated ' 'and will be removed soon' ) super(KeyPolicy, self).__init__()
def get_nodes(admin_ip): msg = ('get_nodes has been deprecated in favor of ' 'NailgunClient.get_nodes_json') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops.client import nailgun ng_client = nailgun.NailgunClient(ip=admin_ip) return ng_client.get_nodes_json()
def get_ssh_to_remote_by_key(self, ip, keyfile): try: with open(keyfile) as f: keys = [RSAKey.from_private_key(f)] except IOError: logger.warning('Loading of SSH key from file failed. Trying to use' ' SSH agent ...') keys = Agent().get_keys() return SSHClient(ip, private_keys=keys)
def router(self, router_name='admin'): msg = ('router has been deprecated in favor of ' 'DevopsEnvironment.get_default_gw') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops.client import DevopsClient env = DevopsClient().get_env(self.name) return env.get_default_gw(l2_network_device_name=router_name)
def get_admin_ip(env): msg = ('get_admin_ip has been deprecated in favor of ' 'DevopsEnvironment.get_admin_ip') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client denv = client.DevopsClient().get_env(env.name) return denv.get_admin_ip()
def get_ssh_to_remote_by_key(ip, keyfile): warn('LEGACY, for fuel-qa compatibility', DeprecationWarning) try: with open(keyfile) as f: keys = [RSAKey.from_private_key(f)] except IOError: logger.warning('Loading of SSH key from file failed. Trying to use' ' SSH agent ...') keys = Agent().get_keys() return SSHClient(ip, auth=SSHAuth(keys=keys))
def get_ssh_to_remote_by_key(ip, keyfile): warnings.warn('LEGACY, for fuel-qa compatibility', DeprecationWarning) try: with open(keyfile) as f: keys = [paramiko.RSAKey.from_private_key(f)] except IOError: logger.warning('Loading of SSH key from file failed. Trying to use' ' SSH agent ...') keys = paramiko.Agent().get_keys() return ssh_client.SSHClient(ip, auth=ssh_client.SSHAuth(keys=keys))
def get_admin_ip(env): msg = ( 'get_admin_ip has been deprecated in favor of ' 'DevopsEnvironment.get_admin_ip') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client denv = client.DevopsClient().get_env(env.name) return denv.get_admin_ip()
def get_admin_remote(env, login=settings.SSH_CREDENTIALS['login'], password=settings.SSH_CREDENTIALS['password']): msg = ('get_admin_remote has been deprecated in favor of ' 'DevopsEnvironment.get_admin_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client denv = client.DevopsClient().get_env(env.name) return denv.get_admin_remote(login=login, password=password)
def get_slave_ip(env, node_mac_address): msg = ('get_slave_ip has been deprecated in favor of ' 'DevopsEnvironment.get_node_ip') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client from devops.client import nailgun denv = client.DevopsClient().get_env(env.name) ng_client = nailgun.NailgunClient(ip=denv.get_admin_ip()) return ng_client.get_slave_ip_by_mac(node_mac_address)
def get_slave_ip(env, node_mac_address): msg = ( 'get_slave_ip has been deprecated in favor of ' 'DevopsEnvironment.get_node_ip') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client from devops.client import nailgun denv = client.DevopsClient().get_env(env.name) ng_client = nailgun.NailgunClient(ip=denv.get_admin_ip()) return ng_client.get_slave_ip_by_mac(node_mac_address)
def _stop_dhcp_tftp(self): if os.path.isfile('{0}/dnsmasq.pid'.format(self.ipmi_driver_root_dir)): try: pid_file = open('{0}/dnsmasq.pid'. format(self.ipmi_driver_root_dir), 'r') for line in pid_file: pid = line.strip().lower() cmd = ['sudo', 'kill', pid] subprocess.call(cmd) pid_file.close() LOGGER.debug('dnsmasq killed') except subprocess.CalledProcessError, e: LOGGER.warning("Can't stop dnsmasq: {0}".format(e.output))
def get_admin_remote( env, login=settings.SSH_CREDENTIALS['login'], password=settings.SSH_CREDENTIALS['password']): msg = ( 'get_admin_remote has been deprecated in favor of ' 'DevopsEnvironment.get_admin_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client denv = client.DevopsClient().get_env(env.name) return denv.get_admin_remote(login=login, password=password)
def __setitem__(self, key, value): rw = ['stdout', 'stderr', 'exit_code'] if key in rw: setattr(self, key, value) return if key in deprecated_aliases: logger.warning( '{key} is read-only and calculated automatically'.format( key=key)) return if key in dir(self): raise error.DevopsError('{key} is read-only!'.format(key=key)) raise IndexError('{key} not found in {dir}'.format(key=key, dir=rw))
def get_node_remote(env, node_name, login=settings.SSH_SLAVE_CREDENTIALS['login'], password=settings.SSH_SLAVE_CREDENTIALS['password']): msg = ('get_node_remote has been deprecated in favor of ' 'DevopsEnvironment.get_node_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops.client import DevopsClient denv = DevopsClient().get_env(env.name) return denv.get_node_remote(node_name=node_name, login=login, password=password)
def add_groups(self, groups): for group_data in groups: driver_data = group_data['driver'] if driver_data['name'] == 'devops.driver.libvirt.libvirt_driver': warnings.warn( "Driver 'devops.driver.libvirt.libvirt_driver' " "has been renamed to 'devops.driver.libvirt', " "please update the tests!", DeprecationWarning) logger.warning("Driver 'devops.driver.libvirt.libvirt_driver' " "has been renamed to 'devops.driver.libvirt', " "please update the tests!") driver_data['name'] = 'devops.driver.libvirt' self.add_group(group_name=group_data['name'], driver_name=driver_data['name'], **driver_data.get('params', {}))
def get_node_remote( env, node_name, login=settings.SSH_SLAVE_CREDENTIALS['login'], password=settings.SSH_SLAVE_CREDENTIALS['password']): msg = ( 'get_node_remote has been deprecated in favor of ' 'DevopsEnvironment.get_node_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops.client import DevopsClient denv = DevopsClient().get_env(env.name) return denv.get_node_remote( node_name=node_name, login=login, password=password)
def get_ssh_to_remote(self, ip, login=settings.SSH_SLAVE_CREDENTIALS['login'], password=settings.SSH_SLAVE_CREDENTIALS['password']): msg = ('get_ssh_to_remote has been deprecated in favor of ' 'DevopsEnvironment.get_node_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client env = client.DevopsClient().get_env(self.name) return ssh_client.SSHClient( ip, auth=ssh_client.SSHAuth( username=login, password=password, keys=env.get_private_keys()))
def get_ssh_to_remote(self, ip, login=settings.SSH_SLAVE_CREDENTIALS['login'], password=settings.SSH_SLAVE_CREDENTIALS['password']): msg = ('get_ssh_to_remote has been deprecated in favor of ' 'DevopsEnvironment.get_node_remote') logger.warning(msg) warnings.warn(msg, DeprecationWarning) from devops import client env = client.DevopsClient().get_env(self.name) return ssh_client.SSHClient(ip, auth=ssh_client.SSHAuth( username=login, password=password, keys=env.get_private_keys()))
def sync_time(env, node_names, skip_sync=False): """Synchronize time on nodes param: env - environment object param: node_names - list of devops node names param: skip_sync - only get the current time without sync return: dict{node_name: node_time, ...} """ logger.warning('sync_time is deprecated. Use DevopsClient instead') warnings.warn( 'sync_time is deprecated. Use DevopsClient.sync_time instead', DeprecationWarning) from devops import client denv = client.DevopsClient().get_env(env.name) return denv.sync_time(node_names=node_names, skip_sync=skip_sync)
def add_groups(self, groups): for group_data in groups: driver_data = group_data['driver'] if driver_data['name'] == 'devops.driver.libvirt.libvirt_driver': warn( "Driver 'devops.driver.libvirt.libvirt_driver' " "has been renamed to 'devops.driver.libvirt', " "please update the tests!", DeprecationWarning) logger.warning( "Driver 'devops.driver.libvirt.libvirt_driver' " "has been renamed to 'devops.driver.libvirt', " "please update the tests!") driver_data['name'] = 'devops.driver.libvirt' self.add_group( group_name=group_data['name'], driver_name=driver_data['name'], **driver_data.get('params', {}) )
def _wait(*args, **kwargs): logger.warning('_wait has been deprecated in favor of wait_pass') warn('_wait has been deprecated in favor of wait_pass', DeprecationWarning) return wait_pass(*args, **kwargs)
def __exec_command(cls, command, cwd=None, env=None, timeout=None, verbose=False): """Command executor helper :type command: str :type cwd: str :type env: dict :type timeout: int :rtype: ExecResult """ def poll_stream(src, verb_logger=None): dst = [] try: for line in src: dst.append(line) if verb_logger is not None: verb_logger( line.decode('utf-8', errors='backslashreplace').rstrip()) except IOError: pass return dst def poll_streams(result, stdout, stderr, verbose): rlist, _, _ = select.select([stdout, stderr], [], []) if rlist: if stdout in rlist: result.stdout += poll_stream( src=stdout, verb_logger=logger.info if verbose else logger.debug) if stderr in rlist: result.stderr += poll_stream( src=stderr, verb_logger=logger.error if verbose else logger.debug) @decorators.threaded(started=True) def poll_pipes(proc, result, stop): """Polling task for FIFO buffers :type proc: subprocess.Popen :type result: ExecResult :type stop: threading.Event """ # Get file descriptors for stdout and stderr streams fd_stdout = proc.stdout.fileno() fd_stderr = proc.stderr.fileno() # Get flags of stdout and stderr streams fl_stdout = fcntl.fcntl(fd_stdout, fcntl.F_GETFL) fl_stderr = fcntl.fcntl(fd_stderr, fcntl.F_GETFL) # Set nonblock mode for stdout and stderr streams fcntl.fcntl(fd_stdout, fcntl.F_SETFL, fl_stdout | os.O_NONBLOCK) fcntl.fcntl(fd_stderr, fcntl.F_SETFL, fl_stderr | os.O_NONBLOCK) while not stop.isSet(): time.sleep(0.1) poll_streams(result=result, stdout=proc.stdout, stderr=proc.stderr, verbose=verbose) proc.poll() if proc.returncode is not None: result.exit_code = proc.returncode result.stdout += poll_stream( src=proc.stdout, verb_logger=logger.info if verbose else logger.debug) result.stderr += poll_stream( src=proc.stderr, verb_logger=logger.error if verbose else logger.debug) stop.set() # 1 Command per run with cls.__lock: result = exec_result.ExecResult(cmd=command) stop_event = threading.Event() if verbose: logger.info("\nExecuting command: {!r}".format( command.rstrip())) else: logger.debug("\nExecuting command: {!r}".format( command.rstrip())) # Run process = subprocess.Popen(args=[command], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cwd, env=env, universal_newlines=False) # Poll output poll_pipes(process, result, stop_event) # wait for process close stop_event.wait(timeout) # Process closed? if stop_event.isSet(): stop_event.clear() return result # Kill not ended process and wait for close try: process.kill() # kill -9 stop_event.wait(5) except OSError: # Nothing to kill logger.warning("{!r} has been completed just after timeout: " "please validate timeout.".format(command)) wait_err_msg = ( 'Wait for {0!r} during {1}s: no return code!\n'.format( command, timeout)) output_brief_msg = ('\tSTDOUT:\n' '{0}\n' '\tSTDERR"\n' '{1}'.format(result.stdout_brief, result.stderr_brief)) logger.debug(wait_err_msg) raise error.TimeoutError(wait_err_msg + output_brief_msg)
def deploy_wait(self): # Do nothing logger.warning('Fuel is going to be installed manually in tests')
def interface_by_network_name(self, network_name): logger.warning('interface_by_network_name is deprecated in favor of ' 'get_interface_by_network_name') raise DeprecationWarning( "'Node.interface_by_network_name' is deprecated. " "Use 'Node.get_interface_by_network_name' instead.")
def nat_interface(self): msg = ('Environment.nat_interface is deprecated.') logger.warning(msg) warnings.warn(msg, DeprecationWarning) return ''
def _connect_sftp(self): try: self.__sftp = self._ssh.open_sftp() except paramiko.SSHException: logger.warning('SFTP enable failed! SSH only is accessible.')
def __exec_command(cls, command, cwd=None, env=None, timeout=None, verbose=True): """Command executor helper :type command: str :type cwd: str :type env: dict :type timeout: int :rtype: ExecResult """ def readlines(stream, verbose, lines_count=100): """Nonblocking read and log lines from stream""" if lines_count < 1: lines_count = 1 result = [] try: for _ in range(1, lines_count): line = stream.readline() if line: result.append(line) if verbose: print(line.rstrip()) except IOError: pass return result @threaded(started=True) def poll_pipes(proc, result, stop): """Polling task for FIFO buffers :type proc: Popen :type result: ExecResult :type stop: Event """ # Get file descriptors for stdout and stderr streams fd_stdout = proc.stdout.fileno() fd_stderr = proc.stderr.fileno() # Get flags of stdout and stderr streams fl_stdout = fcntl.fcntl(fd_stdout, fcntl.F_GETFL) fl_stderr = fcntl.fcntl(fd_stderr, fcntl.F_GETFL) # Set nonblock mode for stdout and stderr streams fcntl.fcntl(fd_stdout, fcntl.F_SETFL, fl_stdout | os.O_NONBLOCK) fcntl.fcntl(fd_stderr, fcntl.F_SETFL, fl_stderr | os.O_NONBLOCK) while not stop.isSet(): sleep(0.1) stdout_diff = readlines(proc.stdout, verbose) stderr_diff = readlines(proc.stderr, verbose) result.stdout += stdout_diff result.stderr += stderr_diff proc.poll() if proc.returncode is not None: result.exit_code = proc.returncode stdout_diff = readlines(proc.stdout, verbose) stderr_diff = readlines(proc.stderr, verbose) result.stdout += stdout_diff result.stderr += stderr_diff stop.set() # 1 Command per run with cls.__lock: result = ExecResult(cmd=command) stop_event = Event() logger.debug("Run command on the host: '{0}'".format(command)) # Run process = Popen(args=[command], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, cwd=cwd, env=env, universal_newlines=False) # Poll output poll_pipes(process, result, stop_event) # wait for process close stop_event.wait(timeout) output_tmpl = ('\tSTDOUT:\n' '{0}\n' '\tSTDERR"\n' '{1}\n') logger.debug(output_tmpl.format(result.stdout, result.stderr)) # Process closed? if stop_event.isSet(): stop_event.clear() return result # Kill not ended process and wait for close try: process.kill() # kill -9 stop_event.wait(5) except OSError: # Nothing to kill logger.warning("{} has been completed just after timeout: " "please validate timeout.".format(command)) no_ec_msg = ( "No return code received while waiting for the command " "'{0}' during {1}s !\n".format(command, timeout)) logger.debug(no_ec_msg) raise TimeoutError( no_ec_msg + output_tmpl.format(result.stdout_brief, result.stderr_brief))
def _tcp_ping(*args, **kwargs): logger.warning('_tcp_ping is deprecated in favor of tcp_ping_') warn('_tcp_ping is deprecated in favor of tcp_ping_', DeprecationWarning) return tcp_ping_(*args, **kwargs)
def admin_net2(self): msg = ('Environment.admin_net2 is deprecated. ' 'Replace by string "admin2".') logger.warning(msg) warnings.warn(msg, DeprecationWarning) return 'admin2'
def __exec_command(cls, command, cwd=None, env=None, timeout=None, verbose=True): """Command executor helper :type command: str :type cwd: str :type env: dict :type timeout: int :rtype: ExecResult """ def readlines(stream, verbose, lines_count=100): """Nonblocking read and log lines from stream""" if lines_count < 1: lines_count = 1 result = [] try: for _ in range(1, lines_count): line = stream.readline() if line: result.append(line) if verbose: print(line.rstrip()) except IOError: pass return result @threaded(started=True) def poll_pipes(proc, result, stop): """Polling task for FIFO buffers :type proc: Popen :type result: ExecResult :type stop: Event """ # Get file descriptors for stdout and stderr streams fd_stdout = proc.stdout.fileno() fd_stderr = proc.stderr.fileno() # Get flags of stdout and stderr streams fl_stdout = fcntl.fcntl(fd_stdout, fcntl.F_GETFL) fl_stderr = fcntl.fcntl(fd_stderr, fcntl.F_GETFL) # Set nonblock mode for stdout and stderr streams fcntl.fcntl(fd_stdout, fcntl.F_SETFL, fl_stdout | os.O_NONBLOCK) fcntl.fcntl(fd_stderr, fcntl.F_SETFL, fl_stderr | os.O_NONBLOCK) while not stop.isSet(): sleep(0.1) stdout_diff = readlines(proc.stdout, verbose) stderr_diff = readlines(proc.stderr, verbose) result.stdout += stdout_diff result.stderr += stderr_diff proc.poll() if proc.returncode is not None: result.exit_code = proc.returncode stdout_diff = readlines(proc.stdout, verbose) stderr_diff = readlines(proc.stderr, verbose) result.stdout += stdout_diff result.stderr += stderr_diff stop.set() # 1 Command per run with cls.__lock: result = ExecResult(cmd=command) stop_event = Event() logger.debug("Run command on the host: '{0}'".format(command)) # Run process = Popen( args=[command], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, cwd=cwd, env=env, universal_newlines=False) # Poll output poll_pipes(process, result, stop_event) # wait for process close stop_event.wait(timeout) output_tmpl = ( '\tSTDOUT:\n' '{0}\n' '\tSTDERR"\n' '{1}\n') logger.debug(output_tmpl.format(result.stdout, result.stderr)) # Process closed? if stop_event.isSet(): stop_event.clear() return result # Kill not ended process and wait for close try: process.kill() # kill -9 stop_event.wait(5) except OSError: # Nothing to kill logger.warning( "{} has been completed just after timeout: " "please validate timeout.".format(command)) no_ec_msg = ( "No return code received while waiting for the command " "'{0}' during {1}s !\n".format(command, timeout)) logger.debug(no_ec_msg) raise TimeoutError( no_ec_msg + output_tmpl.format( result.stdout_brief, result.stderr_brief ))
def _get_file_size(*args, **kwargs): logger.warning( '_get_file_size has been deprecated in favor of get_file_size') warn('_get_file_size has been deprecated in favor of get_file_size', DeprecationWarning) return get_file_size(*args, **kwargs)
def _underscored(*args): logger.warning('_underscored has been deprecated in favor of underscored') warn('_underscored has been deprecated in favor of underscored', DeprecationWarning) return underscored(*args)
def _tcp_ping(*args, **kwargs): logger.warning('_tcp_ping is deprecated in favor of tcp_ping') warn('_tcp_ping is deprecated in favor of tcp_ping', DeprecationWarning) return tcp_ping_(*args, **kwargs)
def __exec_command(cls, command, cwd=None, env=None, timeout=None, verbose=False): """Command executor helper :type command: str :type cwd: str :type env: dict :type timeout: int :rtype: ExecResult """ def poll_stream(src, verb_logger=None): dst = [] try: for line in src: dst.append(line) if verb_logger is not None: verb_logger( line.decode('utf-8', errors='backslashreplace').rstrip() ) except IOError: pass return dst def poll_streams(result, stdout, stderr, verbose): rlist, _, _ = select.select( [stdout, stderr], [], []) if rlist: if stdout in rlist: result.stdout += poll_stream( src=stdout, verb_logger=logger.info if verbose else logger.debug) if stderr in rlist: result.stderr += poll_stream( src=stderr, verb_logger=logger.error if verbose else logger.debug) @decorators.threaded(started=True) def poll_pipes(proc, result, stop): """Polling task for FIFO buffers :type proc: subprocess.Popen :type result: ExecResult :type stop: threading.Event """ # Get file descriptors for stdout and stderr streams fd_stdout = proc.stdout.fileno() fd_stderr = proc.stderr.fileno() # Get flags of stdout and stderr streams fl_stdout = fcntl.fcntl(fd_stdout, fcntl.F_GETFL) fl_stderr = fcntl.fcntl(fd_stderr, fcntl.F_GETFL) # Set nonblock mode for stdout and stderr streams fcntl.fcntl(fd_stdout, fcntl.F_SETFL, fl_stdout | os.O_NONBLOCK) fcntl.fcntl(fd_stderr, fcntl.F_SETFL, fl_stderr | os.O_NONBLOCK) while not stop.isSet(): time.sleep(0.1) poll_streams( result=result, stdout=proc.stdout, stderr=proc.stderr, verbose=verbose ) proc.poll() if proc.returncode is not None: result.exit_code = proc.returncode result.stdout += poll_stream( src=proc.stdout, verb_logger=logger.info if verbose else logger.debug) result.stderr += poll_stream( src=proc.stderr, verb_logger=logger.error if verbose else logger.debug) stop.set() # 1 Command per run with cls.__lock: result = exec_result.ExecResult(cmd=command) stop_event = threading.Event() message = log_templates.CMD_EXEC.format(cmd=command.rstrip()) if verbose: logger.info(message) else: logger.debug(message) # Run process = subprocess.Popen( args=[command], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cwd, env=env, universal_newlines=False) # Poll output poll_pipes(process, result, stop_event) # wait for process close stop_event.wait(timeout) # Process closed? if stop_event.isSet(): stop_event.clear() return result # Kill not ended process and wait for close try: process.kill() # kill -9 stop_event.wait(5) except OSError: # Nothing to kill logger.warning( u"{!s} has been completed just after timeout: " "please validate timeout.".format(command)) wait_err_msg = log_templates.CMD_WAIT_ERROR.format( cmd=command.rstrip(), timeout=timeout) output_brief_msg = ('\tSTDOUT:\n' '{0}\n' '\tSTDERR"\n' '{1}'.format(result.stdout_brief, result.stderr_brief)) logger.debug(wait_err_msg) raise error.TimeoutError(wait_err_msg + output_brief_msg)