def __init__(self): self.owner = None self.host = None self.ssh_login_shell = True flags.verbose == ('-v' in sys.argv or '--verbose' in sys.argv) argv = sys.argv[1:] self.args = [] # detect and replace host and owner options while argv: arg = argv.pop(0) if arg.startswith("--user="******"--user="******"") elif arg.startswith("--host="): self.host = arg.replace("--host=", "") elif arg == "--login": self.ssh_login_shell = True elif arg == "--no-login": self.ssh_login_shell = False 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
def __init__( self ): self.owner = None self.host = None self.ssh_login_shell = True 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=", "") elif arg == "--login": self.ssh_login_shell = True elif arg == "--no-login": self.ssh_login_shell = False 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
def get( self ): if self.verbose: print "Retrieving suite port number", if is_remote_host( self.host ) or is_remote_user( self.owner ): self.port = self.get_remote() else: self.port = self.get_local() if self.verbose: print '...', self.port return self.port
def get( self ): if self.verbose: print "Retrieving suite port number..." if is_remote_host( self.host ) or is_remote_user( self.owner ): str_port = self.get_remote() else: str_port = self.get_local() try: # convert to integer port = int( str_port ) except ValueError, x: # this also catches an empty port file (touch) print >> sys.stderr, x print >> sys.stderr, "ERROR: bad port file", self.locn raise PortFileError( "ERROR, illegal port file content: " + str_port )
def get_passphrase_file( self, pfile=None, suitedir=None ): """ Passphrase location, order of preference: 1/ The pfile argument - used for passphrase creation by "cylc register". 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 + '@' + get_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 for suite ' + self.suite + ' not found on ' + user + '@' + get_hostname() return self.location
def get_passphrase_file(self, pfile=None, suitedir=None): """ Passphrase location, order of preference: 1/ The pfile argument - used for passphrase creation by "cylc register". 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 + '@' + get_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 for suite ' + self.suite + ' not found on ' + user + '@' + get_hostname( ) return self.location