mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-16 15:45:04 +08:00
Merge pull request #20531 from natefoo/config-script-fixes
[25.0] Fix `galaxy-config` script, move install to `galaxy-dependencies` in app package
This commit is contained in:
+44
-39
@@ -5,19 +5,12 @@ import string
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
|
||||
try:
|
||||
import pip
|
||||
except ImportError:
|
||||
pip = None # type: ignore[assignment]
|
||||
|
||||
|
||||
CONFIGURE_URL = "https://docs.galaxyproject.org/en/master/admin/"
|
||||
|
||||
DESCRIPTION = "Initialize a directory with a minimal Galaxy config."
|
||||
HELP_CONFIG_DIR = "Directory containing the configuration files for Galaxy."
|
||||
HELP_DATA_DIR = "Directory containing Galaxy-created data."
|
||||
HELP_FORCE = "Overwrite existing files if they already exist."
|
||||
HELP_INSTALL = "Install optional dependencies required by specified configuration (e.g. drmaa, etc...)."
|
||||
HELP_HOST = (
|
||||
'Host to bind Galaxy to - defaults to localhost. Specify an IP address or "all" to listen on all interfaces.'
|
||||
)
|
||||
@@ -26,41 +19,57 @@ HELP_DB_CONN = "Galaxy database connection URI."
|
||||
|
||||
DEFAULT_HOST = "localhost"
|
||||
DEFAULT_YML = "galaxy.yml"
|
||||
DEFAULT_DB_CONN = "sqlite:///./database/universe.sqlite?isolation_level=IMMEDIATE"
|
||||
|
||||
SAMPLES_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "sample"))
|
||||
GALAXY_CONFIG_TEMPLATE_FILE = os.path.join(SAMPLES_PATH, "galaxy.yml.sample")
|
||||
STATIC_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, "web", "framework", "static"))
|
||||
CLIENT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, "client"))
|
||||
|
||||
MSG_CONFIG_SUMMARY = """
|
||||
For help on configuring Galaxy, consult the documentation at: \n {}
|
||||
Perform additional configuration by editing the config file at:
|
||||
|
||||
{config_path}
|
||||
|
||||
For help on configuring Galaxy, consult the documentation at:
|
||||
|
||||
{configure_url}
|
||||
|
||||
Additional sample configuration files for various Galaxy components (jobs,
|
||||
datatypes, etc.) can be found in:\n {}
|
||||
datatypes, etc.) can be found in:
|
||||
|
||||
Start Galaxy by running the command from directory [{}]:
|
||||
{samples_path}
|
||||
|
||||
Advanced job configurations can be generated with galaxy-job-config-init. It
|
||||
can be installed and run with:
|
||||
|
||||
pip install galaxy-job-config-init
|
||||
galaxy-job-config-init --help
|
||||
|
||||
Some Galaxy dependencies are optional based on your configuration. You can
|
||||
install them with:
|
||||
|
||||
galaxy-dependencies --install
|
||||
|
||||
Start Galaxy by running the command:
|
||||
|
||||
galaxy -c {config_path}
|
||||
"""
|
||||
|
||||
# The sample is used as the default config file for Galaxy started without a config, and we don't want to duplicate the
|
||||
# whole thing into galaxy.config for templating, so for now just substitute some lines. In the future we will build
|
||||
# configs differently.
|
||||
GALAXY_CONFIG_SUBSTITUTIONS = {
|
||||
" #config_dir: false": " config_dir: ${config_dir}",
|
||||
" #data_dir: false": " data_dir: ${data_dir}",
|
||||
" #database_connection: sqlite:///./database/universe.sqlite?isolation_level=IMMEDIATE": " database_connection: ${database_connection}",
|
||||
" #config_dir: null": " config_dir: ${config_dir}",
|
||||
" #data_dir: null": " data_dir: ${data_dir}",
|
||||
" # bind: localhost:8080": " bind: ${host}:${port}",
|
||||
}
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
dependencies = []
|
||||
arg_parser = ArgumentParser(description=DESCRIPTION)
|
||||
arg_parser.add_argument("--config-dir", default=".", help=HELP_CONFIG_DIR)
|
||||
arg_parser.add_argument("--data-dir", default="./data", help=HELP_DATA_DIR)
|
||||
arg_parser.add_argument("--host", default=DEFAULT_HOST, help=HELP_HOST)
|
||||
arg_parser.add_argument("--port", default="8080", help=HELP_PORT)
|
||||
arg_parser.add_argument("--db-conn", default=DEFAULT_DB_CONN, help=HELP_DB_CONN)
|
||||
arg_parser.add_argument("--install", action="store_true", help=HELP_INSTALL)
|
||||
arg_parser.add_argument("--db-conn", help=HELP_DB_CONN)
|
||||
arg_parser.add_argument("--force", action="store_true", default=False, help=HELP_FORCE)
|
||||
args = arg_parser.parse_args(argv)
|
||||
config_dir = args.config_dir
|
||||
@@ -70,33 +79,39 @@ def main(argv=None):
|
||||
data_dir = os.path.abspath(data_dir)
|
||||
|
||||
mode = _determine_mode(args)
|
||||
if args.db_conn.startswith("postgresql://"):
|
||||
dependencies.append("psycopg2-binary")
|
||||
if args.db_conn:
|
||||
GALAXY_CONFIG_SUBSTITUTIONS[" #database_connection: null"] = " database_connection: ${database_connection}"
|
||||
|
||||
for directory in (config_dir, data_dir):
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
print(f"Bootstrapping Galaxy configuration into directory {relative_config_dir}")
|
||||
print(f"* Bootstrapping Galaxy configuration into directory: {relative_config_dir}")
|
||||
_handle_galaxy_yml(args, config_dir, data_dir)
|
||||
_handle_install(args, dependencies)
|
||||
_print_config_summary(args, mode, relative_config_dir)
|
||||
|
||||
|
||||
def _print_config_summary(args, mode, relative_config_dir):
|
||||
_print_galaxy_yml_info(args, mode)
|
||||
print(MSG_CONFIG_SUMMARY.format(CONFIGURE_URL, SAMPLES_PATH, relative_config_dir))
|
||||
config_path = os.path.join(args.config_dir, DEFAULT_YML)
|
||||
print(
|
||||
MSG_CONFIG_SUMMARY.format(
|
||||
configure_url=CONFIGURE_URL,
|
||||
samples_path=SAMPLES_PATH,
|
||||
config_path=config_path,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _print_galaxy_yml_info(args, mode):
|
||||
print(" - galaxy.yml created, update to configure Galaxy.")
|
||||
print(f" * Target web server {mode}")
|
||||
print("* Configuration created")
|
||||
print(f" - Target web server [{mode}]")
|
||||
if args.host == DEFAULT_HOST:
|
||||
print(" * Binding to host localhost, remote clients will not be able to connect.")
|
||||
print(f" - Binding to [localhost:{args.port}], remote clients will not be able to connect.")
|
||||
elif _determine_host(args) == "0.0.0.0":
|
||||
print(" * Binding to all network interfaces.")
|
||||
print(" - Binding to all network interfaces.")
|
||||
else:
|
||||
print(" * Binding to host [%s].", args.host)
|
||||
print(f" - Binding to [{args.host}:{args.port}].")
|
||||
|
||||
|
||||
def _determine_mode(args):
|
||||
@@ -120,8 +135,6 @@ def _handle_galaxy_yml(args, config_dir, data_dir):
|
||||
host=_determine_host(args),
|
||||
config_dir=config_dir,
|
||||
data_dir=data_dir,
|
||||
client_dir=CLIENT_PATH,
|
||||
static_path=STATIC_PATH,
|
||||
database_connection=args.db_conn,
|
||||
)
|
||||
|
||||
@@ -139,14 +152,6 @@ def _handle_galaxy_yml(args, config_dir, data_dir):
|
||||
open(yml_file, "w").write(galaxy_config)
|
||||
|
||||
|
||||
def _handle_install(args, dependencies):
|
||||
if args.install and dependencies:
|
||||
if pip is None:
|
||||
raise ImportError("Bootstrapping Galaxy dependencies requires pip.")
|
||||
|
||||
pip.main(["install"] + dependencies)
|
||||
|
||||
|
||||
def _check_file(path, force):
|
||||
if os.path.exists(path) and not force:
|
||||
print(f"File {path} exists, exiting. Run with --force to replace configuration.", file=sys.stderr)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import errno
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
from subprocess import check_call
|
||||
|
||||
import galaxy.dependencies
|
||||
|
||||
DESCRIPTION = "Install optional Galaxy dependencies based on configuration values"
|
||||
PINNED_REQUIREMENTS = os.path.join(os.path.dirname(__file__), "pinned-requirements.txt")
|
||||
|
||||
HELP_PINNED = (
|
||||
"Include pinned required dependencies in install command, ensures all dependencies are installed at "
|
||||
"expected versions for the Galaxy release"
|
||||
)
|
||||
HELP_INSTALL = "Perform install, if unset then only output what would have been performed"
|
||||
HELP_FREEZE = "Instead of installing, output requirent format to stdout"
|
||||
HELP_CONFIG_FILE = "Path to Galaxy config file (galaxy.yml)"
|
||||
|
||||
# Warnings raised by dependency imports
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
dependencies = []
|
||||
arg_parser = ArgumentParser(description=DESCRIPTION)
|
||||
arg_parser.add_argument("--pinned", action="store_true", help=HELP_PINNED)
|
||||
arg_parser.add_argument("--install", action="store_true", help=HELP_INSTALL)
|
||||
arg_parser.add_argument("--freeze", action="store_true", help=HELP_FREEZE)
|
||||
arg_parser.add_argument("--config_file", "-c", help=HELP_CONFIG_FILE)
|
||||
args = arg_parser.parse_args(argv)
|
||||
config_file = args.config_file
|
||||
if config_file and not os.path.exists(config_file):
|
||||
print(f"{arg_parser.prog}: {config_file}: {os.strerror(errno.ENOENT)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
dependencies = galaxy.dependencies.optional(config_file)
|
||||
if args.freeze:
|
||||
_handle_freeze(args, dependencies)
|
||||
elif dependencies or args.pinned:
|
||||
_handle_install(args, dependencies)
|
||||
else:
|
||||
print("Nothing to install", file=sys.stderr)
|
||||
|
||||
|
||||
def _handle_freeze(args, dependencies):
|
||||
print("# generated with galaxy-dependencies")
|
||||
if args.pinned:
|
||||
print(f"-r {PINNED_REQUIREMENTS}")
|
||||
print("\n".join(dependencies))
|
||||
|
||||
|
||||
def _handle_install(args, dependencies):
|
||||
req_file = []
|
||||
if args.pinned:
|
||||
req_file = ["-r", PINNED_REQUIREMENTS]
|
||||
cmd = [sys.executable, "-m", "pip", "install"] + req_file + dependencies
|
||||
print("Installing dependencies with:", file=sys.stderr)
|
||||
print(f"> {shlex.join(cmd)}", file=sys.stderr)
|
||||
if args.install:
|
||||
check_call(cmd)
|
||||
else:
|
||||
print("Dry run, use --install to perform installation", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -85,6 +85,7 @@ python_requires = >=3.9
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
galaxy-main = galaxy.main:main
|
||||
galaxy-dependencies = galaxy.dependencies.script:main
|
||||
|
||||
[options.packages.find]
|
||||
exclude =
|
||||
|
||||
Reference in New Issue
Block a user