コード例 #1
0
ファイル: thread.py プロジェクト: RemoteConnectionManager/RCM
    def run(self):
        try:
            logic_logger.debug('Thread ' + str(self.threadnum) + ' is started')

            if self.gui_cmd:
                self.gui_cmd(active=True)

            if self.configFile:
                commandlist = self.service_command.split()
                commandlist.append(self.configFile)
                self.service_process = subprocess.Popen(
                    commandlist,
                    bufsize=1,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    stdin=subprocess.PIPE,
                    shell=False,
                    universal_newlines=True)
                self.service_process.wait()
            else:
                if self.tunnelling_method == 'internal':
                    self.execute_service_command_with_internal_ssh_tunnel()
                elif self.tunnelling_method == 'external':
                    self.execute_service_command_with_external_ssh_tunnel()
                else:
                    logic_logger.error(
                        str(self.tunnelling_method) + 'is not a valid option!')

            self.terminate()

        except Exception as e:
            self.terminate()
            logic_logger.error("Error running service command\n-->" +
                               self.service_command + "<--\n Error:" + str(e) +
                               " ---- " + str(traceback.format_exc()))
コード例 #2
0
ファイル: thread.py プロジェクト: hpcit/RCM
    def run(self):
        logic_logger.debug('Thread ' + str(self.threadnum) + ' is started')

        if self.gui_cmd:
            self.gui_cmd(active=True)

        if self.configFile:
            commandlist = self.vnc_command.split()
            commandlist.append(self.configFile)
            logic_logger.debug('This is thread ' + str(self.threadnum)
                               + ' CONFIGFILE, executing-->' + ' '.join(commandlist) + "<--")
            self.vnc_process = subprocess.Popen(commandlist,
                                                bufsize=1,
                                                stdout=subprocess.PIPE,
                                                stderr=subprocess.PIPE,
                                                stdin=subprocess.PIPE,
                                                shell=False,
                                                universal_newlines=True)
            self.vnc_process.wait()
        else:
            if self.tunnelling_method == 'internal':
                self.execute_vnc_command_with_internal_ssh_tunnel()
            elif self.tunnelling_method == 'external' or self.tunnelling_method == 'via':
                self.execute_vnc_command_with_external_ssh_tunnel()
            else:
                logic_logger.error(str(self.tunnelling_method) + 'is not a valid option!')

        self.vnc_process = None

        if self.gui_cmd:
            self.gui_cmd(active=False)
コード例 #3
0
ファイル: rcm_utils.py プロジェクト: hpcit/RCM
def get_server_command(host, user, passwd=''):
    """
    It call bare ssh server to  check if on login node, the user has defined a variable
    named RCM_SERVER_COMMAND, in tht case the content of that variable overrides the default
    rcm command string used for the remaining part of the server interaction
     """

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    logic_logger.info("getting server command from host " + host +
                      " with user " + user)
    try:
        ssh.connect(host, username=user, password=passwd)
    except Exception as e:
        logic_logger.error("ERROR {0}: ".format(e) +
                           "in ssh.connect to host " + host)
        raise e

    chan = ssh.get_transport().open_session()
    chan.get_pty()
    stdin = chan.makefile('wb')
    stdout = chan.makefile('rb')

    start_string = '_##start##_'
    end_string = '_##end##_'
    evn_variable = '${RCM_SERVER_COMMAND}'
    get_rcm_server_command = 'echo ' + start_string + evn_variable + end_string + '\n'
    chan.invoke_shell()
    chan.sendall(get_rcm_server_command)
    stdin.flush()

    chan.settimeout(20)

    loop = True
    output = ''
    rcm_server_command = ''

    while loop:
        try:
            # python3
            if sys.version_info >= (3, 0):
                line = str(stdout.readline(), 'utf-8')
            # python2
            else:
                line = stdout.readline()
            logic_logger.debug("parsing output line: ->" + line + "<-")

            if end_string in line and start_string in line:
                tmp_command = line.split(end_string)[0].split(start_string)[1]
                if not evn_variable in tmp_command:
                    rcm_server_command = tmp_command
                    loop = False
            output += line
        except socket.timeout:
            logic_logger.warning(
                "WARNING TIMEOUT: unable to grab output of -->" +
                get_rcm_server_command + "< on host:" + host)
            loop = False
    return rcm_server_command
コード例 #4
0
 def kill_session_thread(self):
     try:
         if self.session_threads:
             for thread in self.session_threads:
                 thread.terminate()
         self.session_threads = None
     except Exception:
         logic_logger.error('Failed to kill a session thread still alive')
コード例 #5
0
ファイル: vnc_client.py プロジェクト: hpcit/RCM
 def build(self):
     exe = rcm_utils.which('vncviewer')
     if not exe:
         logic_logger.error(
             "vncviewer not found! Check the PATH environment variable.")
         return
     if sys.platform == 'win32':
         # if the executable path contains spaces, it has to be put inside apexes
         exe = "\"" + exe + "\""
     self.exe = exe
     logic_logger.debug("vncviewer path: " + self.exe)
コード例 #6
0
ファイル: rcm_utils.py プロジェクト: hpcit/RCM
def get_threads_exceptions():
    go = True
    exc = None
    while go:
        try:
            exc = threads_exception_queue.get(block=False)
        except queue.Empty:
            go = False
        else:
            logic_logger.error("one thread raised ->" + exc)
    if exc:
        raise Exception("ERROR: " + exc + " in thread")
コード例 #7
0
    def prex(self, cmd, commandnode=''):
        """
        This is the function that wrap all the remote comman execution, accept the input command
        and return the remote server output that comes after the rcm.serverOutputString separation
        string
        """
        if self.commandnode == '':
            commandnode = self.proxynode
        else:
            commandnode = self.commandnode
            self.commandnode = ''
        fullcommand = self.ssh_remote_exec_command + "@" + commandnode + ' ' + cmd

        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        logic_logger.debug("on " + commandnode + " run-->" +
                           self.config['remote_rcm_server'] + ' ' + cmd + "<")

        try:
            ssh.connect(commandnode,
                        username=self.remoteuser,
                        password=self.passwd,
                        timeout=10)
        except Exception as e:
            logic_logger.warning("ERROR {0}: ".format(e) +
                                 "in ssh.connect to node->" + commandnode +
                                 "< user->" + self.remoteuser + "<")
            return ('')

        self.auth_method = ssh.get_transport().auth_handler.auth_method

        stdin, stdout, stderr = ssh.exec_command(
            self.config['remote_rcm_server'] + ' ' + cmd)
        myout = ''.join(stdout)
        myerr = stderr.readlines()
        if myerr:
            logic_logger.error(myerr)
            raise Exception("Server error: {0}".format(myerr))

        # find where the real server output starts
        index = myout.find(rcm.serverOutputString)
        if index != -1:
            index += len(rcm.serverOutputString)
            myout = myout[index:]
        return myout
コード例 #8
0
    def __init__(self):

        self.set_env()

        if sys.platform.startswith('darwin'):
            exe = "open"
        else:
            exe = rcm_utils.which('vncviewer')
            if not exe:
                logic_logger.error(
                    "vncviewer not found! Check the PATH environment variable."
                )
            if sys.platform == 'win32':
                # if the executable path contains spaces, it has to be put inside apexes
                exe = "\"" + exe + "\""
            # self.exe = exe
            logic_logger.debug("vncviewer path: " + exe)

        super(TurboVNCExecutable, self).__init__(exe)
コード例 #9
0
    def __init__(self):

        self.set_env()

        # ssh executable
        if sys.platform == 'win32':
            exe = rcm_utils.which('PLINK')
        else:
            exe = rcm_utils.which('ssh')
        if not exe:
            if sys.platform == 'win32':
                logic_logger.error(
                    "plink.exe not found! Check the PATH environment variable."
                )
            else:
                logic_logger.error("ssh not found!")
            return
        if sys.platform == 'win32':
            # if the executable path contains spaces, it has to be put inside apexes
            exe = "\"" + exe + "\""

        super(SSHExecutable, self).__init__(exe)
コード例 #10
0
    def __init__(self, pack_info=None):
        self.proxynode = ''
        self.remoteuser = ''
        self.passwd = ''
        self.auth_method = ''

        self.session_thread = []
        self.commandnode = ''

        # here we instatiate the remote procedure call stub, it will automatically
        # have all the methods of rcm_protoclo_server.rcm_protocol class
        # --- TO BE DONE --- handle automatically output type
        self.protocol = rcm_protocol_client.get_protocol()

        def mycall(command):
            return self.prex(command)

        self.protocol.mycall = mycall

        if not pack_info:
            self.pack_info = rcm_utils.pack_info()
        else:
            self.pack_info = pack_info

        self.config = dict()
        self.config['ssh'] = dict()
        self.config['ssh']['win32'] = ("PLINK.EXE", " -ssh", "echo yes | ")
        self.config['ssh']['linux2'] = ("ssh", "", "")
        # for python3
        self.config['ssh']['linux'] = ("ssh", "", "")
        self.config['ssh']['darwin'] = ("ssh", "", "")
        self.config['remote_rcm_server'] = json.loads(
            parser.get('Settings', 'preload_command', fallback='""')
        ) + "module load rcm; python $RCM_HOME/bin/server/rcm_new_server.py"

        self.activeConnectionsList = []

        # set the environment
        if getattr(sys, 'frozen', False):
            logic_logger.debug("Running in a bundle")
            # if running in a bundle, we hardcode the path
            # of the built-in vnc viewer and plink (windows only)
            os.environ['JAVA_HOME'] = resource_path('turbovnc')
            os.environ['JDK_HOME'] = os.environ['JAVA_HOME']
            os.environ['JRE_HOME'] = os.path.join(os.environ['JAVA_HOME'],
                                                  'jre')
            os.environ['CLASSPATH'] = os.path.join(os.environ['JAVA_HOME'], 'lib') + \
                os.pathsep + os.path.join(os.environ['JRE_HOME'], 'lib')
            os.environ['PATH'] = os.path.join(
                os.environ['JAVA_HOME'],
                'bin') + os.pathsep + os.environ['PATH']
            logic_logger.debug("JAVA_HOME: " + str(os.environ['JAVA_HOME']))
            logic_logger.debug("JRE_HOME: " + str(os.environ['JRE_HOME']))
            logic_logger.debug("JDK_HOME: " + str(os.environ['JDK_HOME']))
            logic_logger.debug("CLASSPATH: " + str(os.environ['CLASSPATH']))
        logic_logger.debug("PATH: " + str(os.environ['PATH']))

        # ssh executable
        if sys.platform == 'win32':
            sshexe = rcm_utils.which('PLINK')
        else:
            sshexe = rcm_utils.which('ssh')
        if not sshexe:
            if sys.platform == 'win32':
                logic_logger.error(
                    "plink.exe not found! Check the PATH environment variable."
                )
            else:
                logic_logger.error("ssh not found!")
            sys.exit()
        if sys.platform == 'win32':
            # if the executable path contains spaces, it has to be put inside apexes
            sshexe = "\"" + sshexe + "\""
        self.ssh_command = self.config['ssh'][sys.platform][2] + \
                           sshexe + \
                           self.config['ssh'][sys.platform][1]
        logic_logger.debug("ssh command: " + self.ssh_command)

        self.vnc_cmdline_builder = vnc_client.VNCClientCommandLineBuilder()
        self.vnc_cmdline_builder.build()
コード例 #11
0
    def vncsession(self, session=None, otp='', gui_cmd=None, configFile=None):
        tunnel_command = ''
        vnc_command = ''
        vncpassword_decrypted = ''
        try:
            tunnelling_method = json.loads(parser.get('Settings',
                                                      'ssh_client'))
        except Exception:
            tunnelling_method = "internal"
        logic_logger.info("Using " + str(tunnelling_method) +
                          " ssh tunnelling")

        if session:
            portnumber = 5900 + int(session.hash['display'])
            local_portnumber = rcm_utils.get_unused_portnumber()
            node = session.hash['node']
            nodelogin = session.hash['nodelogin']
            tunnel = session.hash['tunnel']
            vncpassword = session.hash.get('vncpassword', '')

            # Decrypt password
            rcm_cipher = cipher.RCMCipher()
            vncpassword_decrypted = rcm_cipher.decrypt(vncpassword)

            logic_logger.debug("portnumber --> " + str(portnumber) +
                               " node --> " + str(node) + " nodelogin --> " +
                               str(nodelogin) + " tunnel --> " + str(tunnel))

            if sys.platform.startswith('darwin'):
                vnc_command = self.vnc_cmdline_builder.get_executable_path() + " -quality 80 -subsampling 2X" \
                              + " -password " + vncpassword_decrypted
                vnc_command += " -loglevel " + str(rcm_utils.vnc_loglevel)
            elif sys.platform == 'win32':
                vnc_command = "echo " + vncpassword_decrypted + " | " + self.vnc_cmdline_builder.get_executable_path() \
                              + " -autopass -nounixlogin"
                vnc_command += " -logfile " + os.path.join(
                    rcm_utils.log_folder(), 'vncviewer_' + nodelogin + '_' +
                    session.hash.get('sessionid', '') + '.log')
                vnc_command += " -loglevel " + str(rcm_utils.vnc_loglevel)
            else:
                vnc_command = self.vnc_cmdline_builder.get_executable_path() + " -quality 80 " \
                              + " -password " + vncpassword_decrypted

            if sys.platform == 'win32' or sys.platform.startswith('darwin'):
                if tunnel == 'y':
                    tunnel_command = self.ssh_command + " -L 127.0.0.1:" + str(local_portnumber) + ":" + node + ":" \
                                     + str(portnumber) + " " + self.login_options + "@" + nodelogin
                    if sys.platform.startswith('darwin'):
                        tunnel_command += " echo 'rcm_tunnel'; sleep 20"
                    else:
                        tunnel_command += " echo 'rcm_tunnel'; sleep 10"
                    vnc_command += " 127.0.0.1:" + str(local_portnumber)
                else:
                    vnc_command += " " + nodelogin + ":" + str(portnumber)
            else:
                if tunnel == 'y':
                    if tunnelling_method == 'internal':
                        vnc_command += " 127.0.0.1:" + str(local_portnumber)
                    elif tunnelling_method == 'external':
                        tunnel_command = self.ssh_command + " -L 127.0.0.1:" + str(local_portnumber) + ":" + node + ":" \
                                         + str(portnumber) + " " + self.login_options + "@" + nodelogin
                    elif tunnelling_method == 'via':
                        vnc_command += " -via '" + self.login_options + "@" + nodelogin + "' " \
                                       + node + ":" + str(session.hash['display'])
                    else:
                        logic_logger.error(tunnelling_method +
                                           ' is not a valid option')
                        return
                else:
                    vnc_command += ' ' + nodelogin + ":" + session.hash[
                        'display']
        else:
            vnc_command = self.vnc_cmdline_builder.get_executable_path(
            ) + " -config "

        logic_logger.debug("tunnel->" +
                           tunnel_command.replace(self.passwd, "****") +
                           "< vnc->" + vnc_command + "< conffile->" +
                           str(configFile) + "<")

        st = thread.SessionThread(tunnel_command, vnc_command, self.proxynode,
                                  self.remoteuser, self.passwd,
                                  vncpassword_decrypted, otp, gui_cmd,
                                  configFile, self.auth_method,
                                  local_portnumber, node, portnumber,
                                  tunnelling_method)

        logic_logger.debug("session  thread--->" + str(st) +
                           "<--- num thread:" + str(len(self.session_thread)))
        self.session_thread.append(st)
        st.start()
コード例 #12
0
    def prex(self, cmd):
        """
        A wrapper around all the remote command execution;
        accept the input command and
        return the remote server output that comes after
        the rcm.serverOutputString separation string
        """
        if self.commandnode == '':
            host = self.proxynode
        else:
            host = self.commandnode
            self.commandnode = ''

        # build the full command
        if self.preload.strip():
            fullcommand = self.preload.strip()

            # if fullcommand ends with ';' add the preset rcm server command, otherwise use it as is
            if fullcommand[-1] == ';':
                fullcommand += ' ' + self.rcm_server_command
        else:
            fullcommand = self.rcm_server_command

        fullcommand += ' ' + cmd
        logic_logger.info(
            "On " + host +
            " run: <br><span style=\" font-size:5; font-weight:400; color:#101010;\" >"
            + fullcommand + "</span>")

        # ssh full command execution
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(host,
                        username=self.user,
                        password=self.password,
                        timeout=10)
            self.auth_method = ssh.get_transport().auth_handler.auth_method
            stdin, stdout, stderr = ssh.exec_command(fullcommand)
            out = ''.join(stdout)
            err = stderr.readlines()
        except Exception as e:
            ssh.close()
            raise RuntimeError(e)
        finally:
            ssh.close()

        if err:
            logic_logger.warning(err)

        # find where the real server output starts
        index = out.find(rcm.serverOutputString)
        if index != -1:
            index += len(rcm.serverOutputString)
            out = out[index:]
        else:
            logic_logger.error(
                "Missing serverOutputString: {0} in server output".format(
                    rcm.serverOutputString))
            if err:
                raise Exception("Server error: {0}".format(err))

        return out