mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-01 15:37:32 +08:00
Add test for proposed prod-like deployment
This commit is contained in:
@@ -89,7 +89,8 @@ These tools can also be exported to disk and loaded like regular tools, enabling
|
||||
## Security considerations
|
||||
|
||||
User-defined tools share the same security risks as interactive tools..
|
||||
See https://training.galaxyproject.org/training-material/topics/admin/tutorials/interactive-tools/tutorial.html#securing-interactive-tools for an extended discussion.
|
||||
See https://training.galaxyproject.org/training-material/topics/admin/tutorials/interactive-tools/tutorial.html#securing-interactive-tools for an extended discussion,
|
||||
and see https://github.com/galaxyproject/galaxy/blob/dev/test/integration/embedded_pulsar_job_conf.yml#L29 for a simple example that uses embedded pulsar to isolate mounts and disables network access.
|
||||
While the feature is in beta we recommend that only trusted users are allowed to use this feature.
|
||||
|
||||
## Limitations
|
||||
|
||||
@@ -1160,6 +1160,7 @@ tools:
|
||||
# Classes can be used to map groups of tools - the current classes include
|
||||
# - local (these special tools that aren't parameterized for remote execution - expression tools, upload, etc..)
|
||||
# - requires_galaxy (these special tools require Galaxy's Python environment during execution)
|
||||
# - user_defined (these tools are defined by the user and should be routed to an isolated job execution environment)
|
||||
# If a tool matches multiple classes, it will match the first class according to the order listed
|
||||
# above in this document (local, requires_galaxy).
|
||||
class: local
|
||||
|
||||
@@ -123,7 +123,7 @@ DEFAULT_JOB_SHELL = "/bin/bash"
|
||||
DEFAULT_LOCAL_WORKERS = 4
|
||||
|
||||
DEFAULT_CLEANUP_JOB = "always"
|
||||
VALID_TOOL_CLASSES = ["local", "requires_galaxy"]
|
||||
VALID_TOOL_CLASSES = ["local", "requires_galaxy", "user_defined"]
|
||||
|
||||
|
||||
class JobDestination(Bunch):
|
||||
|
||||
@@ -33,6 +33,7 @@ from galaxy_test.base.populators import (
|
||||
DatasetPopulator,
|
||||
skip_without_tool,
|
||||
stage_rules_example,
|
||||
TOOL_WITH_SHELL_COMMAND,
|
||||
)
|
||||
from ._framework import ApiTestCase
|
||||
|
||||
@@ -54,29 +55,6 @@ MINIMAL_TOOL_NO_ID = {
|
||||
"outputs": {"output1": {"format": "txt", "type": "data"}},
|
||||
}
|
||||
|
||||
TOOL_WITH_SHELL_COMMAND = {
|
||||
"id": "basecommand",
|
||||
"name": "Base command tool",
|
||||
"class": "GalaxyUserTool",
|
||||
"container": "busybox",
|
||||
"version": "1.0.0",
|
||||
"shell_command": "cat '$(inputs.input.path)' > output.fastq",
|
||||
"inputs": [
|
||||
{
|
||||
"type": "data",
|
||||
"name": "input",
|
||||
"format": "txt",
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "data",
|
||||
"from_work_dir": "output.fastq",
|
||||
"name": "output",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class TestsTools:
|
||||
dataset_populator: DatasetPopulator
|
||||
|
||||
@@ -3,12 +3,10 @@ from galaxy.tool_util_models import UserToolSource
|
||||
from galaxy_test.base.populators import (
|
||||
DatasetCollectionPopulator,
|
||||
DatasetPopulator,
|
||||
)
|
||||
from ._framework import ApiTestCase
|
||||
from .test_tools import (
|
||||
TestsTools,
|
||||
TOOL_WITH_SHELL_COMMAND,
|
||||
)
|
||||
from ._framework import ApiTestCase
|
||||
from .test_tools import TestsTools
|
||||
|
||||
|
||||
class TestUnprivilegedToolsApi(ApiTestCase, TestsTools):
|
||||
|
||||
@@ -141,6 +141,29 @@ workflow_str = resource_string(__name__, "data/test_workflow_1.ga")
|
||||
# Simple workflow that takes an input and filters with random lines twice in a
|
||||
# row - first grabbing 8 lines at random and then 6.
|
||||
workflow_random_x2_str = resource_string(__name__, "data/test_workflow_2.ga")
|
||||
# example of user defined tool
|
||||
TOOL_WITH_SHELL_COMMAND = {
|
||||
"id": "basecommand",
|
||||
"name": "Base command tool",
|
||||
"class": "GalaxyUserTool",
|
||||
"container": "busybox",
|
||||
"version": "1.0.0",
|
||||
"shell_command": "cat '$(inputs.input.path)' > output.fastq",
|
||||
"inputs": [
|
||||
{
|
||||
"type": "data",
|
||||
"name": "input",
|
||||
"format": "txt",
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "data",
|
||||
"from_work_dir": "output.fastq",
|
||||
"name": "output",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
DEFAULT_TIMEOUT = 60 # Secs to wait for state to turn ok
|
||||
|
||||
|
||||
@@ -16,7 +16,15 @@ execution:
|
||||
pulsar_embed:
|
||||
runner: pulsar_embed
|
||||
remote_metadata: true
|
||||
user_defined:
|
||||
runner: pulsar_embed
|
||||
remote_metadata: true
|
||||
docker_enabled: true
|
||||
require_container: true
|
||||
docker_net: "none"
|
||||
|
||||
tools:
|
||||
- class: local
|
||||
environment: local
|
||||
- class: user_defined
|
||||
environment: user_defined
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
"""Integration tests for user defined tools with Pulsar embedded runner."""
|
||||
|
||||
import os
|
||||
|
||||
from galaxy.tool_util_models import UserToolSource
|
||||
from galaxy_test.api.test_tools import TestsTools
|
||||
from galaxy_test.base.populators import (
|
||||
DatasetPopulator,
|
||||
TOOL_WITH_SHELL_COMMAND,
|
||||
)
|
||||
from galaxy_test.driver import integration_util
|
||||
|
||||
SCRIPT_DIRECTORY = os.path.abspath(os.path.dirname(__file__))
|
||||
EMBEDDED_PULSAR_JOB_CONFIG_FILE = os.path.join(SCRIPT_DIRECTORY, "embedded_pulsar_job_conf.yml")
|
||||
|
||||
|
||||
class TestUserDefinedToolRecommendedJobSetup(integration_util.IntegrationTestCase, TestsTools):
|
||||
"""Exercies how user defined tools could be run in production."""
|
||||
|
||||
framework_tool_and_types = True
|
||||
dataset_populator: DatasetPopulator
|
||||
|
||||
@classmethod
|
||||
def handle_galaxy_config_kwds(cls, config):
|
||||
super().handle_galaxy_config_kwds(config)
|
||||
config["job_config_file"] = EMBEDDED_PULSAR_JOB_CONFIG_FILE
|
||||
config["enable_celery_tasks"] = False
|
||||
config["metadata_strategy"] = "directory"
|
||||
config["admin_users"] = "udt@galaxy.org"
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
||||
|
||||
def test_user_defined_runs_in_correct_destination(self):
|
||||
with (
|
||||
self.dataset_populator.test_history() as history_id,
|
||||
self.dataset_populator.user_tool_execute_permissions(),
|
||||
):
|
||||
# Create a new dynamic tool.
|
||||
# This is a shell command tool that will echo the input dataset.
|
||||
dynamic_tool = self.dataset_populator.create_unprivileged_tool(UserToolSource(**TOOL_WITH_SHELL_COMMAND))
|
||||
# Run tool.
|
||||
dataset = self.dataset_populator.new_dataset(history_id=history_id, content="abc")
|
||||
response = self._run(
|
||||
history_id=history_id,
|
||||
tool_uuid=dynamic_tool["uuid"],
|
||||
inputs={"input": {"src": "hda", "id": dataset["id"]}},
|
||||
wait_for_job=True,
|
||||
assert_ok=True,
|
||||
)
|
||||
|
||||
output_content = self.dataset_populator.get_history_dataset_content(history_id)
|
||||
assert output_content == "abc\n"
|
||||
with self._different_user(email="udt@galaxy.org"):
|
||||
destination_params = self._get(f"/api/jobs/{response['jobs'][0]['id']}/destination_params").json()
|
||||
|
||||
assert destination_params["Runner"] == "pulsar_embed"
|
||||
assert destination_params["require_container"]
|
||||
Reference in New Issue
Block a user