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 background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as_root=False): # First check if the connection is set up to interact with gem5 self._check_ready() # Create the logfile for stderr/stdout redirection command_name = command.split(' ')[0].split('/')[-1] redirection_file = 'BACKGROUND_{}.log'.format(command_name) trial = 0 while os.path.isfile(redirection_file): # Log file already exists so add to name redirection_file = 'BACKGROUND_{}{}.log'.format( command_name, trial) trial += 1 # Create the command to pass on to gem5 shell complete_command = '{} >> {} 2>&1 &'.format(command, redirection_file) output = self._gem5_shell(complete_command, as_root=as_root) output = strip_bash_colors(output) gem5_logger.info('STDERR/STDOUT of background command will be ' 'redirected to {}. Use target.pull() to ' 'get this file'.format(redirection_file)) return output
def _execute_and_wait_for_prompt(self, command, timeout=None, as_root=False, strip_colors=True, log=True): self.conn.prompt(0.1) # clear an existing prompt if there is one. if as_root: command = "sudo -- sh -c '{}'".format( escape_single_quotes(command)) if log: logger.debug(command) self.conn.sendline(command) if self.password: index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5) if index == 0: self.conn.sendline(self.password) else: # not as_root if log: logger.debug(command) self.conn.sendline(command) timed_out = self._wait_for_prompt(timeout) # the regex removes line breaks potential introduced when writing # command to shell. output = process_backspaces(self.conn.before) output = re.sub(r'\r([^\n])', r'\1', output) if '\r\n' in output: # strip the echoed command output = output.split('\r\n', 1)[1] if timed_out: self.cancel_running_command() raise TimeoutError(command, output) if strip_colors: output = strip_bash_colors(output) return output
def _execute_and_wait_for_prompt(self, command, timeout=None, as_root=False, strip_colors=True, log=True): self.conn.prompt(0.1) # clear an existing prompt if there is one. if as_root: command = "sudo -- sh -c '{}'".format(escape_single_quotes(command)) if log: logger.debug(command) self.conn.sendline(command) if self.password: index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5) if index == 0: self.conn.sendline(self.password) else: # not as_root if log: logger.debug(command) self.conn.sendline(command) timed_out = self._wait_for_prompt(timeout) # the regex removes line breaks potential introduced when writing # command to shell. output = process_backspaces(self.conn.before) output = re.sub(r"\r([^\n])", r"\1", output) if "\r\n" in output: # strip the echoed command output = output.split("\r\n", 1)[1] if timed_out: self.cancel_running_command() raise TimeoutError(command, output) if strip_colors: output = strip_bash_colors(output) return output
def execute(self, command, timeout=1000, check_exit_code=True, as_root=False, strip_colors=True): """ Execute a command on the gem5 platform """ # First check if the connection is set up to interact with gem5 self._check_ready() output = self._gem5_shell(command, check_exit_code=check_exit_code, as_root=as_root) if strip_colors: output = strip_bash_colors(output) return output
def execute(self, command, timeout=1000, check_exit_code=True, as_root=False, strip_colors=True): """ Execute a command on the gem5 platform """ # First check if the connection is set up to interact with gem5 self._check_ready() output = self._gem5_shell(command, check_exit_code=check_exit_code, as_root=as_root) if strip_colors: output = strip_bash_colors(output) return output
def pull(self, source, dest, timeout=0): #pylint: disable=unused-argument """ Pull a file from the gem5 device using m5 writefile The file is copied to the local directory within the guest as the m5 writefile command assumes that the file is local. The file is then written out to the host system using writefile, prior to being moved to the destination on the host. """ # First check if the connection is set up to interact with gem5 self._check_ready() result = self._gem5_shell("ls {}".format(source)) files = strip_bash_colors(result).split() for filename in files: dest_file = os.path.basename(filename) logger.debug("pull_file {} {}".format(filename, dest_file)) # writefile needs the file to be copied to be in the current # working directory so if needed, copy to the working directory # We don't check the exit code here because it is non-zero if the # source and destination are the same. The ls below will cause an # error if the file was not where we expected it to be. if os.path.isabs(source): if os.path.dirname(source) != self.execute( 'pwd', check_exit_code=False): self._gem5_shell("cat {} > {}".format( quote(filename), quote(dest_file))) self._gem5_shell("sync") self._gem5_shell("ls -la {}".format(dest_file)) logger.debug('Finished the copy in the simulator') self._gem5_util("writefile {}".format(dest_file)) if 'cpu' not in filename: while not os.path.exists( os.path.join(self.gem5_out_dir, dest_file)): time.sleep(1) # Perform the local move if os.path.exists(os.path.join(dest, dest_file)): logger.warning( 'Destination file {} already exists!'\ .format(dest_file)) else: shutil.move(os.path.join(self.gem5_out_dir, dest_file), dest) logger.debug("Pull complete.")
def pull(self, source, dest, timeout=0): #pylint: disable=unused-argument """ Pull a file from the gem5 device using m5 writefile The file is copied to the local directory within the guest as the m5 writefile command assumes that the file is local. The file is then written out to the host system using writefile, prior to being moved to the destination on the host. """ # First check if the connection is set up to interact with gem5 self._check_ready() result = self._gem5_shell("ls {}".format(source)) files = strip_bash_colors(result).split() for filename in files: dest_file = os.path.basename(filename) logger.debug("pull_file {} {}".format(filename, dest_file)) # writefile needs the file to be copied to be in the current # working directory so if needed, copy to the working directory # We don't check the exit code here because it is non-zero if the # source and destination are the same. The ls below will cause an # error if the file was not where we expected it to be. if os.path.isabs(source): if os.path.dirname(source) != self.execute('pwd', check_exit_code=False): self._gem5_shell("cat '{}' > '{}'".format(filename, dest_file)) self._gem5_shell("sync") self._gem5_shell("ls -la {}".format(dest_file)) logger.debug('Finished the copy in the simulator') self._gem5_util("writefile {}".format(dest_file)) if 'cpu' not in filename: while not os.path.exists(os.path.join(self.gem5_out_dir, dest_file)): time.sleep(1) # Perform the local move if os.path.exists(os.path.join(dest, dest_file)): logger.warning( 'Destination file {} already exists!'\ .format(dest_file)) else: shutil.move(os.path.join(self.gem5_out_dir, dest_file), dest) logger.debug("Pull complete.")
def _execute_and_wait_for_prompt(self, command, timeout=None, as_root=False, strip_colors=True, log=True): self.conn.prompt(0.1) # clear an existing prompt if there is one. if self.username == 'root': # As we're already root, there is no need to use sudo. as_root = False if as_root: command = self.sudo_cmd.format(escape_single_quotes(command)) if log: logger.debug(command) self.conn.sendline(command) if self.password: index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5) if index == 0: self.conn.sendline(self.password) else: # not as_root if log: logger.debug(command) self.conn.sendline(command) timed_out = self._wait_for_prompt(timeout) # the regex removes line breaks potential introduced when writing # command to shell. if sys.version_info[0] == 3: output = process_backspaces( self.conn.before.decode(sys.stdout.encoding, 'replace')) else: output = process_backspaces(self.conn.before) output = re.sub(r'\r([^\n])', r'\1', output) if '\r\n' in output: # strip the echoed command output = output.split('\r\n', 1)[1] if timed_out: self.cancel_running_command() raise TimeoutError(command, output) if strip_colors: output = strip_bash_colors(output) return output
def background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as_root=False): # First check if the connection is set up to interact with gem5 self._check_ready() # Create the logfile for stderr/stdout redirection command_name = command.split(' ')[0].split('/')[-1] redirection_file = 'BACKGROUND_{}.log'.format(command_name) trial = 0 while os.path.isfile(redirection_file): # Log file already exists so add to name redirection_file = 'BACKGROUND_{}{}.log'.format(command_name, trial) trial += 1 # Create the command to pass on to gem5 shell complete_command = '{} >> {} 2>&1 &'.format(command, redirection_file) output = self._gem5_shell(complete_command, as_root=as_root) output = strip_bash_colors(output) gem5_logger.info('STDERR/STDOUT of background command will be ' 'redirected to {}. Use target.pull() to ' 'get this file'.format(redirection_file)) return output
def _execute_and_wait_for_prompt(self, command, timeout=None, as_root=False, strip_colors=True, log=True): self.conn.prompt(0.1) # clear an existing prompt if there is one. if as_root and self.connected_as_root: # As we're already root, there is no need to use sudo. as_root = False if as_root: command = self.sudo_cmd.format(quote(command)) if log: logger.debug(command) self._sendline(command) if self.password: index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5) if index == 0: self._sendline(self.password) else: # not as_root if log: logger.debug(command) self._sendline(command) timed_out = self._wait_for_prompt(timeout) if sys.version_info[0] == 3: output = process_backspaces( self.conn.before.decode(sys.stdout.encoding or 'utf-8', 'replace')) else: output = process_backspaces(self.conn.before) if timed_out: self.cancel_running_command() raise TimeoutError(command, output) if strip_colors: output = strip_bash_colors(output) return output