예제 #1
0
 def deleteLog(cls, nodename, host, auto_pw_request=False, user=None, pw=None):
     '''
     Deletes the log file associated with the given node.
     @param nodename: the name of the node (with name space)
     @type nodename: C{str}
     @param host: the host name or ip where the log file are to delete
     @type host: C{str}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     rospy.loginfo("delete log for '%s' on '%s'", utf8(nodename), utf8(host))
     if nm.is_local(host):
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         pidFile = nm.screen().getScreenPidFile(node=nodename)
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(screenLog):
             os.remove(screenLog)
         if os.path.isfile(pidFile):
             os.remove(pidFile)
         if os.path.isfile(roslog):
             os.remove(roslog)
     else:
         try:
             # output ignored: output, error, ok
             nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--delete_logs', nodename], user, pw, auto_pw_request, close_stdin=True, close_stdout=True, close_stderr=True)
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
예제 #2
0
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.topic.name
     elif role == self.NODENAMES_ROLE:
         return utf8(self.topic.publisherNodes) + utf8(self.topic.subscriberNodes)
     else:
         return QStandardItem.data(self, role)
예제 #3
0
 def storeCache(self, history_file, cache, history_len):
     '''
     Stores the cache to a file.
     @param history_file: the name of the history file
     @type history_file: C{str}
     @param cache: the dictionary with values
     @type cache: C{dict}
     @param history_len: the maximal count of value for a key
     @type history_len: C{int}
     '''
     ignored = dict()
     with codecs.open(os.path.join(nm.settings().cfg_path, history_file),
                      'w',
                      encoding='utf-8') as f:
         for key in cache.keys():
             count = 0
             for value in cache[key]:
                 if count < history_len:
                     try:
                         f.write(''.join([key, ':=', utf8(value), '\n']))
                     except UnicodeEncodeError, e:
                         ignored[key] = (value, utf8(e))
                     except:
                         import traceback
                         rospy.logwarn("Storing history aborted: %s",
                                       traceback.format_exc(3))
                     count += 1
예제 #4
0
    def run(self):
        '''
        '''
        try:
            if self._target is not None:
                if 'pqid' in self._target.func_code.co_varnames:
                    self._target(*self._args, pqid=self._id)
                else:
                    self._target(*self._args)
                self.finished_signal.emit(self._id)
            else:
                self.error_signal.emit(self._id, 'No target specified')
        except InteractionNeededError as ine:
            self.request_interact_signal.emit(self._id, self.descr, ine)
        except DetailedError as err:
            self.error_signal.emit(self._id, err.title, err.value, err.detailed_text)
        except Exception:
            import traceback
#      print traceback.print_exc()
            formatted_lines = traceback.format_exc(1).splitlines()
            last_line = formatted_lines[-1]
            index = 1
            while not last_line and len(formatted_lines) > index:
                index += 1
                last_line = formatted_lines[-index]
            self.error_signal.emit(self._id, 'Progress Job Error',
                                   "%s failed:\n%s" % (utf8(self.descr), utf8(last_line)),
                                   utf8(traceback.format_exc(4)))
            rospy.logwarn("%s failed:\n\t%s", utf8(self.descr), utf8(last_line))
 def deleteLog(cls, nodename, host, auto_pw_request=False, user=None, pw=None):
     '''
     Deletes the log file associated with the given node.
     @param nodename: the name of the node (with name space)
     @type nodename: C{str}
     @param host: the host name or ip where the log file are to delete
     @type host: C{str}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     rospy.loginfo("delete log for '%s' on '%s'", utf8(nodename), utf8(host))
     if nm.is_local(host):
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         pidFile = nm.screen().getScreenPidFile(node=nodename)
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(screenLog):
             os.remove(screenLog)
         if os.path.isfile(pidFile):
             os.remove(pidFile)
         if os.path.isfile(roslog):
             os.remove(roslog)
     else:
         try:
             # output ignored: output, error, ok
             _, stdout, _, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--delete_logs', nodename], user, pw, auto_pw_request, close_stdin=True, close_stdout=False, close_stderr=True)
             if ok:
                 stdout.readlines()
                 stdout.close()
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
 def run(self):
     '''
     '''
     if self._masteruri:
         service_names = interface_finder.get_refresh_service(
             self._masteruri, self._wait)
         err_msg = ''
         for service_name in service_names:
             rospy.logdebug("service 'refresh' found on %s as %s",
                            self._masteruri, service_name)
             if self._wait:
                 rospy.wait_for_service(service_name)
             socket.setdefaulttimeout(3)
             refreshMasters = rospy.ServiceProxy(service_name,
                                                 std_srvs.srv.Empty)
             try:
                 _ = refreshMasters()
                 self.ok_signal.emit(self._masteruri)
             except rospy.ServiceException, e:
                 rospy.logwarn("ERROR Service call 'refresh' failed: %s",
                               utf8(e))
                 self.err_signal.emit(
                     self._masteruri,
                     "ERROR Service call 'refresh' failed: %s" %
                     utf8(err_msg), True)
             finally:
                 socket.setdefaulttimeout(None)
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.topic.name
     elif role == self.NODENAMES_ROLE:
         return utf8(self.topic.publisherNodes) + utf8(self.topic.subscriberNodes)
     else:
         return QStandardItem.data(self, role)
예제 #8
0
 def loadCache(self, history_file):
     '''
     Loads the content of the given file and return it as cache.
     @param history_file: the name of the history file
     @type history_file: C{str}
     @return: the dictionary with arguments
     @rtype: C{dict(str(name):[str(value), ...], ...)}
     '''
     result = {}
     historyFile = os.path.join(nm.settings().cfg_path, history_file)
     if os.path.isfile(historyFile):
         with codecs.open(historyFile, 'r', encoding='utf-8') as f:
             line = utf8(f.readline())
             while line:
                 if line:
                     line = line.strip()
                     if line:
                         key, sep, value = line.partition(':=')
                         if sep:
                             if key not in result.keys():
                                 result[key] = [value]
                             elif len(result[key]) <= nm.settings(
                             ).param_history_length:
                                 result[key].append(value)
                 line = utf8(f.readline())
     return result
예제 #9
0
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.service.name
     elif role == self.TYPE_ROLE:
         return utf8(self.service.get_service_class(False))
     elif role == self.NODENAMES_ROLE:
         return utf8(self.service.serviceProvider)
     else:
         return QStandardItem.data(self, role)
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.service.name
     elif role == self.TYPE_ROLE:
         return utf8(self.service.get_service_class(False))
     elif role == self.NODENAMES_ROLE:
         return utf8(self.service.serviceProvider)
     else:
         return QStandardItem.data(self, role)
 def __eq__(self, item):
     '''
     Compares the value of parameter.
     '''
     if isinstance(item, str) or isinstance(item, unicode):
         return utf8(self.value) == utf8(item)
     elif not (item is None):
         return utf8(self.value) == utf8(item.value)
     return False
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.name
     elif role == self.VALUE_ROLE:
         return utf8(self.value)
     elif role == self.TYPE_ROLE:
         return utf8(type(self.value).replace('<type \'').replace('\'>'))
     else:
         return QStandardItem.data(self, role)
 def killScreens(cls, node, host, auto_ok_request=True, user=None, pw=None):
     '''
     Searches for the screen associated with the given node and kill this screens.
     @param node: the name of the node those screen output to show
     @type node: C{str}
     @param host: the host name or ip where the screen is running
     @type host: C{str}
     '''
     if node is None or len(node) == 0:
         return False
     try:
         # get the available screens
         screens = cls._getActiveScreens(host,
                                         cls.createSessionName(node),
                                         auto_ok_request,
                                         user=user,
                                         pwd=pw)  # user=user, pwd=pwd
         if screens:
             do_kill = True
             if auto_ok_request:
                 from node_manager_fkie.detailed_msg_box import MessageBox
                 result = MessageBox.question(None,
                                              "Kill SCREENs?",
                                              '\n'.join(screens),
                                              buttons=MessageBox.Ok
                                              | MessageBox.Cancel)
                 if result == MessageBox.Ok:
                     do_kill = True
             if do_kill:
                 for s in screens:
                     pid, _, _ = s.partition('.')
                     if pid:
                         try:
                             nm.starter()._kill_wo(host, int(pid),
                                                   auto_ok_request, user,
                                                   pw)
                         except:
                             import traceback
                             rospy.logwarn(
                                 "Error while kill screen (PID: %s) on host '%s': %s",
                                 utf8(pid), utf8(host),
                                 traceback.format_exc(1))
                 if nm.is_local(host):
                     SupervisedPopen(
                         [cls.SCREEN, '-wipe'],
                         object_id='screen -wipe',
                         description="screen: clean up the socket with -wipe"
                     )
                 else:
                     nm.ssh().ssh_exec(host, [cls.SCREEN, '-wipe'],
                                       close_stdin=True,
                                       close_stdout=True,
                                       close_stderr=True)
     except nm.AuthenticationRequest as e:
         raise nm.InteractionNeededError(e, cls.killScreens,
                                         (node, host, auto_ok_request))
    def __init__(self, context):
        super(NodeManager, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('NodeManagerFKIE')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q", "--quiet", action="store_true",
                            dest="quiet",
                            help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns
        node_manager_fkie.init_settings()
        masteruri = node_manager_fkie.settings().masteruri()
        node_manager_fkie.init_globals(masteruri)
        # Create QWidget
        try:
            self._widget = MainWindow()
#          self._widget.read_view_history()
        except Exception, e:
            MessageBox.critical(self, "Node Manager", utf8(e))
            raise
예제 #15
0
 def service_type_str(self):
     stype = ''
     try:
         stype = utf8(self.service.get_service_class(False))
     except Exception:
         pass
     return stype
def interpret_path(path):
    '''
    Tries to determine the path of the included file. The statement of
    C{$(find 'package')} will be resolved.
    @param path: the sting which contains the included path
    @type path: C{str}
    @return: C{$(find 'package')} will be resolved. The prefixes `file:///`, `package://` or `pkg://` are also resolved.
    Otherwise the parameter itself normalized by `os.path.normpath` will be returned.
    @rtype: C{str}
    '''
    path = path.strip()
    index = path.find('$')
    if index > -1:
        startIndex = path.find('(', index)
        if startIndex > -1:
            endIndex = path.find(')', startIndex + 1)
            script = path[startIndex + 1:endIndex].split()
            if len(script) == 2 and (script[0] == 'find'):
                try:
                    pkg = roslib.packages.get_pkg_dir(script[1])
                    return os.path.normpath('%s/%s' % (pkg, path[endIndex + 1:]))
                except Exception as e:
                    rospy.logwarn(utf8(e))
    else:
        try:
            return resolve_url(path)
        except ValueError, e:
            pass
예제 #17
0
    def __init__(self, filenames, search_text='', parent=None):
        '''
        @param filenames: a list with filenames. The last one will be activated.
        @type filenames: C{[str, ...]}
        @param search_text: if not empty, searches in new document for first occurrence of the given text
        @type search_text: C{str} (Default: C{Empty String})
        '''
        QMainWindow.__init__(self, parent)
        self.setObjectName('Editor - %s' % utf8(filenames))
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.setWindowFlags(Qt.Window)
        self.mIcon = QIcon(":/icons/crystal_clear_edit_launch.png")
        self._error_icon = QIcon(":/icons/crystal_clear_warning.png")
        self._empty_icon = QIcon()
        self.setWindowIcon(self.mIcon)
        window_title = "ROSLaunch Editor"
        if filenames:
            window_title = self.__getTabName(filenames[0])
        self.setWindowTitle(window_title)
        self.init_filenames = list(filenames)
        self._search_thread = None
        # list with all open files
        self.files = []
        # create tabs for files
        self.main_widget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.main_widget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(1)
        self.verticalLayout.setObjectName("verticalLayout")

        self.tabWidget = EditorTabWidget(self)
        self.tabWidget.setTabPosition(QTabWidget.North)
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setMovable(False)
        self.tabWidget.setObjectName("tabWidget")
        self.tabWidget.tabCloseRequested.connect(self.on_close_tab)
        self.tabWidget.currentChanged.connect(self.on_tab_changed)

        self.verticalLayout.addWidget(self.tabWidget)
        self.buttons = self._create_buttons()
        self.verticalLayout.addWidget(self.buttons)
        self.setCentralWidget(self.main_widget)

        self.find_dialog = TextSearchFrame(self.tabWidget, self)
        self.find_dialog.search_result_signal.connect(self.on_search_result)
        self.find_dialog.replace_signal.connect(self.on_replace)
        self.addDockWidget(Qt.RightDockWidgetArea, self.find_dialog)

        self.graph_view = GraphViewWidget(self.tabWidget, self)
        self.graph_view.load_signal.connect(self.on_graph_load_file)
        self.graph_view.goto_signal.connect(self.on_graph_goto)
        self.addDockWidget(Qt.RightDockWidgetArea, self.graph_view)
        # open the files
        for f in filenames:
            if f:
                self.on_load_request(os.path.normpath(f), search_text)
        self.readSettings()
        self.find_dialog.setVisible(False)
        self.graph_view.setVisible(False)
 def run(self):
     '''
     '''
     if self._masteruri:
         found = False
         service_names = interface_finder.get_listmaster_service(self._masteruri, self._wait)
         err_msg = ''
         for service_name in service_names:
             rospy.logdebug("service 'list_masters' found on %s as %s", self._masteruri, service_name)
             if self._wait:
                 rospy.wait_for_service(service_name)
             socket.setdefaulttimeout(3)
             discoverMasters = rospy.ServiceProxy(service_name, DiscoverMasters)
             try:
                 resp = discoverMasters()
             except rospy.ServiceException, e:
                 err_msg = "Service call 'list_masters' failed: %s" % utf8(e)
                 rospy.logwarn(err_msg)
                 self.err_signal.emit(self._masteruri, "Service call '%s' failed: %s" % (service_name, err_msg), False)
             else:
                 if resp.masters:
                     self.master_list_signal.emit(self._masteruri, service_name, resp.masters)
                     found = True
                 else:
                     self.err_signal.emit(self._masteruri, "local 'master_discovery' reports empty master list, it seems he has a problem", False)
             finally:
                 socket.setdefaulttimeout(None)
    def __init__(self, context):
        super(NodeManager, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('NodeManagerFKIE')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q",
                            "--quiet",
                            action="store_true",
                            dest="quiet",
                            help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print 'arguments: ', args
            print 'unknowns: ', unknowns
        node_manager_fkie.init_settings()
        masteruri = node_manager_fkie.settings().masteruri()
        node_manager_fkie.init_globals(masteruri)
        # Create QWidget
        try:
            self._widget = MainWindow()
#          self._widget.read_view_history()
        except Exception, e:
            MessageBox.critical(self, "Node Manager", utf8(e))
            raise
예제 #20
0
    def __init__(self, filenames, search_text='', parent=None):
        '''
        @param filenames: a list with filenames. The last one will be activated.
        @type filenames: C{[str, ...]}
        @param search_text: if not empty, searches in new document for first occurrence of the given text
        @type search_text: C{str} (Default: C{Empty String})
        '''
        QMainWindow.__init__(self, parent)
        self.setObjectName('Editor - %s' % utf8(filenames))
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.setWindowFlags(Qt.Window)
        self.mIcon = QIcon(":/icons/crystal_clear_edit_launch.png")
        self._error_icon = QIcon(":/icons/crystal_clear_warning.png")
        self._empty_icon = QIcon()
        self.setWindowIcon(self.mIcon)
        window_title = "ROSLaunch Editor"
        if filenames:
            window_title = self.__getTabName(filenames[0])
        self.setWindowTitle(window_title)
        self.init_filenames = list(filenames)
        self._search_thread = None
        # list with all open files
        self.files = []
        # create tabs for files
        self.main_widget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.main_widget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(1)
        self.verticalLayout.setObjectName("verticalLayout")

        self.tabWidget = EditorTabWidget(self)
        self.tabWidget.setTabPosition(QTabWidget.North)
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setMovable(False)
        self.tabWidget.setObjectName("tabWidget")
        self.tabWidget.tabCloseRequested.connect(self.on_close_tab)
        self.tabWidget.currentChanged.connect(self.on_tab_changed)

        self.verticalLayout.addWidget(self.tabWidget)
        self.buttons = self._create_buttons()
        self.verticalLayout.addWidget(self.buttons)
        self.setCentralWidget(self.main_widget)

        self.find_dialog = TextSearchFrame(self.tabWidget, self)
        self.find_dialog.search_result_signal.connect(self.on_search_result)
        self.find_dialog.replace_signal.connect(self.on_replace)
        self.addDockWidget(Qt.RightDockWidgetArea, self.find_dialog)

        self.graph_view = GraphViewWidget(self.tabWidget, self)
        self.graph_view.load_signal.connect(self.on_graph_load_file)
        self.graph_view.goto_signal.connect(self.on_graph_goto)
        self.addDockWidget(Qt.RightDockWidgetArea, self.graph_view)
        # open the files
        for f in filenames:
            if f:
                self.on_load_request(os.path.normpath(f), search_text)
        self.readSettings()
        self.find_dialog.setVisible(False)
        self.graph_view.setVisible(False)
예제 #21
0
 def on_heartbeat_received(self, msg, address, is_multicast):
     force_update = False
     with self.mutex:
         try:
             hostname = self._hosts[address[0]]
         except:
             self.status_text_signal.emit("resolve %s" % address[0])
             hostname = nm.nameres().hostname(utf8(address[0]),
                                              resolve=True)
             self._hosts[address[0]] = hostname
         try:
             (_version,
              _msg_tuple) = Discoverer.msg2masterState(msg, address)
             index = address[1] - self.default_port
             if index not in self._discovered:
                 self._discovered[index] = dict()
             self._discovered[index][address] = (hostname, time.time())
             if hostname not in self._msg_counts:
                 self._msg_counts[hostname] = 0
             self._msg_counts[hostname] += 1
             self._received_msgs += 1
             force_update = True
         except:
             print traceback.format_exc(1)
     if force_update:
         self._updateDisplay()
예제 #22
0
 def stop(self):
     '''
     Deletes all queued tasks and wait 3 seconds for the end of current running
     thread.
     '''
     try:
         val = self._progress_bar.value()
         if val < len(self.__progress_queue):
             print "  Stop progress queue '%s'..." % self._name
             thread = self.__progress_queue[val]
             self.__progress_queue = []
             if thread.is_alive():
                 thread.join(3)
             print "  Progress queue '%s' stopped!" % self._name
     except Exception:
         import traceback
         print utf8(traceback.format_exc())
 def __init__(self, name, value, parent=None):
     '''
     Initialize the item object.
     @param name: the name of the parameter
     @type name: C{str}
     @param value: the value of the parameter
     @type value: C{str}
     '''
     QStandardItem.__init__(
         self,
         utf8(value) if not isinstance(value, Binary) else utf8(value))
     self._name = name
     '''@ivar: the name of parameter '''
     self._value = value
     '''@ivar: the value of the parameter '''
     if isinstance(value, (str, unicode)) and value.find('\n') > -1:
         self.setSizeHint(QSize(-1, 45))
예제 #24
0
    def _on_progress_canceled(self):
        try:
            if self.__progress_queue:
                try:
                    pthread = self.__progress_queue[self._progress_bar.value()]
                    pthread.finished_signal.disconnect(self._progress_thread_finished)
                    pthread.error_signal.disconnect(self._progress_thread_error)
                    pthread.request_interact_signal.disconnect(self._on_request_interact)
#          self.__progress_queue[self._progress_bar.value()].terminate()
                except:
                    pass
            self.__progress_queue = []
            self._progress_frame.setVisible(False)
            self.__running = False
        except:
            import traceback
            print utf8(traceback.format_exc(1))
예제 #25
0
 def data(self, role):
     if role == self.NAME_ROLE:
         return self.service.name
     elif role == self.TYPE_ROLE:
         return self.service_type_str
     elif role == self.NODENAMES_ROLE:
         return utf8(self.service.serviceProvider)
     else:
         return QStandardItem.data(self, role)
예제 #26
0
 def _kill_wo(self, host, pid, auto_pw_request=False, user=None, pw=None):
     rospy.loginfo("kill %s on %s", utf8(pid), host)
     if nm.is_local(host):
         os.kill(pid, signal.SIGKILL)
         rospy.loginfo("kill: %s", utf8(pid))
     else:
         # kill on a remote machine
         cmd = ['kill -9', str(pid)]
         _, stdout, stderr, ok = nm.ssh().ssh_exec(host, cmd, user, pw, False, close_stdin=True)
         if ok:
             output = stdout.read()
             error = stderr.read()
             stdout.close()
             stderr.close()
             if error:
                 rospy.logwarn("ERROR while kill %s: %s", utf8(pid), error)
                 raise StartException(utf8(''.join(['The host "', host, '" reports:\n', error])))
             if output:
                 rospy.logdebug("STDOUT while kill %s on %s: %s", utf8(pid), host, output)
 def _kill_wo(self, host, pid, auto_pw_request=False, user=None, pw=None):
     rospy.loginfo("kill %s on %s", utf8(pid), host)
     if nm.is_local(host):
         os.kill(pid, signal.SIGKILL)
         rospy.loginfo("kill: %s", utf8(pid))
     else:
         # kill on a remote machine
         cmd = ['kill -9', str(pid)]
         _, stdout, stderr, ok = nm.ssh().ssh_exec(host, cmd, user, pw, False, close_stdin=True)
         if ok:
             output = stdout.read()
             error = stderr.read()
             stdout.close()
             stderr.close()
             if error:
                 rospy.logwarn("ERROR while kill %s: %s", utf8(pid), error)
                 raise StartException(utf8(''.join(['The host "', host, '" reports:\n', error])))
             if output:
                 rospy.logdebug("STDOUT while kill %s on %s: %s", utf8(pid), host, output)
예제 #28
0
 def _updateDisplay(self):
     self.display_clear_signal.emit()
     text = '<div style="font-family:Fixedsys,Courier,monospace; padding:10px;">\n'
     for index, addr_dict in self._discovered.items():
         text = ''.join([
             text, 'Network <b>',
             utf8(index), '</b>: <a href="',
             utf8(index), '">join</a><dl>'
         ])
         for addr, (hostname, ts) in addr_dict.items():
             text = ''.join([
                 text, '<dt>',
                 self._getTsStr(ts), '   <b><u>',
                 utf8(hostname), '</u></b> ',
                 utf8(addr), ', received messages: ',
                 str(self._msg_counts[hostname]), '</dt>\n'
             ])
         text = ''.join([text, '</dl><br>'])
     text = ''.join([text, '</div>'])
     self.display_append_signal.emit(text)
    def __init__(self,
                 default_mcast_group,
                 default_port,
                 networks_count,
                 parent=None):
        '''
        Creates an input dialog.
        @param default_port: the default discovery port
        @type default_port: C{int}
        @param networks_count: the count of discovering ports
        @type networks_count: C{int}
        '''
        QDialog.__init__(self, parent=parent)
        threading.Thread.__init__(self)
        self.default_port = default_port
        self.setObjectName('NetworkDiscoveryDialog')
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.setWindowFlags(Qt.Window)
        self.setWindowTitle('Network Discovery')
        self.resize(728, 512)
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")
        self.verticalLayout.setContentsMargins(1, 1, 1, 1)

        self.display = QTextBrowser(self)
        self.display.setReadOnly(True)
        self.verticalLayout.addWidget(self.display)
        self.display_clear_signal.connect(self.display.clear)
        self.display_append_signal.connect(self.display.append)
        self.display.anchorClicked.connect(self.on_anchorClicked)

        self.status_label = QLabel('0 messages', self)
        self.verticalLayout.addWidget(self.status_label)
        self.status_text_signal.connect(self.status_label.setText)
        self._msg_counts = dict()

        self._networks_count = networks_count
        self._running = True
        self._received_msgs = 0
        self._discovered = dict()
        self._hosts = dict()  # resolution for hostname and address
        self.mutex = threading.RLock()
        self.sockets = []
        with self.mutex:
            try:
                for p in range(networks_count):
                    msock = DiscoverSocket(default_port + p,
                                           default_mcast_group)
                    self.sockets.append(msock)
                    msock.settimeout(self.TIMEOUT)
            except Exception as e:
                self.display.setText(utf8(e))
        self.setDaemon(True)
        self.start()
예제 #30
0
 def _removeFromCache(self, cache, key, value):
     uvalue = utf8(value)
     if key and uvalue:
         if key in cache:
             value_list = cache[key]
             try:
                 value_list.remove(uvalue)
             except:
                 pass
             if len(value_list) == 0:
                 del cache[key]
예제 #31
0
    def _prepareROSMaster(cls, masteruri):
        if masteruri is None:
            masteruri = masteruri_from_ros()
        # start roscore, if needed
        try:
            if not os.path.isdir(nm.ScreenHandler.LOG_PATH):
                os.makedirs(nm.ScreenHandler.LOG_PATH)
            socket.setdefaulttimeout(3)
            master = xmlrpclib.ServerProxy(masteruri)
            master.getUri(rospy.get_name())
            # restart ROSCORE on different masteruri?, not now...
#      master_uri = master.getUri(rospy.get_name())
#      if masteruri != master_uri[2]:
#        # kill the local roscore...
#        raise
        except:
            # run a roscore
            master_host = get_hostname(masteruri)
            if nm.is_local(master_host, True):
                master_port = get_port(masteruri)
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ros_hostname = NameResolution.get_ros_hostname(masteruri)
                if ros_hostname:
                    new_env['ROS_HOSTNAME'] = ros_hostname
                cmd_args = '%s roscore --port %d' % (nm.ScreenHandler.getSceenCmd('/roscore--%d' % master_port), master_port)
                for n in [1, 2, 3, 4]:
                    try:
                        if n == 1:
                            print("Launch ROS Master in screen  ...")
                            SupervisedPopen(shlex.split(cmd_args), env=new_env, object_id="ROSCORE", description="Start roscore")
                        elif n == 2:
                            print("ROS Master takes too long for start, wait for next 10 sec ...")
                        elif n == 3:
                            print("A really slow start, wait for last 10 sec ...")
                        # wait for roscore to avoid connection problems while init_node
                        result = -1
                        count = 1
                        while result == -1 and count < 11:
                            try:
                                master = xmlrpclib.ServerProxy(masteruri)
                                result, _, _ = master.getUri(rospy.get_name())  # _:=uri, msg
                                return
                            except Exception:
                                time.sleep(1)
                                count += 1
                        if n == 4 and count >= 11:
                            raise StartException('Cannot connect to ROS-Master: %s\n--> please run "roscore" manually!' % utf8(masteruri))
                    except Exception as e:
                        raise Exception("Error while call '%s': %s" % (cmd_args, utf8(e)))
            else:
                raise Exception("ROS master '%s' is not reachable" % masteruri)
        finally:
            socket.setdefaulttimeout(None)
    def _prepareROSMaster(cls, masteruri):
        if masteruri is None:
            masteruri = masteruri_from_ros()
        # start roscore, if needed
        try:
            if not os.path.isdir(nm.ScreenHandler.LOG_PATH):
                os.makedirs(nm.ScreenHandler.LOG_PATH)
            socket.setdefaulttimeout(3)
            master = xmlrpclib.ServerProxy(masteruri)
            master.getUri(rospy.get_name())
            # restart ROSCORE on different masteruri?, not now...
#      master_uri = master.getUri(rospy.get_name())
#      if masteruri != master_uri[2]:
#        # kill the local roscore...
#        raise
        except:
            # run a roscore
            master_host = get_hostname(masteruri)
            if nm.is_local(master_host, True):
                master_port = get_port(masteruri)
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ros_hostname = NameResolution.get_ros_hostname(masteruri)
                if ros_hostname:
                    new_env['ROS_HOSTNAME'] = ros_hostname
                cmd_args = '%s roscore --port %d' % (nm.ScreenHandler.getSceenCmd('/roscore--%d' % master_port), master_port)
                for n in [1, 2, 3, 4]:
                    try:
                        if n == 1:
                            print("Launch ROS Master in screen  ...")
                            SupervisedPopen(shlex.split(cmd_args), env=new_env, object_id="ROSCORE", description="Start roscore")
                        elif n == 2:
                            print("ROS Master takes too long for start, wait for next 10 sec ...")
                        elif n == 3:
                            print("A really slow start, wait for last 10 sec ...")
                        # wait for roscore to avoid connection problems while init_node
                        result = -1
                        count = 1
                        while result == -1 and count < 11:
                            try:
                                master = xmlrpclib.ServerProxy(masteruri)
                                result, _, _ = master.getUri(rospy.get_name())  # _:=uri, msg
                                return
                            except Exception:
                                time.sleep(1)
                                count += 1
                        if n == 4 and count >= 11:
                            raise StartException('Cannot connect to ROS-Master: %s\n--> please run "roscore" manually!' % utf8(masteruri))
                    except Exception as e:
                        raise Exception("Error while call '%s': %s" % (cmd_args, utf8(e)))
            else:
                raise Exception("ROS master '%s' is not reachable" % masteruri)
        finally:
            socket.setdefaulttimeout(None)
예제 #33
0
 def _add2Cache(self, cache, key, value):
     uvalue = utf8(value)
     if key and uvalue:
         if key not in cache:
             cache[key] = [uvalue]
         elif uvalue not in cache[key]:
             cache[key].insert(0, uvalue)
             if len(cache[key]) >= nm.settings().param_history_length:
                 cache[key].pop()
         else:
             cache[key].remove(uvalue)
             cache[key].insert(0, uvalue)
예제 #34
0
 def str2list(self, l):
     if isinstance(l, list):
         return l
     try:
         l = l.strip('[]')
         l = l.replace('u"', '')
         l = l.replace('"', '')
         l = l.replace("'", '')
         l = l.replace(",", ' ')
         return [utf8(i).strip() for i in l.split(' ') if i]
     except:
         return []
예제 #35
0
 def _getSSH(self, host, user, pw=None, do_connect=True, auto_pw_request=False):
     '''
     @return: the paramiko ssh client
     @rtype: U{paramiko.SSHClient<http://docs.paramiko.org/en/1.10/api/client.html>}
     @raise BadHostKeyException: - if the server's host key could not be verified
     @raise AuthenticationException: - if authentication failed
     @raise SSHException: - if there was any other error connecting or establishing an SSH session
     @raise socket.error: - if a socket error occurred while connecting
     '''
     session = SSHhandler.SSH_SESSIONS.get(host, paramiko.SSHClient())
     if session is None or (not session.get_transport() is None and (not session.get_transport().is_active() or session._transport.get_username() != user)):
         t = SSHhandler.SSH_SESSIONS.pop(host)
         del t
         if host in self.SSH_AUTH:
             del self.SSH_AUTH[host]
         session = SSHhandler.SSH_SESSIONS.get(host, paramiko.SSHClient())
     if session._transport is None:
         session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         while (session.get_transport() is None or not session.get_transport().authenticated) and do_connect:
             try:
                 session.connect(host, username=user, password=pw, timeout=3, compress=True)
                 self.SSH_AUTH[host] = user
             except Exception, e:
                 if utf8(e) in ['Authentication failed.', 'No authentication methods available', 'Private key file is encrypted']:
                     if auto_pw_request:
                         # 'print "REQUEST PW-AUTO"
                         res, user, pw = self._requestPW(user, host)
                         if not res:
                             return None
                         self.SSH_AUTH[host] = user
                     else:
                         raise AuthenticationRequest(user, host, utf8(e))
                 else:
                     rospy.logwarn("ssh connection to %s failed: %s", host, utf8(e))
                     raise Exception(' '.join(["ssh connection to", host, "failed:", utf8(e)]))
             else:
                 SSHhandler.SSH_SESSIONS[host] = session
         if not session.get_transport() is None:
             session.get_transport().set_keepalive(10)
 def mastermonitor_loop(self):
     '''
     The method test periodically the state of the ROS master. The new state will
     be published as 'state_signal'.
     '''
     import os
     current_check_hz = OwnMasterMonitoring.ROSMASTER_HZ
     while (not rospy.is_shutdown() and not self._do_finish):
         try:
             if not self._do_pause:
                 cputimes = os.times()
                 cputime_init = cputimes[0] + cputimes[1]
                 if self._master_monitor.checkState():
                     mon_state = self._master_monitor.getCurrentState()
                     # publish the new state
                     state = MasterState(
                         MasterState.STATE_CHANGED,
                         ROSMaster(
                             utf8(self._local_addr), utf8(self._masteruri),
                             mon_state.timestamp, mon_state.timestamp_local,
                             True, rospy.get_name(), ''.join([
                                 'http://localhost:',
                                 utf8(self._master_monitor.rpcport)
                             ])))
                     self.state_signal.emit(state)
                 # adapt the check rate to the CPU usage time
                 cputimes = os.times()
                 cputime = cputimes[0] + cputimes[1] - cputime_init
                 if current_check_hz * cputime > 0.20:
                     current_check_hz = float(current_check_hz) / 2.0
                 elif current_check_hz * cputime < 0.10 and current_check_hz < OwnMasterMonitoring.ROSMASTER_HZ:
                     current_check_hz = float(current_check_hz) * 2.0
         except MasterConnectionException, mce:
             self._handle_exception(
                 "MasterConnectionException while master check loop", mce)
         except RuntimeError, ree:
             # will thrown on exit of the app while try to emit the signal
             self._handle_exception("RuntimeError while master check loop",
                                    ree)
예제 #37
0
 def run(self):
     '''
     '''
     if self._service and self._service_uri:
         try:
             if self._delay_exec > 0:
                 time.sleep(self._delay_exec)
             _, resp = nm.starter().callService(self._service_uri, self._service, ListNodes)
             self.update_signal.emit(self._service_uri, self._service, resp.nodes)
         except:
             import traceback
             lines = traceback.format_exc(1).splitlines()
             rospy.logwarn("Error while retrieve the node list from %s[%s]: %s", utf8(self._service), utf8(self._service_uri), utf8(lines[-1]))
             self.err_signal.emit(self._service_uri, self._service, lines[-1])
    def createSessionName(cls, node=None):
        '''
        Creates a name for the screen session. All slash separators are replaced by
        L{SLASH_SEP}
        @param node: the name of the node
        @type node: C{str}
        @return: name for the screen session.
        @rtype: C{str}
        '''
#    package_name = utf8(package) if not package is None else ''
#    lanchfile_name = utf8(launchfile).replace('.launch', '') if not launchfile is None else ''
        node_name = utf8(node).replace('/', cls.SLASH_SEP) if node is not None else ''
#    result = ''.join([node_name, '.', package_name, '.', lanchfile_name])
        return node_name
예제 #39
0
 def ssh_x11_exec(self, host, cmd, title=None, user=None):
     '''
     Executes a command on remote host using a terminal with X11 forwarding.
     @todo: establish connection using paramiko SSH library.
     @param host: the host
     @type host: C{str}
     @param cmd: the list with command and arguments
     @type cmd: C{[str,...]}
     @param title: the title of the new opened terminal, if it is None, no new terminal will be created
     @type title: C{str} or C{None}
     @param user: user name
     @return: the result of C{subprocess.Popen(command)}
     @see: U{http://docs.python.org/library/subprocess.html?highlight=subproces#subprocess}
     '''
     with self.mutex:
         try:
             # workaround: use ssh in a terminal with X11 forward
             user = nm.settings().host_user(host) if user is None else user
             if host in self.SSH_AUTH:
                 user = self.SSH_AUTH[host]
             # generate string for SSH command
             ssh_str = ' '.join(['/usr/bin/ssh',
                                 '-aqtx',
                                 '-oClearAllForwardings=yes',
                                 '-oConnectTimeout=5',
                                 '-oStrictHostKeyChecking=no',
                                 '-oVerifyHostKeyDNS=no',
                                 '-oCheckHostIP=no',
                                 ''.join([user, '@', host])])
             if title is not None:
                 cmd_str = nm.settings().terminal_cmd([ssh_str, ' '.join(cmd)], title)
             else:
                 cmd_str = utf8(' '.join([ssh_str, ' '.join(cmd)]))
             rospy.loginfo("REMOTE x11 execute on %s: %s", host, cmd_str)
             return SupervisedPopen(shlex.split(cmd_str), object_id=utf8(title), description="REMOTE x11 execute on %s: %s" % (host, cmd_str))
         except:
             raise
 def openLog(cls, nodename, host, user=None, only_screen=False):
     '''
     Opens the log file associated with the given node in a new terminal.
     @param nodename: the name of the node (with name space)
     @type nodename: C{str}
     @param host: the host name or ip where the log file are
     @type host: C{str}
     @return: C{True}, if a log file was found
     @rtype: C{bool}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     rospy.loginfo("show log for '%s' on '%s'", utf8(nodename), utf8(host))
     title_opt = 'LOG %s on %s' % (nodename, host)
     if nm.is_local(host):
         found = False
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         if os.path.isfile(screenLog):
             cmd = nm.settings().terminal_cmd([nm.settings().log_viewer, screenLog], title_opt)
             rospy.loginfo("open log: %s", cmd)
             SupervisedPopen(shlex.split(cmd), object_id="Open log", description="Open log for '%s' on '%s'" % (utf8(nodename), utf8(host)))
             found = True
         # open roslog file
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(roslog) and not only_screen:
             title_opt = title_opt.replace('LOG', 'ROSLOG')
             cmd = nm.settings().terminal_cmd([nm.settings().log_viewer, roslog], title_opt)
             rospy.loginfo("open ROS log: %s", cmd)
             SupervisedPopen(shlex.split(cmd), object_id="Open log", description="Open log for '%s' on '%s'" % (utf8(nodename), utf8(host)))
             found = True
         return found
     else:
         ps = nm.ssh().ssh_x11_exec(host, [nm.settings().start_remote_script, '--show_screen_log', nodename], title_opt, user)
         if not only_screen:
             ps = nm.ssh().ssh_x11_exec(host, [nm.settings().start_remote_script, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'), user)
     return False
 def mastermonitor_loop(self):
     '''
     The method test periodically the state of the ROS master. The new state will
     be published as 'state_signal'.
     '''
     import os
     current_check_hz = OwnMasterMonitoring.ROSMASTER_HZ
     while (not rospy.is_shutdown() and not self._do_finish):
         try:
             if not self._do_pause:
                 cputimes = os.times()
                 cputime_init = cputimes[0] + cputimes[1]
                 if self._master_monitor.checkState():
                     mon_state = self._master_monitor.getCurrentState()
                     # publish the new state
                     state = MasterState(MasterState.STATE_CHANGED,
                                         ROSMaster(utf8(self._local_addr),
                                                   utf8(self._masteruri),
                                                   mon_state.timestamp,
                                                   mon_state.timestamp_local,
                                                   True,
                                                   rospy.get_name(),
                                                   ''.join(['http://localhost:', utf8(self._master_monitor.rpcport)])))
                     self.state_signal.emit(state)
                 # adapt the check rate to the CPU usage time
                 cputimes = os.times()
                 cputime = cputimes[0] + cputimes[1] - cputime_init
                 if current_check_hz * cputime > 0.20:
                     current_check_hz = float(current_check_hz) / 2.0
                 elif current_check_hz * cputime < 0.10 and current_check_hz < OwnMasterMonitoring.ROSMASTER_HZ:
                     current_check_hz = float(current_check_hz) * 2.0
         except MasterConnectionException, mce:
             self._handle_exception("MasterConnectionException while master check loop", mce)
         except RuntimeError, ree:
             # will thrown on exit of the app while try to emit the signal
             self._handle_exception("RuntimeError while master check loop", ree)
예제 #42
0
 def _on_edit_interface_clicked(self):
     self._new_iface = False
     self.interface_field.setVisible(False)
     self.toolButton_CreateInterface.setVisible(False)
     self.toolButton_EditInterface.setVisible(False)
     self.textedit.setVisible(True)
     if self.interface_field.currentText() in self._interfaces_files:
         try:
             with open(self._interfaces_files[self.interface_field.currentText()], 'rw') as f:
                 iface = f.read()
                 self.textedit.setText(iface)
         except Exception as e:
             MessageBox.warning(self, "Edit sync interface",
                                "Error while open interface",
                                utf8(e))
     self.resize(350, 300)
 def run(self):
     '''
     '''
     if self._masteruri:
         service_names = interface_finder.get_refresh_service(self._masteruri, self._wait)
         err_msg = ''
         for service_name in service_names:
             rospy.logdebug("service 'refresh' found on %s as %s", self._masteruri, service_name)
             if self._wait:
                 rospy.wait_for_service(service_name)
             socket.setdefaulttimeout(3)
             refreshMasters = rospy.ServiceProxy(service_name, std_srvs.srv.Empty)
             try:
                 _ = refreshMasters()
                 self.ok_signal.emit(self._masteruri)
             except rospy.ServiceException, e:
                 rospy.logwarn("ERROR Service call 'refresh' failed: %s", utf8(e))
                 self.err_signal.emit(self._masteruri, "ERROR Service call 'refresh' failed: %s" % utf8(err_msg), True)
             finally:
                 socket.setdefaulttimeout(None)
 def get_log_path(cls, host, nodes=[], auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         if len(nodes) == 1:
             return nm.screen().getScreenLogFile(node=nodes[0])
         else:
             return nm.screen().LOG_PATH
     else:
         request = '[]' if len(nodes) != 1 else nodes[0]
         try:
             socket.setdefaulttimeout(3)
             _, stdout, _, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--ros_log_path', request], user, pw, auto_pw_request, close_stdin=True, close_stderr=True)
             if ok:
                 output = stdout.read()
                 stdout.close()
                 return output.strip()
             else:
                 raise StartException(utf8(''.join(['Get log path from "', host, '" failed'])))
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.get_log_path, (host, nodes, auto_pw_request))
         finally:
             socket.setdefaulttimeout(None)
 def transfer_files(cls, host, path, auto_pw_request=False, user=None, pw=None):
     '''
     Copies the given file to the remote host. Uses caching of remote paths.
     '''
     # get package of the file
     if nm.is_local(host):
         # it's local -> no copy needed
         return
     (pkg_name, pkg_path) = package_name(os.path.dirname(path))
     if pkg_name is not None:
         # get the subpath of the file
         subfile_path = path.replace(pkg_path, '')
         # get the path of the package on the remote machine
         try:
             output = ''
             error = ''
             ok = True
             if host in CACHED_PKG_PATH and pkg_name in CACHED_PKG_PATH[host]:
                 output = CACHED_PKG_PATH[host][pkg_name]
             else:
                 if host not in CACHED_PKG_PATH:
                     CACHED_PKG_PATH[host] = dict()
                 _, stdout, stderr, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--package', pkg_name], user, pw, auto_pw_request, close_stdin=True)
                 output = stdout.read()
                 error = stderr.read()
                 stdout.close()
                 stderr.close()
             if ok:
                 if error:
                     rospy.logwarn("ERROR while transfer %s to %s: %s", path, host, error)
                     raise StartException(utf8(''.join(['The host "', host, '" reports:\n', error])))
                 if output:
                     CACHED_PKG_PATH[host][pkg_name] = output
                     nm.ssh().transfer(host, path, os.path.join(output.strip(), subfile_path.strip(os.sep)), user)
                 else:
                     raise StartException("Remote host no returned any answer. Is there the new version of node_manager installed?")
             else:
                 raise StartException("Can't get path from remote host. Is there the new version of node_manager installed?")
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(e, cls.transfer_files, (host, path, auto_pw_request))
 def ntpdate(cls, host, cmd, user=None, pw=None):
     '''
     Opens the log file associated with the given node in a new terminal.
     @param host: the host name or ip where the log file are
     @type host: C{str}
     @param cmd: command to set the time 
     @type cmd: C{str}
     @return: C{True}, if a log file was found
     @rtype: C{bool}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     mesg = "synchronize time on '%s' using '%s'" % (utf8(host), cmd)
     rospy.loginfo(mesg)
     title_opt = "ntpdate on %s" % str(host)  # '%s on %s' % (cmd, host)
     if nm.is_local(host):
         cmd = nm.settings().terminal_cmd([cmd], title_opt, noclose=True)
         rospy.loginfo("EXEC: %s" % cmd)
         ps = SupervisedPopen(shlex.split(cmd), object_id=cmd, description=mesg)
     else:
         ps = nm.ssh().ssh_x11_exec(host, [cmd, ';echo "";echo "this terminal will be closed in 10 sec...";sleep 10'], title_opt, user)
     return False
예제 #47
0
 def ssh_exec(self, host, cmd, user=None, pw=None, auto_pw_request=False, get_pty=False, close_stdin=False, close_stdout=False, close_stderr=False):
     '''
     Executes a command on remote host. Returns the output channels with
     execution result or None. The connection will be established using paramiko
     SSH library.
     @param host: the host
     @type host: C{str}
     @param cmd: the list with command and arguments
     @type cmd: C{[str,...]}
     @param user: user name
     @param pw: the password
     @return: the 4-tuple stdin, stdout, stderr and boolean of the executing command
     @rtype: C{tuple(ChannelFile, ChannelFile, ChannelFile, boolean)}
     @see: U{http://www.lag.net/paramiko/docs/paramiko.SSHClient-class.html#exec_command}
     '''
     with self.mutex:
         try:
             ssh = self._getSSH(host, nm.settings().host_user(host) if user is None else user, pw, True, auto_pw_request)
             if ssh is not None:
                 cmd_str = utf8(' '.join(cmd))
                 rospy.loginfo("REMOTE execute on %s@%s: %s", ssh._transport.get_username(), host, cmd_str)
                 (stdin, stdout, stderr) = (None, None, None)
                 if get_pty:
                     (stdin, stdout, stderr) = ssh.exec_command(cmd_str, get_pty=get_pty)
                 else:
                     (stdin, stdout, stderr) = ssh.exec_command(cmd_str)
                 if close_stdin:
                     stdin.close()
                 if close_stdout:
                     stdout.close()
                 if close_stderr:
                     stderr.close()
                 return stdin, stdout, stderr, True
         except AuthenticationRequest as e:
             raise
         except Exception as e:
             raise
     raise Exception('Cannot login @%s' % host)
예제 #48
0
    def accept(self):
        if self.textedit.isVisible():
            try:
                tmp_file = os.path.join(nm.screen().LOG_PATH, 'tmp_sync_interface.sync')
                with open(tmp_file, 'w+') as f:
                    f.write(self.textedit.toPlainText())
                from master_discovery_fkie.common import read_interface
                read_interface(tmp_file)
                if not self._new_iface and self.interface_field.currentText() in self._interfaces_files:
                    fileName = self._interfaces_files[self.interface_field.currentText()]
                else:
                    fileName, _ = QFileDialog.getSaveFileName(self, 'Save sync interface', '/home', "Sync Files (*.sync)")
                if fileName:
                    with open(fileName, 'w+') as f:
                        self._interface_filename = fileName
                        f.write(self.textedit.toPlainText())
                        if self._new_iface:
                            self.interface_field.clear()
                            self._interfaces_files = None
                        self._on_select_interface_clicked()
#        QDialog.accept(self)
#        self.resetView()
            except Exception as e:
                MessageBox.warning(self, "Create sync interface",
                                   "Error while create interface",
                                   utf8(e))
        elif self.interface_field.isVisible():
            interface = self.interface_field.currentText()
            if self._interfaces_files and interface in self._interfaces_files:
                self._interface_filename = self._interfaces_files[interface]
                self._sync_args = []
                self._sync_args.append(''.join(['_interface_url:=', interface]))
                QDialog.accept(self)
                self.resetView()
        else:
            QDialog.accept(self)
            self.resetView()
예제 #49
0
 def _requestPW(self, user, host):
     '''
     Open the dialog to input the user name and password to open an SSH connection.
     '''
     from python_qt_binding.QtCore import Qt
     from python_qt_binding import loadUi
     try:
         from python_qt_binding.QtGui import QDialog
     except:
         from python_qt_binding.QtWidgets import QDialog
     result = False
     pw = None
     pwInput = QDialog()
     ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'PasswordInput.ui')
     loadUi(ui_file, pwInput)
     pwInput.setWindowTitle(''.join(['Enter the password for user ', user, ' on ', host]))
     pwInput.userLine.setText(utf8(user))
     pwInput.pwLine.setText("")
     pwInput.pwLine.setFocus(Qt.OtherFocusReason)
     if pwInput.exec_():
         result = True
         user = pwInput.userLine.text()
         pw = pwInput.pwLine.text()
     return result, user, pw
예제 #50
0
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         inc_files = LaunchConfig.included_files(cursor.block().text(), recursive=False)
         if inc_files:
             try:
                 qf = QFile(inc_files[0])
                 if not qf.exists():
                     # create a new file, if it does not exists
                     result = MessageBox.question(self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), buttons=MessageBox.Yes | MessageBox.No)
                     if result == MessageBox.Yes:
                         d = os.path.dirname(qf.fileName())
                         if not os.path.exists(d):
                             os.makedirs(d)
                         with open(qf.fileName(), 'w') as f:
                             if qf.fileName().endswith('.launch'):
                                 f.write('<launch>\n\n</launch>')
                         event.setAccepted(True)
                         self.load_request_signal.emit(qf.fileName())
                 else:
                     event.setAccepted(True)
                     self.load_request_signal.emit(qf.fileName())
             except Exception, e:
                 MessageBox.critical(self, "Error", "File not found %s" % inc_files[0], detailed_text=utf8(e))
    def callService(self, service_uri, service, service_type, service_args=[]):
        '''
        Calls the service and return the response.
        To call the service the ServiceProxy can't be used, because it uses
        environment variables to determine the URI of the running service. In our
        case this service can be running using another ROS master. The changes on the
        environment variables is not thread safe.
        So the source code of the rospy.SerivceProxy (tcpros_service.py) was modified.

        @param service_uri: the URI of the service
        @type service_uri: C{str}
        @param service: full service name (with name space)
        @type service: C{str}
        @param service_type: service class
        @type service_type: ServiceDefinition: service class
        @param service_args: arguments
        @return: the tuple of request and response.
        @rtype: C{(request object, response object)}
        @raise StartException: on error

        @see: U{rospy.SerivceProxy<http://docs.ros.org/kinetic/api/rospy/html/rospy.impl.tcpros_service.ServiceProxy-class.html>}

        '''
        service = str(service)
        rospy.loginfo("Call service %s[%s]: %s, %s", utf8(service), utf8(service_uri), utf8(service_type), utf8(service_args))
        from rospy.core import parse_rosrpc_uri, is_shutdown
#    from rospy.msg import args_kwds_to_message
        from rospy.exceptions import TransportInitError, TransportException
        from rospy.impl.tcpros_base import TCPROSTransport, DEFAULT_BUFF_SIZE  # ,TCPROSTransportProtocol
        from rospy.impl.tcpros_service import TCPROSServiceClient
        from rospy.service import ServiceException
        request = service_type._request_class()
        import genpy
        try:
            now = rospy.get_rostime()
            import std_msgs.msg
            keys = {'now': now, 'auto': std_msgs.msg.Header(stamp=now)}
            genpy.message.fill_message_args(request, service_args, keys)
        except genpy.MessageException as e:
            def argsummary(args):
                if type(args) in [tuple, list]:
                    return '\n'.join([' * %s (type %s)' % (a, type(a).__name__) for a in args])
                else:
                    return ' * %s (type %s)' % (args, type(args).__name__)
            raise StartException("Incompatible arguments to call service:\n%s\nProvided arguments are:\n%s\n\nService arguments are: [%s]" % (e, argsummary(service_args), genpy.message.get_printable_message_args(request)))

#    request = args_kwds_to_message(type._request_class, args, kwds)
        protocol = TCPROSServiceClient(service, service_type, headers={})
        transport = TCPROSTransport(protocol, service)
        # initialize transport
        dest_addr, dest_port = parse_rosrpc_uri(service_uri)
        # connect to service
        transport.buff_size = DEFAULT_BUFF_SIZE
        try:
            transport.connect(dest_addr, dest_port, service_uri, timeout=5)
        except TransportInitError as e:
            # can be a connection or md5sum mismatch
            raise StartException(''.join(["unable to connect to service: ", utf8(e)]))
        transport.send_message(request, 0)
        try:
            responses = transport.receive_once()
            if len(responses) == 0:
                raise StartException("service [%s] returned no response" % service)
            elif len(responses) > 1:
                raise StartException("service [%s] returned multiple responses: %s" % (service, len(responses)))
        except TransportException as e:
            # convert lower-level exception to exposed type
            if is_shutdown():
                raise StartException("node shutdown interrupted service call")
            else:
                raise StartException("transport error completing service call: %s" % (utf8(e)))
        except ServiceException, e:
            raise StartException("Service error: %s" % (utf8(e)))
import rospy

from master_discovery_fkie.master_monitor import MasterMonitor, MasterConnectionException
import master_discovery_fkie.interface_finder as interface_finder

from node_manager_fkie.common import utf8

try:
    import std_srvs.srv
    from multimaster_msgs_fkie.msg import LinkStatesStamped, MasterState, ROSMaster  # , LinkState, SyncMasterInfo, SyncTopicInfo
    from multimaster_msgs_fkie.srv import DiscoverMasters  # , GetSyncInfo
except ImportError, e:
    import sys
    print >> sys.stderr, "Can't import messages and services of multimaster_msgs_fkie. Is multimaster_msgs_fkie package compiled?"
    raise ImportError(utf8(e))


class MasterListService(QObject):
    '''
    A class to retrieve the ROS master list from a ROS service. The service
    will be determine using U{master_discovery_fkie.interface_finder.get_listmaster_service()<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#interface-finder-module>}

    '''
    masterlist_signal = Signal(str, str, list)
    '''@ivar: a signal with a list of the masters retrieved from the master_discovery service 'list_masters'.
  ParameterB{:} C{masteruri}, C{service name}, C{[U{master_discovery_fkie.msg.ROSMaster<http://docs.ros.org/api/multimaster_msgs_fkie/html/msg/ROSMaster.html>}, ...]}'''
    masterlist_err_signal = Signal(str, str)
    '''@ivar: this signal is emitted if an error while calling #list_masters'
  service of master_discovery is failed.
  ParameterB{:} C{masteruri}, C{error}'''
    def runNode(cls, runcfg):
        '''
        Start the node with given name from the given configuration.
        @param runcfg: the configuration containing the start parameter
        @type runcfg: AdvRunCfg
        @raise StartException: if the screen is not available on host.
        @raise Exception: on errors while resolving host
        @see: L{node_manager_fkie.is_local()}
        '''
        # 'print "RUN node", node, time.time()
        n = runcfg.roslaunch_config.getNode(runcfg.node)
        if n is None:
            raise StartException(''.join(["Node '", runcfg.node, "' not found!"]))

        env = list(n.env_args)
        # set logging options
        if runcfg.logging is not None:
            if not runcfg.logging.is_default('console_format'):
                env.append(('ROSCONSOLE_FORMAT', '%s' % runcfg.logging.console_format))
        if n.respawn:
            # set the respawn environment variables
            respawn_params = cls._get_respawn_params(rospy.names.ns_join(n.namespace, n.name), runcfg.roslaunch_config.Roscfg.params)
            if respawn_params['max'] > 0:
                env.append(('RESPAWN_MAX', '%d' % respawn_params['max']))
            if respawn_params['min_runtime'] > 0:
                env.append(('RESPAWN_MIN_RUNTIME', '%d' % respawn_params['min_runtime']))
            if respawn_params['delay'] > 0:
                env.append(('RESPAWN_DELAY', '%d' % respawn_params['delay']))
        prefix = n.launch_prefix if n.launch_prefix is not None else ''
        if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1:
            rospy.loginfo("SCREEN prefix removed before start!")
            prefix = ''
        args = ['__ns:=%s' % n.namespace.rstrip(rospy.names.SEP), '__name:=%s' % n.name]
        if n.cwd is not None:
            args.append('__cwd:=%s' % n.cwd)

        # add remaps
        for remap in n.remap_args:
            args.append(''.join([remap[0], ':=', remap[1]]))

        # get host of the node
        host = runcfg.roslaunch_config.hostname
        env_loader = ''
        if n.machine_name:
            machine = runcfg.roslaunch_config.Roscfg.machines[n.machine_name]
            if machine.address not in ['localhost', '127.0.0.1']:
                host = machine.address
                if runcfg.masteruri is None:
                    runcfg.masteruri = nm.nameres().masteruri(n.machine_name)
            # TODO: env-loader support?
#      if hasattr(machine, "env_loader") and machine.env_loader:
#        env_loader = machine.env_loader
        # set the host to the given host
        if runcfg.force2host is not None:
            host = runcfg.force2host

        # set the ROS_MASTER_URI
        if runcfg.masteruri is None:
            runcfg.masteruri = masteruri_from_ros()
            env.append(('ROS_MASTER_URI', runcfg.masteruri))
            ros_hostname = NameResolution.get_ros_hostname(runcfg.masteruri)
            if ros_hostname:
                env.append(('ROS_HOSTNAME', ros_hostname))

        abs_paths = list()  # tuples of (parameter name, old value, new value)
        not_found_packages = list()  # package names
        # set the global parameter
        if runcfg.masteruri is not None and runcfg.masteruri not in runcfg.roslaunch_config.global_param_done:
            global_node_names = cls.getGlobalParams(runcfg.roslaunch_config.Roscfg)
            rospy.loginfo("Register global parameter:\n  %s", '\n  '.join("%s%s" % (utf8(v)[:80], '...' if len(utf8(v)) > 80 else'') for v in global_node_names.values()))
            abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(runcfg.masteruri, global_node_names, [], runcfg.user, runcfg.pw, runcfg.auto_pw_request)
            runcfg.roslaunch_config.global_param_done.append(runcfg.masteruri)

        # add params
        if runcfg.masteruri is not None:
            nodens = ''.join([n.namespace, n.name, rospy.names.SEP])
            params = dict()
            for param, value in runcfg.roslaunch_config.Roscfg.params.items():
                if param.startswith(nodens):
                    params[param] = value
            clear_params = []
            for cparam in runcfg.roslaunch_config.Roscfg.clear_params:
                if cparam.startswith(nodens):
                    clear_params.append(cparam)
            rospy.loginfo("Delete parameter:\n  %s", '\n  '.join(clear_params))
            rospy.loginfo("Register parameter:\n  %s", '\n  '.join("%s%s" % (utf8(v)[:80], '...' if len(utf8(v)) > 80 else'') for v in params.values()))
            abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(runcfg.masteruri, params, clear_params, runcfg.user, runcfg.pw, runcfg.auto_pw_request)
        # 'print "RUN prepared", node, time.time()

        if nm.is_local(host, wait=True):
            nm.screen().testScreen()
            if runcfg.executable:
                cmd_type = runcfg.executable
            else:
                try:
                    cmd = roslib.packages.find_node(n.package, n.type)
                except (Exception, roslib.packages.ROSPkgException) as starterr:
                    # multiple nodes, invalid package
                    raise StartException("Can't find resource: %s" % starterr)
                # handle diferent result types str or array of string
                if isinstance(cmd, types.StringTypes):
                    cmd = [cmd]
                cmd_type = ''
                if cmd is None or len(cmd) == 0:
                    raise StartException("%s in package [%s] not found!\n\nThe package "
                                         "was created?\nIs the binary executable?\n" % (n.type, n.package))
                if len(cmd) > 1:
                    if runcfg.auto_pw_request:
                        # Open selection for executables, only if the method is called from the main GUI thread
                        try:
                            try:
                                from python_qt_binding.QtGui import QInputDialog
                            except:
                                from python_qt_binding.QtWidgets import QInputDialog
                            item, result = QInputDialog.getItem(None, 'Multiple executables %s in %s' % (n.type, n.package),
                                                                'Select an executable',
                                                                cmd, 0, False)
                            if result:
                                # open the selected screen
                                cmd_type = item
                            else:
                                return
                        except:
                            raise StartException('Multiple executables with same name in package found!')
                    else:
                        err = BinarySelectionRequest(cmd, 'Multiple executables')
                        raise nm.InteractionNeededError(err, cls.runNode,
                                                        (runcfg,))
                else:
                    cmd_type = cmd[0]
            # determine the current working path, Default: the package of the node
            cwd = get_ros_home()
            if not (n.cwd is None):
                if n.cwd == 'ROS_HOME':
                    cwd = get_ros_home()
                elif n.cwd == 'node':
                    cwd = os.path.dirname(cmd_type)
            cls._prepareROSMaster(runcfg.masteruri)
            node_cmd = [nm.settings().respawn_script if n.respawn else '', prefix, cmd_type]
            cmd_args = [nm.screen().getSceenCmd(runcfg.node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(utf8(n.args))
            cmd_args[len(cmd_args):] = args
            rospy.loginfo("RUN: %s", ' '.join(cmd_args))
            new_env = dict(os.environ)
            new_env['ROS_MASTER_URI'] = runcfg.masteruri
            ros_hostname = NameResolution.get_ros_hostname(runcfg.masteruri)
            if ros_hostname:
                new_env['ROS_HOSTNAME'] = ros_hostname
            # add the namespace environment parameter to handle some cases,
            # e.g. rqt_cpp plugins
            if n.namespace:
                new_env['ROS_NAMESPACE'] = n.namespace
            # set logging options
            if runcfg.logging is not None:
                if not runcfg.logging.is_default('loglevel'):
                    env.append(('ROSCONSOLE_CONFIG_FILE', nm.settings().rosconsole_cfg_file(n.package)))
            for key, value in env:
                new_env[key] = value
            SupervisedPopen(shlex.split(utf8(' '.join(cmd_args))), cwd=cwd,
                            env=new_env, object_id="Run node", description="Run node "
                            "[%s]%s" % (utf8(n.package), utf8(n.type)))
            nm.filewatcher().add_binary(cmd_type, runcfg.node, runcfg.masteruri, runcfg.roslaunch_config.Filename)
        else:
            # 'print "RUN REMOTE", node, time.time()
            # start remote
            if runcfg.roslaunch_config.PackageName is None:
                raise StartException("Can't run remote without a valid package name!")
            # thus the prefix parameters while the transfer are not separated
            if prefix:
                prefix = ''.join(['"', prefix, '"'])
            # setup environment
            env_command = ''
            if env_loader:
                rospy.logwarn("env_loader in machine tag currently not supported")
                raise StartException("env_loader in machine tag currently not supported")
            if env:
                new_env = dict()
                try:
                    for (k, v) in env:
                        v_value, is_abs_path, found, package = cls._resolve_abs_paths(v, host, runcfg.user, runcfg.pw, runcfg.auto_pw_request)
                        new_env[k] = v_value
                        if is_abs_path:
                            abs_paths.append(('ENV', "%s=%s" % (k, v), "%s=%s" % (k, v_value)))
                            if not found and package:
                                not_found_packages.append(package)
                    env_command = "env " + ' '.join(["%s=\'%s\'" % (k, v) for (k, v) in new_env.items()])
                except nm.AuthenticationRequest as e:
                    raise nm.InteractionNeededError(e, cls.runNode, (runcfg,))

            startcmd = [env_command, nm.settings().start_remote_script,
                        '--package', utf8(n.package),
                        '--node_type', utf8(n.type),
                        '--node_name', utf8(runcfg.node),
                        '--node_respawn true' if n.respawn else '']
            if runcfg.masteruri is not None:
                startcmd.append('--masteruri')
                startcmd.append(runcfg.masteruri)
            if prefix:
                startcmd[len(startcmd):] = ['--prefix', prefix]
            if runcfg.logging is not None:
                if not runcfg.logging.is_default('loglevel'):
                    startcmd.append('--loglevel')
                    startcmd.append(nm.settings().logging.loglevel)

            # rename the absolute paths in the args of the node
            node_args = []
            try:
                for a in n.args.split():
                    a_value, is_abs_path, found, package = cls._resolve_abs_paths(a, host, runcfg.user, runcfg.pw, runcfg.auto_pw_request)
                    node_args.append(a_value)
                    if is_abs_path:
                        abs_paths.append(('ARGS', a, a_value))
                        if not found and package:
                            not_found_packages.append(package)

                startcmd[len(startcmd):] = node_args
                startcmd[len(startcmd):] = args
                rospy.loginfo("Run remote on %s: %s", host, utf8(' '.join(startcmd)))
                # 'print "RUN CALL", node, time.time()
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, runcfg.user, runcfg.pw, runcfg.auto_pw_request, close_stdin=True)
                output = stdout.read()
                error = stderr.read()
                stdout.close()
                stderr.close()
                # 'print "RUN CALLOK", node, time.time()
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(e, cls.runNode, (runcfg,))

            if ok:
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", runcfg.node, error)
                    raise StartException(utf8(''.join(['The host "', host, '" reports:\n', error])))
                if output:
                    rospy.loginfo("STDOUT while start '%s': %s", runcfg.node, output)
            # inform about absolute paths in parameter value
            if len(abs_paths) > 0:
                rospy.loginfo("Absolute paths found while start:\n%s", utf8('\n'.join([''.join([p, '\n  OLD: ', ov, '\n  NEW: ', nv]) for p, ov, nv in abs_paths])))

            if len(not_found_packages) > 0:
                packages = '\n'.join(not_found_packages)
                raise StartException(utf8('\n'.join(['Some absolute paths are not renamed because following packages are not found on remote host:', packages])))