Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
fd662f6
image: first prototype
josefhandl Aug 29, 2023
4c0240c
remove custom file-staging script
josefhandl Oct 25, 2023
888d7b2
runner: add outputs, simplify inputs/outputs descriptors
josefhandl Oct 25, 2023
46312c2
runner: add outputs, specify inputs/outputs to FILE type
josefhandl Oct 25, 2023
e3677f0
runner: remove old custom file-staging script
josefhandl Oct 25, 2023
f1b6e44
edit tes-runner readme
josefhandl Oct 26, 2023
79b3006
runner: add sample job_config
josefhandl Oct 26, 2023
e082960
update README.md, fix example task json
josefhandl Nov 2, 2023
53504dc
add call stack print to the error handlers
josefhandl Nov 10, 2023
9b16e61
runs executors sequentialy from one command
josefhandl Nov 10, 2023
e69fe30
Changed the cluster_files_directory to job_working_directory
BorisYourich Nov 15, 2023
92f33c6
rename dts hosts in test's jsons
josefhandl Nov 15, 2023
28950ad
Merge branch 'main' into dev
josefhandl Nov 15, 2023
5077a1b
git Pulsar job_status checking
josefhandl Nov 15, 2023
e4bd5f2
fix forgotten funtion call
josefhandl Nov 15, 2023
84c5afa
increse timeouts for several tests
josefhandl Nov 15, 2023
cca7583
add MTU parameter to the docker-compose.yaml, fix issues with MTU on …
josefhandl Nov 20, 2023
5ccf389
Merge pull request #2 from CESNET/tesp-image
josefhandl Nov 21, 2023
6fa0ef0
rename test-image
josefhandl Nov 21, 2023
53d1bd1
rename test image for docker registry
josefhandl Nov 21, 2023
2149130
edit test-image
josefhandl Nov 21, 2023
388987d
Stage-in and Stage out of files without copying through TESP
BorisYourich Dec 15, 2023
925764c
Working prototype with functioning TES runner for Galaxy and optimise…
BorisYourich Feb 19, 2024
b56c9f5
Cleaned code, added support for mixed outputs (from_work_dir + final …
BorisYourich Feb 21, 2024
b0ec7d4
Added Singularity exec and CONTAINER_TYPE config
BorisYourich Apr 29, 2024
6f06d7a
Error prints uncommented
BorisYourich Apr 29, 2024
55a713d
run_script.sh mount fixed
BorisYourich Apr 29, 2024
ee09acc
singularity input fix
BorisYourich May 6, 2024
cebedea
Singularity command fix
BorisYourich May 20, 2024
fee1e49
Singularity update
BorisYourich May 20, 2024
adc009b
Singularity stage-out fix
BorisYourich May 20, 2024
4de45af
Singularity event_actions fix
BorisYourich May 20, 2024
bdd1429
Singularity bind mounts stop iteration fix
BorisYourich May 29, 2024
a073654
Singularity bind mounts stop iteration fix
BorisYourich May 29, 2024
b435643
Singularity bind mounts fix
BorisYourich May 29, 2024
a5511ef
Singularity stage in url fix
BorisYourich May 29, 2024
b9fc28f
Singularity stage in url fix
BorisYourich May 29, 2024
2355016
Singularity stage in - out bind_mount fix
BorisYourich May 31, 2024
192b4b1
Singularity stage out bind_mount fix
BorisYourich May 31, 2024
98fe833
Stage-out moved into same call as stage-in and run command
BorisYourich Jun 3, 2024
8919783
Fixed try-except block
BorisYourich Jun 12, 2024
af0a9ad
Changed Singularity command formatting
BorisYourich Jun 12, 2024
c3e9c1e
Changed Singularity command_str formatting
BorisYourich Jun 12, 2024
cecb814
Changed event actions container_command formatting
BorisYourich Jun 12, 2024
e89c91a
Changed event actions run_command formatting
BorisYourich Jun 12, 2024
2cf3c73
Changed pulsar_request params formatting
BorisYourich Jun 17, 2024
5cc2624
Fixed multiple run_script mount
BorisYourich Jun 17, 2024
e112fbe
Working Singularity version
BorisYourich Jun 17, 2024
e8e10cf
Working Streamlined file transfer version
BorisYourich Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Example JSON file:
{
"inputs": [
{
"url": "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.5.tar.xz",
"url": "http://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.5.tar.xz",
"path": "/data/kernel.tar.gz",
"type": "FILE"
}
Expand All @@ -47,7 +47,7 @@ Example JSON file:
],
"workdir": "/data/",
"stdout": "/tmp/stdout.log",
"stderr": "/tmp/stderr.log",
"stderr": "/tmp/stderr.log"
}
]
}
Expand Down
15 changes: 13 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ services:
dockerfile: docker/tesp_api/Dockerfile
target: development
image: tesp-api
environment:
- CONTAINER_TYPE=singularity # Set to "docker", "singularity", or "both"
container_name: tesp-api
privileged: true
ports:
- "8080:8080"
depends_on:
- tesp-db
volumes:
- ./:/app
extra_hosts:
- "host.docker.internal:host-gateway"
- /opt/pysetup/files/staging/:/opt/pysetup/files/staging/
# extra_hosts:
# - "host.docker.internal:host-gateway"

tesp-db:
image: mongo:latest
Expand Down Expand Up @@ -103,3 +107,10 @@ services:
volumes:
- ./docker/ftpserver/data/:/tmp
- ./docker/ftpserver/ftpserver.json:/app/ftpserver.json

# Some cloud providers may require a lower MTU!
networks:
default:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1442
1 change: 1 addition & 0 deletions docker/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
496e1025-de54-47bf-8939-75bc2ccdfd7b
1 change: 1 addition & 0 deletions docker/ftpserver/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d98140f5-e5fe-4201-acb7-7cf7c04d8d64
1 change: 1 addition & 0 deletions docker/minio/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c25dba2d-8185-4503-869e-ac8dbb44da33
1 change: 1 addition & 0 deletions docker/minio/initial_data/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b1e73b29-c1a9-447c-83cf-1124c37a1192
1 change: 1 addition & 0 deletions docker/pulsar_amqp/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
322072f7-5bbc-4ee4-88b2-1b8bcdee66fd
1 change: 1 addition & 0 deletions docker/pulsar_rest/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1de80fb0-0436-4a19-9371-2e6048985315
2 changes: 1 addition & 1 deletion docker/pulsar_rest/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ WORKDIR $PYSETUP_PATH
COPY startup.sh startup.sh
RUN pulsar-config --host 0.0.0.0
EXPOSE 8913
CMD ["/bin/bash", "./startup.sh"]
CMD ["/bin/bash", "./startup.sh"]
1 change: 1 addition & 0 deletions docker/rabbitmq/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
896b638d-1803-4d64-b134-ed43a1c7a649
1 change: 1 addition & 0 deletions docker/tesp_api/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
203b5739-380c-47c1-b0d8-c08fea4d83af
1 change: 1 addition & 0 deletions tes-runner/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4a2ac601-8171-4f03-9a2a-0c3021d890ec
9 changes: 8 additions & 1 deletion tes-runner/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# TES Runner prototype

**This directory contains a prototype of a TES runner for the Galaxy project. The code is taken from the [Pull Request (https://github.com/galaxyproject/galaxy/pull/14462)](https://github.com/galaxyproject/galaxy/pull/14462) and modified.**
**This directory contains a prototype of a TES runner for the Galaxy project. The code is taken from the [Pull Request (https://github.com/galaxyproject/galaxy/pull/14462)](https://github.com/galaxyproject/galaxy/pull/14462) and modified.**

This directory contains two files:
- `tes.py` - TES Runner for Galaxy
- `job_config.yaml` - Sample config for the TES Runner

Runners are located in `<galaxy>/lib/galaxy/jobs/runners/`.
Job config is located in `<galaxy>/config/`.
16 changes: 16 additions & 0 deletions tes-runner/job_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
runners:
local_runner:
load: galaxy.jobs.runners.local:LocalJobRunner
workers: 1
tes_runner:
load: galaxy.jobs.runners.tes:TESJobRunner

execution:
default: tesp_env
environments:
local_env:
runner: local_runner
tesp_env:
runner: tes_runner
tes_master_addr: http://<tes-server-address>:8080
default_docker_image: hub.cerit.io/josef_handl/tesp-test-image # prototype - for testing purpose only
105 changes: 61 additions & 44 deletions tes-runner/tes.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,18 @@ def file_creation_executor(self, docker_image: str, work_dir: str):
}
return file_executor

def job_executor(self, remote_image: str, command_line: str, env: dict):
def job_executor(self, remote_image: str, command_line: str, env: dict, work_dir: str):
"""
Returns the executor for executing jobs
"""
command_list = shlex.split(command_line)
replacements = {'../outputs/tool_stdout': 'tool_stdout',
'../outputs/tool_stderr;': 'tool_stderr;'}
command_list = [replacements.get(item, item) for item in command_list]
job_executor = {
"workdir": "/",
"workdir": work_dir,
"image": remote_image,
"command": shlex.split(command_line),
"command": command_list,
"env": env
}
return job_executor
Expand All @@ -166,18 +170,15 @@ def file_staging_out_executor(self, docker_image: str, command: list):
}
return staging_out_executor

def base_job_script(self, mounted_dir: list, work_dir: str, output_files: list, description: str):
def base_job_script(self, mounted_dir: list, work_dir: str, description: str):
"""
Retruns the basic structure for job-script
"""
execution_script = {
"name": "Galaxy Job Execution",
"description": description,
"inputs": [
{
"path": os.path.join(work_dir, 'createfiles.sh'),
"content": self.output_file_gen_script(output_files),
}],
"inputs": [],
"outputs": [],
"executors": [],
"volumes": mounted_dir
}
Expand All @@ -197,17 +198,6 @@ def output_file_gen_script(self, output_files: list):
script[-1] = '\n'
return ' '.join(script)

def staging_out_command(self, script_path: str, output_files: list, api_url: str, work_dir: str):
"""
Generates command for staging out of files
"""
command = ["python", script_path, api_url, work_dir]

for file in output_files:
command.append(file)

return command

def env_variables(self, job_wrapper: JobWrapper):
"""
Get environment variables from job_wrapper
Expand All @@ -223,26 +213,41 @@ def env_variables(self, job_wrapper: JobWrapper):
env_vars["_GALAXY_JOB_HOME_DIR"] = self.container_workdir
return env_vars

def input_url(self, api_url: str, path: str):
def inout_url(self, api_url: str, path: str):
"""
Get URL for path
"""
file_link = f"{api_url}&path={path}"
return file_link

def input_descriptors(self, api_url: str, input_paths: list, type: str = "FILE"):
def in_descriptors(self, api_url: str, in_paths: list, type: str = "FILE"):
"""
Get Input Descriptor for Jobfile
Get Input / Output Descriptor for Jobfile
"""
input_description = []
in_description = []

for path in input_paths:
input_description.append({
"url": self.input_url(api_url, path),
for path in in_paths:
in_description.append({
"url": self.inout_url(api_url, path),
"path": path,
"type": type
})
return input_description
return in_description

def out_descriptors(self, api_url: str, out_paths: list[dict], type: str = "FILE"):
"""
Get Input / Output Descriptor for Jobfile
"""
out_description = []

for path in out_paths:
out_description.append({
"url": self.inout_url(api_url, path['return_path']),
"path": path['tes_path'],
"type": type
})
return out_description


def get_job_directory_files(self, work_dir: str):
"""
Expand Down Expand Up @@ -292,10 +297,9 @@ def build_script(self, job_wrapper: JobWrapper, client_args: dict):
tool_dir = job_wrapper.tool.tool_dir
work_dir = job_wrapper.working_directory
object_store_path = job_wrapper.object_store.file_path
script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "util/file-staging.py")

input_files = self.__get_inputs(job_wrapper)
output_files = self.get_output_files(job_wrapper)
output_files_dict = self.get_output_files(job_wrapper)
extra_files = job_wrapper.extra_filenames
tool_files = pulsar.client.staging.up.JobInputs(job_wrapper.command_line, extra_files).find_referenced_subfiles(tool_dir)

Expand All @@ -307,7 +311,7 @@ def build_script(self, job_wrapper: JobWrapper, client_args: dict):
include_metadata=False,
create_tool_working_directory=False,
include_work_dir_outputs=False,
remote_job_directory=job_wrapper.working_directory
remote_job_directory=work_dir
)

env_var = self.env_variables(job_wrapper)
Expand All @@ -322,18 +326,16 @@ def build_script(self, job_wrapper: JobWrapper, client_args: dict):
if (staging_out_url is None):
staging_out_url = client_args['files_endpoint']

staging_out_command = self.staging_out_command(script_path, output_files, staging_out_url, job_wrapper.working_directory)

job_script = self.base_job_script([work_dir, object_store_path], work_dir, output_files, job_wrapper.tool.description)
job_script = self.base_job_script([work_dir, object_store_path], work_dir, job_wrapper.tool.description)

job_script["inputs"].extend(self.input_descriptors(client_args['files_endpoint'], [script_path]))
job_script["inputs"].extend(self.input_descriptors(client_args['files_endpoint'], tool_files))
job_script["inputs"].extend(self.input_descriptors(client_args['files_endpoint'], self.get_job_directory_files(work_dir)))
job_script["inputs"].extend(self.input_descriptors(client_args['files_endpoint'], input_files))
job_script["inputs"].extend(self.in_descriptors(client_args['files_endpoint'], tool_files))
job_script["inputs"].extend(self.in_descriptors(client_args['files_endpoint'], self.get_job_directory_files(work_dir)))
job_script["inputs"].extend(self.in_descriptors(client_args['files_endpoint'], input_files))

job_script["executors"].append(self.file_creation_executor(staging_out_image, work_dir))
job_script["executors"].append(self.job_executor(remote_image, command_line, env_var))
job_script["executors"].append(self.file_staging_out_executor(staging_out_image, staging_out_command))
job_script["outputs"].extend(self.out_descriptors(client_args['files_endpoint'], output_files_dict))

job_script["executors"].append(self.job_executor(remote_image, command_line, env_var, work_dir))

return job_script

Expand Down Expand Up @@ -384,8 +386,23 @@ def get_output_files(self, job_wrapper: JobWrapper):
"""
Utility for getting list of Output Files
"""
output_paths = job_wrapper.job_io.get_output_fnames()
return [str(o) for o in output_paths]
out_dicts = []
work_dir = job_wrapper.working_directory
existing_fpaths = []
for pair in self.get_work_dir_outputs(job_wrapper):
out_dicts.append({
'tes_path': work_dir + "/" + os.path.basename(pair[0]),
'return_path': pair[1]
})
existing_fpaths.append(pair[1])
for output in job_wrapper.job_io.get_output_fnames():
if str(output) not in existing_fpaths:
out_dicts.append({
'tes_path': str(output),
'return_path': str(output)
})

return out_dicts

def __finish_job(self, data: dict, job_wrapper: JobWrapper):
"""
Expand Down Expand Up @@ -499,11 +516,11 @@ def recover(self, job: model.Job, job_wrapper: JobWrapper):
if job_id is None:
self.put(job_wrapper)
return
job_state = TESJobState(job_wrapper=job_wrapper, files_dir=self.app.config.cluster_files_directory)
job_state = TESJobState(job_wrapper=job_wrapper, files_dir=self.app.config.job_working_directory)
job_state.job_id = str(job_id)
job_state.job_wrapper = job_wrapper
job_state.job_destination = job_wrapper.job_destination
job_state.user_log = os.path.join(self.app.config.cluster_files_directory, 'galaxy_%s.tes.log' % galaxy_id_tag)
job_state.user_log = os.path.join(self.app.config.job_working_directory, 'galaxy_%s.tes.log' % galaxy_id_tag)
job_state.register_cleanup_file_attribute('user_log')
if job.state == model.Job.states.RUNNING:
log.debug("(%s/%s) is still in running state, adding to the DRM queue" % (job.id, job.job_runner_external_id))
Expand Down
9 changes: 0 additions & 9 deletions tes-runner/util/TES-Dockerfile/Dockerfile

This file was deleted.

38 changes: 0 additions & 38 deletions tes-runner/util/file-staging.py

This file was deleted.

1 change: 1 addition & 0 deletions tesp_api/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f3737a9d-3a5b-4a48-a6dd-3a946ba323e0
1 change: 1 addition & 0 deletions tesp_api/api/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d7ddef8d-e6ce-4527-87c3-5c9184d2a581
1 change: 1 addition & 0 deletions tesp_api/api/endpoints/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4af13e94-e4f1-4a64-bf8e-9ba24f2a1aa8
3 changes: 3 additions & 0 deletions tesp_api/api/endpoints/task_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
response_model=TesCreateTaskResponseModel,
description=descriptions["tasks-create"])
async def create_task(tes_task: TesTask = Body(...)) -> Response:
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
print("TES TASK JSON")
print(tes_task.json())
task_to_create = RegisteredTesTask(
**tes_task.dict(),
state=TesTaskState.QUEUED,
Expand Down
1 change: 1 addition & 0 deletions tesp_api/api/model/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
277ef504-a166-41c4-965d-ef782b11a716
1 change: 1 addition & 0 deletions tesp_api/config/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fa24e399-e81b-4782-9431-6f6dce6b8eec
1 change: 1 addition & 0 deletions tesp_api/repository/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2bfe5a17-3edb-48ac-8822-41567a217155
1 change: 1 addition & 0 deletions tesp_api/repository/model/.uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a6006489-8472-4031-a60e-dd4a74cb4768
Loading