Esempio n. 1
0
    def initialize(self):
        """ initialize the shell connection.  """

        with self.pty_shell.rlock:

            if self.initialized:
                self.logger.warn("initialization race")
                return

            if self.posix:
                # run a POSIX compatible shell, usually /bin/sh, in interactive mode
                # also, turn off tty echo
                command_shell = "exec /bin/sh -i"

                # use custom shell if so requested
                if 'shell' in self.options and self.options['shell']:
                    command_shell = "exec %s" % self.options['shell']
                    self.logger.info("custom  command shell: %s" %
                                     command_shell)

                self.logger.debug("running command shell:         %s" %
                                  command_shell)
                self.pty_shell.write(" stty -echo ; unset HISTFILE ; %s\n" %
                                     command_shell)

                # make sure this worked, and that we find the prompt. We use
                # a versatile prompt pattern to account for the custom shell case.
                _, out = self.find([self.prompt])

                # make sure this worked, and that we find the prompt. We use
                # a versatile prompt pattern to account for the custom shell case.
                try:
                    # set and register new prompt
                    self.run_async(" unset PROMPT_COMMAND ; " +
                                   " unset HISTFILE ; " +
                                   "PS1='PROMPT-$?->'; " + "PS2=''; " +
                                   "export PS1 PS2 2>&1 >/dev/null\n")
                    self.set_prompt(new_prompt="PROMPT-(\d+)->$")

                    self.logger.debug("got new shell prompt")

                except Exception as e:
                    raise se.NoSuccess(
                        "Shell startup on target host failed: %s" % e)

                try:
                    # got a command shell, finally!
                    # for local shells, we now change to the current working
                    # directory.  Remote shells will remain in the default pwd
                    # (usually $HOME).
                    if sumisc.host_is_local(surl.Url(self.url).host):
                        pwd = os.getcwd()
                        self.run_sync(' cd %s' % pwd)
                except Exception as e:
                    # We will ignore any errors.
                    self.logger.warning("local cd to %s failed" % pwd)

            self.pty_shell.flush()
            self.initialized = True
            self.finalized = False
Esempio n. 2
0
    def initialize (self) :
        """ initialize the shell connection.  """

        with self.pty_shell.rlock :

            if  self.initialized :
                self.logger.warn ("initialization race")
                return


            # run a POSIX compatible shell, usually /bin/sh, in interactive mode
            # also, turn off tty echo
            command_shell = "exec /bin/sh -i"

            # use custom shell if so requested
            if  'shell' in self.opts and self.opts['shell'] :
                command_shell = "exec %s" % self.opts['shell']
                self.logger.info ("custom  command shell: %s" % command_shell)


            self.logger.debug    ("running command shell:         %s"   % command_shell)
            self.pty_shell.write (" stty -echo ; unset HISTFILE ; %s\n" % command_shell)

            # make sure this worked, and that we find the prompt. We use
            # a versatile prompt pattern to account for the custom shell case.
            _, out = self.find (["^(.*[\$#%>\]])\s*$"])

            # make sure this worked, and that we find the prompt. We use
            # a versatile prompt pattern to account for the custom shell case.
            try :
                # set and register new prompt
                self.run_async  ( " unset PROMPT_COMMAND ; "
                                + " unset HISTFILE ; "
                                + "PS1='PROMPT-$?->'; "
                                + "PS2=''; "
                                + "export PS1 PS2 2>&1 >/dev/null\n")
                self.set_prompt (new_prompt="PROMPT-(\d+)->$")

                self.logger.debug ("got new shell prompt")

            except Exception as e :
                raise se.NoSuccess ("Shell startup on target host failed: %s" % e)


            try :
                # got a command shell, finally!
                # for local shells, we now change to the current working
                # directory.  Remote shells will remain in the default pwd
                # (usually $HOME).
                if  sumisc.host_is_local (surl.Url(self.url).host) :
                    pwd = os.getcwd ()
                    self.run_sync (' cd %s' % pwd)
            except Exception as e :
                # We will ignore any errors.
                self.logger.warning ("local cd to %s failed" % pwd)
                
                

            self.initialized = True
            self.finalized   = False
Esempio n. 3
0
    def _create_master_entry (self, url, session, logger) :
        # FIXME: cache 'which' results, etc
        # FIXME: check 'which' results

        with self.rlock :
      # if True :

            info = {}

            info['schema']    = url.schema.lower ()
            info['host_str']  = url.host
            info['logger']    = logger
            info['url']       = url
            info['pass']      = ""
            info['key_pass']  = {}

            if  not info['schema'] :
                info['schema'] = 'local'
                    

            # find out what type of shell we have to deal with
            if  info['schema']   in _SCHEMAS_SSH :
                info['type']     = "ssh"
                info['ssh_exe']  = ru.which ("ssh")
                info['scp_exe']  = ru.which ("scp")
                info['sftp_exe'] = ru.which ("sftp")

            elif info['schema']  in _SCHEMAS_GSI :
                info['type']     = "ssh"
                info['ssh_exe']  = ru.which ("gsissh")
                info['scp_exe']  = ru.which ("gsiscp")
                info['sftp_exe'] = ru.which ("gsisftp")

            elif info['schema']  in _SCHEMAS_SH :
                info['type']     = "sh"
                info['sh_args']  = "-i"
                info['sh_env']   = "/usr/bin/env TERM=vt100"
                info['cp_env']   = "/usr/bin/env TERM=vt100"
                info['fs_root']  = "/"

                if  "SHELL" in os.environ :
                    info['sh_exe'] =  ru.which (os.environ["SHELL"])
                    info['cp_exe'] =  ru.which ("cp")
                else :
                    info['sh_exe'] =  ru.which ("sh")
                    info['cp_exe'] =  ru.which ("cp")

            else :
                raise se.BadParameter._log (self.logger, \
                	  "cannot handle schema '%s://'" % url.schema)


            # depending on type, create command line (args, env etc)
            #
            # We always set term=vt100 to avoid ansi-escape sequences in the prompt
            # and elsewhere.  Also, we have to make sure that the shell is an
            # interactive login shell, so that it interprets the users startup
            # files, and reacts on commands.

            try :
                info['latency'] = sumisc.get_host_latency (url)

                # FIXME: note that get_host_latency is considered broken (see
                # saga/utils/misc.py line 73), and will return a constant 250ms.

            except Exception  as e :
                info['latency'] = 1.0  # generic value assuming slow link
                info['logger'].warning ("Could not contact host '%s': %s" % (url, e))
                
            if  info['type'] == "sh" :

                if not sumisc.host_is_local (url.host) :
                    raise se.BadParameter._log (self.logger, \
                            "expect local host for '%s://', not '%s'" % (url.schema, url.host))

                if  'user' in info and info['user'] :
                    pass
                else :
                    info['user'] = getpass.getuser ()

            else :
                info['ssh_env']   =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['scp_env']   =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['sftp_env']  =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['ssh_args']  =  "-t "                       # force pty
                info['scp_args']  =  ""
                info['sftp_args'] =  ""

                if  session :

                    for context in session.contexts :

                        # ssh can also handle UserPass contexts, and ssh type contexts.
                        # gsissh can handle the same, but also X509 contexts.

                        if  context.type.lower () == "ssh" :
                            if  info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI :

                                if  context.attribute_exists ("user_id") and context.user_id :
                                    info['user']  = context.user_id

                                if  context.attribute_exists ("user_key")  and  context.user_key  :
                                    info['ssh_args']  += "-o IdentityFile=%s " % context.user_key 
                                    info['scp_args']  += "-o IdentityFile=%s " % context.user_key 
                                    info['sftp_args'] += "-o IdentityFile=%s " % context.user_key 

                                    if  context.attribute_exists ("user_pass") and context.user_pass :
                                        info['key_pass'][context.user_key] = context.user_pass

                        if  context.type.lower () == "userpass" :
                            if  info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI :
                                if  context.attribute_exists ("user_id") and context.user_id :
                                    info['user']       = context.user_id
                                if  context.attribute_exists ("user_pass") and context.user_pass :
                                    info['pass']       = context.user_pass

                        if  context.type.lower () == "x509" :
                            if  info['schema'] in _SCHEMAS_GSI :

                                if  context.attribute_exists ("user_proxy")  and   context.user_proxy :
                                    info['ssh_env']   += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info['scp_env']   += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info['sftp_env']  += "X509_USER_PROXY='%s' " % context.user_proxy
                       
                                if  context.attribute_exists ("user_cert")   and  context.user_cert :
                                    info['ssh_env']   += "X509_USER_CERT='%s' " % context.user_cert
                                    info['scp_env']   += "X509_USER_CERT='%s' " % context.user_cert
                                    info['sftp_env']  += "X509_USER_CERT='%s' " % context.user_cert
                       
                                if  context.attribute_exists ("user_key")    and  context.user_key :
                                    info['ssh_env']   += "X509_USER_key='%s' "  % context.user_key
                                    info['scp_env']   += "X509_USER_key='%s' "  % context.user_key
                                    info['sftp_env']  += "X509_USER_key='%s' "  % context.user_key
                       
                                if  context.attribute_exists ("cert_repository") and context.cert_repository :
                                    info['ssh_env']   += "X509_CERT_DIR='%s' "  % context.cert_repository
                                    info['scp_env']   += "X509_CERT_DIR='%s' "  % context.cert_repository
                                    info['sftp_env']  += "X509_CERT_DIR='%s' "  % context.cert_repository

                if url.port and url.port != -1 :
                    info['ssh_args']  += "-p %d " % int(url.port)
                    info['scp_args']  += "-p %d " % int(url.port)
                    info['sftp_args'] += "-P %d " % int(url.port)


                # all ssh based shells allow for user_id and user_pass from contexts
                # -- but the data given in the URL take precedence

                if url.username   :  info['user'] = url.username
                if url.password   :  info['pass'] = url.password

                ctrl_user = pwd.getpwuid (os.getuid ()).pw_name
                ctrl_base = "/tmp/saga_ssh_%s" % ctrl_user


                if  'user' in info and info['user'] :
                    info['host_str'] = "%s@%s"  % (info['user'], info['host_str'])
                    info['ctrl'] = "%s_%%h_%%p.%s.%s.ctrl" % (ctrl_base, os.getpid (), info['user'])
                else :
                    info['user'] = getpass.getuser ()
                    info['ctrl'] = "%s_%%h_%%p.%s.ctrl" % (ctrl_base, os.getpid ())

                info['m_flags']  = _SSH_FLAGS_MASTER % ({'ctrl' : info['ctrl']})
                info['s_flags']  = _SSH_FLAGS_SLAVE  % ({'ctrl' : info['ctrl']})
                info['fs_root']  = url

                info['fs_root'].path = "/"


            # keep all collected info in the master dict, and return it for
            # registration
            return info
Esempio n. 4
0
    def _create_master_entry (self, url, session, prompt, logger, posix,
            interactive) :
        # FIXME: cache 'which' results, etc
        # FIXME: check 'which' results

        with self.rlock :


            info = {'posix' : posix}

            # get and evaluate session config
            if  not session :
                session = saga.Session (default=True)

            session_cfg = session.get_config ('saga.utils.pty')
            info['ssh_copy_mode']  = session_cfg['ssh_copy_mode'].get_value ()
            info['ssh_share_mode'] = session_cfg['ssh_share_mode'].get_value ()
            info['ssh_timeout']    = session_cfg['ssh_timeout'].get_value ()

            logger.info ("ssh copy  mode set to '%s'" % info['ssh_copy_mode' ])
            logger.info ("ssh share mode set to '%s'" % info['ssh_share_mode'])
            logger.info ("ssh timeout    set to '%s'" % info['ssh_timeout'])


            # fill the info dict with details for this master channel, and all
            # related future slave channels
            info['schema']    = url.schema.lower ()
            info['host_str']  = url.host
            info['prompt']    = prompt
            info['logger']    = logger
            info['url']       = url
            info['pass']      = ""
            info['key_pass']  = {}
            info['scripts']   = _SCRIPTS

            if  not info['schema'] :
                info['schema'] = 'local'


            # find out what type of shell we have to deal with
            if  info['schema'] in _SCHEMAS_SSH :
                info['shell_type'] = "ssh"
                info['copy_mode']  = info['ssh_copy_mode']
                info['share_mode'] = info['ssh_share_mode']
                info['ssh_exe']    = self._which ("ssh")
                info['scp_exe']    = self._which ("scp")
                info['sftp_exe']   = self._which ("sftp")

            elif info['schema'] in _SCHEMAS_GSI :
                info['shell_type'] = "ssh"
                info['copy_mode']  = info['ssh_copy_mode']
                info['share_mode'] = info['ssh_share_mode']
                info['ssh_exe']    = self._which ("gsissh")
                info['scp_exe']    = self._which ("gsiscp")
                info['sftp_exe']   = self._which ("gsisftp")

            elif info['schema'] in _SCHEMAS_SH :
                info['shell_type'] = "sh"
                info['copy_mode']  = "sh"
                info['share_mode'] = "auto"
                info['sh_env']     = "/usr/bin/env TERM=vt100 PS1='PROMPT-$?->'"
                info['cp_env']     = "/usr/bin/env TERM=vt100 PS1='PROMPT-$?->'"
                info['scp_root']   = "/"

                if interactive: info['sh_args'] = "-i"
                else          : info['sh_args'] = ""

                if  "SHELL" in os.environ :
                    info['sh_exe'] =  self._which (os.environ["SHELL"])
                    info['cp_exe'] =  self._which ("cp")
                else :
                    info['sh_exe'] =  self._which ("sh")
                    info['cp_exe'] =  self._which ("cp")

            else :
                raise se.BadParameter._log (self.logger, \
                          "cannot handle schema '%s://'" % url.schema)


            # If an SSH timeout has been specified set up the ConnectTimeout
            # string
            if info['ssh_timeout']:
                info['ssh_connect_timeout'] = ('-o ConnectTimeout=%s' 
                    % int(float(info['ssh_timeout'])))
            else:
                info['ssh_connect_timeout'] = ''

            # depending on type, create command line (args, env etc)
            #
            # We always set term=vt100 to avoid ansi-escape sequences in the prompt
            # and elsewhere.  Also, we have to make sure that the shell is an
            # interactive login shell, so that it interprets the users startup
            # files, and reacts on commands.

            try :
                info['latency'] = sumisc.get_host_latency (url)

                # FIXME: note that get_host_latency is considered broken (see
                # saga/utils/misc.py line 73), and will return a constant 250ms.

            except Exception  as e :
                info['latency'] = 1.0  # generic value assuming slow link
                info['logger'].warning ("Could not contact host '%s': %s" % (url, e))

            if  info['shell_type'] == "sh" :

                info['sh_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes

                if not sumisc.host_is_local (url.host) :
                    raise se.BadParameter._log (self.logger, \
                            "expect local host for '%s://', not '%s'" % (url.schema, url.host))

                if  'user' in info and info['user'] :
                    pass
                else :
                    info['user'] = getpass.getuser ()

            else :
                info['ssh_env']   =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['scp_env']   =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['sftp_env']  =  "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['ssh_args']  =  "-t "                       # force pty
                info['scp_args']  =  _SCP_FLAGS
                info['sftp_args'] =  _SFTP_FLAGS

                if  session :

                    for context in session.contexts :

                        # ssh can also handle UserPass contexts, and ssh type contexts.
                        # gsissh can handle the same, but also X509 contexts.

                        if  context.type.lower () == "ssh" :
                            if  info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI :

                                if  context.attribute_exists ("user_id") and context.user_id :
                                    info['user']  = context.user_id

                                if  context.attribute_exists ("user_key")  and  context.user_key  :
                                    info['ssh_args']  += "-o IdentityFile=%s " % context.user_key
                                    info['scp_args']  += "-o IdentityFile=%s " % context.user_key
                                    info['sftp_args'] += "-o IdentityFile=%s " % context.user_key

                                    if  context.attribute_exists ("user_pass") and context.user_pass :
                                        info['key_pass'][context.user_key] = context.user_pass

                        if  context.type.lower () == "userpass" :
                            if  info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI :
                                if  context.attribute_exists ("user_id") and context.user_id :
                                    info['user']       = context.user_id
                                if  context.attribute_exists ("user_pass") and context.user_pass :
                                    info['pass']       = context.user_pass

                        if  context.type.lower () == "x509" :
                            if  info['schema'] in _SCHEMAS_GSI :

                                if  context.attribute_exists ("user_proxy")  and   context.user_proxy :
                                    info['ssh_env']   += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info['scp_env']   += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info['sftp_env']  += "X509_USER_PROXY='%s' " % context.user_proxy

                                if  context.attribute_exists ("user_cert")   and  context.user_cert :
                                    info['ssh_env']   += "X509_USER_CERT='%s' " % context.user_cert
                                    info['scp_env']   += "X509_USER_CERT='%s' " % context.user_cert
                                    info['sftp_env']  += "X509_USER_CERT='%s' " % context.user_cert

                                if  context.attribute_exists ("user_key")    and  context.user_key :
                                    info['ssh_env']   += "X509_USER_key='%s' "  % context.user_key
                                    info['scp_env']   += "X509_USER_key='%s' "  % context.user_key
                                    info['sftp_env']  += "X509_USER_key='%s' "  % context.user_key

                                if  context.attribute_exists ("cert_repository") and context.cert_repository :
                                    info['ssh_env']   += "X509_CERT_DIR='%s' "  % context.cert_repository
                                    info['scp_env']   += "X509_CERT_DIR='%s' "  % context.cert_repository
                                    info['sftp_env']  += "X509_CERT_DIR='%s' "  % context.cert_repository

                if url.port and url.port != -1 :
                    info['ssh_args']  += "-p %d " % int(url.port)
                    info['scp_args']  += "-p %d " % int(url.port)
                    info['sftp_args'] += "-P %d " % int(url.port)


                # all ssh based shells allow for user_id and user_pass from contexts
                # -- but the data given in the URL take precedence

                if url.username   :  info['user'] = url.username
                if url.password   :  info['pass'] = url.password

                ctrl_user = pwd.getpwuid (os.getuid ()).pw_name
                ctrl_base = "/tmp/saga_ssh_%s" % ctrl_user


                if  'user' in info and info['user'] :
                    info['host_str'] = "%s@%s"  % (info['user'], info['host_str'])
                    info['ctrl'] = "%s_%%h_%%p.%s.ctrl" % (ctrl_base, info['user'])
                else :
                    info['user'] = getpass.getuser ()
                    info['ctrl'] = "%s_%%h_%%p.ctrl" % (ctrl_base)

                info['m_flags']  = _SSH_FLAGS_MASTER % ({'share_mode' : info['share_mode'],
                                                         'ctrl'       : info['ctrl'],
                                                         'connect_timeout': info['ssh_connect_timeout']})
                info['s_flags']  = _SSH_FLAGS_SLAVE  % ({'share_mode' : info['share_mode'],
                                                         'ctrl'       : info['ctrl'],
                                                         'connect_timeout': info['ssh_connect_timeout']})

                logger.debug('SSH Connection M_FLAGS: %s' % info['m_flags'])
                logger.debug('SSH Connection S_FLAGS: %s' % info['s_flags'])
                
                # we want the userauth and hostname parts of the URL, to get the
                # scp-scope fs root.
                info['scp_root']  = ""
                has_auth          = False
                if  url.username :
                    info['scp_root'] += url.username
                    has_auth          = True
                if  url.password :
                    info['scp_root'] += ":"
                    info['scp_root'] += url.password
                    has_auth          = True
                if  has_auth :
                    info['scp_root'] += "@"
                info['scp_root']     += "%s:" % url.host

                # FIXME: port needs to be handled as parameter
              # if  url.port :
              #     info['scp_root'] += ":%d" % url.port


            # keep all collected info in the master dict, and return it for
            # registration
            return info
Esempio n. 5
0
    def _create_master_entry(self, url, session, prompt, logger, posix,
                             interactive):
        # FIXME: cache 'which' results, etc
        # FIXME: check 'which' results

        with self.rlock:

            info = {'posix': posix}

            # get and evaluate session config
            if not session:
                session = saga.Session(default=True)

            session_cfg = session.get_config('saga.utils.pty')
            info['ssh_copy_mode'] = session_cfg['ssh_copy_mode'].get_value()
            info['ssh_share_mode'] = session_cfg['ssh_share_mode'].get_value()
            info['ssh_timeout'] = session_cfg['ssh_timeout'].get_value()

            logger.info("ssh copy  mode set to '%s'" % info['ssh_copy_mode'])
            logger.info("ssh share mode set to '%s'" % info['ssh_share_mode'])
            logger.info("ssh timeout    set to '%s'" % info['ssh_timeout'])

            # fill the info dict with details for this master channel, and all
            # related future slave channels
            info['schema'] = url.schema.lower()
            info['host_str'] = url.host
            info['prompt'] = prompt
            info['logger'] = logger
            info['url'] = url
            info['pass'] = ""
            info['key_pass'] = {}
            info['scripts'] = _SCRIPTS

            if not info['schema']:
                info['schema'] = 'local'

            # find out what type of shell we have to deal with
            if info['schema'] in _SCHEMAS_SSH:
                info['shell_type'] = "ssh"
                info['copy_mode'] = info['ssh_copy_mode']
                info['share_mode'] = info['ssh_share_mode']
                info['ssh_exe'] = self._which("ssh")
                info['scp_exe'] = self._which("scp")
                info['sftp_exe'] = self._which("sftp")

            elif info['schema'] in _SCHEMAS_GSI:
                info['shell_type'] = "ssh"
                info['copy_mode'] = info['ssh_copy_mode']
                info['share_mode'] = info['ssh_share_mode']
                info['ssh_exe'] = self._which("gsissh")
                info['scp_exe'] = self._which("gsiscp")
                info['sftp_exe'] = self._which("gsisftp")

            elif info['schema'] in _SCHEMAS_SH:
                info['shell_type'] = "sh"
                info['copy_mode'] = "sh"
                info['share_mode'] = "auto"
                info[
                    'sh_env'] = "/usr/bin/env TERM=vt100 PROMPT_COMMAND='' PS1='PROMPT-$?->'"
                info[
                    'cp_env'] = "/usr/bin/env TERM=vt100 PROMPT_COMMAND='' PS1='PROMPT-$?->'"
                info['scp_root'] = "/"

                if interactive: info['sh_args'] = "-i"
                else: info['sh_args'] = ""

                if "SHELL" in os.environ:
                    info['sh_exe'] = self._which(os.environ["SHELL"])
                    info['cp_exe'] = self._which("cp")
                else:
                    info['sh_exe'] = self._which("sh")
                    info['cp_exe'] = self._which("cp")

            else:
                raise se.BadParameter._log (self.logger, \
                          "cannot handle schema '%s://'" % url.schema)

            # If an SSH timeout has been specified set up the ConnectTimeout
            # string
            if info['ssh_timeout']:
                info['ssh_connect_timeout'] = ('-o ConnectTimeout=%s' %
                                               int(float(info['ssh_timeout'])))
            else:
                info['ssh_connect_timeout'] = ''

            # depending on type, create command line (args, env etc)
            #
            # We always set term=vt100 to avoid ansi-escape sequences in the prompt
            # and elsewhere.  Also, we have to make sure that the shell is an
            # interactive login shell, so that it interprets the users startup
            # files, and reacts on commands.

            try:
                info['latency'] = sumisc.get_host_latency(url)

                # FIXME: note that get_host_latency is considered broken (see
                # saga/utils/misc.py line 73), and will return a constant 250ms.

            except Exception as e:
                info['latency'] = 1.0  # generic value assuming slow link
                info['logger'].warning("Could not contact host '%s': %s" %
                                       (url, e))

            if info['shell_type'] == "sh":

                info[
                    'sh_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes

                if not sumisc.host_is_local(url.host):
                    raise se.BadParameter._log (self.logger, \
                            "expect local host for '%s://', not '%s'" % (url.schema, url.host))

                if 'user' in info and info['user']:
                    pass
                else:
                    info['user'] = getpass.getuser()

            else:
                info[
                    'ssh_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info[
                    'scp_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info[
                    'sftp_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['ssh_args'] = "-t "  # force pty
                info['scp_args'] = _SCP_FLAGS
                info['sftp_args'] = _SFTP_FLAGS

                if session:

                    for context in session.contexts:

                        # ssh can also handle UserPass contexts, and ssh type contexts.
                        # gsissh can handle the same, but also X509 contexts.

                        if context.type.lower() == "ssh":
                            if info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI:

                                if context.attribute_exists(
                                        "user_id") and context.user_id:
                                    info['user'] = context.user_id

                                if context.attribute_exists(
                                        "user_key") and context.user_key:
                                    info[
                                        'ssh_args'] += "-o IdentityFile=%s " % context.user_key
                                    info[
                                        'scp_args'] += "-o IdentityFile=%s " % context.user_key
                                    info[
                                        'sftp_args'] += "-o IdentityFile=%s " % context.user_key

                                    if context.attribute_exists(
                                            "user_pass") and context.user_pass:
                                        info['key_pass'][
                                            context.
                                            user_key] = context.user_pass

                        if context.type.lower() == "userpass":
                            if info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI:
                                if context.attribute_exists(
                                        "user_id") and context.user_id:
                                    info['user'] = context.user_id
                                if context.attribute_exists(
                                        "user_pass") and context.user_pass:
                                    info['pass'] = context.user_pass

                        if context.type.lower() == "x509":
                            if info['schema'] in _SCHEMAS_GSI:

                                if context.attribute_exists(
                                        "user_proxy") and context.user_proxy:
                                    info[
                                        'ssh_env'] += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info[
                                        'scp_env'] += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info[
                                        'sftp_env'] += "X509_USER_PROXY='%s' " % context.user_proxy

                                if context.attribute_exists(
                                        "user_cert") and context.user_cert:
                                    info[
                                        'ssh_env'] += "X509_USER_CERT='%s' " % context.user_cert
                                    info[
                                        'scp_env'] += "X509_USER_CERT='%s' " % context.user_cert
                                    info[
                                        'sftp_env'] += "X509_USER_CERT='%s' " % context.user_cert

                                if context.attribute_exists(
                                        "user_key") and context.user_key:
                                    info[
                                        'ssh_env'] += "X509_USER_key='%s' " % context.user_key
                                    info[
                                        'scp_env'] += "X509_USER_key='%s' " % context.user_key
                                    info[
                                        'sftp_env'] += "X509_USER_key='%s' " % context.user_key

                                if context.attribute_exists(
                                        "cert_repository"
                                ) and context.cert_repository:
                                    info[
                                        'ssh_env'] += "X509_CERT_DIR='%s' " % context.cert_repository
                                    info[
                                        'scp_env'] += "X509_CERT_DIR='%s' " % context.cert_repository
                                    info[
                                        'sftp_env'] += "X509_CERT_DIR='%s' " % context.cert_repository

                if url.port and url.port != -1:
                    info['ssh_args'] += "-o Port=%d " % int(url.port)
                    info['scp_args'] += "-o Port=%d " % int(url.port)
                    info['sftp_args'] += "-o Port=%d " % int(url.port)

                # all ssh based shells allow for user_id and user_pass from contexts
                # -- but the data given in the URL take precedence

                if url.username: info['user'] = url.username
                if url.password: info['pass'] = url.password

                ctrl_user = pwd.getpwuid(os.getuid()).pw_name
                ctrl_base = "/tmp/saga_ssh_%s" % ctrl_user

                if 'user' in info and info['user']:
                    info['host_str'] = "%s@%s" % (info['user'],
                                                  info['host_str'])
                    info['ctrl'] = "%s_%%h_%%p.%s.ctrl" % (ctrl_base,
                                                           info['user'])
                else:
                    info['user'] = getpass.getuser()
                    info['ctrl'] = "%s_%%h_%%p.ctrl" % (ctrl_base)

                info['m_flags'] = _SSH_FLAGS_MASTER % (
                    {
                        'share_mode': info['share_mode'],
                        'ctrl': info['ctrl'],
                        'connect_timeout': info['ssh_connect_timeout']
                    })
                info['s_flags'] = _SSH_FLAGS_SLAVE % (
                    {
                        'share_mode': info['share_mode'],
                        'ctrl': info['ctrl'],
                        'connect_timeout': info['ssh_connect_timeout']
                    })

                logger.debug('SSH Connection M_FLAGS: %s' % info['m_flags'])
                logger.debug('SSH Connection S_FLAGS: %s' % info['s_flags'])

                # we want the userauth and hostname parts of the URL, to get the
                # scp-scope fs root.
                info['scp_root'] = ""
                has_auth = False
                if url.username:
                    info['scp_root'] += url.username
                    has_auth = True
                if url.password:
                    info['scp_root'] += ":"
                    info['scp_root'] += url.password
                    has_auth = True
                if has_auth:
                    info['scp_root'] += "@"
                info['scp_root'] += "%s:" % url.host

                # FIXME: port needs to be handled as parameter
            # if  url.port :
            #     info['scp_root'] += ":%d" % url.port

            # keep all collected info in the master dict, and return it for
            # registration
            return info
Esempio n. 6
0
    def _create_master_entry(self, url, session, prompt, logger):
        # FIXME: cache 'which' results, etc
        # FIXME: check 'which' results

        with self.rlock:
            # if True :

            info = {}

            info['schema'] = url.schema.lower()
            info['host_str'] = url.host
            info['prompt'] = prompt
            info['logger'] = logger
            info['url'] = url
            info['pass'] = ""
            info['key_pass'] = {}
            info['scripts'] = _SCRIPTS

            if not info['schema']:
                info['schema'] = 'local'

            # find out what type of shell we have to deal with
            if info['schema'] in _SCHEMAS_SSH:
                info['type'] = "ssh"
                info['ssh_exe'] = ru.which("ssh")
                info['scp_exe'] = ru.which("scp")
                info['sftp_exe'] = ru.which("sftp")

            elif info['schema'] in _SCHEMAS_GSI:
                info['type'] = "ssh"
                info['ssh_exe'] = ru.which("gsissh")
                info['scp_exe'] = ru.which("gsiscp")
                info['sftp_exe'] = ru.which("gsisftp")

            elif info['schema'] in _SCHEMAS_SH:
                info['type'] = "sh"
                info['sh_args'] = "-i"
                info['sh_env'] = "/usr/bin/env TERM=vt100 PS1='PROMPT-$?->'"
                info['cp_env'] = "/usr/bin/env TERM=vt100 PS1='PROMPT-$?->'"
                info['fs_root'] = "/"

                if "SHELL" in os.environ:
                    info['sh_exe'] = ru.which(os.environ["SHELL"])
                    info['cp_exe'] = ru.which("cp")
                else:
                    info['sh_exe'] = ru.which("sh")
                    info['cp_exe'] = ru.which("cp")

            else:
                raise se.BadParameter._log (self.logger, \
                          "cannot handle schema '%s://'" % url.schema)

            # depending on type, create command line (args, env etc)
            #
            # We always set term=vt100 to avoid ansi-escape sequences in the prompt
            # and elsewhere.  Also, we have to make sure that the shell is an
            # interactive login shell, so that it interprets the users startup
            # files, and reacts on commands.

            try:
                info['latency'] = sumisc.get_host_latency(url)

                # FIXME: note that get_host_latency is considered broken (see
                # saga/utils/misc.py line 73), and will return a constant 250ms.

            except Exception as e:
                info['latency'] = 1.0  # generic value assuming slow link
                info['logger'].warning("Could not contact host '%s': %s" %
                                       (url, e))

            if info['type'] == "sh":

                info[
                    'sh_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes

                if not sumisc.host_is_local(url.host):
                    raise se.BadParameter._log (self.logger, \
                            "expect local host for '%s://', not '%s'" % (url.schema, url.host))

                if 'user' in info and info['user']:
                    pass
                else:
                    info['user'] = getpass.getuser()

            else:
                info[
                    'ssh_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info[
                    'scp_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info[
                    'sftp_env'] = "/usr/bin/env TERM=vt100 "  # avoid ansi escapes
                info['ssh_args'] = "-t "  # force pty
                info['scp_args'] = ""
                info['sftp_args'] = ""

                if session:

                    for context in session.contexts:

                        # ssh can also handle UserPass contexts, and ssh type contexts.
                        # gsissh can handle the same, but also X509 contexts.

                        if context.type.lower() == "ssh":
                            if info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI:

                                if context.attribute_exists(
                                        "user_id") and context.user_id:
                                    info['user'] = context.user_id

                                if context.attribute_exists(
                                        "user_key") and context.user_key:
                                    info[
                                        'ssh_args'] += "-o IdentityFile=%s " % context.user_key
                                    info[
                                        'scp_args'] += "-o IdentityFile=%s " % context.user_key
                                    info[
                                        'sftp_args'] += "-o IdentityFile=%s " % context.user_key

                                    if context.attribute_exists(
                                            "user_pass") and context.user_pass:
                                        info['key_pass'][
                                            context.
                                            user_key] = context.user_pass

                        if context.type.lower() == "userpass":
                            if info['schema'] in _SCHEMAS_SSH + _SCHEMAS_GSI:
                                if context.attribute_exists(
                                        "user_id") and context.user_id:
                                    info['user'] = context.user_id
                                if context.attribute_exists(
                                        "user_pass") and context.user_pass:
                                    info['pass'] = context.user_pass

                        if context.type.lower() == "x509":
                            if info['schema'] in _SCHEMAS_GSI:

                                if context.attribute_exists(
                                        "user_proxy") and context.user_proxy:
                                    info[
                                        'ssh_env'] += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info[
                                        'scp_env'] += "X509_USER_PROXY='%s' " % context.user_proxy
                                    info[
                                        'sftp_env'] += "X509_USER_PROXY='%s' " % context.user_proxy

                                if context.attribute_exists(
                                        "user_cert") and context.user_cert:
                                    info[
                                        'ssh_env'] += "X509_USER_CERT='%s' " % context.user_cert
                                    info[
                                        'scp_env'] += "X509_USER_CERT='%s' " % context.user_cert
                                    info[
                                        'sftp_env'] += "X509_USER_CERT='%s' " % context.user_cert

                                if context.attribute_exists(
                                        "user_key") and context.user_key:
                                    info[
                                        'ssh_env'] += "X509_USER_key='%s' " % context.user_key
                                    info[
                                        'scp_env'] += "X509_USER_key='%s' " % context.user_key
                                    info[
                                        'sftp_env'] += "X509_USER_key='%s' " % context.user_key

                                if context.attribute_exists(
                                        "cert_repository"
                                ) and context.cert_repository:
                                    info[
                                        'ssh_env'] += "X509_CERT_DIR='%s' " % context.cert_repository
                                    info[
                                        'scp_env'] += "X509_CERT_DIR='%s' " % context.cert_repository
                                    info[
                                        'sftp_env'] += "X509_CERT_DIR='%s' " % context.cert_repository

                if url.port and url.port != -1:
                    info['ssh_args'] += "-p %d " % int(url.port)
                    info['scp_args'] += "-p %d " % int(url.port)
                    info['sftp_args'] += "-P %d " % int(url.port)

                # all ssh based shells allow for user_id and user_pass from contexts
                # -- but the data given in the URL take precedence

                if url.username: info['user'] = url.username
                if url.password: info['pass'] = url.password

                ctrl_user = pwd.getpwuid(os.getuid()).pw_name
                ctrl_base = "/tmp/saga_ssh_%s" % ctrl_user

                if 'user' in info and info['user']:
                    info['host_str'] = "%s@%s" % (info['user'],
                                                  info['host_str'])
                    info['ctrl'] = "%s_%%h_%%p.%s.ctrl" % (ctrl_base,
                                                           info['user'])
                else:
                    info['user'] = getpass.getuser()
                    info['ctrl'] = "%s_%%h_%%p.ctrl" % (ctrl_base)

                info['m_flags'] = _SSH_FLAGS_MASTER % ({'ctrl': info['ctrl']})
                info['s_flags'] = _SSH_FLAGS_SLAVE % ({'ctrl': info['ctrl']})
                info['fs_root'] = url

                info['fs_root'].path = "/"

            # keep all collected info in the master dict, and return it for
            # registration
            return info