Files
galaxy/scripts/dump_library_paths.py
2024-04-29 00:09:38 +01:00

160 lines
4.6 KiB
Python

"""Dump paths to library dataset files (e.g. for backups). Caveats:
- Does not perform any permissions checks on library *contents* (but you can restrict to "public" libraries).
- Only the latest version of undeleted library datasets are dumped.
To use with rsync:
$ python dump_library_paths.py [options] -o libfiles.txt --relative /srv/galaxy/datasets
$ rsync -arvPR --files-from=libfiles.txt /srv/galaxy/datasets backup@backuphost:/backup/galaxy/datasets
Or all in one:
$ python dump_library_paths.py [options] --relative /srv/galaxy/datasets | rsync -arvPR \
--files-from=- /srv/galaxy/datasets backuphost:/backup/galaxy/datasets
"""
import logging
import os
import sys
from sqlalchemy import (
false,
not_,
)
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, "lib")))
import galaxy.config
import galaxy.model.mapping
from galaxy.objectstore import build_object_store_from_config
from galaxy.util.script import main_factory
DESCRIPTION = "Locate all datasets in libraries."
ARGUMENTS = (
(
("-v", "--verbose"),
dict(
action="store_true",
default=False,
help="Verbose logging output",
),
),
(
("-o", "--output"),
dict(
default="stdout",
help="Write output to file",
),
),
(
("-p", "--public"),
dict(action="store_true", default=False, help='Only dump files in "public" libraries'),
),
(
("--relative",),
dict(
default=None,
help="Write paths relative to the given directory",
),
),
(
("--exists",),
dict(
action="store_true",
default=False,
help="Check for dataset existence, warn if it does not exist",
),
),
)
logging.basicConfig(stream=sys.stderr)
log = logging.getLogger(__name__)
def _config_logging(args):
if args.verbose:
log.setLevel(logging.DEBUG)
def _get_libraries(args, model):
log.debug("Setting up query")
library_access_action = model.security_agent.permitted_actions.LIBRARY_ACCESS.action
query = model.context.query(model.Library)
query = query.filter(model.Library.table.c.deleted == false())
if args.public:
restricted_library_ids = {
lp.library_id
for lp in (
model.context.query(model.LibraryPermissions)
.filter(model.LibraryPermissions.table.c.action == library_access_action)
.distinct()
)
}
if restricted_library_ids:
query = query.filter(not_(model.Library.table.c.id.in_(restricted_library_ids)))
query = query.order_by(model.Library.table.c.name)
return query
def _walk_library(folder):
datasets = set()
for f in folder.folders:
datasets.update(_walk_library(f))
for ld in folder.active_datasets:
datasets.add(ld.library_dataset_dataset_association.dataset)
return datasets
def _walk_libraries(args, model):
for library in _get_libraries(args, model):
for dataset in _walk_library(library.root_folder):
yield (library, dataset)
def _open_output(args):
if args.output == "stdout":
return sys.stdout
else:
return open(args.output, "w")
def _path(path, args):
if args.relative is not None:
return os.path.relpath(path, args.relative)
else:
return path
def _get_library_dataset_paths(args, kwargs):
_config_logging(args)
config = galaxy.config.Configuration(**kwargs)
object_store = build_object_store_from_config(config)
model = galaxy.model.mapping.init("/tmp/", kwargs.get("database_connection"), object_store=object_store)
output = _open_output(args)
last_library = None
log.debug("Beginning library walk")
for library, dataset in _walk_libraries(args, model):
if library != last_library:
log.info("Library: %s", library.name)
filename = object_store.get_filename(dataset)
files_dir = dataset.get_extra_files_path()
if (args.exists and object_store.exists(dataset)) or not args.exists:
output.write(f"{_path(filename, args)}\n")
elif args.exists:
log.warning("Missing %s", filename)
if files_dir and os.path.exists(files_dir):
output.write(f"{_path(files_dir, args)}\n")
last_library = library
output.close()
ACTIONS = {
"get_library_dataset_paths": _get_library_dataset_paths,
}
if __name__ == "__main__":
main = main_factory(
description=DESCRIPTION, actions=ACTIONS, arguments=ARGUMENTS, default_action="get_library_dataset_paths"
)
main()