Ejemplo n.º 1
0
    def __init__(self, host, **kwargs):
        sys.stdout.flush()
        sys.stdin.flush()
        self.tunnel = core.connect(host)
        rport = self.tunnel._rport

        link = (host, rport)

        self.session = core.execute(link, host)

        self.host = host
        self.local_server = 'localhost:%d' % self.tunnel._lport
        self.remote_server = '%s:%d' % (host, self.tunnel._rport)
        self.pid = core.getpid(host)

        password = str(self.tunnel._lport) + str(self.pid)  #create secret code
        servers = [server, server_2, server_3]
        passwords = ['']
        for i in range(len(servers)):
            passwords = check_password(servers, passwords, password)

        sys.stdout.flush()
        sys.stdin.flush()
        print('SSH tunnel from:  %s -> to: %s,' %
              (self.local_server, self.remote_server))
        print('pid %d' % self.pid)
Ejemplo n.º 2
0
    def __init__(self, hostname, **kwargs):

        import sys
        sys.stdout.flush()
        sys.stdin.flush()

        self.tunnel = PC.connect(hostname)
        remport = self.tunnel._rport

        import sys
        sys.stdout.flush()
        sys.stdin.flush()

        self.input = open('/dev/null', 'r')

        import pp
        the_file = pp.__file__
        the_dir = os.path.dirname(the_file)
        the_server = the_dir + '/scripts/ppserver.py'  ## NB!!!

        secret = kwargs.pop('secret', '')

        if not secret:
            command = """
            export PYTHONPATH=%s
            export PATH=%s
            export LD_LIBRARY_PATH=%s        
            export LD_PRELOAD=%s        
            %s -p%d
            """ % (os.environ['PYTHONPATH'], os.environ['PATH'],
                   os.environ['LD_LIBRARY_PATH'],
                   os.environ.get('LD_PRELOAD', ''), the_server, remport)
        else:
            command = """
            export PYTHONPATH=%s
            export PATH=%s
            export LD_LIBRARY_PATH=%s        
            export LD_PRELOAD=%s        
            %s -p%d -s%s 
            """ % (os.environ['PYTHONPATH'], os.environ['PATH'],
                   os.environ['LD_LIBRARY_PATH'],
                   os.environ.get('LD_PRELOAD',
                                  ''), the_server, remport, secret)

        ## execute the command!
        self.session = PC.execute(command,
                                  hostname,
                                  options='-q -T',
                                  stdin=self.input,
                                  bg=True)

        r = self.session.response()
        if self.session._stdout:
            self.session._stdout.flush()

        import time
        time.sleep(0.2)  ## sleep...

        self.hostname = hostname
        self.local_server = 'localhost:%d' % self.tunnel._lport
        self.remote_server = '%s:%d' % (hostname, self.tunnel._rport)

        target = '[P,p]ython[^#]*' + 'ppserver'
        self.pid = PC.getpid(target, hostname)

        sys.stdout.flush()
        sys.stdin.flush()
        logger.debug('SSH tunnel:  %s <--> %s , #PID %d' %
                     (self.local_server, self.remote_server, self.pid))
Ejemplo n.º 3
0
    def __init__(self,
                 remote,
                 environment='',
                 script=None,
                 profile=None,
                 secret=None,
                 timeout=-1,
                 silent=True):

        self.__session = None
        self.__pid = 0

        ## split user@remote
        remote_user, at, remote = remote.rpartition('@')

        import socket
        remote = socket.getfqdn(remote).lower()

        ## ## merge user@remote
        ## if remote_user and at :
        ##     import getpass
        ##     local_user = getpass.getuser()
        ##     if remote_user.lower() != local_user.lower() :
        ##         remote = ''.join ( ( remote_user, at , remote ) )

        remote = ''.join((remote_user, at, remote))

        self.__remote_host = remote

        ## SSH tunnel
        self.__tunnel = PS.Tunnel('SSH-tunnel %s' % self.remote_host)
        self.tunnel.connect(self.remote_host)

        logger.debug('Create SSH tunnel: %s' % self.tunnel)

        self.__local_port = self.tunnel._lport
        self.__remote_port = self.tunnel._rport

        ## SSH session
        self.__session = PS.Pipe('SSH-session', host=self.remote_host)

        logger.debug('Create SSH session: %s' % self.session)

        import logging
        verbose = logging.root.manager.disable <= logging.DEBUG
        self.session.verbose = verbose
        self.tunnel.verbose = verbose
        del logging

        # ==================================================================
        # Get configuration information for the given remote host
        if (not environment) or (not script) or (not profile):
            from ostap.parallel.utils import get_remote_conf
            e, s, p = get_remote_conf(remote)
            if e and not environment: environment = e
            if s and not script: script = s
            if p and not profile: profile = p

        if script:
            if os.path.exists(script) and os.path.isfile(script): pass
            else:
                logger.error("The script %s does not exist, skip it!" % script)
                script = None

        ## temporary directory on remote host
        self.__tmpdir = None
        if environment or script or profile:
            self.session(
                command='mktemp -d -t pathos-$(date +%Y-%b-%d)-XXXXXXXXX')
            self.session.launch()
            r = self.session.response()
            if r and 1 < len(r):
                self.__tmpdir = r[:-1]
                logger.verbose('Created remote temporary directory %s:%s' %
                               (self.remote_host, self.__tmpdir))
            else:
                logger.error('Cannot create remote temporary directory at %s' %
                             self.remote_host)

        self.__environment = None
        if environment:
            import ostap.utils.cleanup as CU
            tmpfile = CU.CleanUp.tempfile(prefix='env-', suffix='.sh')
            with open(tmpfile, 'w') as tf:
                tf.write(environment)
                tf.write('\n')
            copier = PS.Copier('SSH-copier')
            destination = "%s:%s" % (self.__remote_host, self.__tmpdir)
            copier(source=tmpfile, destination=destination)
            copier.launch()
            r = copier.response()
            if r: logger.error('SCP: response from %s : %s' % (copier, r))
            del copier
            self.__environment = os.path.join(self.__tmpdir,
                                              os.path.basename(tmpfile))
            logger.verbose('SCP: environment %s:%s is copied' %
                           (self.remote_host, self.__environment))

        self.__script = None
        if script and os.path.exists(script) and os.path.isfile(script):
            copier = PS.Copier('SSH-copier')
            destination = "%s:%s" % (self.__remote_host, self.__remote_tmpdir)
            copier(source=script, destination=destination)
            copier.launch()
            r = copier.response()
            if r: logger.error('SPC: response from %s : %s' % (copier, r))
            del copier
            self.__script = os.path.join(self.__tmpdir,
                                         os.path.basename(script))
            logger.verbose('SCP: script      %s:%s is copied' %
                           (self.remote_host, self.__script))

        self.__profile = None
        if profile:
            self.session(command='[ -f %s ] && echo "1" || echo "0" ' %
                         profile)
            self.session.launch()
            r = self.session.response()
            try:
                if int(r): self.__profile = profile
            except:
                pass
            if self.__profile:
                logger.verbose("Profile %s:%s is found" %
                               (self.remote_host, profile))
            else:
                logger.warning("Profile %s:%s is NOT found" %
                               (self.remote_host, profile))

        commands = []
        if self.__profile: commands.append(' source %s ' % profile)
        if self.__environment:
            commands.append(' source %s ' % self.__environment)
        if self.__script: commands.append(' source %s ' % self.__script)

        ## pp-server itself:
        if secret and 1 < timeout:
            commands.append('ppserver -p %-7d -s %s -t %d' %
                            (self.remote_port, secret, timeout))
            pattern = '[P,p]ython *.*ppserver *-p *%d *-s *%s *-t *%d' % (
                self.remote_port, secret, timeout)
        elif secret:
            commands.append('ppserver -p %-7d -s %s' %
                            (self.remote_port, secret))
            pattern = '[P,p]ython *.*ppserver *-p *%d *-s *%s' % (
                self.remote_port, secret)
        elif 1 < timeout:
            commands.append('ppserver -p %-7d -t %d' %
                            (self.remote_port, timeout))
            pattern = '[P,p]ython *.*ppserver *-p *%d *-t *%d' % (
                self.remote_port, timeout)
        else:
            commands.append('ppserver -p %-7d' % self.remote_port)
            pattern = '[P,p]ython *.*ppserver *-p *%d' % self.remote_port

        command = ' && '.join(commands)
        self.session(command=command, background=True, options='-f')
        self.session.launch()
        r = self.session.response()
        if r: logger.error('SERVER:response from %s : %s' % (self.session, r))

        for i in range(15):
            try:
                import time
                time.sleep(1)
                self.__pid = PC.getpid(pattern, self.remote_host)
                logger.verbose('PID for remote ppserver is %s:%d' %
                               (self.remote_host, self.__pid))
            except OSError:
                pass
            if self.__pid > 0: break
        else:
            logger.warning('Cannot acquire PID for remote ppserver at %s:%s' %
                           (self.remote_host, self.remote_port))

        sys.stdout.flush()  ## needed?
        sys.stdin.flush()  ## needed ?

        logger.debug("%s" % self)
        logger.verbose(command)

        if not silent:
            logger.info('Tunnel: %6d -> %s:%s pid:%-6d' %
                        (self.local_port, self.remote_host, self.remote_port,
                         self.pid))
Ejemplo n.º 4
0
    def __init__ ( self               ,
                   remote             ,
                   environment = ''   ,
                   script      = None ,
                   profile     = None ,
                   secret      = None ,
                   timeout     =   -1 ,
                   silent      = True ) :

        self.__session = None
        self.__pid     = 0
        self.__active  = False
        self.__silent  = True if silent else False
        
        ## split user@remote
        remote_user , at , remote = remote.rpartition('@')
        
        import socket        
        remote = socket.getfqdn ( remote ).lower()  

        ## ## merge user@remote 
        ## if remote_user and at : 
        ##     import getpass
        ##     local_user = getpass.getuser()
        ##     if remote_user.lower() != local_user.lower() :
        ##         remote = ''.join ( ( remote_user, at , remote ) )
                
        remote = ''.join ( ( remote_user, at , remote ) )

        self.__logger = getLogger('pptunnel:%s' % remote )
        
        self.__remote_host = remote 
        
        ## SSH tunnel 
        self.__tunnel       = PS.Tunnel  ( 'SSH-tunnel %s' %  self.remote_host  )
        self.tunnel.connect ( self.remote_host )

        self.logger.debug ('Create SSH tunnel : %s' %  self.tunnel )
        
        self.__local_port   = self.tunnel._lport 
        self.__remote_port  = self.tunnel._rport 
                                  
        ## SSH session
        self.__session      = PS.Pipe ( 'SSH-session' , host = self.remote_host )  

        self.logger.debug ('Create SSH session: %s' % self.session )
        
        # import logging
        # verbose = logging.root.manager.disable <= logging.DEBUG 
        # self.session.verbose = verbose
        # self.tunnel .verbose = verbose 
        # del logging

        with keepLevel () : 
            # =================================================================
            # Get configuration information for the given remote host
            if ( not environment ) or ( not script ) or ( not profile ) :
                from ostap.parallel.utils import get_remote_conf 
                e , s , p = get_remote_conf ( remote ) 
                if e and not environment : environment = e
                if s and not script      : script      = s
                if p and not profile     : profile     = p
        
        if script :
            if os.path.exists ( script ) and os.path.isfile ( script ) : pass
            else :
                self.logger.error ("The script %s does not exist, skip it!" % script )
                script = None 
                                  
        ## temporary directory on remote host 
        self.__tmpdir = None 
        if environment or script or profile or ( not self.silent ) or True :
            self.logger.verbose( 'Creating remote temporary directory' ) 
            ## self.session  ( command =  'TMPDIR=${TMPDIR} mktemp -d -t $(whoami)-ostap-pathos-$(date +%Y-%b-%d)-XXXXXXXXX' )
            self.session  ( command =  'mktemp -d -t $(whoami)-ostap-pathos-$(date +%Y-%b-%d)-XXXXXXXXX' )
            self.session.launch()
            r = self.session.response()
            if r and 1 < len ( r ) : 
                self.__tmpdir = r [:-1] 
                self.logger.debug   ('Created remote temporary directory %s' % self.__tmpdir ) 
            else :
                self.logger.error   ('Cannot create remote temporary directory' ) 

        self.__environment = None
        if  environment :
            ##
            self.logger.verbose ( "Processing the environment:\n%s" % environment  ) 
            ##
            import ostap.utils.cleanup as CU
            tmpfile = CU.CleanUp.tempfile ( prefix = 'ostap-env-' , suffix = '.sh' )
            with open ( tmpfile , 'w' ) as tf :
                tf.write( environment )
                tf.write('\n')
            copier      = PS.Copier ( 'SSH-copier' )
            destination = "%s:%s" % ( self.__remote_host , self.__tmpdir )
            copier ( source = tmpfile , destination = destination )
            copier.launch()
            r = copier.response()
            if r : self.logger.error ('SCP: response from %s : %s' % ( copier , r ) ) 
            del copier
            self.__environment = os.path.join ( self.__tmpdir , os.path.basename ( tmpfile ) )
            self.logger.debug ('Environment is copied to %s:%s ' % ( self.remote_host , self.environment ) )
            
        self.__script = None 
        if  script and os.path.exists ( script ) and os.path.isfile ( script ) :
            self.logger.verbose  ("Processing the script %s" % scriot )
            with open ( script , 'r' ) as f :
                for line in f :
                    if not line : continue 
                    self.logger.verbose  ( line[:-1] )
            ## 
            copier      = PS.Copier ( 'SSH-copier' )
            destination = "%s:%s" % ( self.__remote_host , self.__remote_tmpdir )
            copier( source = script , destination = destination )
            copier.launch()
            r =  copier.response()
            if r : self.logger.error ('SPC: response from %s : %s' % ( copier , r ) ) 
            del copier
            self.__script = os.path.join ( self.__tmpdir , os.path.basename ( script ) )
            self.logger.debug ('Script      %s is copied to %s:%s' %  ( script , self.remote_host , self.__script ) )
                
        self.__profile = None 
        if profile :
            self.logger.verbose ("Processing the profile %s" % profile )             
            self.session  ( command =  '[ -f %s ] && echo "1" || echo "0" ' %  profile  )
            self.session.launch()
            r = self.session.response()
            try :
                if int ( r ) : self.__profile = profile
            except :
                pass
            if self.__profile :
                self.logger.debug   ("Profile %s:%s is found"     %  ( self.remote_host , profile ) )
                if enabledVerbose() :
                    copier = PS.Copier ( 'SSH-copier' )
                    import ostap.utils.cleanup as CU
                    tmpdir = CU.CleanUp.tempdir ()
                    source = "%s:%s" %  ( self.__remote_host , self.__profile )
                    copier ( source = source , destination = tmpdir )
                    copier.launch()
                    r =  copier.response()
                    if r : self.logger.error ('SPC: response from %s : %s' % ( copier , r ) ) 
                    del copier
                    local_profile = os.path.join ( tmpdir , os.path.basename ( self.__profile ) )
                    with open ( local_profile , 'r' ) as f :
                        for line in f :
                            if not line : continue
                            self.logger.verbose ( line[:-1] )
                else : 
                    self.logger.error ("Profile %s:%s is NOT found" %  ( self.remote_host , profile ) )

        commands = []
        if self.__profile     : commands.append ( ' source %s ' % profile            )
        if self.__environment : commands.append ( ' source %s ' % self.__environment )
        if self.__script      : commands.append ( ' source %s ' % self.__script      )

        
        ## pp-server itself:
        if   secret and 1 < timeout :
            commands.append ( 'ppserver -p %-7d -s %s -t %d'           % ( self.remote_port , secret , timeout ) )
            pattern = '[P,p]ython *.*ppserver *-p *%d *-s *%s *-t *%d' % ( self.remote_port , secret , timeout )
        elif secret :
            commands.append ( 'ppserver -p %-7d -s %s'                 % ( self.remote_port , secret ) ) 
            pattern = '[P,p]ython *.*ppserver *-p *%d *-s *%s'         % ( self.remote_port , secret )
        elif 1 < timeout : 
            commands.append ( 'ppserver -p %-7d -t %d'                 % ( self.remote_port , timeout ) ) 
            pattern = '[P,p]ython *.*ppserver *-p *%d *-t *%d'         % ( self.remote_port , timeout )
        else             : 
            commands.append ( 'ppserver -p %-7d'                       %   self.remote_port  ) 
            pattern = '[P,p]ython *.*ppserver *-p *%d'                 %   self.remote_port 


        pid_file = "%s/ppserver.pid" % self.__tmpdir if self.__tmpdir else None
        if pid_file : 
            commands[-1] +=  " -P %s"  % pid_file 
            pattern      += " *-P %s"  % pid_file 
            
        command = ' && '.join ( commands )
        self.session ( command = command , background = True , options = '-f' ) 
        self.session.launch()
        r = self.session.response()
        if r : self.logger.error ('SERVER:response from %s : %s' % ( self.session , r ) )
        self.logger.debug ( 'Command launched "%s"' %  command )   

        ## try to pickup PID through the PID-file (could be more efficient)
        if pid_file :
            self.logger.verbose ( "Use PID-file %s " % pid_file ) 
            time.sleep ( 0.5 ) 
            for i in range ( 10   ) :
                time.sleep ( 0.25 ) 
                command = 'cat %s' % pid_file 
                self.session.verbose   = False
                self.session ( command = command )
                self.session.launch   ()
                response = self.session.response()
                if not response : continue
                try :
                    pid = int ( response )
                except ValueError :
                    pid = 0                    
                if 0 < pid : 
                    self.__pid = pid
                    break
                
        ## pickup PID via parsing 
        if not self.pid :
            self.logger.verbose ( "Use regex '%s' to locate PID" % pattern )
            time.sleep ( 0.5 ) 
            for i in range ( 20 ) :
                try :
                    time.sleep ( 0.25 )
                    self.__pid = PC.getpid ( pattern , self.remote_host )
                except OSError : pass
                if 0 < self.pid : break

        if not self.pid : 
            self.logger.error ('Cannot acquire PID for remote ppserver at %s:%s' % ( self.remote_host , self.remote_port ) )
        else :
            self.logger.debug ('PID for remote ppserver is %-6d ' % self.pid )
            
        sys.stdout.flush () ## needed? 
        sys.stdin .flush () ## needed ?

        if not self.silent : 
            self.logger.info  ( 'Tunnel: %6d -> %s:%s pid:%-6d' % ( self.local_port , self.remote_host , self.remote_port , self.pid ) )
        else  :
            self.logger.debug ( "Tunnel:%s" % self )


        self.start ()