toil 6.1.0a1__py3-none-any.whl → 8.0.0__py3-none-any.whl
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.
- toil/__init__.py +122 -315
- toil/batchSystems/__init__.py +1 -0
- toil/batchSystems/abstractBatchSystem.py +173 -89
- toil/batchSystems/abstractGridEngineBatchSystem.py +272 -148
- toil/batchSystems/awsBatch.py +244 -135
- toil/batchSystems/cleanup_support.py +26 -16
- toil/batchSystems/contained_executor.py +31 -28
- toil/batchSystems/gridengine.py +86 -50
- toil/batchSystems/htcondor.py +166 -89
- toil/batchSystems/kubernetes.py +632 -382
- toil/batchSystems/local_support.py +20 -15
- toil/batchSystems/lsf.py +134 -81
- toil/batchSystems/lsfHelper.py +13 -11
- toil/batchSystems/mesos/__init__.py +41 -29
- toil/batchSystems/mesos/batchSystem.py +290 -151
- toil/batchSystems/mesos/executor.py +79 -50
- toil/batchSystems/mesos/test/__init__.py +31 -23
- toil/batchSystems/options.py +46 -28
- toil/batchSystems/registry.py +53 -19
- toil/batchSystems/singleMachine.py +296 -125
- toil/batchSystems/slurm.py +603 -138
- toil/batchSystems/torque.py +47 -33
- toil/bus.py +186 -76
- toil/common.py +664 -368
- toil/cwl/__init__.py +1 -1
- toil/cwl/cwltoil.py +1136 -483
- toil/cwl/utils.py +17 -22
- toil/deferred.py +63 -42
- toil/exceptions.py +5 -3
- toil/fileStores/__init__.py +5 -5
- toil/fileStores/abstractFileStore.py +140 -60
- toil/fileStores/cachingFileStore.py +717 -269
- toil/fileStores/nonCachingFileStore.py +116 -87
- toil/job.py +1225 -368
- toil/jobStores/abstractJobStore.py +416 -266
- toil/jobStores/aws/jobStore.py +863 -477
- toil/jobStores/aws/utils.py +201 -120
- toil/jobStores/conftest.py +3 -2
- toil/jobStores/fileJobStore.py +292 -154
- toil/jobStores/googleJobStore.py +140 -74
- toil/jobStores/utils.py +36 -15
- toil/leader.py +668 -272
- toil/lib/accelerators.py +115 -18
- toil/lib/aws/__init__.py +74 -31
- toil/lib/aws/ami.py +122 -87
- toil/lib/aws/iam.py +284 -108
- toil/lib/aws/s3.py +31 -0
- toil/lib/aws/session.py +214 -39
- toil/lib/aws/utils.py +287 -231
- toil/lib/bioio.py +13 -5
- toil/lib/compatibility.py +11 -6
- toil/lib/conversions.py +104 -47
- toil/lib/docker.py +131 -103
- toil/lib/ec2.py +361 -199
- toil/lib/ec2nodes.py +174 -106
- toil/lib/encryption/_dummy.py +5 -3
- toil/lib/encryption/_nacl.py +10 -6
- toil/lib/encryption/conftest.py +1 -0
- toil/lib/exceptions.py +26 -7
- toil/lib/expando.py +5 -3
- toil/lib/ftp_utils.py +217 -0
- toil/lib/generatedEC2Lists.py +127 -19
- toil/lib/humanize.py +6 -2
- toil/lib/integration.py +341 -0
- toil/lib/io.py +141 -15
- toil/lib/iterables.py +4 -2
- toil/lib/memoize.py +12 -8
- toil/lib/misc.py +66 -21
- toil/lib/objects.py +2 -2
- toil/lib/resources.py +68 -15
- toil/lib/retry.py +126 -81
- toil/lib/threading.py +299 -82
- toil/lib/throttle.py +16 -15
- toil/options/common.py +843 -409
- toil/options/cwl.py +175 -90
- toil/options/runner.py +50 -0
- toil/options/wdl.py +73 -17
- toil/provisioners/__init__.py +117 -46
- toil/provisioners/abstractProvisioner.py +332 -157
- toil/provisioners/aws/__init__.py +70 -33
- toil/provisioners/aws/awsProvisioner.py +1145 -715
- toil/provisioners/clusterScaler.py +541 -279
- toil/provisioners/gceProvisioner.py +282 -179
- toil/provisioners/node.py +155 -79
- toil/realtimeLogger.py +34 -22
- toil/resource.py +137 -75
- toil/server/app.py +128 -62
- toil/server/celery_app.py +3 -1
- toil/server/cli/wes_cwl_runner.py +82 -53
- toil/server/utils.py +54 -28
- toil/server/wes/abstract_backend.py +64 -26
- toil/server/wes/amazon_wes_utils.py +21 -15
- toil/server/wes/tasks.py +121 -63
- toil/server/wes/toil_backend.py +142 -107
- toil/server/wsgi_app.py +4 -3
- toil/serviceManager.py +58 -22
- toil/statsAndLogging.py +224 -70
- toil/test/__init__.py +282 -183
- toil/test/batchSystems/batchSystemTest.py +460 -210
- toil/test/batchSystems/batch_system_plugin_test.py +90 -0
- toil/test/batchSystems/test_gridengine.py +173 -0
- toil/test/batchSystems/test_lsf_helper.py +67 -58
- toil/test/batchSystems/test_slurm.py +110 -49
- toil/test/cactus/__init__.py +0 -0
- toil/test/cactus/test_cactus_integration.py +56 -0
- toil/test/cwl/cwlTest.py +496 -287
- toil/test/cwl/measure_default_memory.cwl +12 -0
- toil/test/cwl/not_run_required_input.cwl +29 -0
- toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
- toil/test/cwl/seqtk_seq.cwl +1 -1
- toil/test/docs/scriptsTest.py +69 -46
- toil/test/jobStores/jobStoreTest.py +427 -264
- toil/test/lib/aws/test_iam.py +118 -50
- toil/test/lib/aws/test_s3.py +16 -9
- toil/test/lib/aws/test_utils.py +5 -6
- toil/test/lib/dockerTest.py +118 -141
- toil/test/lib/test_conversions.py +113 -115
- toil/test/lib/test_ec2.py +58 -50
- toil/test/lib/test_integration.py +104 -0
- toil/test/lib/test_misc.py +12 -5
- toil/test/mesos/MesosDataStructuresTest.py +23 -10
- toil/test/mesos/helloWorld.py +7 -6
- toil/test/mesos/stress.py +25 -20
- toil/test/options/__init__.py +13 -0
- toil/test/options/options.py +42 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +320 -150
- toil/test/provisioners/clusterScalerTest.py +440 -250
- toil/test/provisioners/clusterTest.py +166 -44
- toil/test/provisioners/gceProvisionerTest.py +174 -100
- toil/test/provisioners/provisionerTest.py +25 -13
- toil/test/provisioners/restartScript.py +5 -4
- toil/test/server/serverTest.py +188 -141
- toil/test/sort/restart_sort.py +137 -68
- toil/test/sort/sort.py +134 -66
- toil/test/sort/sortTest.py +91 -49
- toil/test/src/autoDeploymentTest.py +141 -101
- toil/test/src/busTest.py +20 -18
- toil/test/src/checkpointTest.py +8 -2
- toil/test/src/deferredFunctionTest.py +49 -35
- toil/test/src/dockerCheckTest.py +32 -24
- toil/test/src/environmentTest.py +135 -0
- toil/test/src/fileStoreTest.py +539 -272
- toil/test/src/helloWorldTest.py +7 -4
- toil/test/src/importExportFileTest.py +61 -31
- toil/test/src/jobDescriptionTest.py +46 -21
- toil/test/src/jobEncapsulationTest.py +2 -0
- toil/test/src/jobFileStoreTest.py +74 -50
- toil/test/src/jobServiceTest.py +187 -73
- toil/test/src/jobTest.py +121 -71
- toil/test/src/miscTests.py +19 -18
- toil/test/src/promisedRequirementTest.py +82 -36
- toil/test/src/promisesTest.py +7 -6
- toil/test/src/realtimeLoggerTest.py +10 -6
- toil/test/src/regularLogTest.py +71 -37
- toil/test/src/resourceTest.py +80 -49
- toil/test/src/restartDAGTest.py +36 -22
- toil/test/src/resumabilityTest.py +9 -2
- toil/test/src/retainTempDirTest.py +45 -14
- toil/test/src/systemTest.py +12 -8
- toil/test/src/threadingTest.py +44 -25
- toil/test/src/toilContextManagerTest.py +10 -7
- toil/test/src/userDefinedJobArgTypeTest.py +8 -5
- toil/test/src/workerTest.py +73 -23
- toil/test/utils/toilDebugTest.py +103 -33
- toil/test/utils/toilKillTest.py +4 -5
- toil/test/utils/utilsTest.py +245 -106
- toil/test/wdl/wdltoil_test.py +818 -149
- toil/test/wdl/wdltoil_test_kubernetes.py +91 -0
- toil/toilState.py +120 -35
- toil/utils/toilConfig.py +13 -4
- toil/utils/toilDebugFile.py +44 -27
- toil/utils/toilDebugJob.py +214 -27
- toil/utils/toilDestroyCluster.py +11 -6
- toil/utils/toilKill.py +8 -3
- toil/utils/toilLaunchCluster.py +256 -140
- toil/utils/toilMain.py +37 -16
- toil/utils/toilRsyncCluster.py +32 -14
- toil/utils/toilSshCluster.py +49 -22
- toil/utils/toilStats.py +356 -273
- toil/utils/toilStatus.py +292 -139
- toil/utils/toilUpdateEC2Instances.py +3 -1
- toil/version.py +12 -12
- toil/wdl/utils.py +5 -5
- toil/wdl/wdltoil.py +3913 -1033
- toil/worker.py +367 -184
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/LICENSE +25 -0
- toil-8.0.0.dist-info/METADATA +173 -0
- toil-8.0.0.dist-info/RECORD +253 -0
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
- toil-6.1.0a1.dist-info/METADATA +0 -125
- toil-6.1.0a1.dist-info/RECORD +0 -237
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
toil/batchSystems/torque.py
CHANGED
|
@@ -18,10 +18,12 @@ import shlex
|
|
|
18
18
|
import tempfile
|
|
19
19
|
from queue import Empty
|
|
20
20
|
from shlex import quote
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import Optional
|
|
22
22
|
|
|
23
|
-
from toil.batchSystems.abstractGridEngineBatchSystem import (
|
|
24
|
-
|
|
23
|
+
from toil.batchSystems.abstractGridEngineBatchSystem import (
|
|
24
|
+
AbstractGridEngineBatchSystem,
|
|
25
|
+
UpdatedBatchJobInfo,
|
|
26
|
+
)
|
|
25
27
|
from toil.lib.conversions import hms_duration_to_seconds
|
|
26
28
|
from toil.lib.misc import CalledProcessErrorStderr, call_command
|
|
27
29
|
|
|
@@ -31,7 +33,7 @@ logger = logging.getLogger(__name__)
|
|
|
31
33
|
class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
32
34
|
|
|
33
35
|
# class-specific Worker
|
|
34
|
-
class
|
|
36
|
+
class GridEngineThread(AbstractGridEngineBatchSystem.GridEngineThread):
|
|
35
37
|
def __init__(
|
|
36
38
|
self, newJobsQueue, updatedJobsQueue, killQueue, killedJobsQueue, boss
|
|
37
39
|
):
|
|
@@ -41,18 +43,17 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
41
43
|
self._version = self._pbsVersion()
|
|
42
44
|
|
|
43
45
|
def _pbsVersion(self):
|
|
44
|
-
"""
|
|
45
|
-
"""
|
|
46
|
+
"""Determines PBS/Torque version via pbsnodes"""
|
|
46
47
|
try:
|
|
47
48
|
out = call_command(["pbsnodes", "--version"])
|
|
48
49
|
if "PBSPro" in out:
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
logger.debug("PBS Pro proprietary Torque version detected")
|
|
51
|
+
self._version = "pro"
|
|
51
52
|
else:
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
logger.debug("Torque OSS version detected")
|
|
54
|
+
self._version = "oss"
|
|
54
55
|
except CalledProcessErrorStderr as e:
|
|
55
|
-
|
|
56
|
+
if e.returncode != 0:
|
|
56
57
|
logger.error("Could not determine PBS/Torque version")
|
|
57
58
|
|
|
58
59
|
return self._version
|
|
@@ -60,6 +61,7 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
60
61
|
"""
|
|
61
62
|
Torque-specific AbstractGridEngineWorker methods
|
|
62
63
|
"""
|
|
64
|
+
|
|
63
65
|
def getRunningJobIDs(self):
|
|
64
66
|
times = {}
|
|
65
67
|
with self.runningJobsLock:
|
|
@@ -75,32 +77,33 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
75
77
|
# PBS plain qstat will return every running job on the system.
|
|
76
78
|
jobids = sorted(list(currentjobs.keys()))
|
|
77
79
|
if self._version == "pro":
|
|
78
|
-
stdout = call_command([
|
|
80
|
+
stdout = call_command(["qstat", "-x"] + jobids)
|
|
79
81
|
elif self._version == "oss":
|
|
80
|
-
stdout = call_command([
|
|
82
|
+
stdout = call_command(["qstat"] + jobids)
|
|
81
83
|
|
|
82
84
|
# qstat supports XML output which is more comprehensive, but PBSPro does not support it
|
|
83
85
|
# so instead we stick with plain commandline qstat tabular outputs
|
|
84
|
-
for currline in stdout.split(
|
|
86
|
+
for currline in stdout.split("\n"):
|
|
85
87
|
items = currline.strip().split()
|
|
86
88
|
if items:
|
|
87
89
|
jobid = items[0].strip().split(".")[0]
|
|
88
90
|
if jobid in currentjobs:
|
|
89
91
|
logger.debug("getRunningJobIDs job status for is: %s", items[4])
|
|
90
|
-
if jobid in currentjobs and items[4] ==
|
|
92
|
+
if jobid in currentjobs and items[4] == "R":
|
|
91
93
|
walltime = items[3].strip()
|
|
92
94
|
logger.debug(
|
|
93
95
|
"getRunningJobIDs qstat reported walltime is: %s", walltime
|
|
94
96
|
)
|
|
95
97
|
# normal qstat has a quirk with job time where it reports '0'
|
|
96
98
|
# when initially running; this catches this case
|
|
97
|
-
if walltime ==
|
|
99
|
+
if walltime == "0":
|
|
98
100
|
walltime = 0.0
|
|
99
101
|
elif not walltime:
|
|
100
102
|
# Sometimes we don't get any data here.
|
|
101
103
|
# See https://github.com/DataBiosphere/toil/issues/3715
|
|
102
104
|
logger.warning(
|
|
103
|
-
"Assuming 0 walltime due to missing field in qstat line: %s",
|
|
105
|
+
"Assuming 0 walltime due to missing field in qstat line: %s",
|
|
106
|
+
currline,
|
|
104
107
|
)
|
|
105
108
|
walltime = 0.0
|
|
106
109
|
else:
|
|
@@ -120,10 +123,12 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
120
123
|
except Empty:
|
|
121
124
|
logger.debug("getUpdatedBatchJob: Job queue is empty")
|
|
122
125
|
else:
|
|
123
|
-
return UpdatedBatchJobInfo(
|
|
126
|
+
return UpdatedBatchJobInfo(
|
|
127
|
+
jobID=jobID, exitStatus=retcode, wallTime=None, exitReason=None
|
|
128
|
+
)
|
|
124
129
|
|
|
125
130
|
def killJob(self, jobID):
|
|
126
|
-
call_command([
|
|
131
|
+
call_command(["qdel", self.getBatchSystemID(jobID)])
|
|
127
132
|
|
|
128
133
|
def prepareSubmission(
|
|
129
134
|
self,
|
|
@@ -132,8 +137,9 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
132
137
|
jobID: int,
|
|
133
138
|
command: str,
|
|
134
139
|
jobName: str,
|
|
135
|
-
job_environment: Optional[
|
|
136
|
-
gpus: Optional[int] = None
|
|
140
|
+
job_environment: Optional[dict[str, str]] = None,
|
|
141
|
+
gpus: Optional[int] = None,
|
|
142
|
+
) -> list[str]:
|
|
137
143
|
return self.prepareQsub(cpu, memory, jobID, job_environment) + [
|
|
138
144
|
self.generateTorqueWrapper(command, jobID)
|
|
139
145
|
]
|
|
@@ -143,21 +149,25 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
143
149
|
|
|
144
150
|
def getJobExitCode(self, torqueJobID):
|
|
145
151
|
if self._version == "pro":
|
|
146
|
-
args = ["qstat", "-x", "-f", str(torqueJobID).split(
|
|
152
|
+
args = ["qstat", "-x", "-f", str(torqueJobID).split(".")[0]]
|
|
147
153
|
elif self._version == "oss":
|
|
148
|
-
args = ["qstat", "-f", str(torqueJobID).split(
|
|
154
|
+
args = ["qstat", "-f", str(torqueJobID).split(".")[0]]
|
|
149
155
|
|
|
150
156
|
stdout = call_command(args)
|
|
151
|
-
for line in stdout.split(
|
|
157
|
+
for line in stdout.split("\n"):
|
|
152
158
|
line = line.strip()
|
|
153
159
|
# Case differences due to PBSPro vs OSS Torque qstat outputs
|
|
154
|
-
if
|
|
160
|
+
if (
|
|
161
|
+
line.startswith("failed")
|
|
162
|
+
or line.startswith("FAILED")
|
|
163
|
+
and int(line.split()[1]) == 1
|
|
164
|
+
):
|
|
155
165
|
return 1
|
|
156
166
|
if line.startswith("exit_status") or line.startswith("Exit_status"):
|
|
157
167
|
status = line.split(" = ")[1]
|
|
158
168
|
logger.debug("Exit Status: %s", status)
|
|
159
169
|
return int(status)
|
|
160
|
-
if
|
|
170
|
+
if "unknown job id" in line.lower():
|
|
161
171
|
# some clusters configure Torque to forget everything about just
|
|
162
172
|
# finished jobs instantly, apparently for performance reasons
|
|
163
173
|
logger.debug(
|
|
@@ -176,8 +186,8 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
176
186
|
cpu: int,
|
|
177
187
|
mem: int,
|
|
178
188
|
jobID: int,
|
|
179
|
-
job_environment: Optional[
|
|
180
|
-
) ->
|
|
189
|
+
job_environment: Optional[dict[str, str]],
|
|
190
|
+
) -> list[str]:
|
|
181
191
|
|
|
182
192
|
# TODO: passing $PWD on command line not working for -d, resorting to
|
|
183
193
|
# $PBS_O_WORKDIR but maybe should fix this here instead of in script?
|
|
@@ -189,9 +199,13 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
189
199
|
environment.update(job_environment)
|
|
190
200
|
|
|
191
201
|
if environment:
|
|
192
|
-
qsubline.append(
|
|
193
|
-
qsubline.append(
|
|
194
|
-
|
|
202
|
+
qsubline.append("-v")
|
|
203
|
+
qsubline.append(
|
|
204
|
+
",".join(
|
|
205
|
+
k + "=" + quote(os.environ[k] if v is None else v)
|
|
206
|
+
for k, v in self.boss.environment.items()
|
|
207
|
+
)
|
|
208
|
+
)
|
|
195
209
|
|
|
196
210
|
reqline = list()
|
|
197
211
|
if self._version == "pro":
|
|
@@ -208,7 +222,7 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
208
222
|
reqline.append("nodes=1:ppn=" + str(int(math.ceil(cpu))))
|
|
209
223
|
|
|
210
224
|
# Other resource requirements can be passed through the environment (see man qsub)
|
|
211
|
-
reqlineEnv = os.getenv(
|
|
225
|
+
reqlineEnv = os.getenv("TOIL_TORQUE_REQS")
|
|
212
226
|
if reqlineEnv is not None:
|
|
213
227
|
logger.debug(
|
|
214
228
|
"Additional Torque resource requirements appended to qsub from "
|
|
@@ -232,7 +246,7 @@ class TorqueBatchSystem(AbstractGridEngineBatchSystem):
|
|
|
232
246
|
# All other qsub parameters can be passed through the environment (see man qsub).
|
|
233
247
|
# No attempt is made to parse them out here and check that they do not conflict
|
|
234
248
|
# with those that we already constructed above
|
|
235
|
-
arglineEnv = os.getenv(
|
|
249
|
+
arglineEnv = os.getenv("TOIL_TORQUE_ARGS")
|
|
236
250
|
if arglineEnv is not None:
|
|
237
251
|
logger.debug(
|
|
238
252
|
"Native Torque options appended to qsub from TOIL_TORQUE_ARGS env. variable: %s",
|