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()))
Exemple #2
0
    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)
Exemple #3
0
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
Exemple #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')
Exemple #5
0
 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)
Exemple #6
0
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")
Exemple #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
Exemple #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)
Exemple #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)
Exemple #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()
Exemple #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()
Exemple #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