def test_port_allocated(self): with open(self.testfilename, 'w') as f: f.write('testContainer 4000 %s\n' % getIP()) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((getIP(), 4000)) s.listen(1) self.exec_helper(['acsstartupContainerPort', '--py', 'testContainer']) s.close()
def fullDescription(self, msg): ''' Prints out a full description of all times that were saved along with other relevant statistical data. Params: message to be printed out Returns: the full description printed to stdout Raises: Nothing ''' #sanity check to see if the timer has stopped if self.last_start_time != 0: self.stop() if self.total_num_starts == 0: print "ACS PROFILER: No start invocations - ", msg return avg_time = self.total_time / self.total_num_starts date = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime()) + str(".000") retVal = "#ACS PROFILER# msg=%s, avg=%f, runs=%d, mindur=%f, maxdur=%f, cpu=Unknown, mem=Unknown, date=%s, ip=%s, lang=py, units=ms %s" % ( msg, avg_time, self.total_num_starts, self.min, self.max, date, str(getIP()), self.extra_descrip) print retVal return retVal
def getManagerCorbaloc(new_corbaloc=None): ''' Get (or set) managers corbaloc. Params: If the developer specifies a value other than None for new_corbaloc, it is assumed this is managers corbaloc and sets it accordingly. Returns: the stringified corbaloc of manager. Raises: Nothing. ''' global MGR_CORBALOC if new_corbaloc != None: #Developer is trying to manually set the singled reference. MGR_CORBALOC = str(new_corbaloc) elif MGR_CORBALOC == None: #If this function has never been called before... #Check command-line args for the corbaloc for i in range(0, len(argv) - 1): if argv[i] == '-managerReference': #Found it! OK to set now. MGR_CORBALOC = argv[i + 1] break if MGR_CORBALOC == None: #Not in the command-line so check an environment variable reference if environ.has_key('MANAGER_REFERENCE'): #Found it! OK to set now. MGR_CORBALOC = environ['MANAGER_REFERENCE'] else: #Assume manager is running under the local machine MGR_CORBALOC = 'corbaloc::' + str( getIP()) + ':' + getManagerPort() + '/Manager' return MGR_CORBALOC
def getManagerCorbaloc(new_corbaloc=None): """ Get (or set) managers corbaloc. Params: If the developer specifies a value other than None for new_corbaloc, it is assumed this is managers corbaloc and sets it accordingly. Returns: the stringified corbaloc of manager. Raises: Nothing. """ global MGR_CORBALOC if new_corbaloc != None: # Developer is trying to manually set the singled reference. MGR_CORBALOC = str(new_corbaloc) elif MGR_CORBALOC == None: # If this function has never been called before... # Check command-line args for the corbaloc for i in range(0, len(argv) - 1): if argv[i] == "-managerReference" or argv[i] == "-m": # Found it! OK to set now. MGR_CORBALOC = argv[i + 1] break if MGR_CORBALOC == None: # Not in the command-line so check an environment variable reference if environ.has_key("MANAGER_REFERENCE"): # Found it! OK to set now. MGR_CORBALOC = environ["MANAGER_REFERENCE"] else: # Assume manager is running under the local machine MGR_CORBALOC = "corbaloc::" + str(getIP()) + ":" + getManagerPort() + "/Manager" return MGR_CORBALOC
def main(prog_args): #------------------------------------------------------------------------------ #--Parse the command-line options. global __DEBUG__ usage_msg = ''' This script is used to generate a command-line to be passed to container startup scripts. It will include such information as the TCP port the container should be run under. Do not call this script directly from your own code!. ''' parser = OptionParser(usage=usage_msg) #end-users can specify a specific port number to run under port_help_msg = ''' TCP port to run the notify service under. If this integer value is in the inclusive range of 0-9, it is assumed that the intended TCP port is really an offset equivalent to the following: REAL TCP PORT = port + 3020 + $ACS_INSTANCE*100. If this integer value is greater than 9, the TCP port is used as provided. ''' parser.add_option("--port", dest="port", help=port_help_msg) #end-users can use this parameter to specify the name of the container name_help_msg = ''' Name of the notify service. Users can optionally specify the name of the notify service directly using this command-line switch. If this switch is not used, it is assumed the first argument after all command-line switches is the name of the notify service. ''' parser.add_option("--name", dest="name", help=name_help_msg) #Debug flag parser.add_option( "--debug", action="store_true", dest="debug", default=0, help="Prints out special debugging info to standard error.") #baseport baseport_help_msg = ''' ACS baseport (i.e., 0-9). Setting this flag overrides the value of $ACS_LOG_STDOUT. ''' parser.add_option("-b", "--baseport", dest="baseport", help=baseport_help_msg, default=None) #-------------------------------------------------------------------------- #--Make commands backwards compatible with pre ACS 6.0 usage. #--Basically this means that commands of the form -xy... should still #--be supported. This manual manipulation of prog_args is necessary as #--optparse only supports switches of the form --xy... #go through every potential command-line switch for i in range(0, len(prog_args)): #if the switch is something like -managerReference change it #to --managerReference if len(prog_args[i] ) > 2 and prog_args[i][0] == '-' and prog_args[i][1] != '-': prog_args[i] = "-" + prog_args[i] #-------------------------------------------------------------------------- #--Parse everything and throw the results into global variables (options, parsed_argv) = parser.parse_args(args=prog_args) cl_port = options.port cl_name = options.name cl_baseport = options.baseport __DEBUG__ = options.debug #-------------------------------------------------------------------------- #--Go through the command-line arguments: #-- creating a few global variables based on them #-- do a little preprocessing on their values #--determine the ACS_INSTANCE if cl_baseport == None: cl_baseport = int(environ['ACS_INSTANCE']) else: cl_baseport = int(cl_baseport) #no notify name specified if cl_name == None: if len(parsed_argv) == 0: stderr.write( "Must specificy a notify service name using the -name option!\n" ) return 5 #error is recoverable - NS name specified as a general argument else: cl_name = parsed_argv.pop(0) #turn the TCP port into the real TCP port if cl_port != None: if __DEBUG__: stderr.write("-port option was specified:" + str(cl_port) + "\n") #string to int newPort = int(cl_port) #try to coerce the port number into a proper TCP port number newPort = coercePortNumber(newPort) else: newPort = None # local container_host = getIP() #-------------------------------------------------------------------- #--GLOBALS----------------------------------------------------------- #get the file which shows us which ports are currently taken up container_file = getPortsFile(cl_baseport) #get dictionaries mapping container names to TCP port numbers and hosts container_ports, container_hosts = getNotifyDict(container_file) #-------------------------------------------------------------------- #--SANITY CHECKS----------------------------------------------------- #recorded host is different from commanded host if container_hosts.has_key( cl_name) and container_hosts[cl_name] != container_host: stderr.write("Trying to run the '" + cl_name + "' notify service on '" + container_host + "' instead of '" + container_hosts[cl_name] + "' impossible!\n") stderr.write( "Changing hosts after a notify service is restarted is not permitted!\n" ) return 8 #recorded TCP port requested is different from commanded TCP port if newPort != None and container_ports.has_key( cl_name) and container_ports[cl_name] != newPort: stderr.write("Trying to change the '" + cl_name + "' notify's TCP port from '" + str(container_ports[cl_name]) + "' to '" + str(newPort) + "' is impossible!\n") stderr.write( "Changing TCP ports after a notify service is restarted is not permitted!\n" ) return 9 #ensure developer hasn't picked something that's already being used elif newPort != None and ( not container_ports.has_key(cl_name)) and portNumberAlreadyUsed( newPort, container_host, container_ports, container_hosts): stderr.write("Port number specified via -port switch, " + str(newPort) + ", is already assigned!\n") return 10 #the desired TCP port is in use by some other process if newPort != None and not portIsFree(container_host, newPort): stderr.write( "Cannot use the '" + str(newPort) + "' TCP port as it's being tied up by some other process!\n") stderr.write( "Use the netstat command to find the offending process!\n") return 11 #----------------------------------------------------------------------------- #debugging purposes only! if __DEBUG__: stderr.write("Command-line TCP port:" + str(cl_port) + "\n") stderr.write("Command-line notify name:" + str(cl_name) + "\n") #----------------------------------------------------------------------------- #--MAIN----------------------------------------------------------------------- #see if it's been set before... temp_port, temp_host = getExistingPort(cl_name, container_ports, container_hosts) #NS already had a port assigned to it. fine. if temp_port != None: #overwrite any value the user may have tried to specify using #the port switch. if it's been set before, it must remain the same. newPort = temp_port container_host = temp_host #if this NS is being run for the first time and #the user doesn't care which port it runs on elif newPort is None: #just get the next available TCP port. This will always #work unless there are 9+ NSs newPort = getNextAvailablePort(container_host, container_ports, container_hosts, cl_baseport) #NS does not already have a port assigned to it and the #new port is not nil... if temp_port == None and newPort != None: container_file.writelines( [cl_name + ' ' + str(newPort) + ' ' + str(container_host) + '\n']) cleanUp() #at this point we should have found a free port number. #we can now close up the container_file so that other containers #can be started immediately. if newPort == None: #could not find a free port. no point in going on. stderr.write("All ports are taken!\n") return 2 print newPort print ################################################################ return 0
def fullDescription(self, msg): ''' Prints out a full description of all times that were saved along with other relevant statistical data. Params: message to be printed out Returns: the full description printed to stdout Raises: Nothing ''' #sanity check to see if the timer has stopped if self.last_start_time != 0: self.stop() if self.total_num_starts == 0: print "ACS PROFILER: No start invocations - ", msg return avg_time = self.total_time / self.total_num_starts date = time.strftime("%Y-%m-%dT%H:%M:%S",time.gmtime())+str(".000") retVal = "#ACS PROFILER# msg=%s, avg=%f, runs=%d, mindur=%f, maxdur=%f, cpu=Unknown, mem=Unknown, date=%s, ip=%s, lang=py, units=ms %s" % (msg, avg_time, self.total_num_starts, self.min, self.max, date, str(getIP()), self.extra_descrip) print retVal return retVal
############################################################################### ''' ''' ############################################################################### import socket import SocketServer from time import sleep from sys import argv from AcsutilPy.ACSPorts import getIP #------------------------------------------------------------------------------ #--GLOBALS ip_addr = getIP() tcp_port = None #------------------------------------------------------------------------------ #--Parse the command-line options. for i in xrange(0, len(argv)): if argv[i]=="-ORBIIOPAddr": #inet:$HOST:$IR_PORT tcp_port = argv[i+1].split(":")[2] break elif argv[i]=="-ORBEndpoint": #iiop://$HOST:$IR_PORT tcp_port = argv[i+1].split(":")[2] break
def main(prog_args): #------------------------------------------------------------------------------ #--Parse the command-line options. global __DEBUG__ usage_msg=''' This script is used to generate a command-line to be passed to container startup scripts. It will include such information as the TCP port the container should be run under. Do not call this script directly from your own code!. ''' parser = OptionParser(usage=usage_msg) #end-users can specify a specific port number to run under port_help_msg=''' TCP port to run the notify service under. If this integer value is in the inclusive range of 0-9, it is assumed that the intended TCP port is really an offset equivalent to the following: REAL TCP PORT = port + 3020 + $ACS_INSTANCE*100. If this integer value is greater than 9, the TCP port is used as provided. ''' parser.add_option("--port", dest="port", help=port_help_msg) #end-users can use this parameter to specify the name of the container name_help_msg=''' Name of the notify service. Users can optionally specify the name of the notify service directly using this command-line switch. If this switch is not used, it is assumed the first argument after all command-line switches is the name of the notify service. ''' parser.add_option("--name", dest="name", help=name_help_msg) #Debug flag parser.add_option("--debug", action="store_true", dest="debug", default=0, help="Prints out special debugging info to standard error.") #baseport baseport_help_msg=''' ACS baseport (i.e., 0-9). Setting this flag overrides the value of $ACS_LOG_STDOUT. ''' parser.add_option("-b", "--baseport", dest="baseport", help=baseport_help_msg, default=None) #-------------------------------------------------------------------------- #--Make commands backwards compatible with pre ACS 6.0 usage. #--Basically this means that commands of the form -xy... should still #--be supported. This manual manipulation of prog_args is necessary as #--optparse only supports switches of the form --xy... #go through every potential command-line switch for i in range(0, len(prog_args)): #if the switch is something like -managerReference change it #to --managerReference if len(prog_args[i])>2 and prog_args[i][0]=='-' and prog_args[i][1]!='-': prog_args[i] = "-" + prog_args[i] #-------------------------------------------------------------------------- #--Parse everything and throw the results into global variables (options, parsed_argv) = parser.parse_args(args=prog_args) cl_port = options.port cl_name = options.name cl_baseport = options.baseport __DEBUG__ = options.debug #-------------------------------------------------------------------------- #--Go through the command-line arguments: #-- creating a few global variables based on them #-- do a little preprocessing on their values #--determine the ACS_INSTANCE if cl_baseport==None: cl_baseport = int(environ['ACS_INSTANCE']) else: cl_baseport=int(cl_baseport) #no notify name specified if cl_name==None: if len(parsed_argv)==0: stderr.write("Must specificy a notify service name using the -name option!\n") return 5 #error is recoverable - NS name specified as a general argument else: cl_name = parsed_argv.pop(0) #turn the TCP port into the real TCP port if cl_port!=None: if __DEBUG__: stderr.write("-port option was specified:" + str(cl_port) + "\n") #string to int newPort = int(cl_port) #try to coerce the port number into a proper TCP port number newPort = coercePortNumber(newPort,cl_baseport) else: newPort=None # local container_host = getIP() #-------------------------------------------------------------------- #--GLOBALS----------------------------------------------------------- #get the file which shows us which ports are currently taken up container_file = getPortsFile(cl_baseport) #get dictionaries mapping container names to TCP port numbers and hosts container_ports, container_hosts = getNotifyDict(container_file) #-------------------------------------------------------------------- #--SANITY CHECKS----------------------------------------------------- #recorded host is different from commanded host if container_hosts.has_key(cl_name) and container_hosts[cl_name]!=container_host: stderr.write("Trying to run the '" + cl_name + "' notify service on '" + container_host + "' instead of '" + container_hosts[cl_name] + "' impossible!\n") stderr.write("Changing hosts after a notify service is restarted is not permitted!\n") return 8 #recorded TCP port requested is different from commanded TCP port if newPort!=None and container_ports.has_key(cl_name) and container_ports[cl_name]!=newPort: stderr.write("Trying to change the '" + cl_name + "' notify's TCP port from '" + str(container_ports[cl_name]) + "' to '" + str(newPort) + "' is impossible!\n") stderr.write("Changing TCP ports after a notify service is restarted is not permitted!\n") return 9 #ensure developer hasn't picked something that's already being used elif newPort!=None and (not container_ports.has_key(cl_name)) and portNumberAlreadyUsed(newPort, container_host, container_ports, container_hosts): stderr.write("Port number specified via -port switch, " + str(newPort) + ", is already assigned!\n") return 10 #the desired TCP port is in use by some other process if newPort!=None and not portIsFree(container_host, newPort): stderr.write("Cannot use the '" + str(newPort) + "' TCP port as it's being tied up by some other process!\n") stderr.write("Use the netstat command to find the offending process!\n") return 11 #----------------------------------------------------------------------------- #debugging purposes only! if __DEBUG__: stderr.write("Command-line TCP port:" + str(cl_port) + "\n") stderr.write("Command-line notify name:" + str(cl_name) + "\n") #----------------------------------------------------------------------------- #--MAIN----------------------------------------------------------------------- #see if it's been set before... temp_port, temp_host = getExistingPort(cl_name, container_ports, container_hosts) #NS already had a port assigned to it. fine. if temp_port != None: #overwrite any value the user may have tried to specify using #the port switch. if it's been set before, it must remain the same. newPort = temp_port container_host = temp_host #if this NS is being run for the first time and #the user doesn't care which port it runs on elif newPort is None: #just get the next available TCP port. This will always #work unless there are 9+ NSs newPort = getNextAvailablePort(container_host, container_ports, container_hosts, cl_baseport) #NS does not already have a port assigned to it and the #new port is not nil... if temp_port==None and newPort!=None: container_file.writelines([cl_name + ' ' + str(newPort) + ' ' + str(container_host) + '\n']) cleanUp() #at this point we should have found a free port number. #we can now close up the container_file so that other containers #can be started immediately. if newPort==None: #could not find a free port. no point in going on. stderr.write("All ports are taken!\n") return 2 print newPort; print ################################################################ return 0
def main(prog_args): #------------------------------------------------------------------------------ #--Parse the command-line options. global __DEBUG__ global container_file usage_msg=''' This script is used to generate a command-line to be passed to container startup scripts. It will include such information as the TCP port the container should be run under. Do not call this script directly from your own code!. ''' parser = OptionParser(usage=usage_msg) #end-users can specify a specific port number to run under port_help_msg=''' TCP port to run the container under. If this integer value is in the inclusive range of 0-24, it is assumed that the intended TCP port is really an offset equivalent to the following: REAL TCP PORT = port*2 + 3050 + $ACS_INSTANCE*100. If this integer value is greater than 24, the TCP port is used as provided. The only stipulation to this is that odd TCP port numbers from 3000-4000 are not available. These are reserved exclusively for so-called remote debuggable containers (Java-only). Also, it is important to note that $ACS_INSTANCE==0 is a special case in which ports 4000-5000 are used implying a total number of 500 allowable containers. ''' parser.add_option("--port", dest="port", help=port_help_msg) #end-users can use this parameter to specify the name of the container name_help_msg=''' Name of the container. Users can optionally specify the name of the container directly using this command-line switch. If this switch is not used, it is assumed the first argument after all command-line switches is the name of the container. ''' parser.add_option("--name", dest="name", help=name_help_msg) #Java containers parser.add_option("--java", action="store_true", dest="java", default=0, help="Specifies the container is Java.") #Alternative Java container class parser.add_option("--custom_java", dest="custom_container", default="alma.acs.container.AcsContainerRunner", help="Alternative Java class to use for the container implementation.") #C++ containers parser.add_option("--cpp", action="store_true", dest="cpp", default=0, help="Specifies the container is C++.") #Python containers parser.add_option("--py", action="store_true", dest="py", default=0, help="Specifies the container is Python.") #Debug flag parser.add_option("--debug", action="store_true", dest="debug", default=0, help="Prints out special debugging info to standard error.") #Reference to manager. mgr_help_msg=''' Set's manager's reference. Tells the container where its manager is. E.g., corbaloc::127.0.0.1:3100/Manager ''' parser.add_option("-m", "--managerReference", dest="manager_reference", help=mgr_help_msg) #Reference to the CDB. cdb_help_msg=''' Sets a reference to the configuration database. Tells the container where to find its own configuration data. This is currently only applicable to C++ containers. E.g., corbaloc::127.0.0.1:3012/CDB ''' parser.add_option("-d", "--DALReference", dest="cdb_ref", help=cdb_help_msg) #Custom executable exe_help_msg=''' Sets a custom executable to be run. The value given here replaces the standard command to start a container in a particular programming language. E.g., you might want to replace the C++ executable, maciContainer, with some specialized container you wrote - myMaciContainer. ''' parser.add_option("-e", "--executable", dest="executable", help=exe_help_msg) #Remote host remote_help_msg=''' Sets a remote PC to run the container under. When this flag is given, the container is run under the host specified from the command-line rather than the localhost. Minimal checks are performed to ensure the remote host actually exists and is reachable. For this to work, it is necessary that SSH be configured in such a way that $USER can ssh into the remote host without being asked for a password. ''' parser.add_option("--remoteHost", dest="remote_host", help=remote_help_msg) remote_debug_msg=''' Makes the Java container accessible by a remote debugger. Deprecated. The remote debuggable Java container feature is now activated by setting $ACS_LOG_SDTOUT less than or equal to the DEBUG log level. ''' parser.add_option("--remoteDebuggable", dest="remote_debuggable", action="store_true", default=0, help=remote_debug_msg) #baseport baseport_help_msg=''' ACS baseport (i.e., 0-9). Setting this flag overrides the value of $ACS_LOG_STDOUT. ''' parser.add_option("-b", "--baseport", dest="baseport", help=baseport_help_msg, default=None) #Container flags flags_help_msg='''Sets flags that are to be passed to the actual container start executables.''' parser.add_option("-p", "--passthrough", dest="container_flags", default=None, help=flags_help_msg) #Start Options flags_help_msg='''Sets options that are to be passed to the actual container start executables.''' parser.add_option("--passthroughProcessStart", dest="start_options", default=None, help=flags_help_msg) #-------------------------------------------------------------------------- #--Make commands backwards compatible with pre ACS 6.0 usage. #--Basically this means that commands of the form -xy... should still #--be supported. This manual manipulation of prog_args is necessary as #--optparse only supports switches of the form --xy... #go through every potential command-line switch for i in range(0, len(prog_args)): #if the switch is something like -managerReference change it #to --managerReference if len(prog_args[i])>2 and prog_args[i][0]=='-' and prog_args[i][1]!='-': prog_args[i] = "-" + prog_args[i] #-------------------------------------------------------------------------- #--Parse everything and throw the results into global variables (options, parsed_argv) = parser.parse_args(args=prog_args) cl_port = options.port cl_name = options.name cl_java = options.java cl_java_container = options.custom_container cl_cpp = options.cpp cl_py = options.py cl_remote_host = options.remote_host cl_remote_debuggable = options.remote_debuggable cl_cdb_ref = options.cdb_ref cl_baseport = options.baseport cl_flags = options.container_flags cl_start_options = options.start_options __DEBUG__ = options.debug #-------------------------------------------------------------------------- #--Go through the command-line arguments: #-- creating a few global variables based on them #-- do a little preprocessing on their values #--determine the ACS_INSTANCE if cl_baseport==None: cl_baseport = int(environ['ACS_INSTANCE']) else: cl_baseport=int(cl_baseport) #--set manager's reference if options.manager_reference==None: if environ.has_key('MANAGER_REFERENCE'): #Found it! OK to set now. cl_manager = environ['MANAGER_REFERENCE'] else: #Assume manager is running under the local machine manager_port = cl_baseport*100 + 3000 + 0 cl_manager = 'corbaloc::' + str(getIP()) + ':' + str(manager_port) + '/Manager' else: cl_manager = options.manager_reference #--set the custom executable if options.executable==None: if cl_java: cl_executable = "acsStartJavaContainer" elif cl_cpp: cl_executable = "maciContainer" elif cl_py: cl_executable = "ACSStartContainerPy" else: stderr.write("Unable to continue. No container type specified!\n") return 3 else: cl_executable = options.executable #--if the remote host is set, setup the command to reflect this if cl_remote_host != None: container_host = cl_remote_host cl_executable = "ssh -f " + environ['USER'] + "@" + cl_remote_host + " " + cl_executable #sanity check to ensure this host exists stuff = subprocess.Popen('ping -c 1 ' + container_host, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read() if ('unknown host' in stuff) or ('request timed out' in stuff): stderr.write("The remote host, " + container_host + ", is not accessible from this machine!\n") return 1 #just use the local address else: container_host = getIP() #no container name specified if cl_name==None: if len(parsed_argv)==0: stderr.write("Must specificy a container name using the -name option!\n") return 5 #error is recoverable - container name specified as a general argument else: cl_name = parsed_argv.pop(0) #turn the TCP port into the real TCP port if cl_port!=None: if __DEBUG__: stderr.write("-port option was specified:" + str(cl_port) + "\n") #string to int newPort = int(cl_port) #try to coerce the port number into a proper TCP port number newPort = coercePortNumber(newPort) else: newPort=None #-------------------------------------------------------------------- #--GLOBALS----------------------------------------------------------- #get the file which shows us which ports are currently taken up container_file = getPortsFile(cl_baseport) #get dictionaries mapping container names to TCP port numbers and hosts container_ports, container_hosts = getContainerDict(container_file) #-------------------------------------------------------------------- #--SANITY CHECKS----------------------------------------------------- #multiple container types specified if (cl_java and cl_cpp) or (cl_java and cl_py) or (cl_cpp and cl_py): stderr.write("Too many -java/-cpp/-py options supplied!\n") stderr.write("Choose only one and try again!\n") return 6 #no container type specified if not(cl_java or cl_cpp or cl_py): stderr.write("You must choose some container type using one of the -java/-cpp/-py options!\n") return 7 #recorded host is different from commanded host if container_hosts.has_key(cl_name) and container_hosts[cl_name]!=container_host: stderr.write("Trying to run the '" + cl_name + "' container on '" + container_host + "' instead of '" + container_hosts[cl_name] + "' impossible!\n") stderr.write("Changing hosts after a container is restarted is not permitted!\n") return 8 #recorded TCP port requested is different from commanded TCP port if newPort!=None and container_ports.has_key(cl_name) and container_ports[cl_name]!=newPort: stderr.write("Trying to change the '" + cl_name + "' container's TCP port from '" + str(container_ports[cl_name]) + "' to '" + str(newPort) + "' is impossible!\n") stderr.write("Changing TCP ports after a container is restarted is not permitted!\n") return 9 #ensure developer hasn't picked something that's already being used elif newPort!=None and (not container_ports.has_key(cl_name)) and portNumberAlreadyUsed(newPort, container_host, container_ports, container_hosts): stderr.write("Port number specified via -port switch, " + str(newPort) + ", is already assigned!\n") return 10 #the desired TCP port is in use by some other process if newPort!=None and not portIsFree(container_host, newPort): stderr.write("Cannot use the '" + str(newPort) + "' TCP port as it's being tied up by some other process!\n") stderr.write("Use the netstat command to find the offending process!\n") return 11 #----------------------------------------------------------------------------- #debugging purposes only! if __DEBUG__: stderr.write("Command-line TCP port:" + str(cl_port) + "\n") stderr.write("Command-line container name:" + str(cl_name) + "\n") stderr.write("New args:" + str(parsed_argv) + "\n") if cl_java: stderr.write("Dealing with a Java container\n") stderr.write("Container implementation class:" + str(cl_java_container) + "\n") elif cl_cpp: stderr.write("Dealing with a C++ container\n") elif cl_py: stderr.write("Dealing with a Python container\n") else: stderr.write("Unknown container type. This is very bad!\n") stderr.write("Manager corbaloc is:" + str(cl_manager) + "\n") stderr.write("Executable to be run is:" + str(cl_executable) + "\n") stderr.write("Remote host to run the container under is:" + str(cl_remote_host) + "\n") stderr.write("Remote debuggable is:" + str(cl_remote_debuggable) + "\n") #----------------------------------------------------------------------------- #--MAIN----------------------------------------------------------------------- #see if it's been set before... temp_port, temp_host = getExistingPort(cl_name, container_ports, container_hosts) #container already had a port assigned to it. fine. if temp_port != None: #overwrite any value the user may have tried to specify using #the port switch. if it's been set before, it must remain the same. newPort = temp_port container_host = temp_host #if this container is being run for the first time and #the user doesn't care which port it runs on elif newPort is None: #just get the next available TCP port. This will always #work unless there are 25+ containers newPort = getNextAvailablePort(container_host, container_ports, container_hosts, cl_baseport) #container does not already have a port assigned to it and the #new port is not nil... if temp_port==None and newPort!=None: container_file.writelines([cl_name + ' ' + str(newPort) + ' ' + str(container_host) + '\n']) cleanUp() #at this point we should have found a free port number. #we can now close up the container_file so that other containers #can be started immediately. if newPort==None: #could not find a free port. no point in going on. stderr.write("All ports are taken!\n") return 2 ################################################################ #generate a new commandline argument i = 0 #name of the executable parsed_argv.insert(i, cl_executable) i = i + 1 #name of the container parsed_argv.insert(i, cl_name) i = i + 1 #add any container flags passed if cl_start_options: #parsed_argv.insert(i, "--passthroughProcessStart") #i = i + 1 parsed_argv.insert(i, cl_start_options) i = i + 1 #figure out the correct language first if cl_java: parsed_argv.insert(i, cl_java_container) i = i + 1 parsed_argv.insert(i, "-OAIAddr") i = i + 1 parsed_argv.insert(i, container_host) i = i + 1 parsed_argv.insert(i, "-OAport") i = i + 1 parsed_argv.insert(i, str(newPort)) i = i + 1 elif cl_cpp: parsed_argv.insert(i, "-ORBEndpoint") i = i + 1 parsed_argv.insert(i, "iiop://" + container_host + ':' + str(newPort)) i = i + 1 if cl_cdb_ref!=None: stderr.write("This container will use " + str(cl_cdb_ref) + " for the CDB.\n") parsed_argv.insert(i, "-d " + str(cl_cdb_ref)) i = i + 1 elif cl_py: parsed_argv.insert(i, "-ORBendPoint") i = i + 1 parsed_argv.insert(i, "giop:tcp:" + container_host + ':' + str(newPort)) i = i + 1 #ACS 2.1 usage retained for backwards compatiablity else: stderr.write("ACS 2.1 usage of this script deprecated and removed\n") return 1 #add the manager reference parsed_argv.insert(i, "-m " + str(cl_manager)) i = i + 1 #add any container flags passed if cl_flags: parsed_argv.insert(i, cl_flags) i = i + 1 ################################################################ #Finally print out the command. for arg in parsed_argv: print arg, print ################################################################ return 0
############################################################################### ''' ''' ############################################################################### import socket import SocketServer from time import sleep from sys import argv from AcsutilPy.ACSPorts import getIP #------------------------------------------------------------------------------ #--GLOBALS ip_addr = getIP() tcp_port = None #------------------------------------------------------------------------------ #--Parse the command-line options. for i in xrange(0, len(argv)): if argv[i] == "-ORBIIOPAddr": #inet:$HOST:$IR_PORT tcp_port = argv[i + 1].split(":")[2] break elif argv[i] == "-ORBEndpoint": #iiop://$HOST:$IR_PORT tcp_port = argv[i + 1].split(":")[2] break
""" from AcsutilPy.ACSPorts import getBasePort from AcsutilPy.ACSPorts import getManagerPort from AcsutilPy.ACSPorts import getNamingServicePort from AcsutilPy.ACSPorts import getNotifyServicePort from AcsutilPy.ACSPorts import getLoggingServicePort from AcsutilPy.ACSPorts import getIRPort from AcsutilPy.ACSPorts import getLogPort from AcsutilPy.ACSPorts import getCDBPort from AcsutilPy.ACSPorts import getContainerDaemonPort from AcsutilPy.ACSPorts import getServicesDaemonPort from AcsutilPy.ACSPorts import getIP ############################################################################### # Test code if __name__ == "__main__": # basically just make sure none of these throw exceptions because multiple values # are actually correct here! print type(getBasePort()) print type(getManagerPort()) print type(getNamingServicePort()) print type(getNotifyServicePort()) print type(getLoggingServicePort()) print type(getIRPort()) print type(getLogPort()) print type(getCDBPort()) print type(getContainerDaemonPort()) print type(getServicesDaemonPort()) print type(getIP())
def test_port_in_use(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((getIP(), 4000)) s.listen(1) self.exec_helper(['acsstartupContainerPort', '--port 4000', '--py', 'testContainer']) s.close()
def test_port_assigned(self): with open(self.testfilename, 'w') as f: f.write('testContainer2 4000 %s\n' % getIP()) self.exec_helper(['acsstartupContainerPort', '--port 4000', '--py', 'testContainer'])
def main(prog_args): #------------------------------------------------------------------------------ #--Parse the command-line options. global __DEBUG__ global container_file usage_msg = ''' This script is used to generate a command-line to be passed to container startup scripts. It will include such information as the TCP port the container should be run under. Do not call this script directly from your own code!. ''' parser = OptionParser(usage=usage_msg) #end-users can specify a specific port number to run under port_help_msg = ''' TCP port to run the container under. If this integer value is in the inclusive range of 0-24, it is assumed that the intended TCP port is really an offset equivalent to the following: REAL TCP PORT = port*2 + 3050 + $ACS_INSTANCE*100. If this integer value is greater than 24, the TCP port is used as provided. The only stipulation to this is that odd TCP port numbers from 3000-4000 are not available. These are reserved exclusively for so-called remote debuggable containers (Java-only). Also, it is important to note that $ACS_INSTANCE==0 is a special case in which ports 4000-5000 are used implying a total number of 500 allowable containers. ''' parser.add_option("--port", dest="port", help=port_help_msg) #end-users can use this parameter to specify the name of the container name_help_msg = ''' Name of the container. Users can optionally specify the name of the container directly using this command-line switch. If this switch is not used, it is assumed the first argument after all command-line switches is the name of the container. ''' parser.add_option("--name", dest="name", help=name_help_msg) #Java containers parser.add_option("--java", action="store_true", dest="java", default=0, help="Specifies the container is Java.") #Alternative Java container class parser.add_option( "--custom_java", dest="custom_container", default="alma.acs.container.AcsContainerRunner", help="Alternative Java class to use for the container implementation.") #C++ containers parser.add_option("--cpp", action="store_true", dest="cpp", default=0, help="Specifies the container is C++.") #Python containers parser.add_option("--py", action="store_true", dest="py", default=0, help="Specifies the container is Python.") #Debug flag parser.add_option( "--debug", action="store_true", dest="debug", default=0, help="Prints out special debugging info to standard error.") #Reference to manager. mgr_help_msg = ''' Set's manager's reference. Tells the container where its manager is. E.g., corbaloc::127.0.0.1:3100/Manager ''' parser.add_option("-m", "--managerReference", dest="manager_reference", help=mgr_help_msg) #Reference to the CDB. cdb_help_msg = ''' Sets a reference to the configuration database. Tells the container where to find its own configuration data. This is currently only applicable to C++ containers. E.g., corbaloc::127.0.0.1:3012/CDB ''' parser.add_option("-d", "--DALReference", dest="cdb_ref", help=cdb_help_msg) #Custom executable exe_help_msg = ''' Sets a custom executable to be run. The value given here replaces the standard command to start a container in a particular programming language. E.g., you might want to replace the C++ executable, maciContainer, with some specialized container you wrote - myMaciContainer. ''' parser.add_option("-e", "--executable", dest="executable", help=exe_help_msg) #Remote host remote_help_msg = ''' Sets a remote PC to run the container under. When this flag is given, the container is run under the host specified from the command-line rather than the localhost. Minimal checks are performed to ensure the remote host actually exists and is reachable. For this to work, it is necessary that SSH be configured in such a way that $USER can ssh into the remote host without being asked for a password. ''' parser.add_option("--remoteHost", dest="remote_host", help=remote_help_msg) remote_debug_msg = ''' Makes the Java container accessible by a remote debugger. Deprecated. The remote debuggable Java container feature is now activated by setting $ACS_LOG_SDTOUT less than or equal to the DEBUG log level. ''' parser.add_option("--remoteDebuggable", dest="remote_debuggable", action="store_true", default=0, help=remote_debug_msg) #baseport baseport_help_msg = ''' ACS baseport (i.e., 0-9). Setting this flag overrides the value of $ACS_LOG_STDOUT. ''' parser.add_option("-b", "--baseport", dest="baseport", help=baseport_help_msg, default=None) #Container flags flags_help_msg = '''Sets flags that are to be passed to the actual container.''' parser.add_option("-p", "--passthrough", dest="container_flags", default=None, help=flags_help_msg) #Start Options opt_help_msg = '''Sets options that are to be passed to the actual container start executables.''' parser.add_option("--passthroughProcessStart", dest="start_options", default=None, help=opt_help_msg) #-------------------------------------------------------------------------- #--Make commands backwards compatible with pre ACS 6.0 usage. #--Basically this means that commands of the form -xy... should still #--be supported. This manual manipulation of prog_args is necessary as #--optparse only supports switches of the form --xy... #go through every potential command-line switch for i in range(0, len(prog_args)): if prog_args[i] == "-h" or prog_args[i] == "--help": parser.print_help() return 0 #if the switch is something like -managerReference change it #to --managerReference if len(prog_args[i] ) > 2 and prog_args[i][0] == '-' and prog_args[i][1] != '-': prog_args[i] = "-" + prog_args[i] #-------------------------------------------------------------------------- #--Parse everything and throw the results into global variables (options, parsed_argv) = parser.parse_args(args=prog_args) cl_port = options.port cl_name = options.name cl_java = options.java cl_java_container = options.custom_container cl_cpp = options.cpp cl_py = options.py cl_remote_host = options.remote_host cl_remote_debuggable = options.remote_debuggable cl_cdb_ref = options.cdb_ref cl_baseport = options.baseport cl_flags = options.container_flags cl_start_options = options.start_options __DEBUG__ = options.debug #-------------------------------------------------------------------------- #--Go through the command-line arguments: #-- creating a few global variables based on them #-- do a little preprocessing on their values #--determine the ACS_INSTANCE if cl_baseport == None: cl_baseport = int(environ['ACS_INSTANCE']) else: cl_baseport = int(cl_baseport) #--set manager's reference if options.manager_reference == None: if environ.has_key('MANAGER_REFERENCE'): #Found it! OK to set now. cl_manager = environ['MANAGER_REFERENCE'] else: #Assume manager is running under the local machine manager_port = cl_baseport * 100 + 3000 + 0 cl_manager = 'corbaloc::' + str( getIP()) + ':' + str(manager_port) + '/Manager' else: cl_manager = options.manager_reference #--set the custom executable if options.executable == None: if cl_java: cl_executable = "acsStartJavaContainer" elif cl_cpp: cl_executable = "maciContainer" elif cl_py: cl_executable = "ACSStartContainerPy" else: stderr.write("Unable to continue. No container type specified!\n") return 3 else: cl_executable = options.executable #--if the remote host is set, setup the command to reflect this if cl_remote_host != None: container_host = cl_remote_host cl_executable = "ssh -f " + environ[ 'USER'] + "@" + cl_remote_host + " " + cl_executable #sanity check to ensure this host exists stuff = subprocess.Popen('ping -c 1 ' + container_host, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read() if ('unknown host' in stuff) or ('request timed out' in stuff): stderr.write("The remote host, " + container_host + ", is not accessible from this machine!\n") return 1 #just use the local address else: container_host = getIP() #no container name specified if cl_name == None: if len(parsed_argv) == 0: stderr.write( "Must specificy a container name using the -name option!\n") return 5 #error is recoverable - container name specified as a general argument else: cl_name = parsed_argv.pop(0) #turn the TCP port into the real TCP port if cl_port != None: if __DEBUG__: stderr.write("-port option was specified:" + str(cl_port) + "\n") #string to int newPort = int(cl_port) #try to coerce the port number into a proper TCP port number newPort = coercePortNumber(newPort) else: newPort = None #-------------------------------------------------------------------- #--GLOBALS----------------------------------------------------------- #get the file which shows us which ports are currently taken up container_file = getPortsFile(cl_baseport) #get dictionaries mapping container names to TCP port numbers and hosts container_ports, container_hosts = getContainerDict(container_file) #-------------------------------------------------------------------- #--SANITY CHECKS----------------------------------------------------- #multiple container types specified if (cl_java and cl_cpp) or (cl_java and cl_py) or (cl_cpp and cl_py): stderr.write("Too many -java/-cpp/-py options supplied!\n") stderr.write("Choose only one and try again!\n") return 6 #no container type specified if not (cl_java or cl_cpp or cl_py): stderr.write( "You must choose some container type using one of the -java/-cpp/-py options!\n" ) return 7 #recorded host is different from commanded host if container_hosts.has_key( cl_name) and container_hosts[cl_name] != container_host: stderr.write("Trying to run the '" + cl_name + "' container on '" + container_host + "' instead of '" + container_hosts[cl_name] + "' impossible!\n") stderr.write( "Changing hosts after a container is restarted is not permitted!\n" ) return 8 #recorded TCP port requested is different from commanded TCP port if newPort != None and container_ports.has_key( cl_name) and container_ports[cl_name] != newPort: stderr.write("Trying to change the '" + cl_name + "' container's TCP port from '" + str(container_ports[cl_name]) + "' to '" + str(newPort) + "' is impossible!\n") stderr.write( "Changing TCP ports after a container is restarted is not permitted!\n" ) return 9 #ensure developer hasn't picked something that's already being used elif newPort != None and ( not container_ports.has_key(cl_name)) and portNumberAlreadyUsed( newPort, container_host, container_ports, container_hosts): stderr.write("Port number specified via -port switch, " + str(newPort) + ", is already assigned!\n") return 10 #the desired TCP port is in use by some other process if newPort != None and not portIsFree(container_host, newPort): stderr.write( "Cannot use the '" + str(newPort) + "' TCP port as it's being tied up by some other process!\n") stderr.write( "Use the netstat command to find the offending process!\n") return 11 #----------------------------------------------------------------------------- #debugging purposes only! if __DEBUG__: stderr.write("Command-line TCP port:" + str(cl_port) + "\n") stderr.write("Command-line container name:" + str(cl_name) + "\n") stderr.write("New args:" + str(parsed_argv) + "\n") if cl_java: stderr.write("Dealing with a Java container\n") stderr.write("Container implementation class:" + str(cl_java_container) + "\n") elif cl_cpp: stderr.write("Dealing with a C++ container\n") elif cl_py: stderr.write("Dealing with a Python container\n") else: stderr.write("Unknown container type. This is very bad!\n") stderr.write("Manager corbaloc is:" + str(cl_manager) + "\n") stderr.write("Executable to be run is:" + str(cl_executable) + "\n") stderr.write("Remote host to run the container under is:" + str(cl_remote_host) + "\n") stderr.write("Remote debuggable is:" + str(cl_remote_debuggable) + "\n") #----------------------------------------------------------------------------- #--MAIN----------------------------------------------------------------------- #see if it's been set before... temp_port, temp_host = getExistingPort(cl_name, container_ports, container_hosts) #container already had a port assigned to it. fine. if temp_port != None: #overwrite any value the user may have tried to specify using #the port switch. if it's been set before, it must remain the same. newPort = temp_port container_host = temp_host #if this container is being run for the first time and #the user doesn't care which port it runs on elif newPort is None: #just get the next available TCP port. This will always #work unless there are 25+ containers newPort = getNextAvailablePort(container_host, container_ports, container_hosts, cl_baseport) #container does not already have a port assigned to it and the #new port is not nil... if temp_port == None and newPort != None: container_file.writelines( [cl_name + ' ' + str(newPort) + ' ' + str(container_host) + '\n']) cleanUp() #at this point we should have found a free port number. #we can now close up the container_file so that other containers #can be started immediately. if newPort == None: #could not find a free port. no point in going on. stderr.write("All ports are taken!\n") return 2 ################################################################ #generate a new commandline argument i = 0 #name of the executable parsed_argv.insert(i, cl_executable) i = i + 1 #name of the container parsed_argv.insert(i, cl_name) i = i + 1 #add any container flags passed if cl_start_options: #parsed_argv.insert(i, "--passthroughProcessStart") #i = i + 1 parsed_argv.insert(i, cl_start_options) i = i + 1 #figure out the correct language first if cl_java: parsed_argv.insert(i, cl_java_container) i = i + 1 parsed_argv.insert(i, "-OAIAddr") i = i + 1 parsed_argv.insert(i, container_host) i = i + 1 parsed_argv.insert(i, "-OAport") i = i + 1 parsed_argv.insert(i, str(newPort)) i = i + 1 elif cl_cpp: parsed_argv.insert(i, "-ORBEndpoint") i = i + 1 parsed_argv.insert(i, "iiop://" + container_host + ':' + str(newPort)) i = i + 1 if cl_cdb_ref != None: stderr.write("This container will use " + str(cl_cdb_ref) + " for the CDB.\n") parsed_argv.insert(i, "-d " + str(cl_cdb_ref)) i = i + 1 elif cl_py: parsed_argv.insert(i, "-ORBendPoint") i = i + 1 parsed_argv.insert(i, "giop:tcp:" + container_host + ':' + str(newPort)) i = i + 1 #ACS 2.1 usage retained for backwards compatiablity else: stderr.write("ACS 2.1 usage of this script deprecated and removed\n") return 1 #add the manager reference parsed_argv.insert(i, "-m " + str(cl_manager)) i = i + 1 #add any container flags passed if cl_flags: parsed_argv.insert(i, cl_flags) i = i + 1 ################################################################ #Finally print out the command. for arg in parsed_argv: print arg, print ################################################################ return 0