diff --git a/client/src/components/providers/StoredWorkflowsProvider.js b/client/src/components/providers/StoredWorkflowsProvider.js index fdcbe91e56b..6740099f9f1 100644 --- a/client/src/components/providers/StoredWorkflowsProvider.js +++ b/client/src/components/providers/StoredWorkflowsProvider.js @@ -21,7 +21,7 @@ export function storedWorkflowsProvider(ctx, callback, extraParams = {}) { } async function storedWorkflowDetails({ storedWorkflowId }) { - const url = `${getAppRoot()}api/workflows/${storedWorkflowId}?instance=true`; + const url = `${getAppRoot()}api/workflows/${storedWorkflowId}`; try { const { data } = await axios.get(url); return data; diff --git a/lib/galaxy/jobs/handler.py b/lib/galaxy/jobs/handler.py index 6eae4ad7bab..3697bbc9b04 100644 --- a/lib/galaxy/jobs/handler.py +++ b/lib/galaxy/jobs/handler.py @@ -738,7 +738,7 @@ class JobHandlerQueue(Monitors): # History is job.state_history started = None finished = None - for history in sorted(job.state_history, key=lambda h: h.update_time): + for history in sorted(job.state_history, key=lambda h: h.create_time): if history.state == "running": started = history.create_time elif history.state == "ok": diff --git a/lib/galaxy/tool_util/deps/conda_util.py b/lib/galaxy/tool_util/deps/conda_util.py index 4b3dcb77731..99bf5edb257 100644 --- a/lib/galaxy/tool_util/deps/conda_util.py +++ b/lib/galaxy/tool_util/deps/conda_util.py @@ -31,12 +31,10 @@ SHELL_UNSAFE_PATTERN = re.compile(r"[\s\"']") IS_OS_X = sys.platform == "darwin" -# BSD 3-clause -CONDA_LICENSE = "http://docs.continuum.io/anaconda/eula" VERSIONED_ENV_DIR_NAME = re.compile(r"__(.*)@(.*)") UNVERSIONED_ENV_DIR_NAME = re.compile(r"__(.*)@_uv_") USE_PATH_EXEC_DEFAULT = False -CONDA_VERSION = "4.6.14" +CONDA_PACKAGE_SPECS = ("conda=4.6.14", "'pyopenssl>=22.1.0'") CONDA_BUILD_VERSION = "3.17.8" USE_LOCAL_DEFAULT = False @@ -113,7 +111,6 @@ class CondaContext(installable.InstallableContext): self.conda_exec = self._bin("conda") self.ensure_channels: List[str] = listify(ensure_channels) self._conda_version = None - self._miniconda_version = None self._conda_build_available = None self.use_local = use_local @@ -130,35 +127,16 @@ class CondaContext(installable.InstallableContext): return self._conda_build_available def _guess_conda_properties(self): - conda_meta_path = self._conda_meta_path - # Perhaps we should call "conda info --json" and parse it but for now we are going - # to assume the default. - conda_version = packaging.version.parse(CONDA_VERSION) - conda_build_available = False - miniconda_version = "3" - - if os.path.exists(conda_meta_path): - for package in os.listdir(conda_meta_path): - package_parts = package.split("-") - if len(package_parts) < 3: - continue - package = "-".join(package_parts[:-2]) - version = package_parts[-2] - # build = package_parts[-1] - if package == "conda": - conda_version = packaging.version.parse(version) - if package == "python" and version.startswith("2"): - miniconda_version = "2" - if package == "conda-build": - conda_build_available = True - - self._conda_version = conda_version - self._miniconda_version = miniconda_version - self._conda_build_available = conda_build_available - - @property - def _conda_meta_path(self): - return os.path.join(self.conda_prefix, "conda-meta") + info = self.conda_info() + self._conda_version = packaging.version.parse(info["conda_version"]) + self._conda_build_available = False + conda_build_version = info.get("conda_build_version") + if conda_build_version != "not installed": + try: + self._conda_version = packaging.version.parse(conda_build_version) + self._conda_build_available = True + except Exception: + pass @property def _override_channels_args(self): @@ -262,6 +240,8 @@ class CondaContext(installable.InstallableContext): Return the process exit code (i.e. 0 in case of success). """ create_args = ["-y", "--quiet"] + if self.conda_version >= packaging.version.parse("4.7.5"): + create_args.append("--strict-channel-priority") if allow_local and self.use_local: create_args.extend(["--use-local"]) create_args.extend(self._override_channels_args) @@ -283,6 +263,8 @@ class CondaContext(installable.InstallableContext): Return the process exit code (i.e. 0 in case of success). """ install_args = ["-y"] + if self.conda_version >= packaging.version.parse("4.7.5"): + install_args.append("--strict-channel-priority") if allow_local and self.use_local: install_args.append("--use-local") install_args.extend(self._override_channels_args) @@ -447,9 +429,7 @@ def install_conda(conda_context, force_conda_build=False): script_path = temp.name download_cmd = commands.download_command(conda_link(), to=script_path) install_cmd = ["bash", script_path, "-b", "-p", conda_context.conda_prefix] - package_targets = [ - f"conda={CONDA_VERSION}", - ] + package_targets = list(CONDA_PACKAGE_SPECS) if force_conda_build or conda_context.use_local: package_targets.append(f"conda-build={CONDA_BUILD_VERSION}") log.info("Installing conda, this may take several minutes.") diff --git a/lib/galaxy/tool_util/deps/views.py b/lib/galaxy/tool_util/deps/views.py index 9bd1fccbd60..885cebdbbfc 100644 --- a/lib/galaxy/tool_util/deps/views.py +++ b/lib/galaxy/tool_util/deps/views.py @@ -340,7 +340,7 @@ class ContainerResolutionView: def show(self, index): return self._container_resolver(index).to_dict() - def resolve(self, **kwds): + def resolve(self, index=None, **kwds): find_best_kwds = { "install": False, "enabled_container_types": ["docker", "singularity"], @@ -348,8 +348,8 @@ class ContainerResolutionView: "session": kwds.get("session"), } - if "index" in kwds: - find_best_kwds["index"] = int(kwds["index"]) + if index is not None: + find_best_kwds["index"] = int(index) if "container_type" in kwds: find_best_kwds["enabled_container_types"] = [kwds["container_type"]] if "resolver_type" in kwds: diff --git a/lib/galaxy_test/api/test_container_resolution.py b/lib/galaxy_test/api/test_container_resolution.py index 37a22618aff..3ba62655ef6 100644 --- a/lib/galaxy_test/api/test_container_resolution.py +++ b/lib/galaxy_test/api/test_container_resolution.py @@ -1,7 +1,8 @@ +from galaxy_test.base.populators import skip_without_tool from ._framework import ApiTestCase -class ContainerResolutionApiTestCase(ApiTestCase): +class TestContainerResolutionApi(ApiTestCase): def test_index(self): response = self._get("container_resolvers", admin=True) assert response.status_code == 200 @@ -11,3 +12,15 @@ class ContainerResolutionApiTestCase(ApiTestCase): response = self._get("container_resolvers/0", admin=True) assert response.status_code == 200 assert isinstance(response.json(), dict) + + @skip_without_tool("cat1") + def test_resolve(self): + tool_id = "cat1" + + # no index + response = self._get(f"container_resolvers/resolve?tool_id={tool_id}", admin=True) + assert response.status_code == 200 + + # with index + response = self._get(f"container_resolvers/0/resolve?tool_id={tool_id}", admin=True) + assert response.status_code == 200