mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'release_20.09' into release_21.01
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
from History</a
|
||||
>
|
||||
<a
|
||||
v-if="user_library_import_dir"
|
||||
v-if="user_library_import_dir_available"
|
||||
class="dropdown-item cursor-pointer"
|
||||
@click="addDatasets('userdir')"
|
||||
>
|
||||
@@ -203,7 +203,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
is_admin: false,
|
||||
user_library_import_dir: false,
|
||||
user_library_import_dir_available: false,
|
||||
library_import_dir: false,
|
||||
allow_library_path_paste: false,
|
||||
list_genomes: [],
|
||||
@@ -225,7 +225,7 @@ export default {
|
||||
const Galaxy = getGalaxyInstance();
|
||||
this.services = new Services();
|
||||
this.is_admin = Galaxy.user.attributes.is_admin;
|
||||
this.user_library_import_dir = Galaxy.config.user_library_import_dir;
|
||||
this.user_library_import_dir_available = Galaxy.config.user_library_import_dir_available;
|
||||
this.library_import_dir = Galaxy.config.library_import_dir;
|
||||
this.allow_library_path_paste = Galaxy.config.allow_library_path_paste;
|
||||
|
||||
|
||||
@@ -411,6 +411,7 @@ var AddDatasets = Backbone.View.extend({
|
||||
if (typeof response.responseJSON !== "undefined") {
|
||||
if (response.responseJSON.err_code === 404001) {
|
||||
Toast.warning(response.responseJSON.err_msg);
|
||||
getGalaxyInstance().modal.hide();
|
||||
} else {
|
||||
Toast.error(response.responseJSON.err_msg);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ class ConfigSerializer(base.ModelSerializer):
|
||||
'file_sources_configured' : lambda config, key, **context: self.app.file_sources.custom_sources_configured,
|
||||
'upload_from_form_button' : _use_config,
|
||||
'release_doc_base_url' : _use_config,
|
||||
'user_library_import_dir_available' : lambda config, key, **context: bool(config.get('user_library_import_dir')),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import subprocess
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
from galaxy.util import (
|
||||
safe_makedirs,
|
||||
string_as_bool,
|
||||
unicodify,
|
||||
which,
|
||||
@@ -335,37 +336,49 @@ def targets_to_mulled_name(targets, hash_func, namespace, resolution_cache=None,
|
||||
return name
|
||||
|
||||
|
||||
class DockerContainerResolver(ContainerResolver):
|
||||
class CliContainerResolver(ContainerResolver):
|
||||
|
||||
container_type = 'docker'
|
||||
cli = 'docker'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._docker_cli_available = bool(which('docker'))
|
||||
self._cli_available = bool(which(self.cli))
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def docker_cli_available(self):
|
||||
return self._docker_cli_available
|
||||
def cli_available(self):
|
||||
return self._cli_available
|
||||
|
||||
@docker_cli_available.setter
|
||||
def docker_cli_available(self, value):
|
||||
@cli_available.setter
|
||||
def cli_available(self, value):
|
||||
if not value:
|
||||
log.info('Docker CLI not available, cannot list or pull images in Galaxy process. Does not impact kubernetes.')
|
||||
self._docker_cli_available = value
|
||||
log.info('{} CLI not available, cannot list or pull images in Galaxy process. Does not impact kubernetes.'.format(self.cli))
|
||||
self._cli_available = value
|
||||
|
||||
|
||||
class CachedMulledDockerContainerResolver(DockerContainerResolver):
|
||||
class SingularityCliContainerResolver(CliContainerResolver):
|
||||
|
||||
container_type = 'singularity'
|
||||
cli = 'singularity'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.cache_directory = kwargs.get("cache_directory", os.path.join(kwargs['app_info'].container_image_cache_path, "singularity", "mulled"))
|
||||
safe_makedirs(self.cache_directory)
|
||||
|
||||
|
||||
class CachedMulledDockerContainerResolver(CliContainerResolver):
|
||||
|
||||
resolver_type = "cached_mulled"
|
||||
shell = '/bin/bash'
|
||||
|
||||
def __init__(self, app_info=None, namespace="biocontainers", hash_func="v2", **kwds):
|
||||
super().__init__(app_info)
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self.namespace = namespace
|
||||
self.hash_func = hash_func
|
||||
|
||||
def resolve(self, enabled_container_types, tool_info, **kwds):
|
||||
if not self.docker_cli_available or tool_info.requires_galaxy_python_environment or self.container_type not in enabled_container_types:
|
||||
if not self.cli_available or tool_info.requires_galaxy_python_environment or self.container_type not in enabled_container_types:
|
||||
return None
|
||||
|
||||
targets = mulled_targets(tool_info)
|
||||
@@ -376,15 +389,13 @@ class CachedMulledDockerContainerResolver(DockerContainerResolver):
|
||||
return "CachedMulledDockerContainerResolver[namespace=%s]" % self.namespace
|
||||
|
||||
|
||||
class CachedMulledSingularityContainerResolver(ContainerResolver):
|
||||
class CachedMulledSingularityContainerResolver(SingularityCliContainerResolver):
|
||||
|
||||
resolver_type = "cached_mulled_singularity"
|
||||
container_type = "singularity"
|
||||
shell = '/bin/bash'
|
||||
|
||||
def __init__(self, app_info=None, hash_func="v2", **kwds):
|
||||
super().__init__(app_info)
|
||||
self.cache_directory = kwds.get("cache_directory", os.path.join(app_info.container_image_cache_path, "singularity", "mulled"))
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self.hash_func = hash_func
|
||||
|
||||
def resolve(self, enabled_container_types, tool_info, **kwds):
|
||||
@@ -398,7 +409,7 @@ class CachedMulledSingularityContainerResolver(ContainerResolver):
|
||||
return "CachedMulledSingularityContainerResolver[cache_directory=%s]" % self.cache_directory
|
||||
|
||||
|
||||
class MulledDockerContainerResolver(DockerContainerResolver):
|
||||
class MulledDockerContainerResolver(CliContainerResolver):
|
||||
"""Look for mulled images matching tool dependencies."""
|
||||
|
||||
resolver_type = "mulled"
|
||||
@@ -406,7 +417,7 @@ class MulledDockerContainerResolver(DockerContainerResolver):
|
||||
protocol: Optional[str] = None
|
||||
|
||||
def __init__(self, app_info=None, namespace="biocontainers", hash_func="v2", auto_install=True, **kwds):
|
||||
super().__init__(app_info)
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self.namespace = namespace
|
||||
self.hash_func = hash_func
|
||||
self.auto_install = string_as_bool(auto_install)
|
||||
@@ -421,10 +432,14 @@ class MulledDockerContainerResolver(DockerContainerResolver):
|
||||
return None
|
||||
|
||||
def pull(self, container):
|
||||
if self.docker_cli_available:
|
||||
if self.cli_available:
|
||||
command = container.build_pull_command()
|
||||
shell(command)
|
||||
|
||||
@property
|
||||
def can_list_containers(self):
|
||||
return self.cli_available
|
||||
|
||||
def resolve(self, enabled_container_types, tool_info, install=False, session=None, **kwds):
|
||||
resolution_cache = kwds.get("resolution_cache")
|
||||
if tool_info.requires_galaxy_python_environment or self.container_type not in enabled_container_types:
|
||||
@@ -444,7 +459,7 @@ class MulledDockerContainerResolver(DockerContainerResolver):
|
||||
type=self.container_type,
|
||||
shell=self.shell,
|
||||
)
|
||||
if self.docker_cli_available:
|
||||
if self.can_list_containers:
|
||||
if install and not self.cached_container_description(
|
||||
targets,
|
||||
namespace=self.namespace,
|
||||
@@ -468,22 +483,20 @@ class MulledDockerContainerResolver(DockerContainerResolver):
|
||||
namespace=self.namespace,
|
||||
hash_func=self.hash_func,
|
||||
resolution_cache=resolution_cache,
|
||||
)
|
||||
) or container_description
|
||||
return container_description
|
||||
|
||||
def __str__(self):
|
||||
return "MulledDockerContainerResolver[namespace=%s]" % self.namespace
|
||||
|
||||
|
||||
class MulledSingularityContainerResolver(MulledDockerContainerResolver):
|
||||
class MulledSingularityContainerResolver(SingularityCliContainerResolver, MulledDockerContainerResolver):
|
||||
|
||||
resolver_type = "mulled_singularity"
|
||||
container_type = "singularity"
|
||||
protocol = 'docker://'
|
||||
|
||||
def __init__(self, app_info=None, namespace="biocontainers", hash_func="v2", auto_install=True, **kwds):
|
||||
super().__init__(app_info)
|
||||
self.cache_directory = kwds.get("cache_directory", os.path.join(app_info.container_image_cache_path, "singularity", "mulled"))
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self.namespace = namespace
|
||||
self.hash_func = hash_func
|
||||
self.auto_install = string_as_bool(auto_install)
|
||||
@@ -493,15 +506,21 @@ class MulledSingularityContainerResolver(MulledDockerContainerResolver):
|
||||
cache_directory=self.cache_directory,
|
||||
hash_func=hash_func)
|
||||
|
||||
@property
|
||||
def can_list_containers(self):
|
||||
# Only needs access to path, doesn't require CLI
|
||||
return True
|
||||
|
||||
def pull(self, container):
|
||||
cmds = container.build_mulled_singularity_pull_command(cache_directory=self.cache_directory, namespace=self.namespace)
|
||||
shell(cmds=cmds)
|
||||
if self.cli_available:
|
||||
cmds = container.build_mulled_singularity_pull_command(cache_directory=self.cache_directory, namespace=self.namespace)
|
||||
shell(cmds=cmds)
|
||||
|
||||
def __str__(self):
|
||||
return "MulledSingularityContainerResolver[namespace=%s]" % self.namespace
|
||||
|
||||
|
||||
class BuildMulledDockerContainerResolver(DockerContainerResolver):
|
||||
class BuildMulledDockerContainerResolver(CliContainerResolver):
|
||||
"""Build for Docker mulled images matching tool dependencies."""
|
||||
|
||||
resolver_type = "build_mulled"
|
||||
@@ -509,7 +528,7 @@ class BuildMulledDockerContainerResolver(DockerContainerResolver):
|
||||
builds_on_resolution = True
|
||||
|
||||
def __init__(self, app_info=None, namespace="local", hash_func="v2", auto_install=True, **kwds):
|
||||
super().__init__(app_info)
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self._involucro_context_kwds = {
|
||||
'involucro_bin': self._get_config_option("involucro_path", None)
|
||||
}
|
||||
@@ -548,20 +567,18 @@ class BuildMulledDockerContainerResolver(DockerContainerResolver):
|
||||
return "BuildDockerContainerResolver[namespace=%s]" % self.namespace
|
||||
|
||||
|
||||
class BuildMulledSingularityContainerResolver(ContainerResolver):
|
||||
class BuildMulledSingularityContainerResolver(SingularityCliContainerResolver):
|
||||
"""Build for Singularity mulled images matching tool dependencies."""
|
||||
|
||||
resolver_type = "build_mulled_singularity"
|
||||
container_type = "singularity"
|
||||
shell = '/bin/bash'
|
||||
builds_on_resolution = True
|
||||
|
||||
def __init__(self, app_info=None, hash_func="v2", auto_install=True, **kwds):
|
||||
super().__init__(app_info)
|
||||
super().__init__(app_info=app_info, **kwds)
|
||||
self._involucro_context_kwds = {
|
||||
'involucro_bin': self._get_config_option("involucro_path", None)
|
||||
}
|
||||
self.cache_directory = kwds.get("cache_directory", os.path.join(app_info.container_image_cache_path, "singularity", "mulled"))
|
||||
self.hash_func = hash_func
|
||||
self.auto_install = string_as_bool(auto_install)
|
||||
self._mulled_kwds = {
|
||||
|
||||
@@ -226,7 +226,7 @@ class ContainerRegistry:
|
||||
# BuildMulledDockerContainerResolver and BuildMulledSingularityContainerResolver both need the docker daemon to build images.
|
||||
# If docker is not available, we don't load them.
|
||||
build_mulled_docker_container_resolver = BuildMulledDockerContainerResolver(self.app_info)
|
||||
if build_mulled_docker_container_resolver.docker_cli_available:
|
||||
if build_mulled_docker_container_resolver.cli_available:
|
||||
default_resolvers.extend([
|
||||
build_mulled_docker_container_resolver,
|
||||
BuildMulledSingularityContainerResolver(self.app_info),
|
||||
|
||||
@@ -11,26 +11,26 @@ from galaxy.tool_util.deps.requirements import ToolRequirement
|
||||
def test_docker_container_resolver_detects_docker_cli_absent(mocker):
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.which', return_value=None)
|
||||
resolver = CachedMulledDockerContainerResolver()
|
||||
assert resolver.docker_cli_available is False
|
||||
assert resolver._cli_available is False
|
||||
|
||||
|
||||
def test_docker_container_resolver_detects_docker_cli(mocker):
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled', return_value='/bin/docker')
|
||||
resolver = CachedMulledDockerContainerResolver()
|
||||
assert resolver.docker_cli_available
|
||||
assert resolver.cli_available
|
||||
|
||||
|
||||
def test_cached_docker_container_docker_cli_absent_resolve(mocker):
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.which', return_value=None)
|
||||
resolver = CachedMulledDockerContainerResolver()
|
||||
assert resolver.docker_cli_available is False
|
||||
assert resolver.cli_available is False
|
||||
assert resolver.resolve(enabled_container_types=[], tool_info={}) is None
|
||||
|
||||
|
||||
def test_docker_container_docker_cli_absent_resolve(mocker):
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.which', return_value=None)
|
||||
resolver = MulledDockerContainerResolver()
|
||||
assert resolver.docker_cli_available is False
|
||||
assert resolver.cli_available is False
|
||||
requirement = ToolRequirement(name="samtools", version="1.10", type="package")
|
||||
tool_info = ToolInfo(requirements=[requirement])
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.targets_to_mulled_name', return_value='samtools:1.10--h2e538c0_3')
|
||||
@@ -42,12 +42,12 @@ def test_docker_container_docker_cli_absent_resolve(mocker):
|
||||
def test_docker_container_docker_cli_exception_resolve(mocker):
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.which', return_value='/bin/docker')
|
||||
resolver = MulledDockerContainerResolver()
|
||||
assert resolver.docker_cli_available is True
|
||||
assert resolver.cli_available is True
|
||||
requirement = ToolRequirement(name="samtools", version="1.10", type="package")
|
||||
tool_info = ToolInfo(requirements=[requirement])
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.targets_to_mulled_name', return_value='samtools:1.10--h2e538c0_3')
|
||||
mocker.patch('galaxy.tool_util.deps.container_resolvers.mulled.docker_cached_container_description', side_effect=CalledProcessError(1, 'bla'))
|
||||
container_description = resolver.resolve(enabled_container_types=['docker'], tool_info=tool_info, install=True)
|
||||
assert resolver.docker_cli_available is True
|
||||
assert resolver.cli_available is True
|
||||
assert container_description.type == 'docker'
|
||||
assert container_description.identifier == 'quay.io/biocontainers/samtools:1.10--h2e538c0_3'
|
||||
|
||||
Reference in New Issue
Block a user