Пример #1
0
    def __init__(self):
        self.owner = None
        self.host = None

        if "-v" in sys.argv or "--verbose" in sys.argv:
            self.verbose = True
        else:
            self.verbose = False

        argv = sys.argv[1:]
        self.args = []
        # detect and replace host and owner options
        while argv:
            arg = argv.pop(0)
            if arg.startswith("--owner="):
                self.owner = arg.replace("--owner=", "")
            elif arg.startswith("--host="):
                self.host = arg.replace("--host=", "")
            else:
                self.args.append(arg)

        if is_remote_user(self.owner) or is_remote_host(self.host):
            self.is_remote = True
        else:
            self.is_remote = False
Пример #2
0
    def get_passphrase_file( self, pfile=None, suitedir=None ):
        """
Passphrase location, order of preference:

1/ The pfile argument (used for initial passphrase creation by the
register command, and optionally on the command line).

2/ The suite definition directory, because suites may be automatically
installed (e.g. by Rose) to remote task hosts, and remote tasks know
this location from their execution environment. Local user command
invocations can use the suite registration database to find the suite
definition directory.  HOWEVER, remote user command invocations cannot
do this even if the local and remote hosts share a common filesystem,
because we cannot be sure if finding the expected suite registration
implies a common filesystem or a different remote suite that happens to
be registered under the same name. User accounts used for remote control
must therefore install the passphrase in the secondary standard
locations (below) or use the command line option to explicitly reveal
the location. Remote tasks with 'ssh messaging = True' look first in the 
suite definition directory of the suite host, which they know through 
the variable CYLC_SUITE_DEF_PATH_ON_SUITE_HOST in the task execution
environment.

3/ Secondary locations:
    (i) $HOME/.cylc/SUITE_HOST/SUITE_OWNER/SUITE_NAME/passphrase
   (ii) $HOME/.cylc/SUITE_HOST/SUITE_NAME/passphrase
  (iii) $HOME/.cylc/SUITE_NAME/passphrase
These are more sensible locations for remote suite control from accounts
that do not actually need the suite definition directory to be installed.
"""
        # 1/ explicit location given on the command line
        if pfile:
            if os.path.isdir( pfile ):
                # if a directory is given assume the filename
                pfile = os.path.join( pfile, 'passphrase' )
            if os.path.isfile( pfile ):
                self.set_location( pfile )

            else:
                # if an explicit location is given, the file must exist
                raise SecurityError, 'ERROR, file not found on ' + user + '@' + hostname + ': ' + pfile

        # 2/ cylc commands with suite definition directory from local registration
        if not self.location and suitedir:
            pfile = os.path.join( suitedir, 'passphrase' )
            if os.path.isfile( pfile ):
                self.set_location( pfile )

        # (2 before 3 else sub-suites load their parent suite's
        # passphrase on start-up because the "cylc run" command runs in
        # a parent suite task execution environment).

        # 3/ running tasks: suite definition directory (from the task execution environment)
        if not self.location:
            try:
                # Test for presence of task execution environment
                suite_host = os.environ['CYLC_SUITE_HOST']
                suite_owner = os.environ['CYLC_SUITE_OWNER']
            except KeyError:
                # not called by a task
                pass
            else:
                # called by a task
                if is_remote_host( suite_host ) or is_remote_user( suite_owner ):
                    # 2(i)/ cylc messaging calls on a remote account.

                    # First look in the remote suite definition
                    # directory ($CYLC_SUITE_DEF_PATH is modified for
                    # remote tasks):
                    try:
                        pfile = os.path.join( os.environ['CYLC_SUITE_DEF_PATH'], 'passphrase' )
                    except KeyError:
                        pass
                    else:
                        if os.path.isfile( pfile ):
                            self.set_location( pfile )

                else:
                    # 2(ii)/ cylc messaging calls on the suite host and account.

                    # Could be a local task or a remote task with 'ssh
                    # messaging = True'. In either case use
                    # $CYLC_SUITE_DEF_PATH_ON_SUITE_HOST which never
                    # changes, not $CYLC_SUITE_DEF_PATH which gets
                    # modified for remote tasks as described above.
                    try:
                        pfile = os.path.join( os.environ['CYLC_SUITE_DEF_PATH_ON_SUITE_HOST'], 'passphrase' )
                    except KeyError:
                        pass
                    else:
                        if os.path.isfile( pfile ):
                            self.set_location( pfile )

        # 4/ other allowed locations, as documented above
        if not self.location:
            locations = []
            # For remote control commands, self.host here will be fully
            # qualified or not depending on what's given on the command line.
            short_host = re.sub( '\..*', '', self.host )

            locations.append( os.path.join( os.environ['HOME'], '.cylc', self.host, self.owner, self.suite, 'passphrase' ))
            if short_host != self.host:
                locations.append( os.path.join( os.environ['HOME'], '.cylc', short_host, self.owner, self.suite, 'passphrase' ))
            locations.append( os.path.join( os.environ['HOME'], '.cylc', self.host, self.suite, 'passphrase' ))
            if short_host != self.host:
                locations.append( os.path.join( os.environ['HOME'], '.cylc', short_host, self.suite, 'passphrase' ))
            locations.append( os.path.join( os.environ['HOME'], '.cylc', self.suite, 'passphrase' ))
            for pfile in locations:
                if os.path.isfile( pfile ):
                    self.set_location( pfile )
                    break

        if not self.location:
            raise SecurityError, 'ERROR: passphrase not found on ' + user + '@' + hostname

        return self.location