def killScreens(cls, host, node, user=None, parent=None):
   '''
   Searches for the screen associated with the given node and kill this screens. 
   @param host: the host name or ip where the screen is running
   @type host: C{str}
   @param node: the name of the node those screen output to show
   @type node: C{str}
   @param parent: the parent widget to show a message box, if a user 
   input is required.
   @type parent: L{PySide.QtGui.QWidget}
   '''
   if node is None or len(node) == 0:
     return False
   # get the available screens
   screens = cls.getActiveScreens(host, cls.createSessionName(node), user=user) #user=user, pwd=pwd
   if screens:
     from PySide import QtGui
     result = QtGui.QMessageBox.question(parent, "Kill SCREENs?", '\n'.join(screens), QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Ok)
     if result & QtGui.QMessageBox.Ok:
       for s in screens:
         pid, sep, name = s.partition('.')
         if pid:
           try:
             nm.starter().kill(host, int(pid))
           except:
             import traceback
             rospy.logwarn("Error while kill screen (PID: %s) on host '%s': %s", str(pid), str(host), str(traceback.format_exc()))
       if nm.is_local(host):
         ps = subprocess.Popen([cls.SCREEN, '-wipe'])
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
       else:
         nm.ssh().ssh_exec(host, [cls.SCREEN, '-wipe'])
 def openLog(cls, nodename, host, user=None):
   '''
   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'", str(nodename), str(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), id="Open log", description="Open log for '%s' on '%s'"%(str(nodename), str(host)))
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       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), id="Open log", description="Open log for '%s' on '%s'"%(str(nodename), str(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)
     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 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'", str(nodename), str(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))
 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'", str(nodename), str(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))
 def _on_display_anchorClicked(self, url, user=None, pw=None):
   try:
     ok = False
     if self.show_only_rate:
       self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh().ssh_exec(url.host(), ['rostopic hz %s'%(self.topic)], user, pw, auto_pw_request=True, get_pty=True)
       self.status_label.setText('connected to %s over SSH'%url.host())
     else:
       self.combobox_displ_hz.setEnabled(False)
       nostr = '--nostr' if self.no_str_checkbox.isChecked() else ''
       noarr = '--noarr' if self.no_arr_checkbox.isChecked() else ''
       self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh().ssh_exec(url.host(), ['rostopic echo %s %s %s'%(nostr, noarr, self.topic)], user, pw, auto_pw_request=True, get_pty=True)
     if ok:
       self.display.clear()
       target = self._read_output_hz if self.show_only_rate else self._read_output
       thread = threading.Thread(target=target, args=((self.ssh_output_file,)))
       thread.setDaemon(True)
       thread.start()
       thread = threading.Thread(target=self._read_error, args=((self.ssh_error_file,)))
       thread.setDaemon(True)
       thread.start()
     elif self.ssh_output_file:
       self.ssh_output_file.close()
       self.ssh_error_file.close()
   except Exception as e:
     self._append_error_text('%s\n'%e)
 def openLog(cls, nodename, host):
   '''
   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()}
   '''
   title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
   if nm.is_local(host):
     found = False
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     if os.path.isfile(screenLog):
       cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
       rospy.loginfo("open log: %s", cmd)
       subprocess.Popen(shlex.split(cmd))
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       title_opt = title_opt.replace('LOG', 'ROSLOG')
       cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
       rospy.loginfo("open ROS log: %s", cmd)
       subprocess.Popen(shlex.split(cmd))
       found = True
     return found
   else:
     nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename], title_opt)
     nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'))
   return False
 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 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:
                 try:
                     from python_qt_binding.QtGui import QMessageBox
                 except:
                     from python_qt_binding.QtWidgets import QMessageBox
                 result = QMessageBox.question(
                     None, "Kill SCREENs?", '\n'.join(screens),
                     QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
                 if result & QMessageBox.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",
                                 str(pid), str(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))
Example #9
0
 def openLog(cls, nodename, host):
     '''
 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'", str(nodename), str(host))
     title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
     if nm.is_local(host):
         found = False
         screenLog = nm.screen().getScreenLogFile(node=nodename)
         if os.path.isfile(screenLog):
             cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
             rospy.loginfo("open log: %s", cmd)
             ps = subprocess.Popen(shlex.split(cmd))
             # wait for process to avoid 'defunct' processes
             thread = threading.Thread(target=ps.wait)
             thread.setDaemon(True)
             thread.start()
             found = True
         #open roslog file
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(roslog):
             title_opt = title_opt.replace('LOG', 'ROSLOG')
             cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
             rospy.loginfo("open ROS log: %s", cmd)
             ps = subprocess.Popen(shlex.split(cmd))
             # wait for process to avoid 'defunct' processes
             thread = threading.Thread(target=ps.wait)
             thread.setDaemon(True)
             thread.start()
             found = True
         return found
     else:
         ps = nm.ssh().ssh_x11_exec(
             host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename],
             title_opt)
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
         ps = nm.ssh().ssh_x11_exec(
             host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename],
             title_opt.replace('LOG', 'ROSLOG'))
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
     return False
 def openLog(cls, nodename, host, user=None):
   '''
   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'", str(nodename), str(host))
   title_opt = ' '.join(['"LOG', nodename, 'on', host, '"'])
   if nm.is_local(host):
     found = False
     screenLog = nm.screen().getScreenLogFile(node=nodename)
     if os.path.isfile(screenLog):
       cmd = nm.terminal_cmd([nm.LESS, screenLog], title_opt)
       rospy.loginfo("open log: %s", cmd)
       ps = subprocess.Popen(shlex.split(cmd))
       # wait for process to avoid 'defunct' processes
       thread = threading.Thread(target=ps.wait)
       thread.setDaemon(True)
       thread.start()
       found = True
     #open roslog file
     roslog = nm.screen().getROSLogFile(nodename)
     if os.path.isfile(roslog):
       title_opt = title_opt.replace('LOG', 'ROSLOG')
       cmd = nm.terminal_cmd([nm.LESS, roslog], title_opt)
       rospy.loginfo("open ROS log: %s", cmd)
       ps = subprocess.Popen(shlex.split(cmd))
       # wait for process to avoid 'defunct' processes
       thread = threading.Thread(target=ps.wait)
       thread.setDaemon(True)
       thread.start()
       found = True
     return found
   else:
     ps = nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_screen_log', nodename], title_opt, user)
     # wait for process to avoid 'defunct' processes
     thread = threading.Thread(target=ps.wait)
     thread.setDaemon(True)
     thread.start()
     ps = nm.ssh().ssh_x11_exec(host, [nm.STARTER_SCRIPT, '--show_ros_log', nodename], title_opt.replace('LOG', 'ROSLOG'), user)
     # wait for process to avoid 'defunct' processes
     thread = threading.Thread(target=ps.wait)
     thread.setDaemon(True)
     thread.start()
   return False
Example #11
0
 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),
                                        user=user)  #user=user, pwd=pwd
         if screens:
             do_kill = True
             if auto_ok_request:
                 from python_qt_binding import QtGui
                 result = QtGui.QMessageBox.question(
                     None, "Kill SCREENs?", '\n'.join(screens),
                     QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel,
                     QtGui.QMessageBox.Ok)
                 if result & QtGui.QMessageBox.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",
                                 str(pid), str(host),
                                 traceback.format_exc())
                 if nm.is_local(host):
                     ps = subprocess.Popen([cls.SCREEN, '-wipe'])
                     # wait for process to avoid 'defunct' processes
                     thread = threading.Thread(target=ps.wait)
                     thread.setDaemon(True)
                     thread.start()
                 else:
                     #            output, error, ok = nm.ssh().ssh_exec(host, [cls.SCREEN, '-wipe'])
                     nm.ssh().ssh_exec(host, [cls.SCREEN, '-wipe'])
     except nm.AuthenticationRequest as e:
         raise nm.InteractionNeededError(e, cls.killScreens,
                                         (node, host, auto_ok_request))
Example #12
0
 def openLog(cls, nodename, host, user=None):
     '''
 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'", str(nodename), str(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),
                             id="Open log",
                             description="Open log for '%s' on '%s'" %
                             (str(nodename), str(host)))
             found = True
         #open roslog file
         roslog = nm.screen().getROSLogFile(nodename)
         if os.path.isfile(roslog):
             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),
                             id="Open log",
                             description="Open log for '%s' on '%s'" %
                             (str(nodename), str(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)
         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 _resolve_abs_paths(cls, value, host, user, pw, auto_pw_request):
     '''
     Replaces the local absolute path by remote absolute path. Only valid ROS
     package paths are resolved.
     @return: value, is absolute path, remote package found (ignore it on local host or if is not absolute path!), package name (if absolute path and remote package NOT found)
     '''
     if isinstance(value, types.StringTypes) and value.startswith('/') and (os.path.isfile(value) or os.path.isdir(value)):
         if nm.is_local(host):
             return value, True, True, ''
         else:
             path = os.path.dirname(value) if os.path.isfile(value) else value
             package, package_path = package_name(path)
             if package:
                 _, stdout, _, ok = nm.ssh().ssh_exec(host, ['rospack', 'find', package], user, pw, auto_pw_request, close_stdin=True, close_stderr=True)
                 output = stdout.read()
                 stdout.close()
                 if ok:
                     if output:
                         value.replace(package_path, output)
                         return value.replace(package_path, output.strip()), True, True, package
                     else:
                         # package on remote host not found!
                         # TODO add error message
                         #      error = stderr.read()
                         pass
             return value, True, False, ''
     else:
         return value, False, False, ''
 def getActiveScreens(cls, host, session='', user=None, pwd=None):
   '''
   Returns the list with all compatible screen names. If the session is set to 
   an empty string all screens will be returned.
   @param host: the host name or IP to search for the screen session.
   @type host: C{str}
   @param session: the name or the suffix of the screen session
   @type session: C{str} (Default: C{''})
   @return: the list with session names
   @rtype: C{[str(session name), ...]}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   output = None
   result = []
   if nm.is_local(host):
     out, out_err = cls.getLocalOutput([cls.SCREEN, '-ls'])
     output = out
   else:
     (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, [cls.SCREEN, ' -ls'])
     if ok:
       stdin.close()
 #        error = stderr.read()
       output = stdout.read()
   if not (output is None):
     splits = output.split()
     for i in splits:
       if i.count('.') > 0 and i.endswith(session):
         result.append(i)
   return result
Example #15
0
 def copylogPath2Clipboards(self,
                            host,
                            nodes=[],
                            auto_pw_request=True,
                            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:
             output, error, ok = nm.ssh().ssh_exec(
                 host, [nm.STARTER_SCRIPT, '--ros_log_path', request], user,
                 pw, auto_pw_request)
             if ok:
                 return output
             else:
                 raise StartException(
                     str(''.join([
                         'Get log path from "', host, '" failed:\n', error
                     ])))
         except nm.AuthenticationRequest as e:
             raise nm.InteractionNeededError(
                 e, cls.deleteLog, (nodename, host, auto_pw_request))
Example #16
0
 def _resolve_abs_paths(cls, value, host):
     '''
 Replaces the local absolute path by remote absolute path. Only valid ROS
 package paths are resolved.
 @return: value, is absolute path, remote package found (ignore it on local host or if is not absolute path!), package name (if absolute path and remote package NOT found)
 '''
     if isinstance(value, types.StringTypes) and value.startswith('/') and (
             os.path.isfile(value) or os.path.isdir(value)):
         if nm.is_local(host):
             return value, True, True, ''
         else:
             #        print "ABS PATH:", value, os.path.dirname(value)
             dir = os.path.dirname(value) if os.path.isfile(
                 value) else value
             package, package_path = LaunchConfig.packageName(dir)
             if package:
                 output, error, ok = nm.ssh().ssh_exec(
                     host, ['rospack', 'find', package])
                 if ok:
                     if output:
                         #              print "  RESOLVED:", output
                         #              print "  PACK_PATH:", package_path
                         value.replace(package_path, output)
                         #              print "  RENAMED:", value.replace(package_path, output.strip())
                         return value.replace(
                             package_path,
                             output.strip()), True, True, package
                     else:
                         # package on remote host not found!
                         # TODO add error message
                         #      error = stderr.read()
                         pass
             return value, True, False, ''
     else:
         return value, False, False, ''
Example #17
0
 def _getActiveScreens(cls, host, session='', auto_pw_request=True, user=None, pwd=None):
     '''
     Returns the list with all compatible screen names. If the session is set to
     an empty string all screens will be returned.
     @param host: the host name or IP to search for the screen session.
     @type host: C{str}
     @param session: the name or the suffix of the screen session
     @type session: C{str} (Default: C{''})
     @return: the list with session names
     @rtype: C{[str(session name), ...]}
     @raise Exception: on errors while resolving host
     @see: L{node_manager_fkie.is_local()}
     '''
     output = None
     result = []
     if nm.is_local(host):
         output = cls.getLocalOutput([cls.SCREEN, '-ls'])
     else:
         _, stdout, _, _ = nm.ssh().ssh_exec(host, [cls.SCREEN, ' -ls'], user, pwd, auto_pw_request, close_stdin=True, close_stderr=True)
         output = stdout.read()
         stdout.close()
     if output:
         splits = output.split()
         for i in splits:
             if i.count('.') > 0 and i.endswith(session) and i.find('._') >= 0:
                 result.append(i)
     return result
Example #18
0
 def openScreenTerminal(cls, host, screen_name, nodename, user=None):
     '''
 Open the screen output in a new terminal.
 @param host: the host name or ip where the screen is running.
 @type host: C{str}
 @param screen_name: the name of the screen to show
 @type screen_name: C{str}
 @param nodename: the name of the node is used for the title of the terminal
 @type nodename: C{str}
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     #create a title of the terminal
     #    pid, session_name = cls.splitSessionName(screen_name)
     title_opt = 'SCREEN %s on %s' % (nodename, host)
     if nm.is_local(host):
         cmd = nm.settings().terminal_cmd([cls.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:
         ps = nm.ssh().ssh_x11_exec(host, [cls.SCREEN, '-x', screen_name],
                                    title_opt, user)
         rospy.loginfo("Open remote screen terminal: %s", ps)
Example #19
0
 def kill(self, host, pid):
     '''
 Kills the process with given process id on given host.
 @param host: the name or address of the host, where the process must be killed.
 @type host: C{str}
 @param pid: the process id
 @type pid: C{int}
 @raise StartException: on error
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     if nm.is_local(host):
         import signal
         os.kill(pid, signal.SIGKILL)
         rospy.loginfo("kill: %s", str(pid))
     else:
         # kill on a remote machine
         cmd = ['kill -9', str(pid)]
         rospy.loginfo("kill remote: %s", ' '.join(cmd))
         (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, cmd)
         if ok:
             stdin.close()
             error = stderr.read()
             if error:
                 rospy.logwarn("ERROR while kill %s: %s", str(pid), error)
                 raise nm.StartException(
                     str(''.join(
                         ['The host "', host, '" reports:\n', error])))
             output = stdout.read()
             if output:
                 rospy.logdebug("STDOUT while kill %s: %s", str(pid),
                                output)
 def _resolve_abs_paths(cls, value, host, user, pw, auto_pw_request):
     '''
     Replaces the local absolute path by remote absolute path. Only valid ROS
     package paths are resolved.
     @return: value, is absolute path, remote package found (ignore it on local host or if is not absolute path!), package name (if absolute path and remote package NOT found)
     '''
     if isinstance(value, types.StringTypes) and value.startswith('/') and (os.path.isfile(value) or os.path.isdir(value)):
         if nm.is_local(host):
             return value, True, True, ''
         else:
             path = os.path.dirname(value) if os.path.isfile(value) else value
             package, package_path = package_name(path)
             if package:
                 _, stdout, _, ok = nm.ssh().ssh_exec(host, ['rospack', 'find', package], user, pw, auto_pw_request, close_stdin=True, close_stderr=True)
                 output = stdout.read()
                 stdout.close()
                 if ok:
                     if output:
                         value.replace(package_path, output)
                         return value.replace(package_path, output.strip()), True, True, package
                     else:
                         # package on remote host not found!
                         # TODO add error message
                         #      error = stderr.read()
                         pass
             return value, True, False, ''
     else:
         return value, False, False, ''
Example #21
0
 def _kill_wo(self, host, pid, auto_pw_request=False, user=None, pw=None):
     rospy.loginfo("kill %s on %s", str(pid), host)
     if nm.is_local(host):
         os.kill(pid, signal.SIGKILL)
         rospy.loginfo("kill: %s", str(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", str(pid), error)
                 raise StartException(
                     str(''.join(
                         ['The host "', host, '" reports:\n', error])))
             if output:
                 rospy.logdebug("STDOUT while kill %s on %s: %s", str(pid),
                                host, output)
Example #22
0
 def deleteLog(cls, nodename, host):
     '''
 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()}
 '''
     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:
         (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(
             host, [nm.STARTER_SCRIPT, '--delete_logs', nodename])
         if ok:
             stdin.close()
  def openScreenTerminal(cls, host, screen_name, nodename, user=None):
    '''
    Open the screen output in a new terminal.
    @param host: the host name or ip where the screen is running.
    @type host: C{str}
    @param screen_name: the name of the screen to show
    @type screen_name: C{str}
    @param nodename: the name of the node is used for the title of the terminal
    @type nodename: C{str}
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
    #create a title of the terminal
#    pid, session_name = cls.splitSessionName(screen_name)
    title_opt = ' '.join(['"SCREEN', nodename, 'on', host, '"'])
    if nm.is_local(host):
      cmd = nm.terminal_cmd([cls.SCREEN, '-x', screen_name], title_opt)
      rospy.loginfo("Open screen terminal: %s", cmd)
      ps = subprocess.Popen(shlex.split(cmd))
      # wait for process to avoid 'defunct' processes
      thread = threading.Thread(target=ps.wait)
      thread.setDaemon(True)
      thread.start()
    else:
      ps = nm.ssh().ssh_x11_exec(host, [cls.SCREEN, '-x', screen_name], title_opt)
      rospy.loginfo("Open remote screen terminal: %s", ps)
      # wait for process to avoid 'defunct' processes
      thread = threading.Thread(target=ps.wait)
      thread.setDaemon(True)
      thread.start()
 def _on_request_interact(self, ident, descr, req):
   '''
   If the interaction of the user is needed a message dialog must be exceuted 
   in the main Qt thread. The requests are done by different request exceptinos.
   These are handled by this method.
   '''
   if isinstance(req.request, nm.AuthenticationRequest):
     res, user, pw = nm.ssh()._requestPW(req.request.user, req.request.host)
     if not res:
       self._on_progress_canceled()
       return
     pt = ProgressThread(ident, descr, req.method, (req.args+(user, pw)))
     pt.finished_signal.connect(self._progress_thread_finished)
     pt.error_signal.connect(self._progress_thread_error)
     pt.request_interact_signal.connect(self._on_request_interact)
     pt.start()
   elif isinstance(req.request, nm.ScreenSelectionRequest):
     from select_dialog import SelectDialog
     items, _ = SelectDialog.getValue('Show screen', '', req.request.choices.keys(), False)
     if not items:
       self._progress_thread_finished(ident)
       return
     res = [req.request.choices[i] for i in items]
     pt = ProgressThread(ident, descr, req.method, (req.args+(res,)))
     pt.finished_signal.connect(self._progress_thread_finished)
     pt.error_signal.connect(self._progress_thread_error)
     pt.request_interact_signal.connect(self._on_request_interact)
     pt.start()
   elif isinstance(req.request, nm.BinarySelectionRequest):
     from select_dialog import SelectDialog
     items, _ = SelectDialog.getValue('Multiple executables', '', req.request.choices, True)
     if not items:
       self._progress_thread_finished(ident)
       return
     res = items[0]
     pt = ProgressThread(ident, descr, req.method, (req.args+(res,)))
     pt.finished_signal.connect(self._progress_thread_finished)
     pt.error_signal.connect(self._progress_thread_error)
     pt.request_interact_signal.connect(self._on_request_interact)
     pt.start()
   elif isinstance(req.request, nm.LaunchArgsSelectionRequest):
     from parameter_dialog import ParameterDialog
     inputDia = ParameterDialog(req.request.args_dict)
     inputDia.setFilterVisible(False)
     inputDia.setWindowTitle(''.join(['Enter the argv for ', req.request.launchfile]))
     if inputDia.exec_():
       params = inputDia.getKeywords()
       argv = []
       for p,v in params.items():
         if v:
           argv.append(''.join([p, ':=', v]))
       res = argv
       pt = ProgressThread(ident, descr, req.method, (req.args+(argv,)))
       pt.finished_signal.connect(self._progress_thread_finished)
       pt.error_signal.connect(self._progress_thread_error)
       pt.request_interact_signal.connect(self._on_request_interact)
       pt.start()
     else:
       self._progress_thread_finished(ident)
       return
Example #25
0
 def openScreenTerminal(cls, host, screen_name, nodename, user=None):
     '''
 Open the screen output in a new terminal.
 @param host: the host name or ip where the screen is running.
 @type host: C{str}
 @param screen_name: the name of the screen to show
 @type screen_name: C{str}
 @param nodename: the name of the node is used for the title of the terminal
 @type nodename: C{str}
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     #create a title of the terminal
     #    pid, session_name = cls.splitSessionName(screen_name)
     title_opt = 'SCREEN %s on %s' % (nodename, host)
     if nm.is_local(host):
         cmd = nm.settings().terminal_cmd([cls.SCREEN, '-x', screen_name],
                                          title_opt)
         rospy.loginfo("Open screen terminal: %s", cmd)
         ps = subprocess.Popen(shlex.split(cmd))
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
     else:
         ps = nm.ssh().ssh_x11_exec(host, [cls.SCREEN, '-x', screen_name],
                                    title_opt, user)
         rospy.loginfo("Open remote screen terminal: %s", ps)
         # wait for process to avoid 'defunct' processes
         thread = threading.Thread(target=ps.wait)
         thread.setDaemon(True)
         thread.start()
 def _getActiveScreens(cls, host, session='', auto_pw_request=True, user=None, pwd=None):
   '''
   Returns the list with all compatible screen names. If the session is set to 
   an empty string all screens will be returned.
   @param host: the host name or IP to search for the screen session.
   @type host: C{str}
   @param session: the name or the suffix of the screen session
   @type session: C{str} (Default: C{''})
   @return: the list with session names
   @rtype: C{[str(session name), ...]}
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   output = None
   result = []
   if nm.is_local(host):
     output = cls.getLocalOutput([cls.SCREEN, '-ls'])
   else:
     _, stdout, _, _ = nm.ssh().ssh_exec(host, [cls.SCREEN, ' -ls'], user, pwd, auto_pw_request, close_stdin=True, close_stderr=True)
     output = stdout.read()
     stdout.close()
   if output:
     splits = output.split()
     for i in splits:
       if i.count('.') > 0 and i.endswith(session) and i.find('._') >= 0:
         result.append(i)
   return result
  def _resolve_abs_paths(cls, value, host):
    '''
    Replaces the local absolute path by remote absolute path. Only valid ROS
    package paths are resolved.
    @return: value, is absolute path, remote package found (ignore it on local host or if is not absolute path!), package name (if absolute path and remote package NOT found)
    '''
    if isinstance(value, types.StringTypes) and value.startswith('/') and (os.path.isfile(value) or os.path.isdir(value)):
      if nm.is_local(host):
        return value, True, True, ''
      else:
#        print "ABS PATH:", value, os.path.dirname(value)
        dir = os.path.dirname(value) if os.path.isfile(value) else value
        package, package_path = LaunchConfig.packageName(dir)
        if package:
          (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, ['rospack', 'find', package])
          if ok:
            stdin.close()
            output = stdout.read()
            if output:
#              print "  RESOLVED:", output
#              print "  PACK_PATH:", package_path
              value.replace(package_path, output)
#              print "  RENAMED:", value.replace(package_path, output.strip())
              return value.replace(package_path, output.strip()), True, True, package
            else:
              # package on remote host not found! 
              # TODO add error message
              #      error = stderr.read()
              pass
        return value, True, False, ''
    else:
      return value, False, False, ''
 def kill(self, host, pid):
   '''
   Kills the process with given process id on given host.
   @param host: the name or address of the host, where the process must be killed.
   @type host: C{str}
   @param pid: the process id
   @type pid: C{int}
   @raise StartException: on error
   @raise Exception: on errors while resolving host
   @see: L{node_manager_fkie.is_local()}
   '''
   if nm.is_local(host): 
     import signal
     os.kill(pid, signal.SIGKILL)
     rospy.loginfo("kill: %s", str(pid))
   else:
     # kill on a remote machine
     cmd = ['kill -9', str(pid)]
     rospy.loginfo("kill remote on %s: %s", host, ' '.join(cmd))
     (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, cmd)
     if ok:
       stdin.close()
       error = stderr.read()
       if error:
         rospy.logwarn("ERROR while kill %s: %s", str(pid), error)
         raise nm.StartException(str(''.join(['The host "', host, '" reports:\n', error])))
       output = stdout.read()
       if output:
         rospy.logdebug("STDOUT while kill %s on %s: %s", str(pid), host, output)
 def _poweroff_wo(self, host, auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         rospy.logwarn("shutdown localhost localhost!")
         cmd = nm.settings().terminal_cmd(['sudo poweroff'], "poweroff")
         SupervisedPopen(shlex.split(cmd), object_id="poweroff", description="poweroff")
     else:
         rospy.loginfo("poweroff %s", host)
         # kill on a remote machine
         cmd = ['sudo poweroff']
         _ = nm.ssh().ssh_exec(host, cmd, 'Shutdown %s' % host, user)
 def _rosclean_wo(self, host, auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         rospy.loginfo("rosclean purge on localhost!")
         cmd = nm.settings().terminal_cmd(['rosclean purge -y'], "rosclean")
         SupervisedPopen(shlex.split(cmd), object_id="rosclean", description="rosclean")
     else:
         rospy.loginfo("rosclean %s", host)
         # kill on a remote machine
         cmd = ['rosclean purge -y']
         _ = nm.ssh().ssh_x11_exec(host, cmd, 'rosclean purge on %s' % host, user)
 def _poweroff_wo(self, host, auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         rospy.logwarn("shutdown localhost localhost!")
         cmd = nm.settings().terminal_cmd(['sudo poweroff'], "poweroff")
         SupervisedPopen(shlex.split(cmd), object_id="poweroff", description="poweroff")
     else:
         rospy.loginfo("poweroff %s", host)
         # kill on a remote machine
         cmd = ['sudo poweroff']
         _ = nm.ssh().ssh_x11_exec(host, cmd, 'Shutdown %s' % host, user)
 def _rosclean_wo(self, host, auto_pw_request=False, user=None, pw=None):
     if nm.is_local(host):
         rospy.loginfo("rosclean purge on localhost!")
         cmd = nm.settings().terminal_cmd(['rosclean purge -y'], "rosclean")
         SupervisedPopen(shlex.split(cmd), object_id="rosclean", description="rosclean")
     else:
         rospy.loginfo("rosclean %s", host)
         # kill on a remote machine
         cmd = ['rosclean purge -y']
         _ = nm.ssh().ssh_x11_exec(host, cmd, 'rosclean purge on %s' % host, user)
 def _on_display_anchorClicked(self, url, user=None, pw=None):
     try:
         ok = False
         if self.show_only_rate:
             self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh(
             ).ssh_exec(url.host(), ['rostopic hz %s' % (self.topic)],
                        user,
                        pw,
                        auto_pw_request=True,
                        get_pty=True)
             self.statusLabel.setText('connected to %s over SSH' %
                                      url.host())
         else:
             nostr = '--nostr' if not self.showStringsCheckBox.isChecked(
             ) else ''
             noarr = '--noarr' if not self.showArraysCheckBox.isChecked(
             ) else ''
             self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh(
             ).ssh_exec(
                 url.host(),
                 ['rostopic echo %s %s %s' % (nostr, noarr, self.topic)],
                 user,
                 pw,
                 auto_pw_request=True,
                 get_pty=True)
         if ok:
             self.display.clear()
             target = self._read_output_hz if self.show_only_rate else self._read_output
             thread = threading.Thread(target=target,
                                       args=((self.ssh_output_file, )))
             thread.setDaemon(True)
             thread.start()
             thread = threading.Thread(target=self._read_error,
                                       args=((self.ssh_error_file, )))
             thread.setDaemon(True)
             thread.start()
         elif self.ssh_output_file:
             self.ssh_output_file.close()
             self.ssh_error_file.close()
     except Exception as e:
         self._append_error_text('%s\n' % e)
 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(str(''.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 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 _kill_wo(self, host, pid, auto_pw_request=False, user=None, pw=None):
   rospy.loginfo("kill %s on %s", str(pid), host)
   if nm.is_local(host): 
     os.kill(pid, signal.SIGKILL)
     rospy.loginfo("kill: %s", str(pid))
   else:
     # kill on a remote machine
     cmd = ['kill -9', str(pid)]
     output, error, ok = nm.ssh().ssh_exec(host, cmd, user, pw, False)
     if ok:
       if error:
         rospy.logwarn("ERROR while kill %s: %s", str(pid), error)
         raise StartException(str(''.join(['The host "', host, '" reports:\n', error])))
       if output:
         rospy.logdebug("STDOUT while kill %s on %s: %s", str(pid), host, output)
 def transfer_files(cls, host, file, 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(file))
   if not pkg_name is None:
     # get the subpath of the file
     subfile_path = file.replace(pkg_path, '')
     # get the path of the package on the remote machine
     try:
       output = ''
       error = ''
       ok = True
       if CACHED_PKG_PATH.has_key(host) and CACHED_PKG_PATH[host].has_key(pkg_name):
         output = CACHED_PKG_PATH[host][pkg_name]
       else:
         if not CACHED_PKG_PATH.has_key(host):
           CACHED_PKG_PATH[host] = dict()
         output, error, ok = nm.ssh().ssh_exec(host, [nm.STARTER_SCRIPT, '--package', pkg_name], user, pw, auto_pw_request)
       if ok:
         if error:
           rospy.logwarn("ERROR while transfer %s to %s: %s", file, host, error)
           raise StartException(str(''.join(['The host "', host, '" reports:\n', error])))
         if output:
           CACHED_PKG_PATH[host][pkg_name] = output
           nm.ssh().transfer(host, file, 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, file, auto_pw_request))
Example #38
0
 def copylogPath2Clipboards(self, host, nodes=[], auto_pw_request=True, 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:
       output, error, ok = nm.ssh().ssh_exec(host, [nm.STARTER_SCRIPT, '--ros_log_path', request], user, pw, auto_pw_request)
       if ok:
         return output
       else:
         raise StartException(str(''.join(['Get log path from "', host, '" failed:\n', error])))
     except nm.AuthenticationRequest as e:
       raise nm.InteractionNeededError(e, cls.deleteLog, (nodename, host, auto_pw_request))
 def _killall_roscore_wo(self, host, auto_pw_request=False, user=None, pw=None):
     rospy.loginfo("killall roscore on %s", host)
     cmd = ['killall', 'roscore']
     if nm.is_local(host):
         SupervisedPopen(cmd, object_id="killall roscore", description="killall roscore")
     else:
         # kill on a remote machine
         _, 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 killall roscore on %s: %s" % (host, error))
                 raise StartException('The host "%s" reports:\n%s' % (host, error))
             if output:
                 rospy.logdebug("STDOUT while killall roscore on %s: %s" % (host, output))
 def _killall_roscore_wo(self, host, auto_pw_request=False, user=None, pw=None):
     rospy.loginfo("killall roscore on %s", host)
     cmd = ['killall', 'roscore']
     if nm.is_local(host):
         SupervisedPopen(cmd, object_id="killall roscore", description="killall roscore")
     else:
         # kill on a remote machine
         _, 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 killall roscore on %s: %s" % (host, error))
                 raise StartException('The host "%s" reports:\n%s' % (host, error))
             if output:
                 rospy.logdebug("STDOUT while killall roscore on %s: %s" % (host, output))
Example #41
0
 def copylogPath2Clipboards(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)
       output, error, ok = nm.ssh().ssh_exec(host, [nm.settings().start_remote_script, '--ros_log_path', request], user, pw, auto_pw_request)
       if ok:
         return output
       else:
         raise StartException(str(''.join(['Get log path from "', host, '" failed:\n', error])))
     except nm.AuthenticationRequest as e:
       raise nm.InteractionNeededError(e, cls.copylogPath2Clipboards, (host, nodes, auto_pw_request))
     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 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(str(''.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 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
  def openScreenTerminal(cls, host, screen_name, nodename, user=None):
    '''
    Open the screen output in a new terminal.
    @param host: the host name or ip where the screen is running.
    @type host: C{str}
    @param screen_name: the name of the screen to show
    @type screen_name: C{str}
    @param nodename: the name of the node is used for the title of the terminal
    @type nodename: C{str}
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
    #create a title of the terminal
#    pid, session_name = cls.splitSessionName(screen_name)
    title_opt = 'SCREEN %s on %s'%(nodename, host)
    if nm.is_local(host):
      cmd = nm.settings().terminal_cmd([cls.SCREEN, '-x', screen_name], title_opt)
      rospy.loginfo("Open screen terminal: %s", cmd)
      SupervisedPopen(shlex.split(cmd), id=title_opt, description="Open screen terminal: %s"%title_opt)
    else:
      ps = nm.ssh().ssh_x11_exec(host, [cls.SCREEN, '-x', screen_name], title_opt, user)
      rospy.loginfo("Open remote screen terminal: %s", ps)
 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'" % (str(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
 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), user=user) #user=user, pwd=pwd
     if screens:
       do_kill = True
       if auto_ok_request:
         from python_qt_binding import QtGui
         result = QtGui.QMessageBox.question(None, "Kill SCREENs?", '\n'.join(screens), QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Ok)
         if result & QtGui.QMessageBox.Ok:
           do_kill = True
       if do_kill:
         for s in screens:
           pid, sep, name = 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", str(pid), str(host), str(traceback.format_exc()))
         if nm.is_local(host):
           ps = subprocess.Popen([cls.SCREEN, '-wipe'])
           # wait for process to avoid 'defunct' processes
           thread = threading.Thread(target=ps.wait)
           thread.setDaemon(True)
           thread.start()
         else:
           output, error, ok = nm.ssh().ssh_exec(host, [cls.SCREEN, '-wipe'])
   except nm.AuthenticationRequest as e:
     raise nm.InteractionNeededError(e, cls.killScreens, (node, host, auto_ok_request))
 def _on_request_interact(self, id, descr, req):
   if isinstance(req.request, nm.AuthenticationRequest):
     res, user, pw = nm.ssh()._requestPW(req.request.user, req.request.host)
     if not res:
       self._on_progress_canceled()
       return
     pt = ProgressThread(id, descr, req.method, (req.args+(user, pw)))
     pt.finished_signal.connect(self._progress_thread_finished)
     pt.error_signal.connect(self._progress_thread_error)
     pt.request_interact_signal.connect(self._on_request_interact)
     pt.start()
   elif isinstance(req.request, nm.ScreenSelectionRequest):
     from select_dialog import SelectDialog
     items = SelectDialog.getValue('Show screen', req.request.choices.keys(), False)
     if not items:
       self._progress_thread_finished(id)
       return
     res = [req.request.choices[i] for i in items]
     pt = ProgressThread(id, descr, req.method, (req.args+(res,)))
     pt.finished_signal.connect(self._progress_thread_finished)
     pt.error_signal.connect(self._progress_thread_error)
     pt.request_interact_signal.connect(self._on_request_interact)
     pt.start()
 def deleteLog(cls, nodename, host):
   '''
   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()}
   '''
   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:
     (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, [nm.STARTER_SCRIPT, '--delete_logs', nodename])
     if ok:
       stdin.close()
  def runNode(cls, node, launch_config, force2host=None, masteruri=None):
    '''
    Start the node with given name from the given configuration.
    @param node: the name of the node (with name space)
    @type node: C{str}
    @param launch_config: the configuration containing the node
    @type launch_config: L{LaunchConfig} 
    @param force2host: start the node on given host.
    @type force2host: L{str} 
    @param masteruri: force the masteruri.
    @type masteruri: L{str} 
    @raise StartException: if the screen is not available on host.
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
    n = launch_config.getNode(node)
    if n is None:
      raise StartException(''.join(["Node '", node, "' not found!"]))
    
    env = list(n.env_args)
    prefix = n.launch_prefix if not n.launch_prefix is None else ''
    if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1:
      rospy.loginfo("SCREEN prefix removed before start!")
      prefix = ''
    args = [''.join(['__ns:=', n.namespace]), ''.join(['__name:=', n.name])]
    if not (n.cwd is None):
      args.append(''.join(['__cwd:=', n.cwd]))
    
    # add remaps
    for remap in n.remap_args:
      args.append(''.join([remap[0], ':=', remap[1]]))

    # get host of the node
    host = launch_config.hostname
    env_loader = ''
    if n.machine_name:
      machine = launch_config.Roscfg.machines[n.machine_name]
      host = machine.address
      #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 not force2host is None:
      host = force2host

    if masteruri is None:
      masteruri = nm.nameres().masteruri(n.machine_name)
    # set the ROS_MASTER_URI
    if masteruri is None:
      masteruri = nm.masteruri_from_ros()
      env.append(('ROS_MASTER_URI', masteruri))

    abs_paths = list() # tuples of (parameter name, old value, new value)
    not_found_packages = list() # package names
    # set the global parameter
    if not masteruri is None and not masteruri in launch_config.global_param_done:
      global_node_names = cls.getGlobalParams(launch_config.Roscfg)
      rospy.loginfo("Register global parameter:\n%s", '\n'.join(global_node_names))
      abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, global_node_names, [])
      launch_config.global_param_done.append(masteruri)

    # add params
    if not masteruri is None:
      nodens = ''.join([n.namespace, n.name, '/'])
      params = dict()
      for param, value in launch_config.Roscfg.params.items():
        if param.startswith(nodens):
          params[param] = value
      clear_params = []
      for cparam in launch_config.Roscfg.clear_params:
        if cparam.startswith(nodens):
          clear_params.append(param)
      rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
      abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(masteruri, params, clear_params)
    if nm.is_local(host): 
      nm.screen().testScreen()
      try:
        cmd = roslib.packages.find_node(n.package, n.type)
      except (Exception, roslib.packages.ROSPkgException) as e:
        # multiple nodes, invalid package
        raise StartException(''.join(["Can't find resource: ", str(e)]))
      # handle diferent result types str or array of string
      import types
      if isinstance(cmd, types.StringTypes):
        cmd = [cmd]
      cmd_type = ''
      if cmd is None or len(cmd) == 0:
        raise nm.StartException(' '.join([n.type, 'in package [', n.package, '] not found!\n\nThe package was created?\nIs the binary executable?\n']))
      if len(cmd) > 1:
        # Open selection for executables
        try:
          from PySide import QtGui
          item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', n.type, 'in', n.package]),
                                            'Select an executable',
                                            cmd, 0, False)
          if result:
            #open the selected screen
            cmd_type = item
          else:
            return
        except:
          raise nm.StartException('Multiple executables with same name in package found!')
      else:
        cmd_type = cmd[0]
      # determine the current working path, Default: the package of the node
      cwd = nm.get_ros_home()
      if not (n.cwd is None):
        if n.cwd == 'ROS_HOME':
          cwd = nm.get_ros_home()
        elif n.cwd == 'node':
          cwd = os.path.dirname(cmd_type)
#      else:
#        cwd = LaunchConfig.packageName(os.path.dirname(cmd_type))
      cls._prepareROSMaster(masteruri)
      node_cmd = [nm.RESPAWN_SCRIPT if n.respawn else '', prefix, cmd_type]
      cmd_args = [nm.screen().getSceenCmd(node)]
      cmd_args[len(cmd_args):] = node_cmd
      cmd_args.append(str(n.args))
      cmd_args[len(cmd_args):] = args
      rospy.loginfo("RUN: %s", ' '.join(cmd_args))
      if not masteruri is None:
        new_env=dict(os.environ)
        new_env['ROS_MASTER_URI'] = masteruri
        ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))), cwd=cwd, env=new_env)
      else:
        ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))), cwd=cwd)
      # wait for process to avoid 'defunct' processes
      thread = threading.Thread(target=ps.wait)
      thread.setDaemon(True)
      thread.start()
    else:
      # start remote
      if launch_config.PackageName is None:
        raise StartException(''.join(["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 nm.StartException("env_loader in machine tag currently not supported")
      if env:
        env_command = "env "+' '.join(["%s=%s"%(k,v) for (k, v) in env])
      
      startcmd = [env_command, nm.STARTER_SCRIPT, 
                  '--package', str(n.package),
                  '--node_type', str(n.type),
                  '--node_name', str(node),
                  '--node_respawn true' if n.respawn else '']
      if not masteruri is None:
        startcmd.append('--masteruri')
        startcmd.append(masteruri)
      if prefix:
        startcmd[len(startcmd):] = ['--prefix', prefix]
      
      #rename the absolute paths in the args of the node
      node_args = []
      for a in n.args.split():
        a_value, is_abs_path, found, package = cls._resolve_abs_paths(a, host)
        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, str(' '.join(startcmd)))
      (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)

      if ok:
        stdin.close()
  #      stderr.close()
  #      stdout.close()
        error = stderr.read()
        if error:
          rospy.logwarn("ERROR while start '%s': %s", node, error)
          raise nm.StartException(str(''.join(['The host "', host, '" reports:\n', error])))
        output = stdout.read()
        if output:
          rospy.loginfo("STDOUT while start '%s': %s", node, output)
      # inform about absolute paths in parameter value
      if len(abs_paths) > 0:
        rospy.loginfo("Absolute paths found while start:\n%s", str('\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 nm.StartException(str('\n'.join(['Some absolute paths are not renamed because following packages are not found on remote host:', packages])))
Example #51
0
    def runNodeWithoutConfig(cls,
                             host,
                             package,
                             binary,
                             name,
                             args=[],
                             masteruri=None,
                             auto_pw_request=False,
                             user=None,
                             pw=None):
        '''
    Start a node with using a launch configuration.
    @param host: the host or ip to run the node
    @type host: C{str} 
    @param package: the ROS package containing the binary
    @type package: C{str} 
    @param binary: the binary of the node to execute
    @type binary: C{str} 
    @param name: the ROS name of the node (with name space)
    @type name: C{str} 
    @param args: the list with arguments passed to the binary
    @type args: C{[str, ...]} 
    @param auto_pw_request: opens question dialog directly, use True only if the method is called from the main GUI thread
    @type auto_pw_request: bool
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        namespace = ''
        for a in args:
            if a.startswith('__ns:='):
                namespace = a.replace('__ns:=', '')
                fullname = roslib.names.ns_join(namespace, name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host):
            try:
                cmd = roslib.packages.find_node(package, binary)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(str(e))
            # handle different result types str or array of string
#      import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException(' '.join(
                    [binary, 'in package [', package, '] not found!']))
            if len(cmd) > 1:
                # Open selection for executables
                #        try:
                #          from python_qt_binding import QtGui
                #          item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', type, 'in', package]),
                #                                            'Select an executable',
                #                                            cmd, 0, False)
                #          if result:
                #            #open the selected screen
                #            cmd_type = item
                #          else:
                #            return
                #        except:
                err = [
                    ''.join([
                        'Multiple executables with same name in package [',
                        package, ']  found:'
                    ])
                ]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = str(' '.join(
                [nm.screen().getSceenCmd(fullname), cmd_type,
                 ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            ps = None
            new_env = dict(os.environ)
            if namespace:
                new_env['ROS_NAMESPACE'] = namespace
            if not masteruri is None:
                cls._prepareROSMaster(masteruri)
                new_env['ROS_MASTER_URI'] = masteruri
            SupervisedPopen(shlex.split(cmd_str),
                            env=new_env,
                            id="Run without config",
                            description="Run without config [%s]%s" %
                            (str(package), str(binary)))
        else:
            # run on a remote machine
            startcmd = [
                nm.settings().start_remote_script, '--package',
                str(package), '--node_type',
                str(binary), '--node_name',
                str(fullname)
            ]
            startcmd[len(startcmd):] = args2
            if not masteruri is None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host,
                                                          startcmd,
                                                          user,
                                                          pw,
                                                          auto_pw_request,
                                                          close_stdin=True)
                if ok:
                    output = stdout.read()
                    error = stderr.read()
                    stdout.close()
                    stderr.close()
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))

    #          from python_qt_binding import QtGui
    #          QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
    #                                      str(''.join(['The host "', host, '" reports:\n', error])),
    #                                      QtGui.QMessageBox.Ok)
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name,
                                       output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(
                    e, cls.runNodeWithoutConfig,
                    (host, package, binary, name, args, masteruri,
                     auto_pw_request))
Example #52
0
    def runNodeWithoutConfig(cls,
                             host,
                             package,
                             type,
                             name,
                             args=[],
                             masteruri=None,
                             auto_pw_request=True,
                             user=None,
                             pw=None):
        '''
    Start a node with using a launch configuration.
    @param host: the host or ip to run the node
    @type host: C{str} 
    @param package: the ROS package containing the binary
    @type package: C{str} 
    @param type: the binary of the node to execute
    @type type: C{str} 
    @param name: the ROS name of the node (with name space)
    @type name: C{str} 
    @param args: the list with arguments passed to the binary
    @type args: C{[str, ...]} 
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        for a in args:
            if a.startswith('__ns:='):
                fullname = roslib.names.ns_join(a.replace('__ns:=', ''), name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host):
            try:
                cmd = roslib.packages.find_node(package, type)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(str(e))
            # handle different result types str or array of string
            import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException(' '.join(
                    [type, 'in package [', package, '] not found!']))
            if len(cmd) > 1:
                # Open selection for executables
                #        try:
                #          from PySide import QtGui
                #          item, result = QtGui.QInputDialog.getItem(None, ' '.join(['Multiple executables', type, 'in', package]),
                #                                            'Select an executable',
                #                                            cmd, 0, False)
                #          if result:
                #            #open the selected screen
                #            cmd_type = item
                #          else:
                #            return
                #        except:
                err = [
                    ''.join([
                        'Multiple executables with same name in package [',
                        package, ']  found:'
                    ])
                ]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = str(' '.join(
                [nm.screen().getSceenCmd(fullname), cmd_type,
                 ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            ps = None
            if not masteruri is None:
                cls._prepareROSMaster(masteruri)
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ps = subprocess.Popen(shlex.split(cmd_str), env=new_env)
            else:
                ps = subprocess.Popen(shlex.split(cmd_str))
            # wait for process to avoid 'defunct' processes
            thread = threading.Thread(target=ps.wait)
            thread.setDaemon(True)
            thread.start()
        else:
            # run on a remote machine
            startcmd = [
                nm.STARTER_SCRIPT, '--package',
                str(package), '--node_type',
                str(type), '--node_name',
                str(fullname)
            ]
            startcmd[len(startcmd):] = args2
            if not masteruri is None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                output, error, ok = nm.ssh().ssh_exec(host, startcmd, user, pw,
                                                      auto_pw_request)
                if ok:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))

    #          from PySide import QtGui
    #          QtGui.QMessageBox.warning(None, 'Error while remote start %s'%str(name),
    #                                      str(''.join(['The host "', host, '" reports:\n', error])),
    #                                      QtGui.QMessageBox.Ok)
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name,
                                       output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name,
                                      error)
                        raise StartException(''.join(
                            ['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(
                    e, cls.runNodeWithoutConfig,
                    (host, package, type, name, args, masteruri,
                     auto_pw_request))
Example #53
0
    def runNode(cls,
                node,
                launch_config,
                force2host=None,
                masteruri=None,
                auto_pw_request=False,
                user=None,
                pw=None,
                item=None):
        '''
    Start the node with given name from the given configuration.
    @param node: the name of the node (with name space)
    @type node: C{str}
    @param launch_config: the configuration containing the node
    @type launch_config: L{LaunchConfig} 
    @param force2host: start the node on given host.
    @type force2host: L{str} 
    @param masteruri: force the masteruri.
    @type masteruri: L{str} 
    @param auto_pw_request: opens question dialog directly, use True only if the method is called from the main GUI thread
    @type auto_pw_request: bool
    @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 = launch_config.getNode(node)
        if n is None:
            raise StartException(''.join(["Node '", node, "' not found!"]))

        env = list(n.env_args)
        if n.respawn:
            # set the respawn environment variables
            respawn_params = cls._get_respawn_params(
                rospy.names.ns_join(n.namespace, n.name),
                launch_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 not n.launch_prefix is None else ''
        if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1:
            rospy.loginfo("SCREEN prefix removed before start!")
            prefix = ''
        args = [
            ''.join(['__ns:=', n.namespace.rstrip(rospy.names.SEP)]),
            ''.join(['__name:=', n.name])
        ]
        if not (n.cwd is None):
            args.append(''.join(['__cwd:=', n.cwd]))

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

        # get host of the node
        host = launch_config.hostname
        env_loader = ''
        if n.machine_name:
            machine = launch_config.Roscfg.machines[n.machine_name]
            if not machine.address in ['localhost', '127.0.0.1']:
                host = machine.address
                if masteruri is None:
                    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 not force2host is None:
            host = force2host

        # set the ROS_MASTER_URI
        if masteruri is None:
            masteruri = masteruri_from_ros()
            env.append(('ROS_MASTER_URI', masteruri))

        abs_paths = list()  # tuples of (parameter name, old value, new value)
        not_found_packages = list()  # package names
        # set the global parameter
        if not masteruri is None and not masteruri in launch_config.global_param_done:
            global_node_names = cls.getGlobalParams(launch_config.Roscfg)
            rospy.loginfo(
                "Register global parameter:\n  %s", '\n  '.join(
                    "%s%s" % (str(v)[:80], '...' if len(str(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(
                    masteruri, global_node_names, [], user, pw,
                    auto_pw_request)
            launch_config.global_param_done.append(masteruri)

        # add params
        if not masteruri is None:
            nodens = ''.join([n.namespace, n.name, rospy.names.SEP])
            params = dict()
            for param, value in launch_config.Roscfg.params.items():
                if param.startswith(nodens):
                    params[param] = value
            clear_params = []
            for cparam in launch_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" % (str(v)[:80], '...' if len(str(v)) > 80 else '')
                    for v in params.values()))
            abs_paths[len(abs_paths):], not_found_packages[
                len(not_found_packages):] = cls._load_parameters(
                    masteruri, params, clear_params, user, pw, auto_pw_request)
        #'print "RUN prepared", node, time.time()

        if nm.is_local(host):
            nm.screen().testScreen()
            if item:
                cmd_type = item
            else:
                try:
                    cmd = roslib.packages.find_node(n.package, n.type)
                except (Exception, roslib.packages.ROSPkgException) as e:
                    # multiple nodes, invalid package
                    raise StartException(''.join(
                        ["Can't find resource: ",
                         str(e)]))
                # 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(' '.join([
                        n.type, 'in package [', n.package,
                        '] not found!\n\nThe package was created?\nIs the binary executable?\n'
                    ]))
                if len(cmd) > 1:
                    if auto_pw_request:
                        # Open selection for executables, only if the method is called from the main GUI thread
                        try:
                            from python_qt_binding import QtGui
                            item, result = QtGui.QInputDialog.getItem(
                                None, ' '.join([
                                    'Multiple executables', n.type, 'in',
                                    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,
                            (node, launch_config, force2host, masteruri,
                             auto_pw_request, user, pw))
                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(masteruri)
            node_cmd = [
                nm.settings().respawn_script if n.respawn else '', prefix,
                cmd_type
            ]
            cmd_args = [nm.screen().getSceenCmd(node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(str(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'] = masteruri
            # add the namespace environment parameter to handle some cases, e.g. rqt_cpp plugins
            if n.namespace:
                new_env['ROS_NAMESPACE'] = n.namespace
            for k, v in env:
                new_env[k] = v
            SupervisedPopen(shlex.split(str(' '.join(cmd_args))),
                            cwd=cwd,
                            env=new_env,
                            id="Run node",
                            description="Run node [%s]%s" %
                            (str(n.package), str(n.type)))
        else:
            #'print "RUN REMOTE", node, time.time()
            # start remote
            if launch_config.PackageName is None:
                raise StartException(''.join(
                    ["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, user, pw, 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, (node, launch_config, force2host,
                                         masteruri, auto_pw_request))

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

            #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, user, pw, 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,
                              str(' '.join(startcmd)))
                #'print "RUN CALL", node, time.time()
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host,
                                                          startcmd,
                                                          user,
                                                          pw,
                                                          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, (node, launch_config, force2host,
                                     masteruri, auto_pw_request))

            if ok:
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", node, error)
                    raise StartException(
                        str(''.join(
                            ['The host "', host, '" reports:\n', error])))
                if output:
                    rospy.loginfo("STDOUT while start '%s': %s", node, output)
            # inform about absolute paths in parameter value
            if len(abs_paths) > 0:
                rospy.loginfo(
                    "Absolute paths found while start:\n%s",
                    str('\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(
                    str('\n'.join([
                        'Some absolute paths are not renamed because following packages are not found on remote host:',
                        packages
                    ])))
Example #54
0
 def _on_request_interact(self, ident, descr, req):
     '''
     If the interaction of the user is needed a message dialog must be exceuted
     in the main Qt thread. The requests are done by different request exceptinos.
     These are handled by this method.
     '''
     if isinstance(req.request, nm.AuthenticationRequest):
         res, user, pw = nm.ssh()._requestPW(req.request.user,
                                             req.request.host)
         if not res:
             self._on_progress_canceled()
             return
         if req.args and isinstance(req.args[0], nm.AdvRunCfg):
             req.args[0].user = user
             req.args[0].pw = pw
         else:
             req.args = req.args + (user, pw)
         pt = ProgressThread(ident, descr, req.method, (req.args))
         pt.finished_signal.connect(self._progress_thread_finished)
         pt.error_signal.connect(self._progress_thread_error)
         pt.request_interact_signal.connect(self._on_request_interact)
         pt.start()
     elif isinstance(req.request, nm.ScreenSelectionRequest):
         from node_manager_fkie.select_dialog import SelectDialog
         items, _ = SelectDialog.getValue('Show screen', '',
                                          req.request.choices.keys(), False)
         if not items:
             self._progress_thread_finished(ident)
             return
         res = [req.request.choices[i] for i in items]
         pt = ProgressThread(ident, descr, req.method, (req.args + (res, )))
         pt.finished_signal.connect(self._progress_thread_finished)
         pt.error_signal.connect(self._progress_thread_error)
         pt.request_interact_signal.connect(self._on_request_interact)
         pt.start()
     elif isinstance(req.request, nm.BinarySelectionRequest):
         from node_manager_fkie.select_dialog import SelectDialog
         items, _ = SelectDialog.getValue('Multiple executables', '',
                                          req.request.choices, True)
         if not items:
             self._progress_thread_finished(ident)
             return
         res = items[0]
         if req.args and isinstance(req.args[0], nm.AdvRunCfg):
             req.args[0].executable = res
         else:
             req.args = req.args + (res, )
         pt = ProgressThread(ident, descr, req.method, (req.args))
         pt.finished_signal.connect(self._progress_thread_finished)
         pt.error_signal.connect(self._progress_thread_error)
         pt.request_interact_signal.connect(self._on_request_interact)
         pt.start()
     elif isinstance(req.request, nm.LaunchArgsSelectionRequest):
         from node_manager_fkie.parameter_dialog import ParameterDialog
         input_dia = ParameterDialog(req.request.args_dict)
         input_dia.setFilterVisible(False)
         input_dia.setWindowTitle('Enter the argv for %s' %
                                  req.request.launchfile)
         if input_dia.exec_():
             params = input_dia.getKeywords()
             argv = []
             for prm, val in params.items():
                 if val:
                     argv.append('%s:=%s' % (prm, val))
             res = argv
             pt = ProgressThread(ident, descr, req.method,
                                 (req.args + (argv, )))
             pt.finished_signal.connect(self._progress_thread_finished)
             pt.error_signal.connect(self._progress_thread_error)
             pt.request_interact_signal.connect(self._on_request_interact)
             pt.start()
         else:
             self._progress_thread_finished(ident)
             return
Example #55
0
    def runNode(cls,
                node,
                launch_config,
                force2host=None,
                masteruri=None,
                auto_pw_request=False,
                user=None,
                pw=None):
        '''
    Start the node with given name from the given configuration.
    @param node: the name of the node (with name space)
    @type node: C{str}
    @param launch_config: the configuration containing the node
    @type launch_config: L{LaunchConfig} 
    @param force2host: start the node on given host.
    @type force2host: L{str} 
    @param masteruri: force the masteruri.
    @type masteruri: L{str} 
    @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 = launch_config.getNode(node)
        if n is None:
            raise StartException(''.join(["Node '", node, "' not found!"]))

        env = list(n.env_args)
        prefix = n.launch_prefix if not n.launch_prefix is None else ''
        if prefix.lower() == 'screen' or prefix.lower().find('screen ') != -1:
            rospy.loginfo("SCREEN prefix removed before start!")
            prefix = ''
        args = [
            ''.join(['__ns:=', n.namespace]), ''.join(['__name:=', n.name])
        ]
        if not (n.cwd is None):
            args.append(''.join(['__cwd:=', n.cwd]))

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

        # get host of the node
        host = launch_config.hostname
        env_loader = ''
        if n.machine_name:
            machine = launch_config.Roscfg.machines[n.machine_name]
            host = machine.address
            #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 not force2host is None:
            host = force2host

        if masteruri is None:
            masteruri = nm.nameres().masteruri(n.machine_name)
        # set the ROS_MASTER_URI
        if masteruri is None:
            masteruri = nm.masteruri_from_ros()
            env.append(('ROS_MASTER_URI', masteruri))

        abs_paths = list()  # tuples of (parameter name, old value, new value)
        not_found_packages = list()  # package names
        # set the global parameter
        if not masteruri is None and not masteruri in launch_config.global_param_done:
            global_node_names = cls.getGlobalParams(launch_config.Roscfg)
            rospy.loginfo("Register global parameter:\n%s",
                          '\n'.join(global_node_names))
            abs_paths[len(abs_paths):], not_found_packages[
                len(not_found_packages):] = cls._load_parameters(
                    masteruri, global_node_names, [])
            launch_config.global_param_done.append(masteruri)

        # add params
        if not masteruri is None:
            nodens = ''.join([n.namespace, n.name, '/'])
            params = dict()
            for param, value in launch_config.Roscfg.params.items():
                if param.startswith(nodens):
                    params[param] = value
            clear_params = []
            for cparam in launch_config.Roscfg.clear_params:
                if cparam.startswith(nodens):
                    clear_params.append(param)
            rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
            abs_paths[len(abs_paths):], not_found_packages[
                len(not_found_packages):] = cls._load_parameters(
                    masteruri, params, clear_params)
        #'print "RUN prepared", node, time.time()

        if nm.is_local(host):
            nm.screen().testScreen()
            try:
                cmd = roslib.packages.find_node(n.package, n.type)
            except (Exception, roslib.packages.ROSPkgException) as e:
                # multiple nodes, invalid package
                raise StartException(''.join(["Can't find resource: ",
                                              str(e)]))
            # handle diferent result types str or array of string
            import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise StartException(' '.join([
                    n.type, 'in package [', n.package,
                    '] not found!\n\nThe package was created?\nIs the binary executable?\n'
                ]))
            if len(cmd) > 1:
                # Open selection for executables
                try:
                    from PySide import QtGui
                    item, result = QtGui.QInputDialog.getItem(
                        None, ' '.join(
                            ['Multiple executables', n.type, 'in', 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:
                cmd_type = cmd[0]
            # determine the current working path, Default: the package of the node
            cwd = nm.get_ros_home()
            if not (n.cwd is None):
                if n.cwd == 'ROS_HOME':
                    cwd = nm.get_ros_home()
                elif n.cwd == 'node':
                    cwd = os.path.dirname(cmd_type)
#      else:
#        cwd = LaunchConfig.packageName(os.path.dirname(cmd_type))
            cls._prepareROSMaster(masteruri)
            node_cmd = [
                nm.RESPAWN_SCRIPT if n.respawn else '', prefix, cmd_type
            ]
            cmd_args = [nm.screen().getSceenCmd(node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(str(n.args))
            cmd_args[len(cmd_args):] = args
            rospy.loginfo("RUN: %s", ' '.join(cmd_args))
            if not masteruri is None:
                new_env = dict(os.environ)
                new_env['ROS_MASTER_URI'] = masteruri
                ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))),
                                      cwd=cwd,
                                      env=new_env)
            else:
                ps = subprocess.Popen(shlex.split(str(' '.join(cmd_args))),
                                      cwd=cwd)
            # wait for process to avoid 'defunct' processes
            thread = threading.Thread(target=ps.wait)
            thread.setDaemon(True)
            thread.start()
        else:
            #'print "RUN REMOTE", node, time.time()
            # start remote
            if launch_config.PackageName is None:
                raise StartException(''.join(
                    ["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:
                env_command = "env " + ' '.join(
                    ["%s=%s" % (k, v) for (k, v) in env])

            startcmd = [
                env_command, nm.STARTER_SCRIPT, '--package',
                str(n.package), '--node_type',
                str(n.type), '--node_name',
                str(node), '--node_respawn true' if n.respawn else ''
            ]
            if not masteruri is None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            if prefix:
                startcmd[len(startcmd):] = ['--prefix', prefix]

            #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)
                    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,
                              str(' '.join(startcmd)))
                #'print "RUN CALL", node, time.time()
                output, error, ok = nm.ssh().ssh_exec(host, startcmd, user, pw,
                                                      auto_pw_request)
                #'print "RUN CALLOK", node, time.time()
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(
                    e, cls.runNode, (node, launch_config, force2host,
                                     masteruri, auto_pw_request))

            if ok:
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", node, error)
                    raise StartException(
                        str(''.join(
                            ['The host "', host, '" reports:\n', error])))
                if output:
                    rospy.loginfo("STDOUT while start '%s': %s", node, output)
            # inform about absolute paths in parameter value
            if len(abs_paths) > 0:
                rospy.loginfo(
                    "Absolute paths found while start:\n%s",
                    str('\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(
                    str('\n'.join([
                        'Some absolute paths are not renamed because following packages are not found on remote host:',
                        packages
                    ])))
    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])))
    def runNodeWithoutConfig(cls, host, package, binary, name, args=[], masteruri=None, auto_pw_request=False, user=None, pw=None):
        '''
        Start a node with using a launch configuration.
        @param host: the host or ip to run the node
        @type host: C{str}
        @param package: the ROS package containing the binary
        @type package: C{str}
        @param binary: the binary of the node to execute
        @type binary: C{str}
        @param name: the ROS name of the node (with name space)
        @type name: C{str}
        @param args: the list with arguments passed to the binary
        @type args: C{[str, ...]}
        @param auto_pw_request: opens question dialog directly, use True only if the method is called from the main GUI thread
        @type auto_pw_request: bool
        @raise Exception: on errors while resolving host
        @see: L{node_manager_fkie.is_local()}
        '''
        # create the name with namespace
        args2 = list(args)
        fullname = roslib.names.ns_join(roslib.names.SEP, name)
        namespace = ''
        for a in args:
            if a.startswith('__ns:='):
                namespace = a.replace('__ns:=', '')
                fullname = roslib.names.ns_join(namespace, name)
        args2.append(''.join(['__name:=', name]))
        # run on local host
        if nm.is_local(host, wait=True):
            try:
                cmd = roslib.packages.find_node(package, binary)
            except roslib.packages.ROSPkgException as e:
                # multiple nodes, invalid package
                raise StartException(utf8(e))
            # handle different result types str or array of string
#      import types
            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!' % (binary, package))
            if len(cmd) > 1:
                # Open selection for executables
                err = [''.join(['Multiple executables with same name in package [', package, ']  found:'])]
                err.extend(cmd)
                raise StartException('\n'.join(err))
            else:
                cmd_type = cmd[0]
            cmd_str = utf8(' '.join([nm.screen().getSceenCmd(fullname), cmd_type, ' '.join(args2)]))
            rospy.loginfo("Run without config: %s", cmd_str)
            new_env = dict(os.environ)
            if namespace:
                new_env['ROS_NAMESPACE'] = namespace
            if masteruri is not None:
                cls._prepareROSMaster(masteruri)
                new_env['ROS_MASTER_URI'] = masteruri
                ros_hostname = NameResolution.get_ros_hostname(masteruri)
                if ros_hostname:
                    new_env['ROS_HOSTNAME'] = ros_hostname
            SupervisedPopen(shlex.split(cmd_str), env=new_env, object_id="Run without config", description="Run without config [%s]%s" % (utf8(package), utf8(binary)))
        else:
            # run on a remote machine
            startcmd = [nm.settings().start_remote_script,
                        '--package', utf8(package),
                        '--node_type', utf8(binary),
                        '--node_name', utf8(fullname)]
            startcmd[len(startcmd):] = args2
            if masteruri is not None:
                startcmd.append('--masteruri')
                startcmd.append(masteruri)
            rospy.loginfo("Run remote on %s: %s", host, ' '.join(startcmd))
            try:
                _, stdout, stderr, ok = nm.ssh().ssh_exec(host, startcmd, user, pw, auto_pw_request, close_stdin=True)
                if ok:
                    output = stdout.read()
                    error = stderr.read()
                    stdout.close()
                    stderr.close()
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name, error)
                        raise StartException(''.join(['The host "', host, '" reports:\n', error]))
                    if output:
                        rospy.logdebug("STDOUT while start '%s': %s", name, output)
                else:
                    if error:
                        rospy.logwarn("ERROR while start '%s': %s", name, error)
                        raise StartException(''.join(['The host "', host, '" reports:\n', error]))
            except nm.AuthenticationRequest as e:
                raise nm.InteractionNeededError(e, cls.runNodeWithoutConfig, (host, package, binary, name, args, masteruri, auto_pw_request))
Example #58
0
 def runNodeWithoutConfig(cls, host, package, type, name, args=[]):
     '''
 Start a node with using a launch configuration.
 @param host: the host or ip to run the node
 @type host: C{str} 
 @param package: the ROS package containing the binary
 @type package: C{str} 
 @param type: the binary of the node to execute
 @type type: C{str} 
 @param name: the ROS name of the node (with name space)
 @type name: C{str} 
 @param args: the list with arguments passed to the binary
 @type args: C{[str, ...]} 
 @raise Exception: on errors while resolving host
 @see: L{node_manager_fkie.is_local()}
 '''
     # create the name with namespace
     fullname = ''.join(['/', name])
     for a in args:
         if a.startswith('__ns:='):
             fullname = ''.join(
                 ['/', a.replace('__ns:=', '').strip('/ '), fullname])
     fullname = fullname.replace('//', '/')
     args2 = list(args)
     args2.append(''.join(['__name:=', name]))
     # run on local host
     if nm.is_local(host):
         try:
             cmd = roslib.packages.find_node(package, type)
         except roslib.packages.ROSPkgException as e:
             # multiple nodes, invalid package
             raise StartException(str(e))
         # handle diferent result types str or array of string
         import types
         if isinstance(cmd, types.StringTypes):
             cmd = [cmd]
         cmd_type = ''
         if cmd is None or len(cmd) == 0:
             raise nm.StartException(' '.join(
                 [type, 'in package [', package, '] not found!']))
         if len(cmd) > 1:
             # Open selection for executables
             try:
                 from PySide import QtGui
                 item, result = QtGui.QInputDialog.getItem(
                     None,
                     ' '.join(['Multiple executables', type, 'in',
                               package]), 'Select an executable', cmd, 0,
                     False)
                 if result:
                     #open the selected screen
                     cmd_type = item
                 else:
                     return
             except:
                 raise nm.StartException(
                     'Multiple executables with same name in package found!'
                 )
         else:
             cmd_type = cmd[0]
         cmd_str = str(' '.join(
             [nm.screen().getSceenCmd(fullname), cmd_type,
              ' '.join(args2)]))
         rospy.loginfo("Run without config: %s", cmd_str)
         subprocess.Popen(shlex.split(cmd_str))
     else:
         # run on a remote machine
         startcmd = [
             nm.STARTER_SCRIPT, '--package',
             str(package), '--node_type',
             str(type), '--node_name',
             str(fullname)
         ]
         startcmd[len(startcmd):] = args2
         rospy.loginfo("Run remote: %s", ' '.join(startcmd))
         (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)
         if ok:
             stdin.close()
             error = stderr.read()
             if error:
                 rospy.logwarn("ERROR while start '%s': %s", name, error)
                 from PySide import QtGui
                 QtGui.QMessageBox.warning(
                     None, 'Error while remote start %s' % str(name),
                     str(''.join(
                         ['The host "', host, '" reports:\n', error])),
                     QtGui.QMessageBox.Ok)
             output = stdout.read()
             if output:
                 rospy.logdebug("STDOUT while start '%s': %s", name, output)
Example #59
0
    def runNode(cls, node, launch_config):
        '''
    Start the node with given name from the given configuration.
    @param node: the name of the node (with name space)
    @type node: C{str}
    @param launch_config: the configuration containing the node
    @type launch_config: L{LaunchConfig} 
    @raise StartException: if the screen is not available on host.
    @raise Exception: on errors while resolving host
    @see: L{node_manager_fkie.is_local()}
    '''
        n = launch_config.getNode(node)
        if n is None:
            raise StartException(''.join(["Node '", node, "' not found!"]))

        env = list(n.env_args)
        prefix = n.launch_prefix if not n.launch_prefix is None else ''
        # thus the parameters while the transfer are not separated
        if prefix:
            prefix = ''.join(['"', prefix, '"'])
        args = [
            ''.join(['__ns:=', n.namespace]), ''.join(['__name:=', n.name])
        ]
        if not (n.cwd is None):
            args.append(''.join(['__cwd:=', n.cwd]))

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

        # get host of the node
        host = launch_config.hostname
        env_loader = ''
        if n.machine_name:
            machine = launch_config.Roscfg.machines[n.machine_name]
            host = machine.address
            #TODO: env-loader support?


#      if hasattr(machine, "env_loader") and machine.env_loader:
#        env_loader = machine.env_loader

        masteruri = nm.nameres().getUri(host=host)
        # set the ROS_MASTER_URI
        if masteruri is None:
            env.append(('ROS_MASTER_URI', nm.masteruri_from_ros()))

        # set the global parameter
        if not masteruri is None and not masteruri in launch_config.global_param_done:
            global_node_names = cls.getGlobalParams(launch_config.Roscfg)
            rospy.loginfo("Register global parameter:\n%s",
                          '\n'.join(global_node_names))
            cls._load_parameters(masteruri, global_node_names, [])
            launch_config.global_param_done.append(masteruri)

        # add params
        if not masteruri is None:
            nodens = ''.join([n.namespace, n.name, '/'])
            params = dict()
            for param, value in launch_config.Roscfg.params.items():
                if param.startswith(nodens):
                    params[param] = value
            clear_params = []
            for cparam in launch_config.Roscfg.clear_params:
                if cparam.startswith(nodens):
                    clear_params.append(param)
            rospy.loginfo("Register parameter:\n%s", '\n'.join(params))
            cls._load_parameters(masteruri, params, clear_params)
        if nm.is_local(host):
            nm.screen().testScreen()
            try:
                cmd = roslib.packages.find_node(n.package, n.type)
            except (Exception, roslib.packages.ROSPkgException) as e:
                # multiple nodes, invalid package
                raise StartException(''.join(["Can't find resource: ",
                                              str(e)]))
            # handle diferent result types str or array of string
            import types
            if isinstance(cmd, types.StringTypes):
                cmd = [cmd]
            cmd_type = ''
            if cmd is None or len(cmd) == 0:
                raise nm.StartException(' '.join([
                    n.type, 'in package [', n.package,
                    '] not found!\n\nThe package was created?\nIs the binary executable?\n'
                ]))
            if len(cmd) > 1:
                # Open selection for executables
                try:
                    from PySide import QtGui
                    item, result = QtGui.QInputDialog.getItem(
                        None, ' '.join(
                            ['Multiple executables', n.type, 'in', n.package]),
                        'Select an executable', cmd, 0, False)
                    if result:
                        #open the selected screen
                        cmd_type = item
                    else:
                        return
                except:
                    raise nm.StartException(
                        'Multiple executables with same name in package found!'
                    )
            else:
                cmd_type = cmd[0]
            node_cmd = [prefix, cmd_type]
            cmd_args = [nm.screen().getSceenCmd(node)]
            cmd_args[len(cmd_args):] = node_cmd
            cmd_args.append(n.args)
            cmd_args[len(cmd_args):] = args
            rospy.loginfo("RUN: %s", ' '.join(cmd_args))
            subprocess.Popen(shlex.split(str(' '.join(cmd_args))))
        else:
            # start remote
            if launch_config.PackageName is None:
                raise StartException(''.join(
                    ["Can't run remote without a valid package name!"]))
            # setup environment
            env_command = ''
            if env_loader:
                rospy.logwarn(
                    "env_loader in machine tag currently not supported")
                raise nm.StartException(
                    "env_loader in machine tag currently not supported")
            if env:
                env_command = "env " + ' '.join(
                    ["%s=%s" % (k, v) for (k, v) in env])

            startcmd = [
                env_command, nm.STARTER_SCRIPT, '--package',
                str(n.package), '--node_type',
                str(n.type), '--node_name',
                str(node)
            ]
            if prefix:
                startcmd[len(startcmd):] = ['--prefix', prefix]

            startcmd[len(startcmd):] = n.args
            startcmd[len(startcmd):] = args
            rospy.loginfo("Run remote: %s", ' '.join(startcmd))
            (stdin, stdout, stderr), ok = nm.ssh().ssh_exec(host, startcmd)

            if ok:
                stdin.close()
                #      stderr.close()
                #      stdout.close()
                error = stderr.read()
                if error:
                    rospy.logwarn("ERROR while start '%s': %s", node, error)
                    raise nm.StartException(
                        str(''.join(
                            ['The host "', host, '" reports:\n', error])))
                output = stdout.read()
                if output:
                    rospy.logdebug("STDOUT while start '%s': %s", node, output)