Implement read-only conda resolver.

This commit is contained in:
John Chilton
2021-01-08 11:09:10 -05:00
parent 80bc83df5a
commit 22aa23e1db
5 changed files with 31 additions and 4 deletions
@@ -236,3 +236,7 @@ copy_dependencies
linking them when creating per job environments. This should be considered somewhat
deprecated because Conda will do this as needed for newer versions of Conda - such
as the version targeted with Galaxy 17.01+.
read_only
If ``True``, Galaxy will not attempt to install or uninstall requirement sets into
this environment.
@@ -25,6 +25,7 @@ class ContainerResolver(Dictifiable, metaclass=ABCMeta):
dict_collection_visible_keys = ['resolver_type', 'can_uninstall_dependencies', 'builds_on_resolution']
can_uninstall_dependencies = False
builds_on_resolution = False
read_only = True # not used for containers, but set for when they are used like dependency resolvers
def __init__(self, app_info=None, **kwds):
"""Default initializer for ``ContainerResolver`` subclasses."""
@@ -19,7 +19,7 @@ class DependencyResolver(Dictifiable, metaclass=ABCMeta):
"""Abstract description of a technique for resolving container images for tool execution."""
# Keys for dictification.
dict_collection_visible_keys = ['resolver_type', 'resolves_simple_dependencies', 'can_uninstall_dependencies']
dict_collection_visible_keys = ['resolver_type', 'resolves_simple_dependencies', 'can_uninstall_dependencies', 'read_only']
# A "simple" dependency is one that does not depend on the the tool
# resolving the dependency. Classic tool shed dependencies are non-simple
# because the repository install context is used in dependency resolution
@@ -29,6 +29,7 @@ class DependencyResolver(Dictifiable, metaclass=ABCMeta):
resolves_simple_dependencies = True
can_uninstall_dependencies = False
config_options: Dict[str, Any] = {}
read_only = True
@abstractmethod
def resolve(self, requirement, **kwds):
@@ -241,9 +242,16 @@ class InstallableDependencyResolver(metaclass=ABCMeta):
""" Mix this into a ``DependencyResolver`` and implement to indicate
the dependency resolver can attempt to install new dependencies.
"""
read_only = False
def install_dependency(self, name, version, type, **kwds):
if self.read_only:
return False
else:
return self._install_dependency(name, version, type, **kwds)
@abstractmethod
def install_dependency(self, name, version, type, **kwds):
def _install_dependency(self, name, version, type, **kwds):
""" Attempt to install this dependency if a recipe to do so
has been registered in some way.
"""
+10 -2
View File
@@ -80,7 +80,9 @@ class CondaDependencyResolver(DependencyResolver, MultipleDependencyResolver, Li
_specification_pattern = re.compile(r"https\:\/\/anaconda.org\/\w+\/\w+")
def __init__(self, dependency_manager, **kwds):
self.can_uninstall_dependencies = True
read_only = _string_as_bool(kwds.get('read_only', 'false'))
self.read_only = read_only
self.can_uninstall_dependencies = not read_only
self._setup_mapping(dependency_manager, **kwds)
self.versionless = _string_as_bool(kwds.get('versionless', 'false'))
self.dependency_manager = dependency_manager
@@ -167,6 +169,9 @@ class CondaDependencyResolver(DependencyResolver, MultipleDependencyResolver, Li
return final_return_code
def install_all(self, conda_targets):
if self.read_only:
return False
env = self.merged_environment_name(conda_targets)
return_code = install_conda_targets(conda_targets, conda_context=self.conda_context, env_name=env)
if return_code != 0:
@@ -335,8 +340,11 @@ class CondaDependencyResolver(DependencyResolver, MultipleDependencyResolver, Li
version = install_target.version
yield self._to_requirement(name, version)
def install_dependency(self, name, version, type, **kwds):
def _install_dependency(self, name, version, type, **kwds):
"Returns True on (seemingly) successfull installation"
# should be checked before called
assert not self.read_only
if type != "package":
log.warning("Cannot install dependencies of type '%s'" % type)
return False
@@ -23,6 +23,12 @@ def test_conda_resolution():
auto_install=True,
use_path_exec=False, # For the test ensure this is always a clean install
)
resolver.read_only = True
req = ToolRequirement(name="samtools", version=None, type="package")
dependency = resolver.resolve(req, job_directory=job_dir)
assert dependency.shell_commands() is None
resolver.read_only = False
req = ToolRequirement(name="samtools", version=None, type="package")
dependency = resolver.resolve(req, job_directory=job_dir)
assert dependency.shell_commands() is not None