mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-24 02:04:04 +08:00
Merge pull request #5769 from jmchilton/unify_scripts
[18.01] Fix scripts/ for YAML/ENV configuration processing
This commit is contained in:
+32
-15
@@ -860,6 +860,31 @@ def get_database_engine_options(kwargs, model_prefix=''):
|
||||
return rval
|
||||
|
||||
|
||||
def get_database_url(config):
|
||||
if config.database_connection:
|
||||
db_url = config.database_connection
|
||||
else:
|
||||
db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % config.database
|
||||
return db_url
|
||||
|
||||
|
||||
def init_models_from_config(config, map_install_models=False, object_store=None, trace_logger=None):
|
||||
db_url = get_database_url(config)
|
||||
from galaxy.model import mapping
|
||||
model = mapping.init(
|
||||
config.file_path,
|
||||
db_url,
|
||||
config.database_engine_options,
|
||||
map_install_models=map_install_models,
|
||||
database_query_profiling_proxy=config.database_query_profiling_proxy,
|
||||
object_store=object_store,
|
||||
trace_logger=trace_logger,
|
||||
use_pbkdf2=config.get_bool('use_pbkdf2', True),
|
||||
slow_query_log_threshold=config.slow_query_log_threshold
|
||||
)
|
||||
return model
|
||||
|
||||
|
||||
def configure_logging(config):
|
||||
"""Allow some basic logging configuration to be read from ini file.
|
||||
|
||||
@@ -1003,10 +1028,7 @@ class ConfiguresGalaxyMixin:
|
||||
"""
|
||||
Preconditions: object_store must be set on self.
|
||||
"""
|
||||
if self.config.database_connection:
|
||||
db_url = self.config.database_connection
|
||||
else:
|
||||
db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % self.config.database
|
||||
db_url = get_database_url(self.config)
|
||||
install_db_url = self.config.install_database_connection
|
||||
# TODO: Consider more aggressive check here that this is not the same
|
||||
# database file under the hood.
|
||||
@@ -1035,17 +1057,12 @@ class ConfiguresGalaxyMixin:
|
||||
install_database_options = self.config.install_database_engine_options
|
||||
verify_tools(self, install_db_url, config_file, install_database_options)
|
||||
|
||||
from galaxy.model import mapping
|
||||
self.model = mapping.init(self.config.file_path,
|
||||
db_url,
|
||||
self.config.database_engine_options,
|
||||
map_install_models=combined_install_database,
|
||||
database_query_profiling_proxy=self.config.database_query_profiling_proxy,
|
||||
object_store=self.object_store,
|
||||
trace_logger=getattr(self, "trace_logger", None),
|
||||
use_pbkdf2=self.config.get_bool('use_pbkdf2', True),
|
||||
slow_query_log_threshold=self.config.slow_query_log_threshold)
|
||||
|
||||
self.model = init_models_from_config(
|
||||
self.config,
|
||||
map_install_models=combined_install_database,
|
||||
object_store=self.object_store,
|
||||
trace_logger=getattr(self, "trace_logger", None)
|
||||
)
|
||||
if combined_install_database:
|
||||
log.info("Install database targetting Galaxy's database configuration.")
|
||||
self.install_model = self.model
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
"""
|
||||
Code to support database helper scripts (create_db.py, manage_db.py, etc...).
|
||||
"""
|
||||
import argparse
|
||||
import logging
|
||||
import os.path
|
||||
|
||||
from galaxy.util.path import get_ext
|
||||
from galaxy.util.properties import find_config_file, load_app_properties
|
||||
from galaxy.util.script import populate_config_args
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -45,17 +47,36 @@ DATABASE = {
|
||||
}
|
||||
|
||||
|
||||
def read_config_file_arg(argv, config_names, cwd=None):
|
||||
if '-c' in argv:
|
||||
pos = argv.index('-c')
|
||||
argv.pop(pos)
|
||||
return argv.pop(pos)
|
||||
if cwd:
|
||||
cwd = [cwd, os.path.join(cwd, 'config')]
|
||||
return find_config_file(config_names, dirs=cwd)
|
||||
def _read_model_arguments(argv, use_argparse=False):
|
||||
if use_argparse:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('database', metavar='DATABASE', type=str,
|
||||
default="galaxy",
|
||||
nargs='?',
|
||||
help='database to target (galaxy, tool_shed, install)')
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args(argv[1:] if argv else [])
|
||||
return args.config_file, args.config_section, args.database
|
||||
else:
|
||||
config_file = None
|
||||
for arg in ["-c", "--config", "--config-file"]:
|
||||
if arg in argv:
|
||||
pos = argv.index(arg)
|
||||
argv.pop(pos)
|
||||
config_file = argv.pop(pos)
|
||||
config_section = None
|
||||
if "--config-section" in argv:
|
||||
pos = argv.index("--config-section")
|
||||
argv.pop(pos)
|
||||
config_section = argv.pop(pos)
|
||||
if argv and (argv[-1] in DATABASE):
|
||||
database = argv.pop() # database name tool_shed, galaxy, or install.
|
||||
else:
|
||||
database = 'galaxy'
|
||||
return config_file, config_section, database
|
||||
|
||||
|
||||
def get_config(argv, cwd=None):
|
||||
def get_config(argv, use_argparse=True, cwd=None):
|
||||
"""
|
||||
Read sys.argv and parse out repository of migrations and database url.
|
||||
|
||||
@@ -84,23 +105,24 @@ def get_config(argv, cwd=None):
|
||||
'lib/galaxy/model/migrate'
|
||||
>>> rmtree(config_dir)
|
||||
"""
|
||||
if argv and (argv[-1] in DATABASE):
|
||||
database = argv.pop() # database name tool_shed, galaxy, or install.
|
||||
else:
|
||||
database = 'galaxy'
|
||||
config_file, config_section, database = _read_model_arguments(argv, use_argparse=use_argparse)
|
||||
database_defaults = DATABASE[database]
|
||||
if config_file is None:
|
||||
config_names = database_defaults.get('config_names', DEFAULT_CONFIG_NAMES)
|
||||
if cwd:
|
||||
cwd = [cwd, os.path.join(cwd, 'config')]
|
||||
config_file = find_config_file(config_names, dirs=cwd)
|
||||
|
||||
config_names = database_defaults.get('config_names', DEFAULT_CONFIG_NAMES)
|
||||
config_file = read_config_file_arg(argv, config_names, cwd=cwd)
|
||||
repo = database_defaults['repo']
|
||||
config_prefix = database_defaults.get('config_prefix', DEFAULT_CONFIG_PREFIX)
|
||||
config_override = database_defaults.get('config_override', 'GALAXY_CONFIG_')
|
||||
default_sqlite_file = database_defaults['default_sqlite_file']
|
||||
if not config_file or get_ext(config_file, ignore='sample') == 'yaml':
|
||||
config_section = database_defaults.get('config_section', None)
|
||||
else:
|
||||
# An .ini file - just let load_app_properties find app:main.
|
||||
config_section = None
|
||||
if config_section is None:
|
||||
if not config_file or get_ext(config_file, ignore='sample') == 'yaml':
|
||||
config_section = database_defaults.get('config_section', None)
|
||||
else:
|
||||
# Just use the default found by load_app_properties.
|
||||
config_section = None
|
||||
properties = load_app_properties(config_file=config_file, config_prefix=config_override, config_section=config_section)
|
||||
|
||||
if ("%sdatabase_connection" % config_prefix) in properties:
|
||||
|
||||
@@ -10,11 +10,30 @@ import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
BLOCK_SIZE = 1024 * 1024
|
||||
|
||||
sha1 = hashlib.sha1
|
||||
sha256 = hashlib.sha256
|
||||
sha = sha1
|
||||
md5 = hashlib.md5
|
||||
|
||||
|
||||
def memory_bound_hexdigest(hash_func, path=None, file=None):
|
||||
hasher = hash_func()
|
||||
if file is None:
|
||||
assert path is not None
|
||||
file = open(path, "rb")
|
||||
else:
|
||||
assert path is None, "Cannot specify path and path keyword arguments."
|
||||
|
||||
try:
|
||||
for block in iter(lambda: file.read(BLOCK_SIZE), b''):
|
||||
hasher.update(block)
|
||||
return hasher.hexdigest()
|
||||
finally:
|
||||
file.close()
|
||||
|
||||
|
||||
def md5_hash_file(path):
|
||||
"""
|
||||
Return a md5 hashdigest for a file or None if path could not be read.
|
||||
|
||||
@@ -11,6 +11,19 @@ ACTIONS = None
|
||||
ARGUMENTS = None
|
||||
DEFAULT_ACTION = None
|
||||
|
||||
ARG_HELP_CONFIG_FILE = """
|
||||
Galaxy config file (defaults to $GALAXY_ROOT/config/galaxy.yml if that file exists
|
||||
or else to ./config/galaxy.ini if that exists). If this isn't set on the
|
||||
command line it can be set with the environment variable GALAXY_CONFIG_FILE.
|
||||
"""
|
||||
|
||||
# ARG_HELP_CONFIG_SECTION = """
|
||||
# Section containing application configuration in the target config file specified with
|
||||
# -c/--config-file. This defaults to 'galaxy' for YAML/JSON configuration files and 'main'
|
||||
# with 'app:' prepended for INI. If this isn't set on the command line it can be set with
|
||||
# the environment variable GALAXY_CONFIG_SECTION.
|
||||
# """
|
||||
|
||||
|
||||
def main_factory(description=None, actions=None, arguments=None, default_action=None):
|
||||
global DESCRIPTION, ACTIONS, ARGUMENTS, DEFAULT_ACTION
|
||||
@@ -26,19 +39,41 @@ def main(argv=None):
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
args = _arg_parser().parse_args(argv)
|
||||
kwargs = _app_properties(args)
|
||||
kwargs = app_properties_from_args(args)
|
||||
action = args.action
|
||||
action_func = ACTIONS[action]
|
||||
action_func(args, kwargs)
|
||||
|
||||
|
||||
def _app_properties(args):
|
||||
# FIXME: you can use galaxy.util.path.extensions for this
|
||||
config_file = args.config_file or find_config_file(args.app)
|
||||
app_properties = load_app_properties(config_file=config_file, config_section=args.config_section)
|
||||
def app_properties_from_args(args, legacy_config_override=None, app=None):
|
||||
config_file = config_file_from_args(args, legacy_config_override=legacy_config_override, app=app)
|
||||
config_section = getattr(args, "config_section", None)
|
||||
app_properties = load_app_properties(config_file=config_file, config_section=config_section)
|
||||
return app_properties
|
||||
|
||||
|
||||
def config_file_from_args(args, legacy_config_override=None, app=None):
|
||||
app = app or getattr(args, "app", "galaxy")
|
||||
config_file = legacy_config_override or args.config_file or find_config_file(app)
|
||||
return config_file
|
||||
|
||||
|
||||
def populate_config_args(parser):
|
||||
# config and config-file respected because we have used different arguments at different
|
||||
# time for scripts.
|
||||
|
||||
# Options (e.g. option_name) not found in this file can have their defaults overridden
|
||||
# set setting GALAXY_CONFIG_OPTION_NAME where OPTION_NAME is option_name converted to upper case.
|
||||
# Options specified in that file can be overridden for this program set setting
|
||||
# GALAXY_CONFIG_OVERRIDE_OPTION_NAME to a new value.
|
||||
parser.add_argument("-c", "--config-file", "--config",
|
||||
default=os.environ.get('GALAXY_CONFIG_FILE', None),
|
||||
help=ARG_HELP_CONFIG_FILE)
|
||||
parser.add_argument("--config-section",
|
||||
default=os.environ.get('GALAXY_CONFIG_SECTION', None),
|
||||
help=argparse.SUPPRESS) # See ARG_HELP_CONFIG_SECTION comment above for unsuppressed details.
|
||||
|
||||
|
||||
def _arg_parser():
|
||||
parser = argparse.ArgumentParser(description=DESCRIPTION)
|
||||
parser.add_argument('action', metavar='ACTION', type=str,
|
||||
@@ -46,10 +81,7 @@ def _arg_parser():
|
||||
default=DEFAULT_ACTION,
|
||||
nargs='?' if DEFAULT_ACTION is not None else None,
|
||||
help='action to perform')
|
||||
parser.add_argument("-c", "--config-file",
|
||||
default=os.environ.get('GALAXY_CONFIG_FILE', None))
|
||||
parser.add_argument("--config-section",
|
||||
default=os.environ.get('GALAXY_CONFIG_SECTION', None))
|
||||
populate_config_args(parser)
|
||||
parser.add_argument("--app",
|
||||
default=os.environ.get('GALAXY_APP', 'galaxy'))
|
||||
for argument in ARGUMENTS:
|
||||
|
||||
@@ -38,6 +38,7 @@ Author: Lance Parsons (lparsons@princeton.edu)
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
@@ -45,12 +46,10 @@ import sys
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
from optparse import OptionParser
|
||||
from time import strftime
|
||||
|
||||
import sqlalchemy as sa
|
||||
from mako.template import Template
|
||||
from six.moves import configparser
|
||||
from sqlalchemy import and_, false
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
@@ -58,6 +57,7 @@ sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pa
|
||||
import galaxy.config
|
||||
import galaxy.model.mapping
|
||||
import galaxy.util
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
from cleanup_datasets import CleanupDatasetsApplication # noqa: I100
|
||||
|
||||
@@ -74,59 +74,59 @@ def main():
|
||||
contains the specified text will be marked as deleted in user's history and
|
||||
the user will be notified by email using the specified template file.
|
||||
"""
|
||||
usage = "usage: %prog [options] galaxy.ini"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-d", "--days", dest="days", action="store",
|
||||
type="int", help="number of days (60)", default=60)
|
||||
parser.add_option("--tool_id", default=None,
|
||||
help="Text to match against tool_id"
|
||||
"Default: match all")
|
||||
parser.add_option("--template", default=None,
|
||||
help="Mako Template file to use as email "
|
||||
"Variables are 'cutoff' for the cutoff in days, "
|
||||
"'email' for users email and "
|
||||
"'datasets' which is a list of tuples "
|
||||
"containing 'dataset' and 'history' names. "
|
||||
"Default: admin_cleanup_deletion_template.txt")
|
||||
parser.add_option("-i", "--info_only", action="store_true",
|
||||
dest="info_only", help="info about the requested action",
|
||||
default=False)
|
||||
parser.add_option("-e", "--email_only", action="store_true",
|
||||
dest="email_only", help="Send emails only, don't delete",
|
||||
default=False)
|
||||
parser.add_option("--smtp", default=None,
|
||||
help="SMTP Server to use to send email. "
|
||||
"Default: [read from galaxy ini file]")
|
||||
parser.add_option("--fromaddr", default=None,
|
||||
help="From address to use to send email. "
|
||||
"Default: [read from galaxy ini file]")
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
ini_file = args[0]
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('legacy_config', metavar='CONFIG', type=str,
|
||||
default=None,
|
||||
nargs='?',
|
||||
help='config file (legacy, use --config instead)')
|
||||
parser.add_argument("-d", "--days", dest="days", action="store",
|
||||
type=int, help="number of days (60)", default=60)
|
||||
parser.add_argument("--tool_id", default=None,
|
||||
help="Text to match against tool_id"
|
||||
"Default: match all")
|
||||
parser.add_argument("--template", default=None,
|
||||
help="Mako Template file to use as email "
|
||||
"Variables are 'cutoff' for the cutoff in days, "
|
||||
"'email' for users email and "
|
||||
"'datasets' which is a list of tuples "
|
||||
"containing 'dataset' and 'history' names. "
|
||||
"Default: admin_cleanup_deletion_template.txt")
|
||||
parser.add_argument("-i", "--info_only", action="store_true",
|
||||
dest="info_only", help="info about the requested action",
|
||||
default=False)
|
||||
parser.add_argument("-e", "--email_only", action="store_true",
|
||||
dest="email_only", help="Send emails only, don't delete",
|
||||
default=False)
|
||||
parser.add_argument("--smtp", default=None,
|
||||
help="SMTP Server to use to send email. "
|
||||
"Default: [read from galaxy ini file]")
|
||||
parser.add_argument("--fromaddr", default=None,
|
||||
help="From address to use to send email. "
|
||||
"Default: [read from galaxy ini file]")
|
||||
populate_config_args(parser)
|
||||
|
||||
config_parser = configparser.ConfigParser({'here': os.getcwd()})
|
||||
config_parser.read(ini_file)
|
||||
config_dict = {}
|
||||
for key, value in config_parser.items("app:main"):
|
||||
config_dict[key] = value
|
||||
args = parser.parse_args()
|
||||
config_override = None
|
||||
if args.legacy_config:
|
||||
config_override = args.legacy_config
|
||||
|
||||
if options.smtp is not None:
|
||||
config_dict['smtp_server'] = options.smtp
|
||||
if config_dict.get('smtp_server') is None:
|
||||
app_properties = app_properties_from_args(args, legacy_config_override=config_override)
|
||||
|
||||
if args.smtp is not None:
|
||||
app_properties['smtp_server'] = args.smtp
|
||||
if app_properties.get('smtp_server') is None:
|
||||
parser.error("SMTP Server must be specified as an option (--smtp) "
|
||||
"or in the config file (smtp_server)")
|
||||
|
||||
if options.fromaddr is not None:
|
||||
config_dict['email_from'] = options.fromaddr
|
||||
if config_dict.get('email_from') is None:
|
||||
if args.fromaddr is not None:
|
||||
app_properties['email_from'] = args.fromaddr
|
||||
if app_properties.get('email_from') is None:
|
||||
parser.error("From address must be specified as an option "
|
||||
"(--fromaddr) or in the config file "
|
||||
"(email_from)")
|
||||
|
||||
scriptdir = os.path.dirname(os.path.abspath(__file__))
|
||||
template_file = options.template
|
||||
template_file = args.template
|
||||
if template_file is None:
|
||||
default_template = os.path.join(scriptdir,
|
||||
'admin_cleanup_deletion_template.txt')
|
||||
@@ -145,24 +145,24 @@ def main():
|
||||
elif not os.path.exists(template_file):
|
||||
parser.error("Specified template file (%s) not found." % template_file)
|
||||
|
||||
config = galaxy.config.Configuration(**config_dict)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
|
||||
app = CleanupDatasetsApplication(config)
|
||||
cutoff_time = datetime.utcnow() - timedelta(days=options.days)
|
||||
cutoff_time = datetime.utcnow() - timedelta(days=args.days)
|
||||
now = strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
print("##########################################")
|
||||
print("\n# %s - Handling stuff older than %i days" % (now, options.days))
|
||||
print("\n# %s - Handling stuff older than %i days" % (now, args.days))
|
||||
|
||||
if options.info_only:
|
||||
if args.info_only:
|
||||
print("# Displaying info only ( --info_only )\n")
|
||||
elif options.email_only:
|
||||
elif args.email_only:
|
||||
print("# Sending emails only, not deleting ( --email_only )\n")
|
||||
|
||||
administrative_delete_datasets(
|
||||
app, cutoff_time, options.days, tool_id=options.tool_id,
|
||||
app, cutoff_time, args.days, tool_id=args.tool_id,
|
||||
template_file=template_file, config=config,
|
||||
email_only=options.email_only, info_only=options.info_only)
|
||||
email_only=args.email_only, info_only=args.info_only)
|
||||
app.shutdown()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from optparse import OptionParser
|
||||
from time import strftime
|
||||
|
||||
import sqlalchemy as sa
|
||||
from six.moves import configparser
|
||||
from sqlalchemy import and_, false, null, true
|
||||
from sqlalchemy.orm import eagerload
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
|
||||
import galaxy.config
|
||||
import galaxy.model.mapping
|
||||
from galaxy.datatypes.registry import Registry
|
||||
from galaxy.exceptions import ObjectNotFound
|
||||
from galaxy.objectstore import build_object_store_from_config
|
||||
from galaxy.util import unicodify
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.INFO)
|
||||
@@ -69,68 +68,65 @@ def main():
|
||||
Another way of stating it is: LibraryDatasetDatasetAssociation objects map LibraryDataset objects to Dataset objects,
|
||||
and Dataset objects may be mapped to History objects via HistoryDatasetAssociation objects.
|
||||
"""
|
||||
usage = "usage: %prog [options] galaxy.ini"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-d", "--days", dest="days", action="store", type="int", help="number of days (60)", default=60)
|
||||
parser.add_option("-r", "--remove_from_disk", action="store_true", dest="remove_from_disk", help="remove datasets from disk when purged", default=False)
|
||||
parser.add_option("-i", "--info_only", action="store_true", dest="info_only", help="info about the requested action", default=False)
|
||||
parser.add_option("-f", "--force_retry", action="store_true", dest="force_retry", help="performs the requested actions, but ignores whether it might have been done before. Useful when -r wasn't used, but should have been", default=False)
|
||||
parser.add_option("-1", "--delete_userless_histories", action="store_true", dest="delete_userless_histories", default=False, help="delete userless histories and datasets")
|
||||
parser.add_option("-2", "--purge_histories", action="store_true", dest="purge_histories", default=False, help="purge deleted histories")
|
||||
parser.add_option("-3", "--purge_datasets", action="store_true", dest="purge_datasets", default=False, help="purge deleted datasets")
|
||||
parser.add_option("-4", "--purge_libraries", action="store_true", dest="purge_libraries", default=False, help="purge deleted libraries")
|
||||
parser.add_option("-5", "--purge_folders", action="store_true", dest="purge_folders", default=False, help="purge deleted library folders")
|
||||
parser.add_option("-6", "--delete_datasets", action="store_true", dest="delete_datasets", default=False, help="mark deletable datasets as deleted and purge associated dataset instances")
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('legacy_config', metavar='CONFIG', type=str,
|
||||
default=None,
|
||||
nargs='?',
|
||||
help='config file (legacy, use --config instead)')
|
||||
parser.add_argument("-d", "--days", dest="days", action="store", type=int, help="number of days (60)", default=60)
|
||||
parser.add_argument("-r", "--remove_from_disk", action="store_true", dest="remove_from_disk", help="remove datasets from disk when purged", default=False)
|
||||
parser.add_argument("-i", "--info_only", action="store_true", dest="info_only", help="info about the requested action", default=False)
|
||||
parser.add_argument("-f", "--force_retry", action="store_true", dest="force_retry", help="performs the requested actions, but ignores whether it might have been done before. Useful when -r wasn't used, but should have been", default=False)
|
||||
parser.add_argument("-1", "--delete_userless_histories", action="store_true", dest="delete_userless_histories", default=False, help="delete userless histories and datasets")
|
||||
parser.add_argument("-2", "--purge_histories", action="store_true", dest="purge_histories", default=False, help="purge deleted histories")
|
||||
parser.add_argument("-3", "--purge_datasets", action="store_true", dest="purge_datasets", default=False, help="purge deleted datasets")
|
||||
parser.add_argument("-4", "--purge_libraries", action="store_true", dest="purge_libraries", default=False, help="purge deleted libraries")
|
||||
parser.add_argument("-5", "--purge_folders", action="store_true", dest="purge_folders", default=False, help="purge deleted library folders")
|
||||
parser.add_argument("-6", "--delete_datasets", action="store_true", dest="delete_datasets", default=False, help="mark deletable datasets as deleted and purge associated dataset instances")
|
||||
populate_config_args(parser)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
ini_file = args[0]
|
||||
args = parser.parse_args()
|
||||
config_override = None
|
||||
if args.legacy_config:
|
||||
config_override = args.legacy_config
|
||||
|
||||
if not (options.purge_folders ^ options.delete_userless_histories ^
|
||||
options.purge_libraries ^ options.purge_histories ^
|
||||
options.purge_datasets ^ options.delete_datasets):
|
||||
if not (args.purge_folders ^ args.delete_userless_histories ^
|
||||
args.purge_libraries ^ args.purge_histories ^
|
||||
args.purge_datasets ^ args.delete_datasets):
|
||||
parser.print_help()
|
||||
sys.exit(0)
|
||||
|
||||
if options.remove_from_disk and options.info_only:
|
||||
if args.remove_from_disk and args.info_only:
|
||||
parser.error("remove_from_disk and info_only are mutually exclusive")
|
||||
|
||||
config_parser = configparser.ConfigParser({'here': os.getcwd()})
|
||||
config_parser.read(ini_file)
|
||||
config_dict = {}
|
||||
for key, value in config_parser.items("app:main"):
|
||||
config_dict[key] = value
|
||||
|
||||
config = galaxy.config.Configuration(**config_dict)
|
||||
|
||||
app_properties = app_properties_from_args(args, legacy_config_override=config_override)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
app = CleanupDatasetsApplication(config)
|
||||
cutoff_time = datetime.utcnow() - timedelta(days=options.days)
|
||||
cutoff_time = datetime.utcnow() - timedelta(days=args.days)
|
||||
now = strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
print("##########################################")
|
||||
print("\n# %s - Handling stuff older than %i days" % (now, options.days))
|
||||
print("\n# %s - Handling stuff older than %i days" % (now, args.days))
|
||||
|
||||
if options.info_only:
|
||||
if args.info_only:
|
||||
print("# Displaying info only ( --info_only )\n")
|
||||
elif options.remove_from_disk:
|
||||
elif args.remove_from_disk:
|
||||
print("Datasets will be removed from disk.\n")
|
||||
else:
|
||||
print("Datasets will NOT be removed from disk.\n")
|
||||
|
||||
if options.delete_userless_histories:
|
||||
delete_userless_histories(app, cutoff_time, info_only=options.info_only, force_retry=options.force_retry)
|
||||
elif options.purge_histories:
|
||||
purge_histories(app, cutoff_time, options.remove_from_disk, info_only=options.info_only, force_retry=options.force_retry)
|
||||
elif options.purge_datasets:
|
||||
purge_datasets(app, cutoff_time, options.remove_from_disk, info_only=options.info_only, force_retry=options.force_retry)
|
||||
elif options.purge_libraries:
|
||||
purge_libraries(app, cutoff_time, options.remove_from_disk, info_only=options.info_only, force_retry=options.force_retry)
|
||||
elif options.purge_folders:
|
||||
purge_folders(app, cutoff_time, options.remove_from_disk, info_only=options.info_only, force_retry=options.force_retry)
|
||||
elif options.delete_datasets:
|
||||
delete_datasets(app, cutoff_time, options.remove_from_disk, info_only=options.info_only, force_retry=options.force_retry)
|
||||
if args.delete_userless_histories:
|
||||
delete_userless_histories(app, cutoff_time, info_only=args.info_only, force_retry=args.force_retry)
|
||||
elif args.purge_histories:
|
||||
purge_histories(app, cutoff_time, args.remove_from_disk, info_only=args.info_only, force_retry=args.force_retry)
|
||||
elif args.purge_datasets:
|
||||
purge_datasets(app, cutoff_time, args.remove_from_disk, info_only=args.info_only, force_retry=args.force_retry)
|
||||
elif args.purge_libraries:
|
||||
purge_libraries(app, cutoff_time, args.remove_from_disk, info_only=args.info_only, force_retry=args.force_retry)
|
||||
elif args.purge_folders:
|
||||
purge_folders(app, cutoff_time, args.remove_from_disk, info_only=args.info_only, force_retry=args.force_retry)
|
||||
elif args.delete_datasets:
|
||||
delete_datasets(app, cutoff_time, args.remove_from_disk, info_only=args.info_only, force_retry=args.force_retry)
|
||||
|
||||
app.shutdown()
|
||||
sys.exit(0)
|
||||
@@ -522,11 +518,9 @@ def _purge_folder(folder, app, remove_from_disk, info_only=False):
|
||||
class CleanupDatasetsApplication(object):
|
||||
"""Encapsulates the state of a Universe application"""
|
||||
def __init__(self, config):
|
||||
if config.database_connection is False:
|
||||
config.database_connection = "sqlite:///%s?isolation_level=IMMEDIATE" % config.database
|
||||
self.object_store = build_object_store_from_config(config)
|
||||
# Setup the database engine and ORM
|
||||
self.model = galaxy.model.mapping.init(config.file_path, config.database_connection, engine_options={}, create_tables=False, object_store=self.object_store)
|
||||
self.model = galaxy.config.init_models_from_config(config, object_store=self.object_store)
|
||||
registry = Registry()
|
||||
registry.load_datatypes()
|
||||
galaxy.model.set_datatypes_registry(registry)
|
||||
|
||||
@@ -6,16 +6,15 @@ pgcleanup.py - A script for cleaning up datasets in Galaxy efficiently, by
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
import psycopg2
|
||||
from six.moves.configparser import ConfigParser
|
||||
from sqlalchemy.engine.url import make_url
|
||||
|
||||
galaxy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
|
||||
@@ -25,6 +24,7 @@ import galaxy.config
|
||||
from galaxy.exceptions import ObjectNotFound
|
||||
from galaxy.objectstore import build_object_store_from_config
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
@@ -39,7 +39,6 @@ class Dataset(Bunch):
|
||||
|
||||
class Cleanup(object):
|
||||
def __init__(self):
|
||||
self.options = None
|
||||
self.args = None
|
||||
self.config = None
|
||||
self.conn = None
|
||||
@@ -61,49 +60,38 @@ class Cleanup(object):
|
||||
self.action_names.append(name)
|
||||
|
||||
def __parse_args(self):
|
||||
default_config = os.path.abspath(os.path.join(galaxy_root, 'config', 'galaxy.ini'))
|
||||
parser = argparse.ArgumentParser()
|
||||
populate_config_args(parser)
|
||||
parser.add_argument('-d', '--debug', action='store_true', dest='debug', help='Enable debug logging', default=False)
|
||||
parser.add_argument('--dry-run', action='store_true', dest='dry_run', help="Dry run (rollback all transactions)", default=False)
|
||||
parser.add_argument('--force-retry', action='store_true', dest='force_retry', help="Retry file removals (on applicable actions)", default=False)
|
||||
parser.add_argument('-o', '--older-than', type=int, dest='days', help='Only perform action(s) on objects that have not been updated since the specified number of days', default=14)
|
||||
parser.add_argument('-U', '--no-update-time', action='store_false', dest='update_time', help="Don't set update_time on updated objects", default=True)
|
||||
parser.add_argument('-s', '--sequence', dest='sequence', help='Comma-separated sequence of actions, chosen from: %s' % self.action_names, default='')
|
||||
parser.add_argument('-w', '--work-mem', dest='work_mem', help='Set PostgreSQL work_mem for this connection', default=None)
|
||||
parser.add_argument('-l', '--log-dir', dest='log_dir', help='Log file directory', default=os.path.join(galaxy_root, 'scripts', 'cleanup_datasets'))
|
||||
self.args = parser.parse_args()
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-c', '--config', dest='config', help='Path to Galaxy config file (config/galaxy.ini)', default=default_config)
|
||||
parser.add_option('-d', '--debug', action='store_true', dest='debug', help='Enable debug logging', default=False)
|
||||
parser.add_option('--dry-run', action='store_true', dest='dry_run', help="Dry run (rollback all transactions)", default=False)
|
||||
parser.add_option('--force-retry', action='store_true', dest='force_retry', help="Retry file removals (on applicable actions)", default=False)
|
||||
parser.add_option('-o', '--older-than', type='int', dest='days', help='Only perform action(s) on objects that have not been updated since the specified number of days', default=14)
|
||||
parser.add_option('-U', '--no-update-time', action='store_false', dest='update_time', help="Don't set update_time on updated objects", default=True)
|
||||
parser.add_option('-s', '--sequence', dest='sequence', help='Comma-separated sequence of actions, chosen from: %s' % self.action_names, default='')
|
||||
parser.add_option('-w', '--work-mem', dest='work_mem', help='Set PostgreSQL work_mem for this connection', default=None)
|
||||
parser.add_option('-l', '--log-dir', dest='log_dir', help='Log file directory', default=os.path.join(galaxy_root, 'scripts', 'cleanup_datasets'))
|
||||
(self.options, self.args) = parser.parse_args()
|
||||
self.args.sequence = [x.strip() for x in self.args.sequence.split(',')]
|
||||
|
||||
self.options.sequence = [x.strip() for x in self.options.sequence.split(',')]
|
||||
|
||||
if self.options.sequence == ['']:
|
||||
if self.args.sequence == ['']:
|
||||
print("Error: At least one action must be specified in the action sequence\n")
|
||||
parser.print_help()
|
||||
sys.exit(0)
|
||||
|
||||
def __setup_logging(self):
|
||||
format = "%(funcName)s %(levelname)s %(asctime)s %(message)s"
|
||||
if self.options.debug:
|
||||
if self.args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG, format=format)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO, format=format)
|
||||
|
||||
def __load_config(self):
|
||||
log.info('Reading config from %s' % self.options.config)
|
||||
config_parser = ConfigParser(dict(here=os.getcwd(),
|
||||
database_connection='sqlite:///database/universe.sqlite?isolation_level=IMMEDIATE'))
|
||||
config_parser.read(self.options.config)
|
||||
|
||||
config_dict = {}
|
||||
for key, value in config_parser.items('app:main'):
|
||||
config_dict[key] = value
|
||||
config_dict['root_dir'] = galaxy_root
|
||||
|
||||
self.config = galaxy.config.Configuration(**config_dict)
|
||||
app_properties = app_properties_from_args(self.args)
|
||||
self.config = galaxy.config.Configuration(**app_properties)
|
||||
|
||||
def __connect_db(self):
|
||||
url = make_url(self.config.database_connection)
|
||||
url = make_url(galaxy.config.get_database_url(self.config))
|
||||
|
||||
log.info('Connecting to database with URL: %s' % url)
|
||||
args = url.translate_connect_args(username='user')
|
||||
@@ -118,9 +106,9 @@ class Cleanup(object):
|
||||
|
||||
def _open_logfile(self):
|
||||
action_name = inspect.stack()[1][3]
|
||||
logname = os.path.join(self.options.log_dir, action_name + '.log')
|
||||
logname = os.path.join(self.args.log_dir, action_name + '.log')
|
||||
|
||||
if self.options.dry_run:
|
||||
if self.args.dry_run:
|
||||
log.debug('--dry-run specified, logging changes to stdout instead of log file: %s' % logname)
|
||||
self.logs[action_name] = sys.stdout
|
||||
else:
|
||||
@@ -145,7 +133,7 @@ class Cleanup(object):
|
||||
self.logs[action_name].write(message.ljust(72, '='))
|
||||
self.logs[action_name].write('\n')
|
||||
|
||||
if self.options.dry_run:
|
||||
if self.args.dry_run:
|
||||
log.debug('--dry-run specified, changes were logged to stdout insted of log file')
|
||||
else:
|
||||
log.debug('Closing log file: %s' % self.logs[action_name].name)
|
||||
@@ -155,14 +143,14 @@ class Cleanup(object):
|
||||
|
||||
def _run(self):
|
||||
ok = True
|
||||
for name in self.options.sequence:
|
||||
for name in self.args.sequence:
|
||||
if name not in self.action_names:
|
||||
log.error('Unknown action in sequence: %s' % name)
|
||||
ok = False
|
||||
if not ok:
|
||||
log.critical('Exiting due to previous error(s)')
|
||||
sys.exit(1)
|
||||
for name in self.options.sequence:
|
||||
for name in self.args.sequence:
|
||||
log.info('Calling %s' % name)
|
||||
self.__getattribute__(name)()
|
||||
log.info('Finished %s' % name)
|
||||
@@ -188,7 +176,7 @@ class Cleanup(object):
|
||||
|
||||
cur = self.conn.cursor()
|
||||
|
||||
if self.options.dry_run:
|
||||
if self.args.dry_run:
|
||||
sql = "SELECT MAX(id) FROM cleanup_event;"
|
||||
cur.execute(sql)
|
||||
max_id = cur.fetchone()[0]
|
||||
@@ -217,9 +205,9 @@ class Cleanup(object):
|
||||
|
||||
cur = self.conn.cursor()
|
||||
|
||||
if self.options.work_mem is not None:
|
||||
log.info('Setting work_mem to %s' % self.options.work_mem)
|
||||
cur.execute('SET work_mem TO %s', (self.options.work_mem,))
|
||||
if self.args.work_mem is not None:
|
||||
log.info('Setting work_mem to %s' % self.args.work_mem)
|
||||
cur.execute('SET work_mem TO %s', (self.args.work_mem,))
|
||||
|
||||
log.info('Executing SQL')
|
||||
cur.execute(sql, args)
|
||||
@@ -228,7 +216,7 @@ class Cleanup(object):
|
||||
return cur
|
||||
|
||||
def _flush(self):
|
||||
if self.options.dry_run:
|
||||
if self.args.dry_run:
|
||||
self.conn.rollback()
|
||||
log.info("--dry-run specified, all changes rolled back")
|
||||
else:
|
||||
@@ -245,7 +233,7 @@ class Cleanup(object):
|
||||
log.error('Unable to get MetadataFile %s filename: %s' % (id, e))
|
||||
return
|
||||
|
||||
if not self.options.dry_run:
|
||||
if not self.args.dry_run:
|
||||
try:
|
||||
os.unlink(filename)
|
||||
except Exception as e:
|
||||
@@ -341,7 +329,7 @@ class Cleanup(object):
|
||||
"""
|
||||
Mark deleted all "anonymous" Histories (not owned by a registered user) that are older than the specified number of days.
|
||||
"""
|
||||
log.info('Marking deleted all userless Histories older than %i days' % self.options.days)
|
||||
log.info('Marking deleted all userless Histories older than %i days' % self.args.days)
|
||||
|
||||
event_id = self._create_event()
|
||||
|
||||
@@ -364,12 +352,12 @@ class Cleanup(object):
|
||||
"""
|
||||
|
||||
update_time_sql = ''
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql = """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, '%s', '%s')
|
||||
args = (self.options.days, event_id)
|
||||
args = (self.args.days, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -385,7 +373,7 @@ class Cleanup(object):
|
||||
Mark deleted all ImplicitlyConvertedDatasetAssociations whose hda_parent_id is purged in this step.
|
||||
Mark purged all HistoryDatasetAssociations for which an ImplicitlyConvertedDatasetAssociation with matching hda_id is deleted in this step.
|
||||
"""
|
||||
log.info('Marking purged all deleted HistoryDatasetAssociations older than %i days' % self.options.days)
|
||||
log.info('Marking purged all deleted HistoryDatasetAssociations older than %i days' % self.args.days)
|
||||
|
||||
event_id = self._create_event()
|
||||
|
||||
@@ -457,16 +445,16 @@ class Cleanup(object):
|
||||
AND NOT purged"""
|
||||
update_time_sql = ""
|
||||
|
||||
if self.options.force_retry:
|
||||
if self.args.force_retry:
|
||||
force_retry_sql = ""
|
||||
else:
|
||||
# only update time if not doing force retry (otherwise a lot of things would have their update times reset that were actually purged a long time ago)
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql = """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, force_retry_sql, '%s', update_time_sql, update_time_sql, update_time_sql, '%s', '%s', '%s', '%s')
|
||||
args = (self.options.days, event_id, event_id, event_id, event_id)
|
||||
args = (self.args.days, event_id, event_id, event_id, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -573,15 +561,15 @@ class Cleanup(object):
|
||||
AND NOT purged"""
|
||||
update_time_sql = ""
|
||||
|
||||
if self.options.force_retry:
|
||||
if self.args.force_retry:
|
||||
force_retry_sql = ""
|
||||
else:
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql += """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, force_retry_sql, '%s', update_time_sql, update_time_sql, update_time_sql, update_time_sql, '%s', '%s', '%s', '%s', '%s')
|
||||
args = (self.options.days, event_id, event_id, event_id, event_id, event_id)
|
||||
args = (self.args.days, event_id, event_id, event_id, event_id, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -627,12 +615,12 @@ class Cleanup(object):
|
||||
"""
|
||||
|
||||
update_time_sql = ""
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql += """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, '%s', '%s')
|
||||
args = (self.options.days, event_id)
|
||||
args = (self.args.days, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -676,12 +664,12 @@ class Cleanup(object):
|
||||
"""
|
||||
|
||||
update_time_sql = ""
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql += """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, '%s', '%s', '%s')
|
||||
args = (self.options.days, self.options.days, event_id)
|
||||
args = (self.args.days, self.args.days, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -721,15 +709,15 @@ class Cleanup(object):
|
||||
AND NOT purged"""
|
||||
update_time_sql = ""
|
||||
|
||||
if self.options.force_retry:
|
||||
if self.args.force_retry:
|
||||
force_retry_sql = ""
|
||||
else:
|
||||
if self.options.update_time:
|
||||
if self.args.update_time:
|
||||
update_time_sql = """,
|
||||
update_time = NOW()"""
|
||||
|
||||
sql = sql % (update_time_sql, force_retry_sql, '%s', '%s')
|
||||
args = (self.options.days, event_id)
|
||||
args = (self.args.days, event_id)
|
||||
cur = self._update(sql, args)
|
||||
self._flush()
|
||||
|
||||
@@ -752,7 +740,7 @@ class Cleanup(object):
|
||||
|
||||
# don't check for existence of the dataset, it should exist
|
||||
self._log('Removing from disk: %s' % filename)
|
||||
if not self.options.dry_run:
|
||||
if not self.args.dry_run:
|
||||
try:
|
||||
os.unlink(filename)
|
||||
except Exception as e:
|
||||
@@ -761,7 +749,7 @@ class Cleanup(object):
|
||||
# extra_files_dir is optional so it's checked first
|
||||
if extra_files_dir is not None and os.path.exists(extra_files_dir):
|
||||
self._log('Removing from disk: %s' % extra_files_dir)
|
||||
if not self.options.dry_run:
|
||||
if not self.args.dry_run:
|
||||
try:
|
||||
shutil.rmtree(extra_files_dir)
|
||||
except Exception as e:
|
||||
|
||||
@@ -8,33 +8,32 @@ script fixes datasets that were generated before the change.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from galaxy.model import mapping
|
||||
from galaxy.model.orm.scripts import get_config
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
|
||||
assert sys.version_info[:2] >= (2, 6)
|
||||
import galaxy.config
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
|
||||
def usage(prog):
|
||||
print("usage: %s galaxy.ini" % prog)
|
||||
print("""
|
||||
DESCRIPTION = """
|
||||
Populates blank uuid fields in datasets with randomly generated values.
|
||||
|
||||
Going forward, these ids will be generated for all new datasets. This
|
||||
script fixes datasets that were generated before the change.
|
||||
""")
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2 or sys.argv == "-h" or sys.argv == "--help":
|
||||
usage(sys.argv[0])
|
||||
sys.exit()
|
||||
ini_file = sys.argv.pop(1)
|
||||
config = get_config(ini_file)
|
||||
parser = argparse.ArgumentParser(DESCRIPTION)
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
model = mapping.init(ini_file, config['db_url'], create_tables=False)
|
||||
app_properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
model = galaxy.config.init_models_from_config(config)
|
||||
|
||||
for row in model.context.query(model.Dataset):
|
||||
if row.uuid is None:
|
||||
@@ -47,6 +46,7 @@ def main():
|
||||
row.uuid = uuid.uuid4()
|
||||
print("Setting Workflow:", row.id, " UUID to ", row.uuid)
|
||||
model.context.flush()
|
||||
print("Complete")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Removes a dataset file ( which was first renamed by appending _purged to the file name ) from disk.
|
||||
Usage: python remove_renamed_datasets_from_disk.py renamed.log
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
assert sys.version_info[:2] >= (2, 6)
|
||||
|
||||
|
||||
def usage(prog):
|
||||
print("usage: %s file" % prog)
|
||||
print("""
|
||||
Removes a set of files from disk. The input file should contain a list of files
|
||||
to be deleted, one per line. The full path must be specified and must begin
|
||||
with /var/opt/galaxy.
|
||||
|
||||
A log of files deleted is created in a file with the same name as that input but
|
||||
with .removed.log appended.
|
||||
""")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2 or sys.argv == "-h" or sys.argv == "--help":
|
||||
usage(sys.argv[0])
|
||||
sys.exit()
|
||||
infile = sys.argv[1]
|
||||
outfile = infile + ".removed.log"
|
||||
out = open(outfile, 'w')
|
||||
|
||||
print("# The following renamed datasets have been removed from disk", file=out)
|
||||
i = 0
|
||||
removed_files = 0
|
||||
for i, line in enumerate(open(infile)):
|
||||
line = line.rstrip('\r\n')
|
||||
if line and line.startswith('/var/opt/galaxy'):
|
||||
try:
|
||||
os.unlink(line)
|
||||
print(line, file=out)
|
||||
removed_files += 1
|
||||
except Exception as exc:
|
||||
print("# Error, exception " + str(exc) + " caught attempting to remove " + line, file=out)
|
||||
print("# Removed " + str(removed_files) + " files", file=out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Renames a dataset file by appending _purged to the file name so that it can later be removed from disk.
|
||||
Usage: python rename_purged_datasets.py purge.log
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
assert sys.version_info[:2] >= (2, 6)
|
||||
|
||||
|
||||
def usage(prog):
|
||||
print("usage: %s file" % prog)
|
||||
print("""
|
||||
Marks a set of files as purged and renames them. The input file should contain a
|
||||
list of files to be purged, one per line. The full path must be specified and
|
||||
must begin with /var/opt/galaxy.
|
||||
A log of files marked as purged is created in a file with the same name as that
|
||||
input but with _purged appended. The resulting files can finally be removed from
|
||||
disk with remove_renamed_datasets_from_disk.py, by supplying it with a list of
|
||||
them.
|
||||
""")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2 or sys.argv == "-h" or sys.argv == "--help":
|
||||
usage(sys.argv[0])
|
||||
sys.exit()
|
||||
infile = sys.argv[1]
|
||||
outfile = infile + ".renamed.log"
|
||||
out = open(outfile, 'w')
|
||||
|
||||
print("# The following renamed datasets can be removed from disk", file=out)
|
||||
i = 0
|
||||
renamed_files = 0
|
||||
for i, line in enumerate(open(infile)):
|
||||
line = line.rstrip('\r\n')
|
||||
if line and line.startswith('/var/opt/galaxy'):
|
||||
try:
|
||||
purged_filename = line + "_purged"
|
||||
os.rename(line, purged_filename)
|
||||
print(purged_filename, file=out)
|
||||
renamed_files += 1
|
||||
except Exception as exc:
|
||||
print("# Error, exception " + str(exc) + " caught attempting to rename " + purged_filename, file=out)
|
||||
print("# Renamed " + str(renamed_files) + " files", file=out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -2,6 +2,8 @@
|
||||
"""
|
||||
Updates dataset.size column.
|
||||
Remember to backup your database before running.
|
||||
|
||||
Deprecated - this doesn't work with modern Galaxy configurations options.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
Updates metadata in the database to match rev 1891.
|
||||
|
||||
Remember to backup your database before running.
|
||||
|
||||
Deprecated - this doesn't work with modern Galaxy configurations options.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
@@ -49,22 +49,26 @@ from flask_socketio import (
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
|
||||
from galaxy.model import mapping
|
||||
from galaxy.model.orm.scripts import get_config
|
||||
from galaxy.util.properties import load_app_properties
|
||||
import galaxy.config
|
||||
from galaxy.util.sanitize_html import sanitize_html
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
from galaxy.web.security import SecurityHelper
|
||||
|
||||
logging.basicConfig()
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Get config file and load up SA session
|
||||
config = get_config(sys.argv)
|
||||
model = mapping.init('/tmp/', config['db_url'])
|
||||
sa_session = model.context.current
|
||||
parser = argparse.ArgumentParser(description='Real-time communication server for Galaxy.')
|
||||
parser.add_argument('--port', type=int, default="7070", help='Port number on which the server should run.')
|
||||
parser.add_argument('--host', default='localhost', help='Hostname of the communication server.')
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
# With the config file we can load the full app properties
|
||||
app_properties = load_app_properties(ini_file=config['config_file'])
|
||||
app_properties = app_properties_from_args(args)
|
||||
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
model = galaxy.config.init_models_from_config(config)
|
||||
sa_session = model.context.current
|
||||
|
||||
# We need the ID secret for configuring the security helper to decrypt
|
||||
# galaxysession cookies.
|
||||
@@ -217,9 +221,4 @@ def leave(message):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Real-time communication server for Galaxy.')
|
||||
parser.add_argument('--port', type=int, default="7070", help='Port number on which the server should run.')
|
||||
parser.add_argument('--host', default='localhost', help='Hostname of the communication server.')
|
||||
|
||||
args = parser.parse_args()
|
||||
socketio.run(app, host=args.host, port=args.port)
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Build index for full-text lucene search of files in data libraries.
|
||||
|
||||
Requires a full text search server and configuration settings in
|
||||
galaxy.ini. See the lucene settings in the data library search section for more
|
||||
details.
|
||||
|
||||
Run from the ~/scripts/data_libraries directory:
|
||||
%sh build_lucene_index.sh
|
||||
"""
|
||||
import csv
|
||||
import os
|
||||
import sys
|
||||
|
||||
import requests
|
||||
from six.moves.configparser import ConfigParser
|
||||
from six.moves.urllib.parse import urlencode
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
|
||||
import galaxy.model.mapping
|
||||
from galaxy import config, model
|
||||
|
||||
|
||||
def main(ini_file):
|
||||
sa_session, gconfig = get_sa_session(ini_file)
|
||||
max_size = float(gconfig.get("fulltext_max_size", 100)) * 1048576
|
||||
ignore_exts = gconfig.get("fulltext_noindex_filetypes", "").split(",")
|
||||
search_url = gconfig.get("fulltext_url", None)
|
||||
if not search_url:
|
||||
raise ValueError("Need to specify search functionality in galaxy.ini")
|
||||
dataset_file = create_dataset_file(get_lddas(sa_session, max_size, ignore_exts))
|
||||
try:
|
||||
build_index(search_url, dataset_file)
|
||||
finally:
|
||||
if os.path.exists(dataset_file):
|
||||
os.remove(dataset_file)
|
||||
|
||||
|
||||
def build_index(search_url, dataset_file):
|
||||
url = "%s/index?%s" % (search_url, urlencode({"docfile": dataset_file}))
|
||||
requests.put(url)
|
||||
|
||||
|
||||
def create_dataset_file(dataset_iter):
|
||||
dataset_file = os.path.join(os.getcwd(), "full-text-search-files.csv")
|
||||
out_handle = open(dataset_file, "w")
|
||||
writer = csv.writer(out_handle)
|
||||
for did, dfile, dname in dataset_iter:
|
||||
writer.writerow([did, dfile, dname])
|
||||
out_handle.close()
|
||||
return dataset_file
|
||||
|
||||
|
||||
def get_lddas(sa_session, max_size, ignore_exts):
|
||||
for ldda in sa_session.query(model.LibraryDatasetDatasetAssociation).filter_by(deleted=False):
|
||||
if (float(ldda.dataset.get_size()) > max_size or ldda.extension in ignore_exts):
|
||||
fname = ""
|
||||
else:
|
||||
fname = ldda.dataset.get_file_name()
|
||||
yield ldda.id, fname, _get_dataset_metadata(ldda).replace("\n", " ")
|
||||
|
||||
|
||||
def _get_dataset_metadata(ldda):
|
||||
"""Retrieve descriptions and information associated with a dataset.
|
||||
"""
|
||||
lds = ldda.library_dataset
|
||||
folder_info = _get_folder_info(lds.folder)
|
||||
lds_info = lds.get_info()
|
||||
if lds_info and not lds_info.startswith("upload"):
|
||||
lds_info = lds_info.replace("no info", "")
|
||||
else:
|
||||
lds_info = ""
|
||||
return "%s %s %s %s %s" % (lds.name or "", lds_info, ldda.metadata.dbkey,
|
||||
ldda.message, folder_info)
|
||||
|
||||
|
||||
def _get_folder_info(folder):
|
||||
"""Get names and descriptions for all parent folders except top level.
|
||||
"""
|
||||
folder_info = ""
|
||||
if folder and folder.parent:
|
||||
folder_info = _get_folder_info(folder.parent)
|
||||
folder_info += " %s %s" % (
|
||||
folder.name.replace("Unnamed folder", ""),
|
||||
folder.description or "")
|
||||
return folder_info
|
||||
|
||||
|
||||
def get_sa_session(ini_file):
|
||||
conf_parser = ConfigParser({'here': os.getcwd()})
|
||||
conf_parser.read(ini_file)
|
||||
kwds = dict()
|
||||
for key, value in conf_parser.items("app:main"):
|
||||
kwds[key] = value
|
||||
ini_config = config.Configuration(**kwds)
|
||||
db_con = ini_config.database_connection
|
||||
if not db_con:
|
||||
db_con = "sqlite:///%s?isolation_level=IMMEDIATE" % ini_config.database
|
||||
model = galaxy.model.mapping.init(ini_config.file_path,
|
||||
db_con,
|
||||
engine_options={},
|
||||
create_tables=False)
|
||||
return model.context.current, ini_config
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv[1:])
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd `dirname $0`/../..
|
||||
python ./scripts/data_libraries/build_lucene_index.py ./config/galaxy.ini
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Build index for full-text whoosh search of files in data libraries.
|
||||
|
||||
Requires configuration settings in galaxy.ini. See the whoosh settings in the
|
||||
data library search section for more details.
|
||||
|
||||
Run from the ~/scripts/data_libraries directory:
|
||||
%sh build_whoosh_index.sh
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from six import text_type
|
||||
from six.moves import configparser
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
|
||||
# Whoosh is compatible with Python 2.5+ Try to import Whoosh and set flag to indicate whether search is enabled.
|
||||
try:
|
||||
from whoosh.filedb.filestore import FileStorage
|
||||
from whoosh.fields import Schema, STORED, TEXT
|
||||
whoosh_search_enabled = True
|
||||
schema = Schema(id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT)
|
||||
import galaxy.model.mapping
|
||||
from galaxy import config, model
|
||||
except ImportError:
|
||||
whoosh_search_enabled = False
|
||||
schema = None
|
||||
|
||||
|
||||
def build_index(sa_session, whoosh_index_dir):
|
||||
storage = FileStorage(whoosh_index_dir)
|
||||
index = storage.create_index(schema)
|
||||
writer = index.writer()
|
||||
|
||||
def to_unicode(a_basestr):
|
||||
if not isinstance(a_basestr, text_type):
|
||||
return text_type(a_basestr, 'utf-8')
|
||||
else:
|
||||
return a_basestr
|
||||
lddas_indexed = 0
|
||||
for id, name, info, dbkey, message in get_lddas(sa_session):
|
||||
writer.add_document(id=id,
|
||||
name=to_unicode(name),
|
||||
info=to_unicode(info),
|
||||
dbkey=to_unicode(dbkey),
|
||||
message=to_unicode(message))
|
||||
lddas_indexed += 1
|
||||
writer.commit()
|
||||
print("Number of active library datasets indexed: ", lddas_indexed)
|
||||
|
||||
|
||||
def get_lddas(sa_session):
|
||||
for ldda in sa_session.query(model.LibraryDatasetDatasetAssociation).filter_by(deleted=False):
|
||||
id = ldda.id
|
||||
name = ldda.name
|
||||
info = ldda.library_dataset.get_info()
|
||||
if info and not info.startswith('upload'):
|
||||
info = info.replace('no info', '')
|
||||
else:
|
||||
info = ''
|
||||
dbkey = ldda.metadata.dbkey
|
||||
if ldda.message:
|
||||
message = ldda.message
|
||||
else:
|
||||
message = ''
|
||||
yield id, name, info, dbkey, message
|
||||
|
||||
|
||||
def get_sa_session_and_needed_config_settings(ini_file):
|
||||
conf_parser = configparser.ConfigParser({'here': os.getcwd()})
|
||||
conf_parser.read(ini_file)
|
||||
kwds = dict()
|
||||
for key, value in conf_parser.items("app:main"):
|
||||
kwds[key] = value
|
||||
config_settings = config.Configuration(**kwds)
|
||||
db_con = config_settings.database_connection
|
||||
if not db_con:
|
||||
db_con = "sqlite:///%s?isolation_level=IMMEDIATE" % config_settings.database
|
||||
model = galaxy.model.mapping.init(config_settings.file_path, db_con, engine_options={}, create_tables=False)
|
||||
return model.context.current, config_settings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if whoosh_search_enabled:
|
||||
ini_file = sys.argv[1]
|
||||
sa_session, config_settings = get_sa_session_and_needed_config_settings(ini_file)
|
||||
whoosh_index_dir = config_settings.whoosh_index_dir
|
||||
build_index(sa_session, whoosh_index_dir)
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd `dirname $0`/../..
|
||||
python ./scripts/data_libraries/build_whoosh_index.py ./config/galaxy.ini
|
||||
+1
-1
@@ -32,7 +32,7 @@ sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pa
|
||||
|
||||
from galaxy.datatypes.registry import Registry
|
||||
from galaxy.model import * # noqa
|
||||
from galaxy.model import set_datatypes_registry # More expclicit than `*` import
|
||||
from galaxy.model import set_datatypes_registry # More explicit than `*` import
|
||||
from galaxy.model.mapping import init
|
||||
from galaxy.model.orm.scripts import get_config
|
||||
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ class GalaxyConfigBuilder(object):
|
||||
def populate_options(cls, arg_parser):
|
||||
arg_parser.add_argument("-c", "--config-file", default=None, help="Galaxy config file (defaults to config/galaxy.ini)")
|
||||
arg_parser.add_argument("--ini-path", default=None, help="DEPRECATED: use -c/--config-file")
|
||||
arg_parser.add_argument("--app", default=None, help="app section in ini file (defaults to 'galaxy' for YAML/JSON, 'main' (w/ 'app:' prepended) for INI")
|
||||
arg_parser.add_argument("--app", default=None, help="app section in config file (defaults to 'galaxy' for YAML/JSON, 'main' (w/ 'app:' prepended) for INI")
|
||||
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 config_file if set)")
|
||||
|
||||
+13
-23
@@ -7,7 +7,6 @@ import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import time
|
||||
@@ -18,41 +17,33 @@ import yaml
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'lib')))
|
||||
import galaxy
|
||||
import galaxy.app
|
||||
import galaxy.config
|
||||
from galaxy.model import mapping
|
||||
from galaxy.objectstore import build_object_store_from_config
|
||||
from galaxy.util.properties import load_app_properties
|
||||
from galaxy.util import hash_util
|
||||
from galaxy.util.script import app_properties_from_args, config_file_from_args, populate_config_args
|
||||
|
||||
sample_config = os.path.abspath(os.path.join(os.path.dirname(__file__), 'grt.yml.sample'))
|
||||
default_config = os.path.abspath(os.path.join(os.path.dirname(__file__), 'grt.yml'))
|
||||
|
||||
|
||||
def _init(config, need_app=False):
|
||||
if config.startswith('/'):
|
||||
config_file = os.path.abspath(config)
|
||||
else:
|
||||
config_file = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, config))
|
||||
|
||||
properties = load_app_properties(ini_file=config_file)
|
||||
def _init(args, need_app=False):
|
||||
properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**properties)
|
||||
object_store = build_object_store_from_config(config)
|
||||
if not config.database_connection:
|
||||
logging.warning("The database connection is empty. If you are using the default value, please uncomment that in your galaxy.ini")
|
||||
|
||||
if need_app:
|
||||
config_file = config_file_from_args(args)
|
||||
app = galaxy.app.UniverseApplication(global_conf={'__file__': config_file, 'here': os.getcwd()})
|
||||
else:
|
||||
app = None
|
||||
|
||||
model = galaxy.config.init_models_from_config(config, object_store=object_store)
|
||||
return (
|
||||
mapping.init(
|
||||
config.file_path,
|
||||
config.database_connection,
|
||||
create_tables=False,
|
||||
object_store=object_store
|
||||
),
|
||||
model,
|
||||
object_store,
|
||||
config.database_connection.split(':')[0],
|
||||
config,
|
||||
app
|
||||
)
|
||||
@@ -167,7 +158,7 @@ def main(argv):
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('-r', '--report-directory', help='Directory to store reports in',
|
||||
default=os.path.abspath(os.path.join('.', 'reports')))
|
||||
parser.add_argument('-c', '--config', help='Path to GRT config file',
|
||||
parser.add_argument('-g', '--grt-config', help='Path to GRT config file',
|
||||
default=default_config)
|
||||
parser.add_argument("-l", "--loglevel", choices=['debug', 'info', 'warning', 'error', 'critical'],
|
||||
help="Set the logging level", default='warning')
|
||||
@@ -175,6 +166,7 @@ def main(argv):
|
||||
help="Batch size for sql queries")
|
||||
parser.add_argument("-m", "--max-records", type=int, default=0,
|
||||
help="Maximum number of records to include in a single report. This option should ONLY be used when reporting historical data. Setting this may require running GRT multiple times to capture all historical logs.")
|
||||
populate_config_args(parser)
|
||||
|
||||
args = parser.parse_args()
|
||||
logging.getLogger().setLevel(getattr(logging, args.loglevel.upper()))
|
||||
@@ -189,7 +181,7 @@ def main(argv):
|
||||
|
||||
annotate('init_start', 'Loading GRT configuration...')
|
||||
try:
|
||||
with open(args.config) as handle:
|
||||
with open(args.grt_config) as handle:
|
||||
config = yaml.safe_load(handle)
|
||||
except Exception:
|
||||
logging.info('Using default GRT configuration')
|
||||
@@ -209,7 +201,7 @@ def main(argv):
|
||||
last_job_sent = -1
|
||||
|
||||
annotate('galaxy_init', 'Loading Galaxy...')
|
||||
model, object_store, engine, gxconfig, app = _init(config['galaxy_config'], need_app=config['grt']['share_toolbox'])
|
||||
model, object_store, gxconfig, app = _init(args, need_app=config['grt']['share_toolbox'])
|
||||
# Galaxy overrides our logging level.
|
||||
logging.getLogger().setLevel(getattr(logging, args.loglevel.upper()))
|
||||
sa_session = model.context.current
|
||||
@@ -345,10 +337,8 @@ def main(argv):
|
||||
os.unlink(REPORT_BASE + '.' + name + '.tsv')
|
||||
|
||||
_times.append(('job_finish', time.time() - _start_time))
|
||||
sha = subprocess.check_output(['sha256sum', REPORT_BASE + '.tar.gz'])
|
||||
sha = hash_util.memory_bound_hexdigest(hash_util.sha256, REPORT_BASE + ".tar.gz")
|
||||
_times.append(('hash_finish', time.time() - _start_time))
|
||||
# Strip out to space
|
||||
sha = sha[0:sha.index(' ')]
|
||||
|
||||
# Now serialize the individual report data.
|
||||
with open(REPORT_BASE + '.json', 'w') as handle:
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# Location of your galaxy config file. The radio telescope will need to
|
||||
# partially initialize a copy of galaxy.
|
||||
galaxy_config: config/galaxy.ini
|
||||
|
||||
grt:
|
||||
# Go to https://telescope.galaxyproject.org to obtain an Instance ID and API key
|
||||
instance_id:
|
||||
|
||||
@@ -20,7 +20,7 @@ def main(argv):
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('-r', '--report-directory', help='Directory in which reports are stored',
|
||||
default=os.path.abspath(os.path.join('.', 'reports')))
|
||||
parser.add_argument('-c', '--config', help='Path to GRT config file',
|
||||
parser.add_argument('-g', '--grt-config', help='Path to GRT config file',
|
||||
default=default_config)
|
||||
parser.add_argument("-l", "--loglevel", choices=['debug', 'info', 'warning', 'error', 'critical'],
|
||||
help="Set the logging level", default='warning')
|
||||
@@ -28,7 +28,7 @@ def main(argv):
|
||||
|
||||
logging.info('Loading GRT configuration...')
|
||||
try:
|
||||
with open(args.config) as handle:
|
||||
with open(args.grt_config) as handle:
|
||||
config = yaml.safe_load(handle)
|
||||
except Exception:
|
||||
logging.info('Using default GRT configuration')
|
||||
|
||||
+24
-38
@@ -6,61 +6,47 @@ returns the disk path of a dataset.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
sys.path.insert(1, os.path.join(os.path.dirname(__file__), os.pardir, 'lib'))
|
||||
|
||||
from galaxy.model import mapping
|
||||
import galaxy.config
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
from galaxy.web import security
|
||||
|
||||
default_config = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'config/galaxy.ini'))
|
||||
parser = argparse.ArgumentParser()
|
||||
populate_config_args(parser)
|
||||
parser.add_argument('-e', '--encode-id', dest='encode_id', help='Encode an ID')
|
||||
parser.add_argument('-d', '--decode-id', dest='decode_id', help='Decode an ID')
|
||||
parser.add_argument('--hda', dest='hda_id', help='Display HistoryDatasetAssociation info')
|
||||
parser.add_argument('--ldda', dest='ldda_id', help='Display LibraryDatasetDatasetAssociation info')
|
||||
args = parser.parse_args()
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-c', '--config', dest='config', help='Path to Galaxy config file (config/galaxy.ini)', default=default_config)
|
||||
parser.add_option('-e', '--encode-id', dest='encode_id', help='Encode an ID')
|
||||
parser.add_option('-d', '--decode-id', dest='decode_id', help='Decode an ID')
|
||||
parser.add_option('--hda', dest='hda_id', help='Display HistoryDatasetAssociation info')
|
||||
parser.add_option('--ldda', dest='ldda_id', help='Display LibraryDatasetDatasetAssociation info')
|
||||
(options, args) = parser.parse_args()
|
||||
app_properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
helper = security.SecurityHelper(id_secret=app_properties.get('id_secret'))
|
||||
model = galaxy.config.init_models_from_config(config)
|
||||
|
||||
try:
|
||||
assert options.encode_id or options.decode_id or options.hda_id or options.ldda_id
|
||||
except Exception:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
if args.encode_id:
|
||||
print('Encoded "%s": %s' % (args.encode_id, helper.encode_id(args.encode_id)))
|
||||
|
||||
options.config = os.path.abspath(options.config)
|
||||
if args.decode_id:
|
||||
print('Decoded "%s": %s' % (args.decode_id, helper.decode_id(args.decode_id)))
|
||||
|
||||
config = ConfigParser(dict(file_path='database/files',
|
||||
id_secret='USING THE DEFAULT IS NOT SECURE!',
|
||||
database_connection='sqlite:///database/universe.sqlite?isolation_level=IMMEDIATE'))
|
||||
config.read(options.config)
|
||||
|
||||
helper = security.SecurityHelper(id_secret=config.get('app:main', 'id_secret'))
|
||||
model = mapping.init(config.get('app:main', 'file_path'), config.get('app:main', 'database_connection'), create_tables=False)
|
||||
|
||||
if options.encode_id:
|
||||
print('Encoded "%s": %s' % (options.encode_id, helper.encode_id(options.encode_id)))
|
||||
|
||||
if options.decode_id:
|
||||
print('Decoded "%s": %s' % (options.decode_id, helper.decode_id(options.decode_id)))
|
||||
|
||||
if options.hda_id:
|
||||
if args.hda_id:
|
||||
try:
|
||||
hda_id = int(options.hda_id)
|
||||
hda_id = int(args.hda_id)
|
||||
except Exception:
|
||||
hda_id = int(helper.decode_id(options.hda_id))
|
||||
hda_id = int(helper.decode_id(args.hda_id))
|
||||
hda = model.context.current.query(model.HistoryDatasetAssociation).get(hda_id)
|
||||
print('HDA "%s" is Dataset "%s" at: %s' % (hda.id, hda.dataset.id, hda.file_name))
|
||||
|
||||
if options.ldda_id:
|
||||
if args.ldda_id:
|
||||
try:
|
||||
ldda_id = int(options.ldda_id)
|
||||
ldda_id = int(args.ldda_id)
|
||||
except Exception:
|
||||
ldda_id = int(helper.decode_id(options.ldda_id))
|
||||
ldda_id = int(helper.decode_id(args.ldda_id))
|
||||
ldda = model.context.current.query(model.HistoryDatasetAssociation).get(ldda_id)
|
||||
print('LDDA "%s" is Dataset "%s" at: %s' % (ldda.id, ldda.dataset.id, ldda.file_name))
|
||||
|
||||
@@ -12,7 +12,8 @@ from galaxy.model.orm.scripts import get_config
|
||||
|
||||
|
||||
def invoke_migrate_main():
|
||||
config = get_config(sys.argv)
|
||||
# Migrate has its own args, so cannot use argparse
|
||||
config = get_config(sys.argv, use_argparse=False)
|
||||
db_url = config['db_url']
|
||||
repo = config['repo']
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Fetch jobs using gops_intersect, gops_merge, gops_subtract, gops_complement, gops_coverage
|
||||
wherein the second dataset doesn't have chr, start and end in standard columns 1, 2 and 3.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import sqlalchemy as sa
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
import galaxy.app
|
||||
import galaxy.model.mapping
|
||||
|
||||
assert sys.version_info[:2] >= (2, 6)
|
||||
|
||||
|
||||
class TestApplication(object):
|
||||
"""Encapsulates the state of a Universe application"""
|
||||
def __init__(self, database_connection=None, file_path=None):
|
||||
print("python path is: " + ", ".join(sys.path), file=sys.stderr)
|
||||
if database_connection is None:
|
||||
raise Exception("CleanupDatasetsApplication requires a database_connection value")
|
||||
if file_path is None:
|
||||
raise Exception("CleanupDatasetsApplication requires a file_path value")
|
||||
self.database_connection = database_connection
|
||||
self.file_path = file_path
|
||||
# Setup the database engine and ORM
|
||||
self.model = galaxy.model.mapping.init(self.file_path, self.database_connection, engine_options={}, create_tables=False)
|
||||
|
||||
|
||||
def main():
|
||||
ini_file = sys.argv[1]
|
||||
conf_parser = ConfigParser({'here': os.getcwd()})
|
||||
conf_parser.read(ini_file)
|
||||
configuration = {}
|
||||
for key, value in conf_parser.items("app:main"):
|
||||
configuration[key] = value
|
||||
database_connection = configuration['database_connection']
|
||||
file_path = configuration['file_path']
|
||||
app = TestApplication(database_connection=database_connection, file_path=file_path)
|
||||
jobs = {}
|
||||
try:
|
||||
for job in app.model.Job.filter(sa.and_(app.model.Job.table.c.create_time.between('2008-05-23', '2008-11-29'),
|
||||
app.model.Job.table.c.state == 'ok',
|
||||
sa.or_(sa.and_(sa.or_(app.model.Job.table.c.tool_id == 'gops_intersect_1',
|
||||
app.model.Job.table.c.tool_id == 'gops_subtract_1',
|
||||
app.model.Job.table.c.tool_id == 'gops_coverage_1'),
|
||||
sa.not_(app.model.Job.table.c.command_line.like('%-2 1,2,3%'))),
|
||||
sa.and_(sa.or_(app.model.Job.table.c.tool_id == 'gops_complement_1',
|
||||
app.model.Job.table.c.tool_id == 'gops_merge_1'),
|
||||
sa.not_(app.model.Job.table.c.command_line.like('%-1 1,2,3%')))))).all():
|
||||
print("# processing job id %s" % str(job.id))
|
||||
for jtoda in job.output_datasets:
|
||||
print("# --> processing JobToOutputDatasetAssociation id %s" % str(jtoda.id))
|
||||
hda = app.model.HistoryDatasetAssociation.get(jtoda.dataset_id)
|
||||
print("# ----> processing HistoryDatasetAssociation id %s" % str(hda.id))
|
||||
if not hda.deleted:
|
||||
# Probably don't need this check, since the job state should suffice, but...
|
||||
if hda.dataset.state == 'ok':
|
||||
history = app.model.History.get(hda.history_id)
|
||||
print("# ------> processing history id %s" % str(history.id))
|
||||
if history.user_id:
|
||||
cmd_line = str(job.command_line)
|
||||
new_output = tempfile.NamedTemporaryFile('w')
|
||||
if job.tool_id in ['gops_intersect_1', 'gops_subtract_1', 'gops_coverage_1']:
|
||||
new_cmd_line = " ".join(map(str, cmd_line.split()[:4])) + " " + new_output.name + " " + " ".join(map(str, cmd_line.split()[5:]))
|
||||
job_output = cmd_line.split()[4]
|
||||
else:
|
||||
new_cmd_line = " ".join(map(str, cmd_line.split()[:3])) + " " + new_output.name + " " + " ".join(map(str, cmd_line.split()[4:]))
|
||||
job_output = cmd_line.split()[3]
|
||||
try:
|
||||
os.system(new_cmd_line)
|
||||
except Exception:
|
||||
pass
|
||||
diff_status = os.system('diff %s %s >> /dev/null' % (new_output.name, job_output))
|
||||
if diff_status == 0:
|
||||
continue
|
||||
print("# --------> Outputs differ")
|
||||
user = app.model.User.get(history.user_id)
|
||||
jobs[job.id] = {}
|
||||
jobs[job.id]['hda_id'] = hda.id
|
||||
jobs[job.id]['hda_name'] = hda.name
|
||||
jobs[job.id]['hda_info'] = hda.info
|
||||
jobs[job.id]['history_id'] = history.id
|
||||
jobs[job.id]['history_name'] = history.name
|
||||
jobs[job.id]['history_update_time'] = history.update_time
|
||||
jobs[job.id]['user_email'] = user.email
|
||||
except Exception as e:
|
||||
print("# caught exception: %s" % e)
|
||||
|
||||
print("\n\n# Number of incorrect Jobs: %d\n\n" % (len(jobs)))
|
||||
print("#job_id\thda_id\thda_name\thda_info\thistory_id\thistory_name\thistory_update_time\tuser_email")
|
||||
for jid in jobs:
|
||||
print('%s\t%s\t"%s"\t"%s"\t%s\t"%s"\t"%s"\t%s' %
|
||||
(str(jid),
|
||||
str(jobs[jid]['hda_id']),
|
||||
jobs[jid]['hda_name'],
|
||||
jobs[jid]['hda_info'],
|
||||
str(jobs[jid]['history_id']),
|
||||
jobs[jid]['history_name'],
|
||||
jobs[jid]['history_update_time'],
|
||||
jobs[jid]['user_email']))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd `dirname $0`/../..
|
||||
python ./scripts/others/incorrect_gops_jobs.py ./config/galaxy.ini >> ./scripts/others/incorrect_gops_jobs.log
|
||||
@@ -1,101 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Fetch gops_join wherein the use specified minimum coverage is not 1.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import sqlalchemy as sa
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
import galaxy.app
|
||||
import galaxy.model.mapping
|
||||
|
||||
assert sys.version_info[:2] >= (2, 6)
|
||||
|
||||
|
||||
class TestApplication(object):
|
||||
"""Encapsulates the state of a Universe application"""
|
||||
def __init__(self, database_connection=None, file_path=None):
|
||||
print("python path is: " + ", ".join(sys.path), file=sys.stderr)
|
||||
if database_connection is None:
|
||||
raise Exception("CleanupDatasetsApplication requires a database_connection value")
|
||||
if file_path is None:
|
||||
raise Exception("CleanupDatasetsApplication requires a file_path value")
|
||||
self.database_connection = database_connection
|
||||
self.file_path = file_path
|
||||
# Setup the database engine and ORM
|
||||
self.model = galaxy.model.mapping.init(self.file_path, self.database_connection, engine_options={}, create_tables=False)
|
||||
|
||||
|
||||
def main():
|
||||
ini_file = sys.argv[1]
|
||||
conf_parser = ConfigParser({'here': os.getcwd()})
|
||||
conf_parser.read(ini_file)
|
||||
configuration = {}
|
||||
for key, value in conf_parser.items("app:main"):
|
||||
configuration[key] = value
|
||||
database_connection = configuration['database_connection']
|
||||
file_path = configuration['file_path']
|
||||
app = TestApplication(database_connection=database_connection, file_path=file_path)
|
||||
jobs = {}
|
||||
try:
|
||||
for job in app.model.Job.filter(sa.and_(app.model.Job.table.c.create_time < '2008-12-16',
|
||||
app.model.Job.table.c.state == 'ok',
|
||||
app.model.Job.table.c.tool_id == 'gops_join_1',
|
||||
sa.not_(app.model.Job.table.c.command_line.like('%-m 1 %')))).all():
|
||||
print("# processing job id %s" % str(job.id))
|
||||
for jtoda in job.output_datasets:
|
||||
print("# --> processing JobToOutputDatasetAssociation id %s" % str(jtoda.id))
|
||||
hda = app.model.HistoryDatasetAssociation.get(jtoda.dataset_id)
|
||||
print("# ----> processing HistoryDatasetAssociation id %s" % str(hda.id))
|
||||
if not hda.deleted:
|
||||
# Probably don't need this check, since the job state should suffice, but...
|
||||
if hda.dataset.state == 'ok':
|
||||
history = app.model.History.get(hda.history_id)
|
||||
print("# ------> processing history id %s" % str(history.id))
|
||||
if history.user_id:
|
||||
cmd_line = str(job.command_line)
|
||||
new_output = tempfile.NamedTemporaryFile('w')
|
||||
new_cmd_line = " ".join(map(str, cmd_line.split()[:4])) + " " + new_output.name + " " + " ".join(map(str, cmd_line.split()[5:]))
|
||||
job_output = cmd_line.split()[4]
|
||||
try:
|
||||
os.system(new_cmd_line)
|
||||
except Exception:
|
||||
pass
|
||||
diff_status = os.system('diff %s %s >> /dev/null' % (new_output.name, job_output))
|
||||
if diff_status == 0:
|
||||
continue
|
||||
print("# --------> Outputs differ")
|
||||
user = app.model.User.get(history.user_id)
|
||||
jobs[job.id] = {}
|
||||
jobs[job.id]['hda_id'] = hda.id
|
||||
jobs[job.id]['hda_name'] = hda.name
|
||||
jobs[job.id]['hda_info'] = hda.info
|
||||
jobs[job.id]['history_id'] = history.id
|
||||
jobs[job.id]['history_name'] = history.name
|
||||
jobs[job.id]['history_update_time'] = history.update_time
|
||||
jobs[job.id]['user_email'] = user.email
|
||||
except Exception as e:
|
||||
print("# caught exception: %s" % e)
|
||||
|
||||
print("\n\n# Number of incorrect Jobs: %d\n\n" % (len(jobs)))
|
||||
print("#job_id\thda_id\thda_name\thda_info\thistory_id\thistory_name\thistory_update_time\tuser_email")
|
||||
for jid in jobs:
|
||||
print('%s\t%s\t"%s"\t"%s"\t%s\t"%s"\t"%s"\t%s' %
|
||||
(str(jid),
|
||||
str(jobs[jid]['hda_id']),
|
||||
jobs[jid]['hda_name'],
|
||||
jobs[jid]['hda_info'],
|
||||
str(jobs[jid]['history_id']),
|
||||
jobs[jid]['history_name'],
|
||||
jobs[jid]['history_update_time'],
|
||||
jobs[jid]['user_email']))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd `dirname $0`/../..
|
||||
python ./scripts/others/incorrect_gops_join_jobs.py ./config/galaxy.ini >> ./scripts/others/incorrect_gops_join_jobs.log
|
||||
+14
-10
@@ -32,14 +32,20 @@ Examples
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import numpy
|
||||
import psycopg2
|
||||
from six.moves import configparser
|
||||
from sqlalchemy.engine import url
|
||||
|
||||
galaxy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
sys.path.insert(1, os.path.join(galaxy_root, 'lib'))
|
||||
|
||||
import galaxy.config
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
|
||||
DATA_SOURCES = ('metrics', 'history')
|
||||
METRICS_SQL = """
|
||||
@@ -78,7 +84,7 @@ def parse_arguments():
|
||||
help='Use SQL `LIKE` operator to find '
|
||||
'a shed-installed tool using the tool\'s '
|
||||
'"short" id')
|
||||
parser.add_argument('-c', '--config', help='Galaxy config file')
|
||||
populate_config_args(parser)
|
||||
parser.add_argument('-d', '--debug',
|
||||
action='store_true',
|
||||
default=False,
|
||||
@@ -110,14 +116,12 @@ def parse_arguments():
|
||||
print('ERROR: Data source `%s` unknown, valid source are: %s'
|
||||
% (args.source, ', '.join(DATA_SOURCES)))
|
||||
|
||||
if args.config:
|
||||
cp = configparser.ConfigParser()
|
||||
cp.readfp(open(args.config))
|
||||
uri = cp.get('app:main', 'database_connection')
|
||||
names = {'database': 'dbname', 'username': 'user'}
|
||||
args.connect_args = url.make_url(uri).translate_connect_args(**names)
|
||||
else:
|
||||
args.connect_args = {}
|
||||
app_properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
uri = args.config.get_database_url(config)
|
||||
|
||||
names = {'database': 'dbname', 'username': 'user'}
|
||||
args.connect_args = url.make_url(uri).translate_connect_args(**names)
|
||||
|
||||
if args.debug:
|
||||
print('Got options:')
|
||||
|
||||
@@ -2,32 +2,36 @@
|
||||
"""
|
||||
Script to encode/decode the IDs that galaxy exposes to users and admins.
|
||||
"""
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'lib')))
|
||||
|
||||
from galaxy.model import mapping
|
||||
from galaxy.model.orm.scripts import get_config
|
||||
from galaxy.util.properties import load_app_properties
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
from galaxy.web.security import SecurityHelper
|
||||
|
||||
logging.basicConfig()
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Get config file and load up SA session
|
||||
config = get_config(sys.argv)
|
||||
model = mapping.init('/tmp/', config['db_url'])
|
||||
sa_session = model.context.current
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('action', metavar='ACTION', type=str,
|
||||
default=None,
|
||||
help='decode|encode')
|
||||
parser.add_argument('value', metavar='VALUE', type=str,
|
||||
default=None,
|
||||
help='value to encode or decode')
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
# With the config file we can load the full app properties
|
||||
app_properties = load_app_properties(ini_file=config['config_file'])
|
||||
app_properties = app_properties_from_args(args)
|
||||
helper = SecurityHelper(id_secret=app_properties.get('id_secret'))
|
||||
|
||||
# We need the ID secret for configuring the security helper to decrypt
|
||||
# galaxysession cookies.
|
||||
if "id_secret" not in app_properties:
|
||||
log.warning('No ID_SECRET specified. Please set the "id_secret" in your galaxy.ini.')
|
||||
log.warning('No ID_SECRET specified. Please set the "id_secret" in your galaxy.yml.')
|
||||
|
||||
id_secret = app_properties.get('id_secret', 'dangerous_default')
|
||||
|
||||
@@ -35,17 +39,10 @@ security_helper = SecurityHelper(id_secret=id_secret)
|
||||
# And get access to the models
|
||||
# Login manager to manage current_user functionality
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
sys.stdout.write("python %s (encode|decode) value\n" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
action = sys.argv[1]
|
||||
value = sys.argv[2]
|
||||
|
||||
if action == 'decode':
|
||||
sys.stdout.write(security_helper.decode_guid(value.lstrip('F')))
|
||||
elif action == 'encode':
|
||||
sys.stdout.write(security_helper.encode_guid(value))
|
||||
if args.action == 'decode':
|
||||
sys.stdout.write(security_helper.decode_guid(args.value.lstrip('F')))
|
||||
elif args.action == 'encode':
|
||||
sys.stdout.write(security_helper.encode_guid(args.value))
|
||||
else:
|
||||
sys.stdout.write("Unknown argument")
|
||||
sys.stdout.write('\n')
|
||||
|
||||
@@ -1,40 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'lib')))
|
||||
|
||||
import galaxy.config
|
||||
from galaxy.model import mapping
|
||||
from galaxy.objectstore import build_object_store_from_config
|
||||
default_config = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'config/galaxy.ini'))
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-c', '--config', dest='config', help='Path to Galaxy config file (config/galaxy.ini)', default=default_config)
|
||||
(options, args) = parser.parse_args()
|
||||
parser = argparse.ArgumentParser()
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def init():
|
||||
options.config = os.path.abspath(options.config)
|
||||
|
||||
config_parser = ConfigParser(dict(here=os.getcwd(),
|
||||
database_connection='sqlite:///database/universe.sqlite?isolation_level=IMMEDIATE'))
|
||||
config_parser.read(options.config)
|
||||
|
||||
config_dict = {}
|
||||
for key, value in config_parser.items("app:main"):
|
||||
config_dict[key] = value
|
||||
|
||||
config = galaxy.config.Configuration(**config_dict)
|
||||
app_properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
|
||||
object_store = build_object_store_from_config(config)
|
||||
return (mapping.init(config.file_path, config.database_connection, create_tables=False, object_store=object_store),
|
||||
object_store)
|
||||
model = galaxy.config.init_models_from_config(config, object_store=object_store)
|
||||
return model, object_store
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'lib')))
|
||||
|
||||
@@ -13,41 +11,30 @@ import galaxy.config
|
||||
from galaxy.model.util import pgcalc
|
||||
from galaxy.objectstore import build_object_store_from_config
|
||||
from galaxy.util import nice_size
|
||||
|
||||
from galaxy.util.script import app_properties_from_args, populate_config_args
|
||||
|
||||
default_config = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'config/galaxy.ini'))
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-c', '--config', dest='config', help='Path to Galaxy config file (config/galaxy.ini)', default=default_config)
|
||||
parser.add_option('-u', '--username', dest='username', help='Username of user to update', default='all')
|
||||
parser.add_option('-e', '--email', dest='email', help='Email address of user to update', default='all')
|
||||
parser.add_option('--dry-run', dest='dryrun', help='Dry run (show changes but do not save to database)', action='store_true', default=False)
|
||||
(options, args) = parser.parse_args()
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-u', '--username', dest='username', help='Username of user to update', default='all')
|
||||
parser.add_argument('-e', '--email', dest='email', help='Email address of user to update', default='all')
|
||||
parser.add_argument('--dry-run', dest='dryrun', help='Dry run (show changes but do not save to database)', action='store_true', default=False)
|
||||
populate_config_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def init():
|
||||
options.config = os.path.abspath(options.config)
|
||||
if options.username == 'all':
|
||||
options.username = None
|
||||
if options.email == 'all':
|
||||
options.email = None
|
||||
|
||||
config_parser = ConfigParser(dict(here=os.getcwd(),
|
||||
database_connection='sqlite:///database/universe.sqlite?isolation_level=IMMEDIATE'))
|
||||
config_parser.read(options.config)
|
||||
if args.username == 'all':
|
||||
args.username = None
|
||||
if args.email == 'all':
|
||||
args.email = None
|
||||
|
||||
config_dict = {}
|
||||
for key, value in config_parser.items("app:main"):
|
||||
config_dict[key] = value
|
||||
|
||||
config = galaxy.config.Configuration(**config_dict)
|
||||
app_properties = app_properties_from_args(args)
|
||||
config = galaxy.config.Configuration(**app_properties)
|
||||
object_store = build_object_store_from_config(config)
|
||||
|
||||
from galaxy.model import mapping
|
||||
|
||||
return (mapping.init(config.file_path, config.database_connection, create_tables=False, object_store=object_store),
|
||||
object_store,
|
||||
config.database_connection.split(':')[0])
|
||||
engine = galaxy.config.get_database_url(config).split(":")[0]
|
||||
return galaxy.config.init_models_from_config(config, object_store=object_store), object_store, engine
|
||||
|
||||
|
||||
def quotacheck(sa_session, users, engine):
|
||||
@@ -62,7 +49,7 @@ def quotacheck(sa_session, users, engine):
|
||||
print('usage changed while calculating, trying again...')
|
||||
return quotacheck(sa_session, user, engine)
|
||||
else:
|
||||
new = pgcalc(sa_session, user.id, dryrun=options.dryrun)
|
||||
new = pgcalc(sa_session, user.id, dryrun=args.dryrun)
|
||||
# yes, still a small race condition between here and the flush
|
||||
print('old usage:', nice_size(current), 'change:', end=' ')
|
||||
if new in (current, None):
|
||||
@@ -72,7 +59,7 @@ def quotacheck(sa_session, users, engine):
|
||||
print('+%s' % (nice_size(new - current)))
|
||||
else:
|
||||
print('-%s' % (nice_size(current - new)))
|
||||
if not options.dryrun and engine not in ('postgres', 'postgresql'):
|
||||
if not args.dryrun and engine not in ('postgres', 'postgresql'):
|
||||
user.set_disk_usage(new)
|
||||
sa_session.add(user)
|
||||
sa_session.flush()
|
||||
@@ -83,7 +70,7 @@ if __name__ == '__main__':
|
||||
model, object_store, engine = init()
|
||||
sa_session = model.context.current
|
||||
|
||||
if not options.username and not options.email:
|
||||
if not args.username and not args.email:
|
||||
user_count = sa_session.query(model.User).count()
|
||||
print('Processing %i users...' % user_count)
|
||||
for i, user in enumerate(sa_session.query(model.User).enable_eagerloads(False).yield_per(1000)):
|
||||
@@ -92,10 +79,10 @@ if __name__ == '__main__':
|
||||
print('100% complete')
|
||||
object_store.shutdown()
|
||||
sys.exit(0)
|
||||
elif options.username:
|
||||
user = sa_session.query(model.User).enable_eagerloads(False).filter_by(username=options.username).first()
|
||||
elif options.email:
|
||||
user = sa_session.query(model.User).enable_eagerloads(False).filter_by(email=options.email).first()
|
||||
elif args.username:
|
||||
user = sa_session.query(model.User).enable_eagerloads(False).filter_by(username=args.username).first()
|
||||
elif args.email:
|
||||
user = sa_session.query(model.User).enable_eagerloads(False).filter_by(email=args.email).first()
|
||||
if not user:
|
||||
print('User not found')
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"""Deprecated - only works with older ini files.
|
||||
"""
|
||||
from sys import argv
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Downloads files to temp locations. This script is invoked by the Transfer
|
||||
Manager (galaxy.jobs.transfer_manager) and should not normally be invoked by
|
||||
hand.
|
||||
|
||||
This is deprecated - it only works with older ini configurations of Galaxy.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
"""Integration tests for various scripts in scripts/.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import yaml
|
||||
from base import integration_util
|
||||
from base.populators import DatasetPopulator
|
||||
|
||||
from galaxy.util import galaxy_directory
|
||||
|
||||
|
||||
def skip_unless_module(module):
|
||||
available = True
|
||||
try:
|
||||
__import__(module)
|
||||
except ImportError:
|
||||
available = False
|
||||
if available:
|
||||
return lambda func: func
|
||||
template = "Module %s could not be loaded, dependent test skipped."
|
||||
return unittest.skip(template % module)
|
||||
|
||||
|
||||
class ScriptsIntegrationTestCase(integration_util.IntegrationTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ScriptsIntegrationTestCase, self).setUp()
|
||||
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
||||
self.config_dir = tempfile.mkdtemp()
|
||||
|
||||
@classmethod
|
||||
def handle_galaxy_config_kwds(cls, config):
|
||||
cls._raw_config = config
|
||||
|
||||
def test_helper(self):
|
||||
script = "helper.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
dataset = self.dataset_populator.new_dataset(history_id, wait=True)
|
||||
dataset_id = dataset["id"]
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file, "--decode-id", dataset_id])
|
||||
assert "Decoded " in output
|
||||
|
||||
def test_cleanup(self):
|
||||
script = "cleanup_datasets/cleanup_datasets.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
delete_response = self.dataset_populator._delete("histories/%s" % history_id)
|
||||
assert delete_response.status_code == 200
|
||||
assert delete_response.json()["purged"] is False
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file, "--days", "0", "--purge_histories"])
|
||||
print(output)
|
||||
history_response = self.dataset_populator._get("histories/%s" % history_id)
|
||||
assert history_response.status_code == 200
|
||||
assert history_response.json()["purged"] is True, history_response.json()
|
||||
|
||||
def test_pgcleanup(self):
|
||||
self._skip_if_not_postgres()
|
||||
|
||||
script = "cleanup_datasets/pgcleanup.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
delete_response = self.dataset_populator._delete("histories/%s" % history_id)
|
||||
assert delete_response.status_code == 200
|
||||
assert delete_response.json()["purged"] is False
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file, "--older-than", "0", "--sequence", "purge_deleted_histories"])
|
||||
print(output)
|
||||
history_response = self.dataset_populator._get("histories/%s" % history_id)
|
||||
assert history_response.status_code == 200
|
||||
assert history_response.json()["purged"] is True, history_response.json()
|
||||
|
||||
def test_set_user_disk_usage(self):
|
||||
script = "set_user_disk_usage.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
self.dataset_populator.new_dataset(history_id, wait=True)
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file])
|
||||
# verify the script runs to completion without crashing
|
||||
assert "100% complete" in output, output
|
||||
|
||||
def test_set_dataset_sizes(self):
|
||||
script = "set_dataset_sizes.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
# TODO: change the size of the dataset and verify this works.
|
||||
history_id = self.dataset_populator.new_history()
|
||||
self.dataset_populator.new_dataset(history_id, wait=True)
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file])
|
||||
# verify the script runs to completion without crashing
|
||||
assert "Completed 100%" in output, output
|
||||
|
||||
def test_populate_uuid(self):
|
||||
script = "cleanup_datasets/populate_uuid.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
self.dataset_populator.new_dataset(history_id, wait=True)
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file])
|
||||
assert "Complete" in output
|
||||
|
||||
def test_grt_export(self):
|
||||
script = "grt/export.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
history_id = self.dataset_populator.new_history()
|
||||
self.dataset_populator.new_dataset(history_id, wait=True)
|
||||
config_file = self.write_config_file()
|
||||
grt_config_file = os.path.join(self.config_dir, "grt.yml")
|
||||
with open(grt_config_file, "w") as f:
|
||||
yaml.dump({"grt": {"share_toolbox": True}, "sanitization": {"tools": []}, "tool_params": {}}, f)
|
||||
self._scripts_check_output(script, ["-c", config_file, "-g", grt_config_file, "-r", self.config_dir])
|
||||
report_files = os.listdir(self.config_dir)
|
||||
json_files = [j for j in report_files if j.endswith(".json")]
|
||||
assert len(json_files) == 1, "Expected one json report file in [%s]" % json_files
|
||||
json_file = os.path.join(self.config_dir, json_files[0])
|
||||
with open(json_file, "r") as f:
|
||||
export = json.load(f)
|
||||
assert export["version"] == 1
|
||||
|
||||
def test_admin_cleanup_datasets(self):
|
||||
self._scripts_check_argparse_help("cleanup_datasets/admin_cleanup_datasets.py")
|
||||
|
||||
@skip_unless_module("flask_socketio")
|
||||
def test_communication_server(self):
|
||||
self._scripts_check_argparse_help("communication/communication_server.py")
|
||||
|
||||
def test_secret_decoder_ring(self):
|
||||
script = "secret_decoder_ring.py"
|
||||
self._scripts_check_argparse_help(script)
|
||||
|
||||
config_file = self.write_config_file()
|
||||
output = self._scripts_check_output(script, ["-c", config_file, "encode", "1"])
|
||||
encoded_id = output.strip()
|
||||
|
||||
output = self._scripts_check_output(script, ["-c", config_file, "decode", encoded_id])
|
||||
assert output.strip() == "1"
|
||||
|
||||
def test_database_scripts(self):
|
||||
self._scripts_check_argparse_help("create_db.py")
|
||||
self._scripts_check_argparse_help("manage_db.py")
|
||||
# TODO: test creating a smaller database - e.g. tool install database based on fresh
|
||||
# config file.
|
||||
|
||||
def test_runtime_stats(self):
|
||||
self._skip_if_not_postgres()
|
||||
self._scripts_check_argparse_help("runtime_stats.py")
|
||||
|
||||
def _skip_if_not_postgres(self):
|
||||
if not self._app.config.database_connection.startswith("post"):
|
||||
raise unittest.SkipTest("Test only valid for postgres")
|
||||
|
||||
def _scripts_check_argparse_help(self, script):
|
||||
# Test imports and argparse repsonse to --help with 0 exit code.
|
||||
output = self._scripts_check_output(script, ["--help"])
|
||||
# Test -h, --help in printed output message.
|
||||
assert "-h, --help" in output
|
||||
|
||||
def _scripts_check_output(self, script, args):
|
||||
cwd = galaxy_directory()
|
||||
cmd = ["python", os.path.join(cwd, "scripts", script)] + args
|
||||
clean_env = {
|
||||
"PATH": os.environ.get("PATH", None),
|
||||
} # Don't let testing environment variables interfere with config.
|
||||
return subprocess.check_output(cmd, cwd=cwd, env=clean_env)
|
||||
|
||||
def write_config_file(self):
|
||||
config_dir = self.config_dir
|
||||
path = os.path.join(config_dir, "galaxy.yml")
|
||||
self._test_driver.temp_directories.extend([config_dir])
|
||||
with open(path, "w") as f:
|
||||
yaml.dump({"galaxy": self._raw_config}, f)
|
||||
|
||||
return path
|
||||
Reference in New Issue
Block a user