snakemake-software-deployment-plugin-container 0.7.1__tar.gz → 0.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/CHANGELOG.md +14 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/PKG-INFO +1 -1
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/pyproject.toml +1 -1
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/src/snakemake_software_deployment_plugin_container/__init__.py +85 -2
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/.github/workflows/ci.yml +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/.github/workflows/conventional-prs.yml +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/.github/workflows/release-please.yml +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/.gitignore +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/LICENSE +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/README.md +0 -0
- {snakemake_software_deployment_plugin_container-0.7.1 → snakemake_software_deployment_plugin_container-0.7.3}/tests/test_plugin.py +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.3](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.7.2...v0.7.3) (2026-09-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* add quiet flag to udocker execution ([fcb5780](https://github.com/snakemake/snakemake-software-deployment-plugin-container/commit/fcb57800287a59cee68c1ec87a47d17a304ce207))
|
|
9
|
+
|
|
10
|
+
## [0.7.2](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.7.1...v0.7.2) (2026-09-08)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Performance Improvements
|
|
14
|
+
|
|
15
|
+
* explicit handling of deployment ([#25](https://github.com/snakemake/snakemake-software-deployment-plugin-container/issues/25)) ([127dff9](https://github.com/snakemake/snakemake-software-deployment-plugin-container/commit/127dff9b49f81a0fd55504676e1385b1dea977f7))
|
|
16
|
+
|
|
3
17
|
## [0.7.1](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.7.0...v0.7.1) (2026-09-07)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: snakemake-software-deployment-plugin-container
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Project-URL: repository, https://github.com/snakemake/snakemake-software-deployment-plugin-container
|
|
5
5
|
Project-URL: documentation, https://snakemake.github.io/snakemake-plugin-catalog/plugins/software-deployment/container.html
|
|
6
6
|
Author-email: Ben Carrillo <ben.uzh@pm.me>, Johannes Köster <johannes.koester@uni-due.de>
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from snakemake_interface_software_deployment_plugins import DeployableEnvBase
|
|
1
4
|
import re
|
|
2
5
|
|
|
3
6
|
__author__ = "ben carrillo"
|
|
@@ -91,7 +94,7 @@ class EnvSpec(EnvSpecBase):
|
|
|
91
94
|
|
|
92
95
|
|
|
93
96
|
# All errors should be wrapped with snakemake-interface-common.errors.WorkflowError
|
|
94
|
-
class Env(EnvBase):
|
|
97
|
+
class Env(DeployableEnvBase, EnvBase):
|
|
95
98
|
# image_repo is the de-referenced repository from where the image was obtained
|
|
96
99
|
image_repo: str
|
|
97
100
|
settings: Settings
|
|
@@ -159,11 +162,65 @@ class Env(EnvBase):
|
|
|
159
162
|
# Return an empty tuple () if no software can be reported.
|
|
160
163
|
return [SoftwareReport(name=self.spec.image_uri)]
|
|
161
164
|
|
|
165
|
+
def is_deployment_path_portable(self) -> bool:
|
|
166
|
+
"""Return whether the deployment path matters for the environment, i.e.
|
|
167
|
+
whether the environment is portable. If this returns False, the deployment
|
|
168
|
+
path is considered for the deployment hash. For example, conda environments are not
|
|
169
|
+
portable because they hardcode the path in binaries, while containers are
|
|
170
|
+
portable.
|
|
171
|
+
"""
|
|
172
|
+
return True
|
|
173
|
+
|
|
174
|
+
async def deploy(self) -> None:
|
|
175
|
+
"""Deploy the environment to self.deployment_path.
|
|
176
|
+
|
|
177
|
+
When issuing shell commands, the environment should use
|
|
178
|
+
self.run_cmd(cmd: str) in order to ensure that it runs within eventual
|
|
179
|
+
parent environments (e.g. a container or an env module).
|
|
180
|
+
"""
|
|
181
|
+
deploy_cmd = self.runtime_manager.deploy_cmd()
|
|
182
|
+
assert deploy_cmd is not None
|
|
183
|
+
self.deployment_path.mkdir(parents=True, exist_ok=True)
|
|
184
|
+
self.run_cmd(
|
|
185
|
+
deploy_cmd,
|
|
186
|
+
check=True,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def remove(self) -> None:
|
|
190
|
+
"""Remove the deployed environment."""
|
|
191
|
+
if (
|
|
192
|
+
self.is_deployable()
|
|
193
|
+
and self.runtime_manager.deployed_image_path() is not None
|
|
194
|
+
):
|
|
195
|
+
self.runtime_manager.deployed_image_path.unlink(missing_ok=True)
|
|
196
|
+
|
|
197
|
+
def is_deployable(self) -> bool:
|
|
198
|
+
return (
|
|
199
|
+
self.settings.runtime is Runtime.UDOCKER
|
|
200
|
+
or self.settings.runtime is Runtime.APPTAINER
|
|
201
|
+
)
|
|
202
|
+
|
|
162
203
|
|
|
163
204
|
@dataclass
|
|
164
205
|
class RuntimeManager:
|
|
165
206
|
env: Env
|
|
166
207
|
|
|
208
|
+
def deployed_image_name(self) -> str:
|
|
209
|
+
return (
|
|
210
|
+
self.env.spec.image_uri.replace("/", "_")
|
|
211
|
+
.replace(":", "_")
|
|
212
|
+
.replace("#", "_")
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
@abstractmethod
|
|
216
|
+
def deployed_image_path(self) -> Path | None: ...
|
|
217
|
+
|
|
218
|
+
@abstractmethod
|
|
219
|
+
def deploy_cmd(self) -> str | None: ...
|
|
220
|
+
|
|
221
|
+
def pre_subcommand_options(self) -> str:
|
|
222
|
+
return ""
|
|
223
|
+
|
|
167
224
|
def options(self) -> str:
|
|
168
225
|
return "--rm"
|
|
169
226
|
|
|
@@ -202,7 +259,9 @@ class RuntimeManager:
|
|
|
202
259
|
def decorate_shellcmd(self, cmd: str) -> str:
|
|
203
260
|
mountpoints = self.get_mountpoint_args()
|
|
204
261
|
return (
|
|
205
|
-
f"{self.env.settings.runtime}
|
|
262
|
+
f"{self.env.settings.runtime}"
|
|
263
|
+
f" {self.pre_subcommand_options()}"
|
|
264
|
+
f" {self.subcommand()}"
|
|
206
265
|
f" {self.options()}"
|
|
207
266
|
f" {self.workdir_option()} {getcwd()!r}" # Working directory inside container
|
|
208
267
|
f" {mountpoints}"
|
|
@@ -234,6 +293,14 @@ class RuntimeManagerApptainer(RuntimeManager):
|
|
|
234
293
|
return super().image_uri()
|
|
235
294
|
return f"docker://{super().image_uri()}"
|
|
236
295
|
|
|
296
|
+
def deployed_image_path(self) -> Path | None:
|
|
297
|
+
return (self.env.deployment_path / self.deployed_image_name()).with_suffix(
|
|
298
|
+
".sif"
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
def deploy_cmd(self) -> str | None:
|
|
302
|
+
return f"apptainer pull {self.deployed_image_path()} {self.image_uri()}"
|
|
303
|
+
|
|
237
304
|
|
|
238
305
|
class RuntimeManagerDocker(RuntimeManager):
|
|
239
306
|
def options(self) -> str:
|
|
@@ -248,11 +315,27 @@ class RuntimeManagerDocker(RuntimeManager):
|
|
|
248
315
|
options += f" --env {env_var}"
|
|
249
316
|
return options
|
|
250
317
|
|
|
318
|
+
def deployed_image_path(self) -> Path | None:
|
|
319
|
+
return None
|
|
320
|
+
|
|
321
|
+
def deploy_cmd(self) -> str | None:
|
|
322
|
+
# No need to deploy anything in docker, the daemon handles that on the fly.
|
|
323
|
+
return None
|
|
324
|
+
|
|
251
325
|
|
|
252
326
|
class RuntimeManagerUdocker(RuntimeManager):
|
|
327
|
+
def pre_subcommand_options(self) -> str:
|
|
328
|
+
return "--quiet"
|
|
329
|
+
|
|
253
330
|
def options(self) -> str:
|
|
254
331
|
options = super().options()
|
|
255
332
|
options += " --nobanner --env TINI_SUBREAPER=1"
|
|
256
333
|
for env_var in self.env.envvars:
|
|
257
334
|
options += f" --env {env_var}={os.environ[env_var]}"
|
|
258
335
|
return options
|
|
336
|
+
|
|
337
|
+
def deployed_image_path(self) -> Path | None:
|
|
338
|
+
return None
|
|
339
|
+
|
|
340
|
+
def deploy_cmd(self) -> str | None:
|
|
341
|
+
return f"UDOCKER_DIR={self.env.deployment_path} udocker pull {self.image_uri()}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|