#!/usr/bin/env python """examines environment, then: - configures classpath as per environment or command-line options - detects Tomcat (on Windows) - detects or configures directories according to command-line options""" import platform import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, sep, pathsep, pardir from glob import glob as _glob # list of JARs that provide the build dependencies # "j" generally means /usr/share/java # when adding a new system JAR file: # 1. check the hard_deps variable at the bottom and add the appropriate packaging information, # 2. add the RPM package that contains the jarfile into the cloud.spec file, and the DEB package into the debian/control file # 3. (the jars specified here will be looked up at runtime with build-classpath, on linux installs) systemjars = { 'common': ( "commons-collections.jar", # "commons-daemon.jar", "commons-dbcp.jar", "commons-logging.jar", "commons-logging-api.jar", "commons-pool.jar", "commons-httpclient.jar", "ws-commons-util.jar", ), 'Fedora': ( "tomcat6-servlet-2.5-api.jar", #"tomcat6/catalina.jar", # all supported distros put the file there ), 'CentOS': ( "tomcat6-servlet-2.5-api.jar", #"tomcat6/catalina.jar", # all supported distros put the file there ), 'Ubuntu': ( "servlet-api-2.5.jar", #"catalina.jar", ), 'Windows': ( "servlet-api.jar", # this ships with Tomcat in lib/ #"catalina.jar", ), 'Mac': ( "servlet-api.jar", ), } #A JAR dependency may be: #- required during compile-time #- required during run-time #A JAR file can be available: #- in Tomcat lib/ #- as a Linux system package #- in the cloud-deps package #- in the cloud-premium package # servlet-api: #- is required during compile-time #- is required during management server run-time #- is available in Tomcat lib/ (Windows/Mac) AND as a system package (Linux) # -> ERGO, we do not need to include it # but it should be named on the SYSTEMJARS (which is then used in the tomcat6.conf to build the MS classpath), # and it should also be in the compile-time CLASSPATH # ===================================== # list of dependencies for configure check # (classname,fedora package name,ubuntu package name) # when adding a package name here, also add to the spec or debian control file hard_deps = [ ('java.io.FileOutputStream',"java-devel","openjdk-6-jdk"), ('javax.servlet.http.Cookie',"tomcat6-servlet-2.5-api","libservlet2.5-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"), ('org.apache.naming.resources.Constants',"tomcat6-lib","libtomcat6-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"), ] conf.check_tool('misc') conf.check_tool('java') conf.check_tool("gnu_dirs") conf.check_tool("python") conf.check_python_version((2,4,0)) conf.check_message_1('Detecting distribution') if platform.system() == 'Windows': conf.env.DISTRO = "Windows" elif platform.system() == 'Darwin': conf.env.DISTRO = "Mac" elif _exists("/etc/network"): conf.env.DISTRO = "Ubuntu" elif _exists("/etc/fedora-release"): conf.env.DISTRO = "Fedora" elif _exists("/etc/centos-release") or _exists("/etc/redhat-release"): conf.env.DISTRO = "CentOS" else: conf.env.DISTRO = "unknown" if conf.env.DISTRO == "unknown": c = "YELLOW" else: c = "GREEN" conf.check_message_2(conf.env.DISTRO,c) if conf.env.DISTRO not in ["Windows","Mac"]: conf.check_tool('compiler_cc') conf.check_cc(lib='pthread') conf.check_cc(lib='dl') # waf uses slashes somewhere along the line in some paths. we fix them on windows. if conf.env.DISTRO in ['Windows']: for pth in [ x for x in conf.env.get_merged_dict().keys() if x.endswith("DIR") ]: conf.env[pth] = conf.env[pth].replace("/","\\") for a in "DBHOST DBUSER DBPW DBDIR".split(): conf.env[a] = getattr(Options.options, a, '') conf.check_message_1('Determining management server user name') msuser = getattr(Options.options, 'MSUSER', '') if msuser: conf.env.MSUSER = msuser conf.check_message_2("%s (forced through --tomcat-user)"%conf.env.MSUSER,"GREEN") else: if conf.env.DISTRO in ['Windows','Mac']: conf.env.MSUSER = 'root' conf.check_message_2("%s (not used on Windows or Mac)"%conf.env.MSUSER,"GREEN") else: conf.env.MSUSER = conf.env.PACKAGE conf.check_message_2("%s (Linux default)"%conf.env.MSUSER,"GREEN") conf.check_message_1('Detecting Tomcat') tomcathome = getattr(Options.options, 'TOMCATHOME', '') if tomcathome: conf.env.TOMCATHOME = tomcathome conf.check_message_2("%s (forced through --with-tomcat)"%conf.env.TOMCATHOME,"GREEN") else: if "TOMCAT_HOME" in conf.environ and conf.environ['TOMCAT_HOME'].strip(): conf.env.TOMCATHOME = conf.environ["TOMCAT_HOME"] conf.check_message_2("%s (got through environment variable %%TOMCAT_HOME%%)"%conf.env.TOMCATHOME,"GREEN") elif "CATALINA_HOME" in conf.environ and conf.environ['CATALINA_HOME'].strip(): conf.env.TOMCATHOME = conf.environ['CATALINA_HOME'] conf.check_message_2("%s (got through environment variable %%CATALINA_HOME%%)"%conf.env.TOMCATHOME,"GREEN") elif _isdir("/usr/share/tomcat6"): conf.env.TOMCATHOME = "/usr/share/tomcat6" conf.check_message_2("%s (detected existence of system directory)"%conf.env.TOMCATHOME,"GREEN") else: conf.env.TOMCATHOME = _join(conf.env.DATADIR,'tomcat6') conf.check_message_2("%s (assumed presence of Tomcat there)"%conf.env.TOMCATHOME,"GREEN") conf.env.AGENTPATH = _join(conf.env.PACKAGE,"agent") conf.env.CPPATH = _join(conf.env.PACKAGE,"console-proxy") conf.env.MSPATH = _join(conf.env.PACKAGE,"management") conf.env.USAGEPATH = _join(conf.env.PACKAGE,"usage") conf.env.SETUPPATH = _join(conf.env.PACKAGE,"setup") conf.env.SERVERPATH = _join(conf.env.PACKAGE,"server") if conf.env.DISTRO in ['Windows','Mac']: conf.env.MSENVIRON = conf.env.TOMCATHOME conf.env.MSCONF = _join(conf.env.TOMCATHOME,"conf") conf.env.MSLOGDIR = _join(conf.env.TOMCATHOME,"logs") conf.env.MSMNTDIR = _join(conf.env.TOMCATHOME,"mnt") else: conf.env.MSENVIRON = _join(conf.env.DATADIR,conf.env.MSPATH) conf.env.MSCONF = _join(conf.env.SYSCONFDIR,conf.env.MSPATH) conf.env.MSLOGDIR = _join(conf.env.LOCALSTATEDIR,"log",conf.env.MSPATH) conf.env.MSMNTDIR = _join(conf.env.SHAREDSTATEDIR,conf.env.PACKAGE,"mnt") conf.env.PIDDIR = _join(conf.env.LOCALSTATEDIR,"run") conf.env.LOCKDIR = _join(conf.env.LOCALSTATEDIR,"lock","subsys") conf.check_message_1('Detecting JAVADIR') javadir = getattr(Options.options, 'JAVADIR', '') if javadir: conf.env.JAVADIR = javadir conf.check_message_2("%s (forced through --javadir)"%conf.env.JAVADIR,"GREEN") elif conf.env.DISTRO in ['Windows','Mac']: conf.env.JAVADIR = _join(conf.env['TOMCATHOME'],'lib') conf.check_message_2("%s (using Tomcat's lib/ directory)"%conf.env.JAVADIR,"GREEN") else: conf.env.JAVADIR = _join(conf.env.DATADIR,'java') conf.check_message_2("%s (using default ${DATADIR}/java directory)"%conf.env.JAVADIR,"GREEN") if conf.env.DISTRO in ["Windows","Mac"]: conf.env.PREMIUMJAVADIR = conf.env.JAVADIR conf.env.PLUGINJAVADIR = conf.env.JAVADIR conf.env.SYSTEMJAVADIR = conf.env.JAVADIR else: conf.env.PREMIUMJAVADIR = _join(conf.env.JAVADIR,"%s-premium"%conf.env.PACKAGE) conf.env.PLUGINJAVADIR = _join(conf.env.JAVADIR,"%s-plugins"%conf.env.PACKAGE) conf.env.SYSTEMJAVADIR = "/usr/share/java" in_javadir = lambda name: _join(conf.env.JAVADIR,_basename(name)) # $PREFIX/share/java in_system_javadir = lambda name: _join(conf.env.SYSTEMJAVADIR,name) # /usr/share/java in_premiumjavadir = lambda name: _join(conf.env.PREMIUMJAVADIR,name) # $PREFIX/share/java/cloud-premium conf.check_message_1('Building classpaths') # == Here we build the run-time classpaths == # The system classpath points to JARs we expect the user has installed using distro packages # not used for Windows and Mac (except for servlet-api.jar) because we install them from the thirdparty/ directory sysjars = list(systemjars['common']) if conf.env.DISTRO in systemjars.keys(): sysjars = sysjars + list(systemjars[conf.env.DISTRO]) conf.env.SYSTEMJARS = " ".join(sysjars) # used by build-classpath in the initscripts conf.env.SYSTEMCLASSPATH = pathsep.join([ in_system_javadir(x) for x in sysjars ]) # used for compile, waf run and simulate_agent # the deps classpath points to JARs that are installed in the cloud-deps package # these will install on Tomcat6's lib/ directory on Windows and Mac depsclasspath = [ in_javadir(_basename(x)) for x in _glob(_join(conf.srcdir,"deps","*.jar")) ] conf.env.DEPSCLASSPATH = pathsep.join(depsclasspath) # the MS classpath points to JARs required to run the management server msclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras core-extras".split() ] conf.env.MSCLASSPATH = pathsep.join(msclasspath) # the agent and simulator classpaths point to JARs required to run these two applications agentclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras agent console-common console-proxy core-extras console-proxy-premium".split() ] conf.env.AGENTCLASSPATH = pathsep.join(agentclasspath) conf.env.AGENTSIMULATORCLASSPATH = pathsep.join(agentclasspath+[in_javadir("%s-agent-simulator.jar"%conf.env.PACKAGE)]) usageclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras usage core-extras".split() ] conf.env.USAGECLASSPATH = pathsep.join(usageclasspath) # the premium classpath was ELIMINATED # CloudStack now detects the premium classpath at runtime by iterating through the JAR files in @PREMIUMJAVADIR@ # premium JARs will install on Tomcat6's lib/ directory on Windows and Mac # The compile path is composed of the # 1. source directories (without including the JARs) # JARs are not included because in case of parallel compilation (IOW, all the time), javac picks up half-written JARs and die compilecp = []# list(srcdirs) # 2.a) the thirdparty/ directory in the source if on Windows / Mac # 2.b) the deps/ directory in the source if on Linux if conf.env.DISTRO in ["Windows","Mac"]: compilecp+= _glob(_join("cloudstack-proprietary","thirdparty","*.jar")) else: compilecp+= _glob(_join("deps","*.jar")) # 3. the system classpath (system-installed JARs) compilecp+= [ conf.env.SYSTEMCLASSPATH ] compilecp+= _glob(_join(conf.env.TOMCATHOME,'bin',"*.jar")) compilecp+= _glob(_join(conf.env.TOMCATHOME,'lib',"*.jar")) conf.env.CLASSPATH = pathsep.join(compilecp) conf.check_message_2('Done','GREEN') conf.env.VERSION = Utils.g_module.VERSION conf.env.AGENTLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${AGENTPATH}"),conf.env) conf.env.AGENTSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${AGENTPATH}"),conf.env) conf.env.AGENTLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${AGENTPATH}"),conf.env) conf.env.USAGELOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${USAGEPATH}"),conf.env) conf.env.USAGESYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${USAGEPATH}"),conf.env) conf.env.CPLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${CPPATH}"),conf.env) conf.env.CPSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CPPATH}"),conf.env) conf.env.CPLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${CPPATH}"),conf.env) conf.env.MSLOG = _join(conf.env.MSLOGDIR,"management-server.log") conf.env.APISERVERLOG = _join(conf.env.MSLOGDIR,"api-server.log") conf.env.AGENTLOG = _join(conf.env.AGENTLOGDIR,"agent.log") conf.env.USAGELOG = _join(conf.env.USAGELOGDIR,"usage.log") conf.env.CPLOG = _join(conf.env.CPLOGDIR,"console-proxy.log") conf.env.SETUPDATADIR = Utils.subst_vars(_join("${DATADIR}","${SETUPPATH}"),conf.env) conf.env.SERVERSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${SERVERPATH}"),conf.env) # log4j config and property config files require backslash escapes on Windows if conf.env.DISTRO in ["Windows"]: for log in "MSLOG APISERVERLOG AGENTLIBDIR USAGELOG AGENTLOG".split(): conf.env[log] = conf.env[log].replace("\\","\\\\") no_java_class = lambda x: conf.check_java_class(x,with_classpath=conf.env.CLASSPATH) != 0 def require_dependency(javacls,packagenames): if no_java_class(javacls): conf.fatal("Cannot find the Java class %s (available in the distro packages: %s)"%( javacls, ", ".join(packagenames))) def check_dependencies(deps): for d in deps: cls,pkgs = d[0],d[1:] require_dependency(cls,pkgs) if not getattr(Options.options, 'NODEPCHECK', ''): check_dependencies(hard_deps) Utils.pprint("WHITE","Configure finished. Use 'python waf showconfig' to show the configure-time environment.")