diff --git a/.gitignore b/.gitignore index 7bbbacdaa..7bbc56406 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,7 @@ pip-log.txt .metadata .tern-project -# Vim +# Vim .*.sw[a-z] *.un~ Session.vim diff --git a/src/WebAppDIRAC/Core/HandlerMgr.py b/src/WebAppDIRAC/Core/HandlerMgr.py index 06afacc3f..ef1ce93d1 100644 --- a/src/WebAppDIRAC/Core/HandlerMgr.py +++ b/src/WebAppDIRAC/Core/HandlerMgr.py @@ -46,16 +46,21 @@ def getPaths(self, dirName): """ pathList = [] for extName in extensionsByPriority(): - # TODO: Would be nicer to set these paths with setuptools metadata - try: - modFile, modPath, desc = imp.find_module(extName) - # to match in the real root path to enabling module web extensions (static, templates...) - realModPath = os.path.realpath(modPath) - except ImportError: - continue - staticPath = os.path.join(realModPath, "WebApp", dirName) - if os.path.isdir(staticPath): - pathList.append(staticPath) + if six.PY3: + metadata = getExtensionMetadata(extension) + pathList += metadata.get("web_resources", {}).get(dirName, []) + else: + # TODO: Would be nicer to set these paths with setuptools metadata + # FIXME: Use static_web_resources + try: + modFile, modPath, desc = imp.find_module(extName) + # to match in the real root path to enabling module web extensions (static, templates...) + realModPath = os.path.realpath(modPath) + except ImportError: + continue + staticPath = os.path.join(realModPath, "WebApp", dirName) + if os.path.isdir(staticPath): + pathList.append(staticPath) return pathList def __calculateRoutes(self): diff --git a/src/WebAppDIRAC/__init__.py b/src/WebAppDIRAC/__init__.py index 83f09f533..72d91e04d 100644 --- a/src/WebAppDIRAC/__init__.py +++ b/src/WebAppDIRAC/__init__.py @@ -38,6 +38,12 @@ def extension_metadata(): + import importlib.resources # pylint: disable=no-name-in-module + return { - "priority": 10 + "priority": 10, + "web_resources": { + "static": [importlib.resources.files("WebAppDIRAC") / "WebApp" / "static"], + "template": [importlib.resources.files("WebAppDIRAC") / "WebApp" / "template"], + } } diff --git a/src/WebAppDIRAC/scripts/dirac_webapp_run.py b/src/WebAppDIRAC/scripts/dirac_webapp_run.py index 518950576..e9dc2234a 100755 --- a/src/WebAppDIRAC/scripts/dirac_webapp_run.py +++ b/src/WebAppDIRAC/scripts/dirac_webapp_run.py @@ -1,10 +1,12 @@ #!/usr/bin/env python - +import os +import six import sys import tornado from DIRAC import gConfig, S_OK from DIRAC.Core.Base import Script +from DIRAC.Core.Utilities.Extensions import extensionsByPriority, getExtensionMetadata from DIRAC.Core.Utilities.DIRACScript import DIRACScript from DIRAC.ConfigurationSystem.Client.LocalConfiguration import LocalConfiguration from DIRAC.FrameworkSystem.Client.Logger import gLogger @@ -14,6 +16,48 @@ __RCSID__ = "$Id$" +def _createStaticSymlinks(targetDir): + """Create symlinks to static web content + + This method is used to populate the directory specified in the local + configuration under ``/WebApp/StaticResourceLinkDir`` so that nginx can + serve this content from a consistent location. + + :params str targetDir: The directory in which to create the symlinks + """ + extensions = extensionsByPriority() + for extension in extensions: + if six.PY3: + metadata = getExtensionMetadata(extension) + staticDirs = metadata.get("web_resources", {}).get("static", []) + else: + staticDirs = [] + try: + modFile, modPath, desc = imp.find_module(extName) + # to match in the real root path to enabling module web extensions (static, templates...) + realModPath = os.path.realpath(modPath) + except ImportError: + continue + staticDirs = [os.path.join(realModPath, "WebApp", "static")] + if not os.path.isdir(staticDirs[0]): + continue + + for i, path in enumerate(sorted(staticDirs)): + destination = os.path.join(targetDir, extension) + # If there is more than one suffix append a counter + if i >= 1: + destination += "-%s" % i + gLogger.notice(" creating symlink from", "%s to %s" % (path, destination)) + if os.path.islink(destination): + if path == os.readlink(destination): + # The link is already up to date + continue + os.unlink(destination) + os.symlink(path, destination) + + # TODO: Check /etc/nginx/conf.d/site.conf and warn if it's inconsistent? + + @DIRACScript() def main(): def disableDevMode(op): @@ -44,6 +88,13 @@ def setHandlers(op): gLogger.fatal("There were errors when loading configuration", result['Message']) sys.exit(1) + result = DIRAC.gConfig.getOption("/WebApp/StaticResourceLinkDir") + if result["OK"]: + gLogger.notice("Creating symlinks to static resources") + _createStaticSymlinks(result["Value"]) + else: + gLogger.warn("Not creating symlinks to static resources", result["Message"]) + gLogger.notice("Set next path(s): ", localCfg.handlersLoc) app = App(handlersLoc=localCfg.handlersLoc) result = app.bootstrap()