def execute(self, command, timeout=None, check_exit_code=True, as_root=False, strip_colors=True, will_succeed=False): self.logger.debug(command) if as_root and not self.connected_as_root: if self.unrooted: raise TargetStableError('unrooted') password = self._get_password() command = 'echo {} | sudo -S -- sh -c '.format( quote(password)) + quote(command) ignore = None if check_exit_code else 'all' try: return check_output(command, shell=True, timeout=timeout, ignore=ignore)[0] except subprocess.CalledProcessError as e: message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'.format( e.returncode, command, e.output) if will_succeed: raise TargetTransientError(message) else: raise TargetStableError(message)
def execute(self, command, timeout=None, check_exit_code=True, as_root=False, strip_colors=True, will_succeed=False): self.logger.debug(command) use_sudo = as_root and not self.connected_as_root if use_sudo: if self.unrooted: raise TargetStableError('unrooted') password = self._get_password() command = "echo {} | sudo -p ' ' -S -- sh -c {}".format(quote(password), quote(command)) ignore = None if check_exit_code else 'all' try: stdout, stderr = check_output(command, shell=True, timeout=timeout, ignore=ignore) except subprocess.CalledProcessError as e: message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'.format( e.returncode, command, e.output) if will_succeed: raise TargetTransientError(message) else: raise TargetStableError(message) # Remove the one-character prompt of sudo -S -p if use_sudo and stderr: stderr = stderr[1:] return stdout + stderr
def execute(self, command, timeout=1000, check_exit_code=True, as_root=False, strip_colors=True, will_succeed=False): """ Execute a command on the gem5 platform """ # First check if the connection is set up to interact with gem5 self._check_ready() try: output = self._gem5_shell(command, check_exit_code=check_exit_code, as_root=as_root) except TargetStableError as e: if will_succeed: raise TargetTransientError(e) else: raise if strip_colors: output = strip_bash_colors(output) return output
def _get_target_ip_address(self, target): with open_serial_connection(port=self.serial_port, baudrate=self.baudrate, timeout=30, init_dtr=0) as tty: tty.sendline( 'su') # this is, apprently, required to query network device # info by name on recent Juno builds... self.logger.debug('Waiting for the Android shell prompt.') tty.expect(target.shell_prompt) self.logger.debug('Waiting for IP address...') wait_start_time = time.time() try: while True: tty.sendline('ip addr list eth0') time.sleep(1) try: tty.expect(r'inet ([1-9]\d*.\d+.\d+.\d+)', timeout=10) return tty.match.group(1) except pexpect.TIMEOUT: pass # We have our own timeout -- see below. if (time.time() - wait_start_time) > self.ready_timeout: raise TargetTransientError( 'Could not acquire IP address.') finally: tty.sendline( 'exit') # exit shell created by "su" call at the start
def execute(self, command, timeout=None, check_exit_code=False, as_root=False, strip_colors=True, will_succeed=False): try: return adb_shell(self.device, command, timeout, check_exit_code, as_root, adb_server=self.adb_server, su_cmd=self.su_cmd) except subprocess.CalledProcessError as e: cls = TargetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError raise cls( e.returncode, command, e.output, e.stderr, ) except TargetStableError as e: if will_succeed: raise TargetTransientError(e) else: raise
def adb_shell(device, command, timeout=None, check_exit_code=False, as_root=False, adb_server=None, su_cmd='su -c {}'): # NOQA _check_env() # On older combinations of ADB/Android versions, the adb host command always # exits with 0 if it was able to run the command on the target, even if the # command failed (https://code.google.com/p/android/issues/detail?id=3254). # Homogenise this behaviour by running the command then echoing the exit # code of the executed command itself. command = r'({}); echo "\n$?"'.format(command) parts = ['adb'] if adb_server is not None: parts += ['-H', adb_server] if device is not None: parts += ['-s', device] parts += ['shell', command if not as_root else su_cmd.format(quote(command))] logger.debug(' '.join(quote(part) for part in parts)) try: raw_output, _ = check_output(parts, timeout, shell=False, combined_output=True) except subprocess.CalledProcessError as e: raise TargetStableError(str(e)) if raw_output: try: output, exit_code, _ = raw_output.replace('\r\n', '\n').replace('\r', '\n').rsplit('\n', 2) except ValueError: exit_code, _ = raw_output.replace('\r\n', '\n').replace('\r', '\n').rsplit('\n', 1) output = '' else: # raw_output is empty exit_code = '969696' # just because output = '' if check_exit_code: exit_code = exit_code.strip() re_search = AM_START_ERROR.findall(output) if exit_code.isdigit(): if int(exit_code): message = ('Got exit code {}\nfrom target command: {}\n' 'OUTPUT: {}') raise TargetStableError(message.format(exit_code, command, output)) elif re_search: message = 'Could not start activity; got the following:\n{}' raise TargetStableError(message.format(re_search[0])) else: # not all digits if re_search: message = 'Could not start activity; got the following:\n{}' raise TargetStableError(message.format(re_search[0])) else: message = 'adb has returned early; did not get an exit code. '\ 'Was kill-server invoked?\nOUTPUT:\n-----\n{}\n'\ '-----' raise TargetTransientError(message.format(raw_output)) return output
def online_all(self, verify=True): self.target._execute_util( 'hotplug_online_all', # pylint: disable=protected-access as_root=self.target.is_rooted) if verify: offline = set(self.target.list_offline_cpus()) if offline: raise TargetTransientError( 'The following CPUs failed to come back online: {}'.format( offline))
def execute(self, command, timeout=None, check_exit_code=False, as_root=False, strip_colors=True, will_succeed=False): try: return adb_shell(self.device, command, timeout, check_exit_code, as_root, adb_server=self.adb_server, su_cmd=self.su_cmd) except TargetStableError as e: if will_succeed: raise TargetTransientError(e) else: raise
def adb_disconnect(device, adb_server=None): _check_env() if not device: return if ":" in device and device in adb_list_devices(adb_server): adb_cmd = get_adb_command(None, 'disconnect', adb_server) command = "{} {}".format(adb_cmd, device) logger.debug(command) retval = subprocess.call(command, stdout=open(os.devnull, 'wb'), shell=True) if retval: raise TargetTransientError('"{}" returned {}'.format(command, retval))
def adb_disconnect(device): _check_env() if not device: return if ":" in device and device in adb_list_devices(): command = "adb disconnect " + device logger.debug(command) retval = subprocess.call(command, stdout=open(os.devnull, 'wb'), shell=True) if retval: raise TargetTransientError('"{}" returned {}'.format( command, retval))
def ssh_get_shell(host, username, password=None, keyfile=None, port=None, timeout=10, telnet=False, original_prompt=None, options=None): _check_env() start_time = time.time() while True: if telnet: if keyfile: raise ValueError( 'keyfile may not be used with a telnet connection.') conn = TelnetPxssh(original_prompt=original_prompt) else: # ssh conn = pxssh.pxssh(echo=False, options=options) try: if keyfile: conn.login(host, username, ssh_key=keyfile, port=port, login_timeout=timeout) else: conn.login(host, username, password, port=port, login_timeout=timeout) break except EOF: timeout -= time.time() - start_time if timeout <= 0: message = 'Could not connect to {}; is the host name correct?' raise TargetTransientError(message.format(host)) time.sleep(5) conn.setwinsize(500, 200) conn.sendline('') conn.prompt() conn.setecho(False) return conn
def execute(self, command, timeout=None, check_exit_code=True, as_root=False, strip_colors=True, will_succeed=False): #pylint: disable=unused-argument if command == '': # Empty command is valid but the __devlib_ec stuff below will # produce a syntax error with bash. Treat as a special case. return '' try: with self.lock: _command = '({}); __devlib_ec=$?; echo; echo $__devlib_ec'.format( command) full_output = self._execute_and_wait_for_prompt( _command, timeout, as_root, strip_colors) split_output = full_output.rsplit('\r\n', 2) try: output, exit_code_text, _ = split_output except ValueError as e: raise TargetStableError( "cannot split reply (target misconfiguration?):\n'{}'". format(full_output)) if check_exit_code: try: exit_code = int(exit_code_text) if exit_code: message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}' raise TargetStableError( message.format(exit_code, command, output)) except (ValueError, IndexError): logger.warning( 'Could not get exit code for "{}",\ngot: "{}"'\ .format(command, exit_code_text)) return output except EOF: raise TargetNotRespondingError('Connection lost.') except TargetStableError as e: if will_succeed: raise TargetTransientError(e) else: raise
def _check_ready(self): """ Check if the gem5 platform is ready """ if not self.ready: raise TargetTransientError('Gem5 is not ready to interact yet')