コード例 #1
0
ファイル: PyroUtil.py プロジェクト: mmp-project/mupif
def runDaemon(host, port, nathost, natport):
    """
    Runs a daemon without geristering to a name server
    :param str(int) host: Host name where daemon runs. This is typically a localhost
    :param int port: Port number where daemon will listen (internal port number)
    :param str(int) nathost: Hostname of the server as reported by nameserver, for secure ssh tunnel it should be set to 'localhost' (external host name)
    :param int natport: Server NAT port, optional (external port)

    :return Instance of the running daemon, None if a problem
    :rtype Pyro4.Daemon
    """
    try:
        daemon = Pyro4.Daemon(host=host, port=port, nathost=nathost, natport=natport)
        log.info('Pyro4 daemon runs on %s:%d using nathost %s:%d' % (host, port, nathost, natport))
    except socket.error as e:
        log.debug('Socket port %s:%d seems to be already in use' % (host,port))
        daemon = None
        raise e

    except Exception:
        log.exception('Can not run Pyro4 daemon on %s:%d using nathost %s:%d' % (host, port, nathost, natport))
        daemon = None
        raise

    return daemon
コード例 #2
0
ファイル: PyroUtil.py プロジェクト: mmp-project/mupif
def sshTunnel(remoteHost, userName, localPort, remotePort, sshClient='ssh', options='', sshHost='', Reverse=False):
    """
    Automatic creation of ssh tunnel, using putty.exe for Windows and ssh for Linux

    :param str remoteHost: IP of remote host
    :param str userName: User name, if empty, current user name is used
    :param int localPort: Local port
    :param int remotePort: Remote port
    :param str sshClient: Path to executable ssh client (on Windows use double backslashes 'C:\\Program Files\\Putty\putty.exe')
    :param str options: Arguments to ssh clinent, e.g. the location of private ssh keys
    :param str sshHost: Computer used for tunelling, optional. If empty, equals to remoteHost
    :param bool Reverse: True if reverse tunnel to be created (default is False)

    :return: Instance of subprocess.Popen running the tunneling command
    :rtype: subprocess.Popen
    :raises Exception: if creation of a tunnel failed
    """

    if sshHost =='':
        sshHost = remoteHost
    if userName =='':
        userName = os.getenv('USER')

    direction = 'L'
    if Reverse == True:
        direction = 'R'

    #use direct system command. Paramiko or sshtunnel do not work.
    #put ssh public key on a server - interaction with a keyboard for password will not work here (password goes through TTY, not stdin)
    if sshClient=='ssh':
        cmd = 'ssh -%s %d:%s:%d %s@%s -N %s' % (direction, localPort, remoteHost, remotePort, userName, sshHost, options)
        log.debug("Creating ssh tunnel via command: " + cmd)
    elif sshClient=='autossh':
        cmd = 'autossh -%s %d:%s:%d %s@%s -N %s' % (direction, localPort, remoteHost, remotePort, userName, sshHost, options)
        log.debug("Creating autossh tunnel via command: " + cmd)
    elif 'putty' in sshClient.lower():
        #need to create a public key *.ppk using puttygen. It can be created by importing Linux private key. The path to that key is given as -i option
        cmd = '%s -%s %d:%s:%d %s@%s -N %s' % (sshClient, direction, localPort, remoteHost, remotePort, userName, sshHost, options)
        log.debug("Creating ssh tunnel via command: " + cmd)
    elif sshClient=='manual':
        #You need ssh server running, e.g. UNIX-sshd or WIN-freesshd
        cmd1 = 'ssh -%s %d:%s:%d %s@%s -N %s' % (direction, localPort, remoteHost, remotePort, userName, sshHost, options)
        cmd2 = 'putty.exe -%s %d:%s:%d %s@%s -N %s' % (direction, localPort, remoteHost, remotePort, userName, sshHost, options)
        log.info("If ssh tunnel does not exist, do it manually using a command e.g. " + cmd1 + " , or " + cmd2)
        return 'manual'
    else:
        log.error("Unknown ssh client, exiting")
        exit(0)
    try:
        tunnel = subprocess.Popen(cmd.split())
    except Exception:
        log.exception("Creation of a tunnel failed. Can not execute the command: %s " % cmd)
        raise

    time.sleep(1.0)

    return tunnel
コード例 #3
0
ファイル: PyroUtil.py プロジェクト: mmp-project/mupif
def allocateApplicationWithJobManager (ns, jobManRec, natPort, sshClient='ssh', options='', sshHost=''):
    """
    Connect to jobManager described by given jobManRec

    :param Pyro4.naming.Nameserver ns: running name server
    :param tuple jobManRec: tuple containing (jobManPort, jobManNatport, jobManHostname, jobManUserName, jobManDNSName), see clientConfig.py
    :param int natPort: nat port in local computer for ssh tunnel for the application
    :param str sshClient: client for ssh tunnel, see :func:`sshTunnel`, default 'ssh'
    :param str options: parameters for ssh tunnel, see :func:`sshTunnel`, default ''
    :param str sshHost: parameters for ssh tunnel, see :func:`sshTunnel`, default ''

    :return: RemoteAppRecord containing application, tunnel to application, tunnel to jobman, jobid
    :rtype: RemoteAppRecord
    :raises Exception: if allocation of job fails
    """
    (jobManPort, jobManNatport, jobManHostname, jobManUserName, jobManName) = jobManRec
    log.debug('Trying to connect to JobManager')
    (jobMan, tunnelJobMan) = connectJobManager (ns, jobManRec, sshClient, options, sshHost)

    if jobMan is None:
       e = OSError("Can not connect to JobManager")
       log.exception(e)
       raise e
    else:
       log.debug('Connected to JobManager %s using tunnel %s' % (jobMan, tunnelJobMan))

    if tunnelJobMan is None:
       e = OSError("Can not create a ssh tunnel to JobManager")
       log.exception(e)
       raise

    try:
        retRec = jobMan.allocateJob(getUserInfo(), natPort=natPort)
        log.info('Allocated job, returned record from jobMan:' +  str(retRec))
    except Exception:
        log.exception("JobManager allocateJob() failed")
        raise

    #create tunnel to application's daemon running on (remote) server
    try:
        tunnelApp = sshTunnel(remoteHost=jobManHostname, userName=jobManUserName, localPort=natPort, remotePort=retRec[2], sshClient=sshClient, options=options, sshHost=sshHost)
    except Exception:
        log.exception("Creating ssh tunnel for application's daemon failed")
        raise
    else:
        log.info("Scenario: Connecting to " + retRec[1] + " " + str(retRec[2]))

    #time.sleep(1)
    # connect to (remote) application, requests remote proxy
    app = connectApp(ns, retRec[1])
    if app==None:
        tunnelApp.terminate()
    return RemoteAppRecord.RemoteAppRecord(app, tunnelApp, jobMan, tunnelJobMan, retRec[1])
コード例 #4
0
ファイル: PyroUtil.py プロジェクト: mmp-project/mupif
def allocateNextApplication (ns, jobManRec, natPort, appRec, sshClient='ssh', options='', sshHost=''):
    """
    Allocate next application instance on a running Job Manager and adds it into
    existing applicationRecord.

    :param Pyro4.naming.Nameserver ns: running name server
    :param tuple jobManRec: tuple containing (jobManPort, jobManNatport, jobManHostname, jobManUserName, jobManDNSName), see clientConfig.py
    :param int natPort: nat port in local computer for ssh tunnel for the application
    :param RemoteAppRecord appRec: existing RemoteAppRecord where a new application will be added
    :param str sshClient: client for ssh tunnel, see :func:`sshTunnel`, default 'ssh'
    :param str options: parameters for ssh tunnel, see :func:`sshTunnel`, default ''
    :param str sshHost: parameters for ssh tunnel, see :func:`sshTunnel`, default ''

    :return: None
    :raises Exception: if allocation of job fails
    :raises Exception: if ssh tunnel to application instance can not be created
    """
    (jobManPort, jobManNatport, jobManHostname, jobManUserName, jobManName) = jobManRec
    jobMan = connectApp(ns, jobManName)

    try:
        retRec = jobMan.allocateJob(getUserInfo(), natPort=natPort)
        log.info('Allocated job, returned record from jobMan:' +  str(retRec))
    except Exception:
        log.exception("jobMan.allocateJob() failed")
        raise

    #create tunnel to application's daemon running on (remote) server
    try:
        tunnelApp = sshTunnel(remoteHost=jobManHostname, userName=jobManUserName, localPort=natPort, remotePort=retRec[2], sshClient=sshClient, options=options, sshHost=sshHost)
    except Exception:
        log.exception("Creating ssh tunnel for application's daemon failed")
        raise
    else:
        log.info("Scenario: Connecting to " + retRec[1] + " " + str(retRec[2]))

    app = connectApp(ns, retRec[1])
    if app==None:
        tunnelApp.terminate()
    appRec.appendNextApplication(app,tunnelApp,retRec[1])
コード例 #5
0
ファイル: PyroUtil.py プロジェクト: mmp-project/mupif
def runAppServer(server, port, nathost, natport, nshost, nsport, nsname, hkey, app, daemon=None):
    """
    Runs a simple application server

    :param str server: Host name of the server (internal host name)
    :param int port: Port number on the server where daemon will listen (internal port number)
    :param str nathost: Hostname of the server as reported by nameserver, for secure ssh tunnel it should be set to 'localhost' (external host name)
    :param int natport: Server NAT port as reported by nameserver (external port)
    :param str nshost: Hostname of the computer running nameserver
    :param int nsport: Nameserver port
    :param str nsname: Name of registered application
    :param str hkey: A password string
    :param instance app: Application instance
    :param daemon: Reference to already running daemon, if available. Optional parameter.

    :raises Exception: if can not run Pyro4 daemon
    """
    externalDaemon = False
    if not daemon:
        try:
            daemon = Pyro4.Daemon(host=server, port=port, nathost=nathost, natport=natport)
            log.info('Pyro4 daemon runs on %s:%d using nathost %s:%d and hkey %s' % (server, port, nathost, natport, hkey))
        except Exception:
            log.exception('Can not run Pyro4 daemon on %s:%d using nathost %s:%d  and hmac %s' % (server, port, nathost, natport, hkey))
            raise
            exit(1)
    else:
        externalDaemon = True

    ns = connectNameServer(nshost, nsport, hkey)
    #register agent
    uri = daemon.register(app)
    ns.register(nsname, uri)
    app.registerPyro(daemon, ns, uri, externalDaemon=externalDaemon)

    log.debug('NameServer %s has registered uri %s' % (nsname, uri) )
    log.debug('Running runAppServer: server:%s, port:%d, nathost:%s, natport:%d, nameServer:%s, nameServerPort:%d, applicationName:%s, daemon URI %s' % (server, port, nathost, natport, nshost, nsport, nsname, uri) )
    daemon.requestLoop()