def _connect(self, masteruri, screen_name, nodename, user=None): self._masteruri = masteruri if self.qfile is not None and self.qfile.isOpen(): self.qfile.close() self.clear_signal.emit() host = get_hostname(masteruri) if nm.is_local(host): self._nodename = nodename if screen_name: screen_log = screen.get_logfile(node=nodename) else: screen_log = screen.get_ros_logfile(node=nodename) self.qfile = QFile(screen_log) self.setWindowTitle(nodename) if self.qfile.open(QIODevice.ReadOnly): self._first_fill = True self.qfile.seek(self.qfile.size() - 1) # self.lread() self._info = "END" self.thread = threading.Thread(target=self._read_log, kwargs={"filename": screen_log}) self.thread.setDaemon(True) self.thread.start() else: self._valid = False else: self._connect_ssh(host, nodename, user) self.logger_handler = LoggerHandler( nodename, masteruri=masteruri, layout=self.scrollAreaWidgetContents.layout()) self.logger_handler.update() return False
def open_screen_terminal(cls, masteruri, screen_name, nodename, use_log_widget=False, user=None): ''' Open the screen output in a new terminal. :param str masteruri: the masteruri where the screen is running. :param str screen_name: the name of the screen to show :param str nodename: the name of the node is used for the title of the terminal :raise Exception: on errors while resolving host :see: L{fkie_node_manager.is_local()} ''' # create a title of the terminal if use_log_widget: nm._MAIN_FORM.open_screen_dock(masteruri, screen_name, nodename, user) return host = get_hostname(masteruri) title_opt = 'SCREEN %s on %s' % (nodename, host) if nm.is_local(host): cmd = nm.settings().terminal_cmd( [screen.SCREEN, '-x', screen_name], title_opt) rospy.loginfo("Open screen terminal: %s", cmd) SupervisedPopen(shlex.split(cmd), object_id=title_opt, description="Open screen terminal: %s" % title_opt) else: rospy.loginfo("Open remote screen terminal for %s to %s" % (nodename, host)) _ps = nm.ssh().ssh_x11_exec(host, [screen.SCREEN, '-x', screen_name], title_opt, user)
def set_current_master(self, masteruri, mastername): self._current_master = masteruri.rstrip(os.path.sep) self._current_master_name = mastername if self._is_root(self._current_path): nm.nmd().file.list_path_threaded(self._current_path) if nmdurl.equal_uri(self._current_path, masteruri_from_master()): self._add_path(nmdurl.nmduri(self._current_master), PathItem.REMOTE_DAEMON, 0, 0, get_hostname(self._current_master_name))
def kill_screens(cls, node, grpc_url, auto_ok_request=True, user=None, pw=None): ''' Searches for the screen associated with the given node and kill this screens. :param str node: the name of the node those screen output to kill :param str grpc_url: the url of node manager daemon where the screen is running ''' if node is None or len(node) == 0: return False try: # get the available screens screens = nm.nmd().screen.get_screens(grpc_url, node) if screens: do_kill = True if auto_ok_request: from fkie_node_manager.detailed_msg_box import MessageBox result = MessageBox.question( None, "Kill SCREENs?", '\n'.join(list(screens.keys())), buttons=MessageBox.Ok | MessageBox.Cancel) if result == MessageBox.Ok: do_kill = True if do_kill: host = get_hostname(grpc_url) for sname, _nname in screens.items(): pid, _, _ = sname.partition('.') if pid: try: nm.nmd().monitor.kill_process( int(pid), grpc_url) # nm.starter()._kill_wo(host, int(pid), auto_ok_request, user, pw) except Exception: import traceback rospy.logwarn( "Error while kill screen (PID: %s) on host '%s': %s", utf8(pid), utf8(host), traceback.format_exc(1)) nm.nmd().screen.wipe_screens(grpc_url) # if nm.is_local(host): # SupervisedPopen([screen.SCREEN, '-wipe'], object_id='screen -wipe', description="screen: clean up the socket with -wipe") # else: # nm.ssh().ssh_exec(host, [screen.SCREEN, '-wipe'], close_stdin=True, close_stdout=True, close_stderr=True) except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.kill_screens, { 'node': node, 'grpc_url': grpc_url, 'auto_ok_request': auto_ok_request, 'user': user, 'pw': pw })
def test_get_hostname(self): hostname = host.get_hostname(None) self.assertEqual( hostname, None, "Hostname from `None` should be `None`, got: %s, expected: %s" % (hostname, None)) hostname = host.get_hostname('') self.assertEqual( hostname, '', "Hostname from `` should be ``, got: %s, expected: %s" % (hostname, '')) name = 'myhost' hostname = host.get_hostname('http://%s' % name) self.assertEqual( hostname, name, "Wrong hostname from `http://%s`, got: %s, expected: %s" % (name, hostname, name)) hostname = host.get_hostname('http://%s:11111' % name) self.assertEqual( hostname, name, "Wrong hostname from `http://%s:11111`, got: %s, expected: %s" % (name, hostname, name)) hostname = host.get_hostname('%s:11111' % name) self.assertEqual( hostname, name, "Wrong hostname from `%s:11111`, got: %s, expected: %s" % (name, hostname, name)) wrong = '%s:11:2' % name hostname = host.get_hostname(wrong) self.assertEqual( hostname, wrong, "Wrong hostname from `%s`, got: %s, expected: %s" % (wrong, hostname, wrong))
def _listed_path(self, url, path, result): if not self.is_current_nmd(url): return root = self.invisibleRootItem() while root.rowCount(): root.removeRow(0) self.pyqt_workaround.clear() # test for ROS root paths and add these if it is in ROS_PACKAGE_PATH isroot = path in ['', os.path.sep] if isroot: self.ros_root_paths[url] = [] # append path items to the list model result_list = [] for path_item in result: if isroot and path_item.type in [FileItem.DIR, FileItem.PACKAGE]: self.ros_root_paths[url].append(path_item.path) item = os.path.normpath(os.path.join(path, path_item.path)) gpath = nmdurl.join(url, item) path_id = PathItem.NOT_FOUND if FileItem.FILE == path_item.type: _, ext = os.path.splitext(path_item.path) if ext in nm.settings( ).launch_view_file_ext or path_item.path.find('.launch.') > 0: path_id = PathItem.FILE elif FileItem.DIR == path_item.type: path_id = PathItem.FOLDER elif FileItem.SYMLINK == path_item.type: pass elif FileItem.PACKAGE == path_item.type: path_id = PathItem.PACKAGE if path_id != PathItem.NOT_FOUND and not os.path.basename( path_item.path).startswith('.'): # TODO: create filter for files result_list.append( (gpath, path_id, path_item.mtime, path_item.size, os.path.basename(path_item.path))) root_path = nmdurl.join(url, path) self._set_new_list(root_path, result_list) isroot = self._is_root(self._current_path) if isroot and not nmdurl.equal_uri(self._current_master, masteruri_from_master()): self._add_path(nmdurl.nmduri(self._current_master), PathItem.REMOTE_DAEMON, 0, 0, get_hostname(self._current_master_name)) self.pathlist_handled.emit(root_path)
def on_launch_selection_activated(self, activated): ''' Tries to load the launch file, if one was activated. ''' selected = self._pathItemsFromIndexes( self.ui_file_view.selectionModel().selectedIndexes(), False) for item in selected: try: self.ui_search_line.set_process_active(True) lfile = self.launchlist_model.expand_item(item.path, item.id) # self.ui_search_line.setText('') if lfile is not None: self.ui_search_line.set_process_active(False) if item.is_launch_file(): nm.settings().launch_history_add(item.path) self.load_signal.emit(item.path, {}, None) elif item.is_profile_file(): nm.settings().launch_history_add(item.path) self.load_profile_signal.emit(item.path) elif item.is_config_file(): self.edit_signal.emit(lfile) if self.launchlist_model.current_path: self.setWindowTitle( 'Launch @%s' % get_hostname(self.launchlist_model.current_grpc)) else: self.setWindowTitle('Launch files') except Exception as e: import traceback print(traceback.format_exc()) rospy.logwarn("Error while load launch file %s: %s" % (item, utf8(e))) MessageBox.warning( self, "Load error", 'Error while load launch file:\n%s' % item.name, "%s" % utf8(e)) try: color = QColor.fromRgb(nm.settings().host_color( self._masteruri2name[nmdurl.masteruri( self.launchlist_model.current_path)], self._default_color.rgb())) self._new_color(color) except Exception as _: pass
def open_screen(cls, node, grpc_url, auto_item_request=False, use_log_widget=False, user=None, pw=None, items=[], use_nmd=True): ''' Searches for the screen associated with the given node and open the screen output in a new terminal. :param str node: the name of the node those screen output to show :param str grpc_url: the url of node manager daemon where the screen is running :raise Exception: on errors while resolving host :see: L{open_screen_terminal()} ''' if node is None or len(node) == 0: return False try: host = get_hostname(grpc_url) try: muri = url.masteruri(grpc_url) except ValueError: muri = host if items: for item in items: # open the selected screen cls.open_screen_terminal(muri, item, node, use_log_widget, user) else: # get the available screens screens = {} try: if use_nmd: screens = nm.nmd().screen.get_screens(grpc_url, node) else: screens = cls._bc_get_active_screens(host, node, False, user=user, pwd=pw) except grpc.RpcError as e: rospy.logwarn( "can not connect to node manager daemon, detect screens using ssh..." ) screens = cls._bc_get_active_screens(host, node, False, user=user, pwd=pw) if len(screens) == 1: cls.open_screen_terminal(muri, list(screens.keys())[0], node, use_log_widget, user) else: # create a list to let the user make a choice, which screen must be open choices = {} for sname, _nname in screens.items(): pid, session_name = screen.split_session_name(sname) choices['%s [%d]' % (session_name, pid)] = sname # Open selection if len(choices) > 0: if len(choices) == 1: cls.open_screen_terminal(muri, choices[0], node, use_log_widget=False, user=user) elif auto_item_request: from select_dialog import SelectDialog items, _ = SelectDialog.getValue( 'Show screen', '', list(choices.keys()), False, store_geometry='show_screens') for item in items: # open the selected screen cls.open_screen_terminal(muri, choices[item], node, use_log_widget=False, user=user) else: raise ScreenSelectionRequest( choices, 'Show screen') else: if use_log_widget: nm._MAIN_FORM.open_screen_dock( muri, '', node, user) raise nm.InteractionNeededError( NoScreenOpenLogRequest(node, host), nm.starter().openLog, (node, host, user)) return len(screens) > 0 except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.open_screen, (node, grpc_url, auto_item_request, use_log_widget)) except ScreenSelectionRequest as e: # set use_log_widget to False on multiple screens for same node raise nm.InteractionNeededError( e, cls.open_screen, (node, grpc_url, auto_item_request, False, user, pw))