Skip to content

Commit 6293dd0

Browse files
committed
Copy from the library directory if set
1 parent ac771d8 commit 6293dd0

File tree

1 file changed

+30
-5
lines changed

1 file changed

+30
-5
lines changed

nf_core/pipelines/download.py

+30-5
Original file line numberDiff line numberDiff line change
@@ -1087,11 +1087,12 @@ def get_singularity_images(self, current_revision: str = "") -> None:
10871087
# Organise containers based on what we need to do with them
10881088
containers_exist: List[str] = []
10891089
containers_cache: List[Tuple[str, str, str]] = []
1090+
containers_library: List[Tuple[str, str, str, Optional[str]]] = []
10901091
containers_download: List[Tuple[str, str, Optional[str]]] = []
10911092
containers_pull: List[Tuple[str, str, Optional[str]]] = []
10921093
for container in self.containers:
10931094
# Fetch the output and cached filenames for this container
1094-
out_path, cache_path = self.singularity_image_filenames(container)
1095+
out_path, cache_path, library_path = self.singularity_image_filenames(container)
10951096

10961097
# Check that the directories exist
10971098
out_path_dir = os.path.dirname(out_path)
@@ -1109,11 +1110,16 @@ def get_singularity_images(self, current_revision: str = "") -> None:
11091110
containers_exist.append(container)
11101111
continue
11111112

1112-
# We have a copy of this in the NXF_SINGULARITY_CACHE dir
1113+
# We have a copy of this in NXF_SINGULARITY_CACHEDIR
11131114
if cache_path and os.path.exists(cache_path):
11141115
containers_cache.append((container, out_path, cache_path))
11151116
continue
11161117

1118+
# We have a copy of this in NXF_SINGULARITY_LIBRARYDIR
1119+
if library_path and os.path.exists(library_path):
1120+
containers_library.append((container, library_path, out_path, cache_path))
1121+
continue
1122+
11171123
# Direct download within Python
11181124
if container.startswith("http"):
11191125
containers_download.append((container, out_path, cache_path))
@@ -1145,6 +1151,12 @@ def get_singularity_images(self, current_revision: str = "") -> None:
11451151
self.singularity_copy_cache_image(*container)
11461152
progress.update(task, advance=1)
11471153

1154+
if containers_library:
1155+
for container in containers_library:
1156+
progress.update(task, description="Copying singularity images from library")
1157+
self.singularity_copy_library_image(*container)
1158+
progress.update(task, advance=1)
1159+
11481160
if containers_download or containers_pull:
11491161
# if clause gives slightly better UX, because Download is no longer displayed if nothing is left to be downloaded.
11501162
with concurrent.futures.ThreadPoolExecutor(max_workers=self.parallel_downloads) as pool:
@@ -1226,19 +1238,20 @@ def get_singularity_images(self, current_revision: str = "") -> None:
12261238
# Task should advance in any case. Failure to pull will not kill the download process.
12271239
progress.update(task, advance=1)
12281240

1229-
def singularity_image_filenames(self, container: str) -> Tuple[str, Optional[str]]:
1241+
def singularity_image_filenames(self, container: str) -> Tuple[str, Optional[str], Optional[str]]:
12301242
"""Check Singularity cache for image, copy to destination folder if found.
12311243
12321244
Args:
12331245
container (str): A pipeline's container name. Can be direct download URL
12341246
or a Docker Hub repository ID.
12351247
12361248
Returns:
1237-
tuple (str, str): Returns a tuple of (out_path, cache_path).
1249+
(str, str, str): Returns a tuple of (out_path, cache_path, library_path).
12381250
out_path is the final target output path. it may point to the NXF_SINGULARITY_CACHEDIR, if cache utilisation was set to 'amend'.
12391251
If cache utilisation was set to 'copy', it will point to the target folder, a subdirectory of the output directory. In the latter case,
12401252
cache_path may either be None (image is not yet cached locally) or point to the image in the NXF_SINGULARITY_CACHEDIR, so it will not be
12411253
downloaded from the web again, but directly copied from there. See get_singularity_images() for implementation.
1254+
library_path is the points to the container in NXF_SINGULARITY_LIBRARYDIR, if the latter is defined.
12421255
"""
12431256

12441257
# Generate file paths
@@ -1281,14 +1294,26 @@ def singularity_image_filenames(self, container: str) -> Tuple[str, Optional[str
12811294
elif self.container_cache_utilisation in ["amend", "copy"]:
12821295
raise FileNotFoundError("Singularity cache is required but no '$NXF_SINGULARITY_CACHEDIR' set!")
12831296

1284-
return (out_path, cache_path)
1297+
library_path = None
1298+
if os.environ.get("NXF_SINGULARITY_LIBRARYDIR"):
1299+
library_path = os.path.join(os.environ["NXF_SINGULARITY_LIBRARYDIR"], out_name)
1300+
1301+
return (out_path, cache_path, library_path)
12851302

12861303
def singularity_copy_cache_image(self, container: str, out_path: str, cache_path: str) -> None:
12871304
"""Copy Singularity image from NXF_SINGULARITY_CACHEDIR to target folder."""
12881305
self.singularity_copy_image(container, cache_path, out_path)
12891306
# Create symlinks to ensure that the images are found even with different registries being used.
12901307
self.symlink_singularity_images(cache_path)
12911308

1309+
def singularity_copy_library_image(
1310+
self, container: str, library_path: str, out_path: str, cache_path: Optional[str]
1311+
) -> None:
1312+
"""Copy Singularity image from NXF_SINGULARITY_LIBRARYDIR to target folder, and possibly NXF_SINGULARITY_CACHEDIR."""
1313+
self.singularity_copy_image(container, library_path, out_path)
1314+
if cache_path:
1315+
self.singularity_copy_image(container, library_path, cache_path)
1316+
12921317
def singularity_copy_image(self, container: str, from_path: str, to_path: str) -> None:
12931318
"""Copy Singularity image between folders. This function is used seamlessly
12941319
across the target directory, NXF_SINGULARITY_CACHEDIR, and NXF_SINGULARITY_LIBRARYDIR."""

0 commit comments

Comments
 (0)