1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/16efc5713d85/
Changeset: 16efc5713d85
User: jmchilton
Date: 2015-02-02 05:54:51+00:00
Summary: Allow web-less job/workflow handlers.
See notes in lib/galaxy/main.py for usage. lib/galaxy/main.py basically sets up an app
(minus web controllers) very much in the way paste would but without binding it to a port.
Pass --server-name to specify a server name (presumably a job handler found in
job_conf.xml).
An optional --daemonize mode is available - though it requires the daemonize library
(install with `pip install daemonize`).
Based on similar initial work in Pulsar (see
https://github.com/galaxyproject/pulsar/blob/master/pulsar/daemon.py).
Affected #: 2 files
diff -r 57217275bebe445be7bdae43b9072bcca47ff3e7 -r
16efc5713d85f631c8ef9ad11895730f4747ea7e lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -318,6 +318,9 @@
# Crummy, but PasteScript does not give you a way to determine this
if arg.lower().startswith('--server-name='):
self.server_name = arg.split('=', 1)[-1]
+ # Allow explicit override of server name in confg params
+ if "server_name" in kwargs:
+ self.server_name = kwargs.get("server_name")
# Store all configured server names
self.server_names = []
for section in global_conf_parser.sections():
diff -r 57217275bebe445be7bdae43b9072bcca47ff3e7 -r
16efc5713d85f631c8ef9ad11895730f4747ea7e lib/galaxy/main.py
--- /dev/null
+++ b/lib/galaxy/main.py
@@ -0,0 +1,245 @@
+""" Entry point for starting Galaxy without starting as part of a web
server.
+
+Example Usage: Start a job/workflow handler without a web server and with
+a given name using.
+
+python lib/galaxy/main.py --server-name handler0
+
+Start as a daemon with (requires daemonized - install with 'pip install
daemonize'):
+
+python lib/galaxy/main.py -d --daemon-log-file=handler0-daemon.log --pid-file
handler0.pid --server-name handler0
+
+In daemon mode logging of Galaxy (as opposed to this script) is configured via
+a loggers section in Galaxy's ini file - this can be overridden with sensible
+defaults logging to a single file with the following:
+
+python lib/galaxy/main.py -d --server-name handler0 --daemon-log-file=handler0-daemon.log
--pid-file handler0.pid --log-file handler0.log
+
+"""
+import logging
+from logging.config import fileConfig
+
+import functools
+import os
+import time
+import sys
+
+try:
+ import ConfigParser as configparser
+except ImportError:
+ import configparser
+
+try:
+ from daemonize import Daemonize
+except ImportError:
+ Daemonize = None
+
+# Vaguely Python 2.6 compatibile ArgumentParser import
+try:
+ from argparser import ArgumentParser
+except ImportError:
+ from optparse import OptionParser
+
+ class ArgumentParser(OptionParser):
+
+ def __init__(self, **kwargs):
+ self.delegate = OptionParser(**kwargs)
+
+ def add_argument(self, *args, **kwargs):
+ if "required" in kwargs:
+ del kwargs["required"]
+ return self.delegate.add_option(*args, **kwargs)
+
+ def parse_args(self, args=None):
+ (options, args) = self.delegate.parse_args(args)
+ return options
+
+REQUIRES_DAEMONIZE_MESSAGE = "Attempted to use Galaxy in daemon mode, but daemonize
is unavailable."
+
+log = logging.getLogger(__name__)
+
+GALAXY_ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..",
".."))
+GALAXY_LIB_DIR = os.path.join(GALAXY_ROOT_DIR, "lib")
+DEFAULT_INI_APP = "main"
+DEFAULT_INIS = ["config/galaxy.ini", "universe_wsgi.ini",
"config/galaxy.ini.sample"]
+
+DEFAULT_PID = "galaxy.pid"
+DEFAULT_VERBOSE = True
+DESCRIPTION = "Daemonized entry point for Galaxy."
+
+
+def load_galaxy_app(
+ config_builder,
+ config_env=False,
+ log=None,
+ **kwds
+):
+ # Allow specification of log so daemon can reuse properly configured one.
+ if log is None:
+ log = logging.getLogger(__name__)
+
+ # If called in daemon mode, set the ROOT directory and ensure Galaxy is on
+ # sys.path.
+ if config_env:
+ try:
+ os.chdir(GALAXY_ROOT_DIR)
+ except Exception:
+ log.exception("Failed to chdir")
+ raise
+ try:
+ sys.path.append(GALAXY_LIB_DIR)
+ except Exception:
+ log.exception("Failed to add Galaxy to sys.path")
+ raise
+
+ config_builder.setup_logging()
+ from galaxy.util.properties import load_app_properties
+ kwds = config_builder.app_kwds()
+ kwds = load_app_properties(**kwds)
+ from galaxy.app import UniverseApplication
+ app = UniverseApplication(
+ global_conf={"__file__": config_builder.ini_path},
+ **kwds
+ )
+ return app
+
+
+def app_loop(args, log):
+ try:
+ config_builder = GalaxyConfigBuilder(args)
+ galaxy_app = load_galaxy_app(
+ config_builder,
+ config_env=True,
+ log=log,
+ )
+ except BaseException:
+ log.exception("Failed to initialize Galaxy application")
+ raise
+ sleep = True
+ while sleep:
+ try:
+ time.sleep(5)
+ except KeyboardInterrupt:
+ sleep = False
+ except SystemExit:
+ sleep = False
+ except Exception:
+ pass
+ try:
+ galaxy_app.shutdown()
+ except Exception:
+ log.exception("Failed to shutdown Galaxy application")
+ raise
+
+
+def absolute_config_path(path, galaxy_root):
+ if path and not os.path.isabs(path):
+ path = os.path.join(galaxy_root, path)
+ return path
+
+
+def find_ini(supplied_ini, galaxy_root):
+ if supplied_ini:
+ return supplied_ini
+
+ # If not explicitly supplied an ini, check server.ini and then
+ # just restort to sample if that has not been configured.
+ for guess in DEFAULT_INIS:
+ ini_path = os.path.join(galaxy_root, guess)
+ if os.path.exists(ini_path):
+ return ini_path
+
+ return guess
+
+
+class GalaxyConfigBuilder(object):
+ """ Generate paste-like configuration from supplied command-line
arguments.
+ """
+
+ def __init__(self, args=None, **kwds):
+ ini_path = kwds.get("ini_path", None) or (args and args.ini_path)
+ # If given app_conf_path - use that - else we need to ensure we have an
+ # ini path.
+ if not ini_path:
+ galaxy_root = kwds.get("galaxy_root", GALAXY_ROOT_DIR)
+ ini_path = find_ini(ini_path, galaxy_root)
+ ini_path = absolute_config_path(ini_path, galaxy_root=galaxy_root)
+ self.ini_path = ini_path
+ self.app_name = kwds.get("app") or (args and args.app) or
DEFAULT_INI_APP
+ self.log_file = (args and args.log_file)
+
+ @classmethod
+ def populate_options(cls, arg_parser):
+ arg_parser.add_argument("-c", "--ini-path", default=None,
help="Galaxy ini config file (defaults to config/galaxy.ini)")
+ arg_parser.add_argument("--app", default=DEFAULT_INI_APP,
help="app section in ini file (defaults to main)")
+ arg_parser.add_argument("-d", "--daemonize", default=False,
help="Daemonzie process", action="store_true")
+ arg_parser.add_argument("--daemon-log-file", default=None,
help="log file for daemon script ")
+ arg_parser.add_argument("--log-file", default=None, help="Galaxy
log file (overrides log configuration in ini_path if set)")
+ arg_parser.add_argument("--pid-file", default=DEFAULT_PID,
help="pid file (default is %s)" % DEFAULT_PID)
+ arg_parser.add_argument("--server-name", default=None, help="set a
galaxy server name")
+
+ def app_kwds(self):
+ config = dict(
+ ini_file=self.ini_path,
+ ini_section="app:%s" % self.app_name,
+ )
+ return config
+
+ def setup_logging(self):
+ # Galaxy will attempt to setup logging if loggers is not present in
+ # ini config file - this handles that loggers block however if present
+ # (the way paste normally would)
+ if not self.ini_path:
+ return
+ raw_config = configparser.ConfigParser()
+ raw_config.read([self.ini_path])
+ if raw_config.has_section('loggers'):
+ config_file = os.path.abspath(self.ini_path)
+ fileConfig(
+ config_file,
+ dict(__file__=config_file, here=os.path.dirname(config_file))
+ )
+
+
+def main():
+ if Daemonize is None:
+ raise ImportError(REQUIRES_DAEMONIZE_MESSAGE)
+
+ arg_parser = ArgumentParser(description=DESCRIPTION)
+ GalaxyConfigBuilder.populate_options(arg_parser)
+ args = arg_parser.parse_args()
+ if args.log_file:
+ os.environ["GALAXY_CONFIG_LOG_DESTINATION"] =
os.path.abspath(args.log_file)
+ if args.server_name:
+ os.environ["GALAXY_CONFIG_SERVER_NAME"] = args.server_name
+ pid_file = args.pid_file
+
+ log.setLevel(logging.DEBUG)
+ log.propagate = False
+ if args.daemonize:
+ keep_fds = []
+ if args.daemon_log_file:
+ fh = logging.FileHandler(args.daemon_log_file, "w")
+ fh.setLevel(logging.DEBUG)
+ log.addHandler(fh)
+ keep_fds.append(fh.stream.fileno())
+ else:
+ fh = logging.StreamHandler(sys.stderr)
+ fh.setLevel(logging.DEBUG)
+ log.addHandler(fh)
+
+ daemon = Daemonize(
+ app="galaxy",
+ pid=pid_file,
+ action=functools.partial(app_loop, args, log),
+ verbose=DEFAULT_VERBOSE,
+ logger=log,
+ keep_fds=keep_fds,
+ )
+ daemon.start()
+ else:
+ app_loop(args, log)
+
+
+if __name__ == "__main__":
+ main()
Repository URL:
https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from
bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.