dstack 0.19.23__py3-none-any.whl → 0.19.24__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.
Potentially problematic release.
This version of dstack might be problematic. Click here for more details.
- dstack/_internal/core/models/instances.py +3 -0
- dstack/_internal/core/models/runs.py +12 -8
- dstack/_internal/server/background/tasks/process_running_jobs.py +1 -2
- dstack/_internal/server/background/tasks/process_runs.py +1 -1
- dstack/_internal/server/migrations/versions/74a1f55209bd_store_enums_as_strings.py +484 -0
- dstack/_internal/server/models.py +11 -12
- dstack/_internal/server/services/jobs/__init__.py +3 -1
- dstack/_internal/server/services/repos.py +1 -1
- dstack/_internal/server/services/runs.py +3 -1
- dstack/_internal/server/services/secrets.py +1 -1
- dstack/_internal/server/statics/index.html +1 -1
- dstack/_internal/server/statics/{main-cc067b7fd1a8f33f97da.js → main-16813e4e1d1c4119eda3.js} +2 -2
- dstack/_internal/server/statics/{main-cc067b7fd1a8f33f97da.js.map → main-16813e4e1d1c4119eda3.js.map} +1 -1
- dstack/version.py +1 -1
- {dstack-0.19.23.dist-info → dstack-0.19.24.dist-info}/METADATA +1 -1
- {dstack-0.19.23.dist-info → dstack-0.19.24.dist-info}/RECORD +19 -18
- {dstack-0.19.23.dist-info → dstack-0.19.24.dist-info}/WHEEL +0 -0
- {dstack-0.19.23.dist-info → dstack-0.19.24.dist-info}/entry_points.txt +0 -0
- {dstack-0.19.23.dist-info → dstack-0.19.24.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -165,6 +165,9 @@ class InstanceAvailability(Enum):
|
|
|
165
165
|
AVAILABLE = "available"
|
|
166
166
|
NOT_AVAILABLE = "not_available"
|
|
167
167
|
NO_QUOTA = "no_quota"
|
|
168
|
+
NO_BALANCE = (
|
|
169
|
+
"no_balance" # Introduced in 0.19.24, may be used after a short compatibility period
|
|
170
|
+
)
|
|
168
171
|
IDLE = "idle"
|
|
169
172
|
BUSY = "busy"
|
|
170
173
|
|
|
@@ -350,15 +350,17 @@ class JobSubmission(CoreModel):
|
|
|
350
350
|
deployment_num: int = 0 # default for compatibility with pre-0.19.14 servers
|
|
351
351
|
submitted_at: datetime
|
|
352
352
|
last_processed_at: datetime
|
|
353
|
-
finished_at: Optional[datetime]
|
|
354
|
-
inactivity_secs: Optional[int]
|
|
353
|
+
finished_at: Optional[datetime] = None
|
|
354
|
+
inactivity_secs: Optional[int] = None
|
|
355
355
|
status: JobStatus
|
|
356
356
|
status_message: str = "" # default for backward compatibility
|
|
357
|
-
termination_reason
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
357
|
+
# termination_reason stores JobTerminationReason.
|
|
358
|
+
# str allows adding new enum members without breaking compatibility with old clients.
|
|
359
|
+
termination_reason: Optional[str] = None
|
|
360
|
+
termination_reason_message: Optional[str] = None
|
|
361
|
+
exit_status: Optional[int] = None
|
|
362
|
+
job_provisioning_data: Optional[JobProvisioningData] = None
|
|
363
|
+
job_runtime_data: Optional[JobRuntimeData] = None
|
|
362
364
|
error: Optional[str] = None
|
|
363
365
|
probes: list[Probe] = []
|
|
364
366
|
|
|
@@ -508,7 +510,9 @@ class Run(CoreModel):
|
|
|
508
510
|
last_processed_at: datetime
|
|
509
511
|
status: RunStatus
|
|
510
512
|
status_message: str = "" # default for backward compatibility
|
|
511
|
-
termination_reason
|
|
513
|
+
# termination_reason stores RunTerminationReason.
|
|
514
|
+
# str allows adding new enum members without breaking compatibility with old clients.
|
|
515
|
+
termination_reason: Optional[str] = None
|
|
512
516
|
run_spec: RunSpec
|
|
513
517
|
jobs: List[Job]
|
|
514
518
|
latest_job_submission: Optional[JobSubmission] = None
|
|
@@ -455,8 +455,7 @@ async def _wait_for_instance_provisioning_data(job_model: JobModel):
|
|
|
455
455
|
|
|
456
456
|
if job_model.instance.status == InstanceStatus.TERMINATED:
|
|
457
457
|
job_model.status = JobStatus.TERMINATING
|
|
458
|
-
|
|
459
|
-
job_model.termination_reason = JobTerminationReason.FAILED_TO_START_DUE_TO_NO_CAPACITY
|
|
458
|
+
job_model.termination_reason = JobTerminationReason.WAITING_INSTANCE_LIMIT_EXCEEDED
|
|
460
459
|
return
|
|
461
460
|
|
|
462
461
|
job_model.job_provisioning_data = job_model.instance.job_provisioning_data
|
|
@@ -574,7 +574,7 @@ def _should_retry_job(run: Run, job: Job, job_model: JobModel) -> Optional[datet
|
|
|
574
574
|
|
|
575
575
|
if (
|
|
576
576
|
last_provisioned_submission.termination_reason is not None
|
|
577
|
-
and last_provisioned_submission.termination_reason.to_retry_event()
|
|
577
|
+
and JobTerminationReason(last_provisioned_submission.termination_reason).to_retry_event()
|
|
578
578
|
in job.job_spec.retry.on_events
|
|
579
579
|
):
|
|
580
580
|
return common.get_current_datetime() - last_provisioned_submission.last_processed_at
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
"""Store enums as strings
|
|
2
|
+
|
|
3
|
+
Revision ID: 74a1f55209bd
|
|
4
|
+
Revises: 728b1488b1b4
|
|
5
|
+
Create Date: 2025-08-06 13:49:28.785378
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "74a1f55209bd"
|
|
15
|
+
down_revision = "728b1488b1b4"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade() -> None:
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
with op.batch_alter_table("users", schema=None) as batch_op:
|
|
23
|
+
batch_op.alter_column(
|
|
24
|
+
"global_role",
|
|
25
|
+
existing_type=postgresql.ENUM("ADMIN", "USER", name="globalrole"),
|
|
26
|
+
type_=sa.String(length=100),
|
|
27
|
+
existing_nullable=False,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
with op.batch_alter_table("members", schema=None) as batch_op:
|
|
31
|
+
batch_op.alter_column(
|
|
32
|
+
"project_role",
|
|
33
|
+
existing_type=postgresql.ENUM("ADMIN", "MANAGER", "USER", name="projectrole"),
|
|
34
|
+
type_=sa.String(length=100),
|
|
35
|
+
existing_nullable=False,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
with op.batch_alter_table("repos", schema=None) as batch_op:
|
|
39
|
+
batch_op.alter_column(
|
|
40
|
+
"type",
|
|
41
|
+
existing_type=postgresql.ENUM("REMOTE", "LOCAL", "VIRTUAL", name="repotype"),
|
|
42
|
+
type_=sa.String(length=100),
|
|
43
|
+
existing_nullable=False,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
with op.batch_alter_table("runs", schema=None) as batch_op:
|
|
47
|
+
batch_op.alter_column(
|
|
48
|
+
"status",
|
|
49
|
+
existing_type=postgresql.ENUM(
|
|
50
|
+
"PENDING",
|
|
51
|
+
"SUBMITTED",
|
|
52
|
+
"PROVISIONING",
|
|
53
|
+
"RUNNING",
|
|
54
|
+
"TERMINATING",
|
|
55
|
+
"TERMINATED",
|
|
56
|
+
"FAILED",
|
|
57
|
+
"DONE",
|
|
58
|
+
name="runstatus",
|
|
59
|
+
),
|
|
60
|
+
type_=sa.String(length=100),
|
|
61
|
+
existing_nullable=False,
|
|
62
|
+
)
|
|
63
|
+
batch_op.alter_column(
|
|
64
|
+
"termination_reason",
|
|
65
|
+
existing_type=postgresql.ENUM(
|
|
66
|
+
"ALL_JOBS_DONE",
|
|
67
|
+
"JOB_FAILED",
|
|
68
|
+
"RETRY_LIMIT_EXCEEDED",
|
|
69
|
+
"STOPPED_BY_USER",
|
|
70
|
+
"ABORTED_BY_USER",
|
|
71
|
+
"SERVER_ERROR",
|
|
72
|
+
name="runterminationreason",
|
|
73
|
+
),
|
|
74
|
+
type_=sa.String(length=100),
|
|
75
|
+
existing_nullable=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
with op.batch_alter_table("jobs", schema=None) as batch_op:
|
|
79
|
+
batch_op.alter_column(
|
|
80
|
+
"status",
|
|
81
|
+
existing_type=postgresql.ENUM(
|
|
82
|
+
"SUBMITTED",
|
|
83
|
+
"PROVISIONING",
|
|
84
|
+
"PULLING",
|
|
85
|
+
"RUNNING",
|
|
86
|
+
"TERMINATING",
|
|
87
|
+
"TERMINATED",
|
|
88
|
+
"ABORTED",
|
|
89
|
+
"FAILED",
|
|
90
|
+
"DONE",
|
|
91
|
+
name="jobstatus",
|
|
92
|
+
),
|
|
93
|
+
type_=sa.String(length=100),
|
|
94
|
+
existing_nullable=False,
|
|
95
|
+
)
|
|
96
|
+
batch_op.alter_column(
|
|
97
|
+
"termination_reason",
|
|
98
|
+
existing_type=postgresql.ENUM(
|
|
99
|
+
"FAILED_TO_START_DUE_TO_NO_CAPACITY",
|
|
100
|
+
"INTERRUPTED_BY_NO_CAPACITY",
|
|
101
|
+
"INSTANCE_UNREACHABLE",
|
|
102
|
+
"WAITING_INSTANCE_LIMIT_EXCEEDED",
|
|
103
|
+
"WAITING_RUNNER_LIMIT_EXCEEDED",
|
|
104
|
+
"TERMINATED_BY_USER",
|
|
105
|
+
"VOLUME_ERROR",
|
|
106
|
+
"GATEWAY_ERROR",
|
|
107
|
+
"SCALED_DOWN",
|
|
108
|
+
"DONE_BY_RUNNER",
|
|
109
|
+
"ABORTED_BY_USER",
|
|
110
|
+
"TERMINATED_BY_SERVER",
|
|
111
|
+
"INACTIVITY_DURATION_EXCEEDED",
|
|
112
|
+
"TERMINATED_DUE_TO_UTILIZATION_POLICY",
|
|
113
|
+
"CONTAINER_EXITED_WITH_ERROR",
|
|
114
|
+
"PORTS_BINDING_FAILED",
|
|
115
|
+
"CREATING_CONTAINER_ERROR",
|
|
116
|
+
"EXECUTOR_ERROR",
|
|
117
|
+
"MAX_DURATION_EXCEEDED",
|
|
118
|
+
name="jobterminationreason",
|
|
119
|
+
),
|
|
120
|
+
type_=sa.String(length=100),
|
|
121
|
+
existing_nullable=True,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
with op.batch_alter_table("fleets", schema=None) as batch_op:
|
|
125
|
+
batch_op.alter_column(
|
|
126
|
+
"status",
|
|
127
|
+
existing_type=postgresql.ENUM(
|
|
128
|
+
"SUBMITTED", "ACTIVE", "TERMINATING", "TERMINATED", "FAILED", name="fleetstatus"
|
|
129
|
+
),
|
|
130
|
+
type_=sa.String(length=100),
|
|
131
|
+
existing_nullable=False,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
with op.batch_alter_table("gateways", schema=None) as batch_op:
|
|
135
|
+
batch_op.alter_column(
|
|
136
|
+
"status",
|
|
137
|
+
existing_type=postgresql.ENUM(
|
|
138
|
+
"SUBMITTED", "PROVISIONING", "RUNNING", "FAILED", name="gatewaystatus"
|
|
139
|
+
),
|
|
140
|
+
type_=sa.String(length=100),
|
|
141
|
+
existing_nullable=False,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
with op.batch_alter_table("instances", schema=None) as batch_op:
|
|
145
|
+
batch_op.alter_column(
|
|
146
|
+
"status",
|
|
147
|
+
existing_type=postgresql.ENUM(
|
|
148
|
+
"PENDING",
|
|
149
|
+
"PROVISIONING",
|
|
150
|
+
"IDLE",
|
|
151
|
+
"BUSY",
|
|
152
|
+
"TERMINATING",
|
|
153
|
+
"TERMINATED",
|
|
154
|
+
name="instancestatus",
|
|
155
|
+
),
|
|
156
|
+
type_=sa.String(length=100),
|
|
157
|
+
existing_nullable=False,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
with op.batch_alter_table("volumes", schema=None) as batch_op:
|
|
161
|
+
batch_op.alter_column(
|
|
162
|
+
"status",
|
|
163
|
+
existing_type=postgresql.ENUM(
|
|
164
|
+
"SUBMITTED", "PROVISIONING", "ACTIVE", "FAILED", name="volumestatus"
|
|
165
|
+
),
|
|
166
|
+
type_=sa.String(length=100),
|
|
167
|
+
existing_nullable=False,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
sa.Enum("ADMIN", "USER", name="globalrole").drop(op.get_bind())
|
|
171
|
+
sa.Enum(
|
|
172
|
+
"ALL_JOBS_DONE",
|
|
173
|
+
"JOB_FAILED",
|
|
174
|
+
"RETRY_LIMIT_EXCEEDED",
|
|
175
|
+
"STOPPED_BY_USER",
|
|
176
|
+
"ABORTED_BY_USER",
|
|
177
|
+
"SERVER_ERROR",
|
|
178
|
+
name="runterminationreason",
|
|
179
|
+
).drop(op.get_bind())
|
|
180
|
+
sa.Enum("SUBMITTED", "PROVISIONING", "RUNNING", "FAILED", name="gatewaystatus").drop(
|
|
181
|
+
op.get_bind()
|
|
182
|
+
)
|
|
183
|
+
sa.Enum("SUBMITTED", "PROVISIONING", "ACTIVE", "FAILED", name="volumestatus").drop(
|
|
184
|
+
op.get_bind()
|
|
185
|
+
)
|
|
186
|
+
sa.Enum(
|
|
187
|
+
"PENDING",
|
|
188
|
+
"SUBMITTED",
|
|
189
|
+
"PROVISIONING",
|
|
190
|
+
"RUNNING",
|
|
191
|
+
"TERMINATING",
|
|
192
|
+
"TERMINATED",
|
|
193
|
+
"FAILED",
|
|
194
|
+
"DONE",
|
|
195
|
+
name="runstatus",
|
|
196
|
+
).drop(op.get_bind())
|
|
197
|
+
sa.Enum("REMOTE", "LOCAL", "VIRTUAL", name="repotype").drop(op.get_bind())
|
|
198
|
+
sa.Enum(
|
|
199
|
+
"SUBMITTED",
|
|
200
|
+
"PROVISIONING",
|
|
201
|
+
"PULLING",
|
|
202
|
+
"RUNNING",
|
|
203
|
+
"TERMINATING",
|
|
204
|
+
"TERMINATED",
|
|
205
|
+
"ABORTED",
|
|
206
|
+
"FAILED",
|
|
207
|
+
"DONE",
|
|
208
|
+
name="jobstatus",
|
|
209
|
+
).drop(op.get_bind())
|
|
210
|
+
sa.Enum(
|
|
211
|
+
"PENDING",
|
|
212
|
+
"PROVISIONING",
|
|
213
|
+
"IDLE",
|
|
214
|
+
"BUSY",
|
|
215
|
+
"TERMINATING",
|
|
216
|
+
"TERMINATED",
|
|
217
|
+
name="instancestatus",
|
|
218
|
+
).drop(op.get_bind())
|
|
219
|
+
sa.Enum("SUBMITTED", "ACTIVE", "TERMINATING", "TERMINATED", "FAILED", name="fleetstatus").drop(
|
|
220
|
+
op.get_bind()
|
|
221
|
+
)
|
|
222
|
+
sa.Enum("ADMIN", "MANAGER", "USER", name="projectrole").drop(op.get_bind())
|
|
223
|
+
sa.Enum(
|
|
224
|
+
"FAILED_TO_START_DUE_TO_NO_CAPACITY",
|
|
225
|
+
"INTERRUPTED_BY_NO_CAPACITY",
|
|
226
|
+
"INSTANCE_UNREACHABLE",
|
|
227
|
+
"WAITING_INSTANCE_LIMIT_EXCEEDED",
|
|
228
|
+
"WAITING_RUNNER_LIMIT_EXCEEDED",
|
|
229
|
+
"TERMINATED_BY_USER",
|
|
230
|
+
"VOLUME_ERROR",
|
|
231
|
+
"GATEWAY_ERROR",
|
|
232
|
+
"SCALED_DOWN",
|
|
233
|
+
"DONE_BY_RUNNER",
|
|
234
|
+
"ABORTED_BY_USER",
|
|
235
|
+
"TERMINATED_BY_SERVER",
|
|
236
|
+
"INACTIVITY_DURATION_EXCEEDED",
|
|
237
|
+
"TERMINATED_DUE_TO_UTILIZATION_POLICY",
|
|
238
|
+
"CONTAINER_EXITED_WITH_ERROR",
|
|
239
|
+
"PORTS_BINDING_FAILED",
|
|
240
|
+
"CREATING_CONTAINER_ERROR",
|
|
241
|
+
"EXECUTOR_ERROR",
|
|
242
|
+
"MAX_DURATION_EXCEEDED",
|
|
243
|
+
name="jobterminationreason",
|
|
244
|
+
).drop(op.get_bind())
|
|
245
|
+
# ### end Alembic commands ###
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def downgrade() -> None:
|
|
249
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
250
|
+
sa.Enum(
|
|
251
|
+
"FAILED_TO_START_DUE_TO_NO_CAPACITY",
|
|
252
|
+
"INTERRUPTED_BY_NO_CAPACITY",
|
|
253
|
+
"INSTANCE_UNREACHABLE",
|
|
254
|
+
"WAITING_INSTANCE_LIMIT_EXCEEDED",
|
|
255
|
+
"WAITING_RUNNER_LIMIT_EXCEEDED",
|
|
256
|
+
"TERMINATED_BY_USER",
|
|
257
|
+
"VOLUME_ERROR",
|
|
258
|
+
"GATEWAY_ERROR",
|
|
259
|
+
"SCALED_DOWN",
|
|
260
|
+
"DONE_BY_RUNNER",
|
|
261
|
+
"ABORTED_BY_USER",
|
|
262
|
+
"TERMINATED_BY_SERVER",
|
|
263
|
+
"INACTIVITY_DURATION_EXCEEDED",
|
|
264
|
+
"TERMINATED_DUE_TO_UTILIZATION_POLICY",
|
|
265
|
+
"CONTAINER_EXITED_WITH_ERROR",
|
|
266
|
+
"PORTS_BINDING_FAILED",
|
|
267
|
+
"CREATING_CONTAINER_ERROR",
|
|
268
|
+
"EXECUTOR_ERROR",
|
|
269
|
+
"MAX_DURATION_EXCEEDED",
|
|
270
|
+
name="jobterminationreason",
|
|
271
|
+
).create(op.get_bind())
|
|
272
|
+
sa.Enum("ADMIN", "MANAGER", "USER", name="projectrole").create(op.get_bind())
|
|
273
|
+
sa.Enum(
|
|
274
|
+
"SUBMITTED", "ACTIVE", "TERMINATING", "TERMINATED", "FAILED", name="fleetstatus"
|
|
275
|
+
).create(op.get_bind())
|
|
276
|
+
sa.Enum(
|
|
277
|
+
"PENDING",
|
|
278
|
+
"PROVISIONING",
|
|
279
|
+
"IDLE",
|
|
280
|
+
"BUSY",
|
|
281
|
+
"TERMINATING",
|
|
282
|
+
"TERMINATED",
|
|
283
|
+
name="instancestatus",
|
|
284
|
+
).create(op.get_bind())
|
|
285
|
+
sa.Enum(
|
|
286
|
+
"SUBMITTED",
|
|
287
|
+
"PROVISIONING",
|
|
288
|
+
"PULLING",
|
|
289
|
+
"RUNNING",
|
|
290
|
+
"TERMINATING",
|
|
291
|
+
"TERMINATED",
|
|
292
|
+
"ABORTED",
|
|
293
|
+
"FAILED",
|
|
294
|
+
"DONE",
|
|
295
|
+
name="jobstatus",
|
|
296
|
+
).create(op.get_bind())
|
|
297
|
+
sa.Enum("REMOTE", "LOCAL", "VIRTUAL", name="repotype").create(op.get_bind())
|
|
298
|
+
sa.Enum(
|
|
299
|
+
"PENDING",
|
|
300
|
+
"SUBMITTED",
|
|
301
|
+
"PROVISIONING",
|
|
302
|
+
"RUNNING",
|
|
303
|
+
"TERMINATING",
|
|
304
|
+
"TERMINATED",
|
|
305
|
+
"FAILED",
|
|
306
|
+
"DONE",
|
|
307
|
+
name="runstatus",
|
|
308
|
+
).create(op.get_bind())
|
|
309
|
+
sa.Enum("SUBMITTED", "PROVISIONING", "ACTIVE", "FAILED", name="volumestatus").create(
|
|
310
|
+
op.get_bind()
|
|
311
|
+
)
|
|
312
|
+
sa.Enum("SUBMITTED", "PROVISIONING", "RUNNING", "FAILED", name="gatewaystatus").create(
|
|
313
|
+
op.get_bind()
|
|
314
|
+
)
|
|
315
|
+
sa.Enum(
|
|
316
|
+
"ALL_JOBS_DONE",
|
|
317
|
+
"JOB_FAILED",
|
|
318
|
+
"RETRY_LIMIT_EXCEEDED",
|
|
319
|
+
"STOPPED_BY_USER",
|
|
320
|
+
"ABORTED_BY_USER",
|
|
321
|
+
"SERVER_ERROR",
|
|
322
|
+
name="runterminationreason",
|
|
323
|
+
).create(op.get_bind())
|
|
324
|
+
sa.Enum("ADMIN", "USER", name="globalrole").create(op.get_bind())
|
|
325
|
+
with op.batch_alter_table("volumes", schema=None) as batch_op:
|
|
326
|
+
batch_op.alter_column(
|
|
327
|
+
"status",
|
|
328
|
+
existing_type=sa.String(length=100),
|
|
329
|
+
type_=postgresql.ENUM(
|
|
330
|
+
"SUBMITTED", "PROVISIONING", "ACTIVE", "FAILED", name="volumestatus"
|
|
331
|
+
),
|
|
332
|
+
existing_nullable=False,
|
|
333
|
+
postgresql_using="status::VARCHAR::volumestatus",
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
with op.batch_alter_table("users", schema=None) as batch_op:
|
|
337
|
+
batch_op.alter_column(
|
|
338
|
+
"global_role",
|
|
339
|
+
existing_type=sa.String(length=100),
|
|
340
|
+
type_=postgresql.ENUM("ADMIN", "USER", name="globalrole"),
|
|
341
|
+
existing_nullable=False,
|
|
342
|
+
postgresql_using="global_role::VARCHAR::globalrole",
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
with op.batch_alter_table("runs", schema=None) as batch_op:
|
|
346
|
+
batch_op.alter_column(
|
|
347
|
+
"termination_reason",
|
|
348
|
+
existing_type=sa.String(length=100),
|
|
349
|
+
type_=postgresql.ENUM(
|
|
350
|
+
"ALL_JOBS_DONE",
|
|
351
|
+
"JOB_FAILED",
|
|
352
|
+
"RETRY_LIMIT_EXCEEDED",
|
|
353
|
+
"STOPPED_BY_USER",
|
|
354
|
+
"ABORTED_BY_USER",
|
|
355
|
+
"SERVER_ERROR",
|
|
356
|
+
name="runterminationreason",
|
|
357
|
+
),
|
|
358
|
+
existing_nullable=True,
|
|
359
|
+
postgresql_using="termination_reason::VARCHAR::runterminationreason",
|
|
360
|
+
)
|
|
361
|
+
batch_op.alter_column(
|
|
362
|
+
"status",
|
|
363
|
+
existing_type=sa.String(length=100),
|
|
364
|
+
type_=postgresql.ENUM(
|
|
365
|
+
"PENDING",
|
|
366
|
+
"SUBMITTED",
|
|
367
|
+
"PROVISIONING",
|
|
368
|
+
"RUNNING",
|
|
369
|
+
"TERMINATING",
|
|
370
|
+
"TERMINATED",
|
|
371
|
+
"FAILED",
|
|
372
|
+
"DONE",
|
|
373
|
+
name="runstatus",
|
|
374
|
+
),
|
|
375
|
+
existing_nullable=False,
|
|
376
|
+
postgresql_using="status::VARCHAR::runstatus",
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
with op.batch_alter_table("repos", schema=None) as batch_op:
|
|
380
|
+
batch_op.alter_column(
|
|
381
|
+
"type",
|
|
382
|
+
existing_type=sa.String(length=100),
|
|
383
|
+
type_=postgresql.ENUM("REMOTE", "LOCAL", "VIRTUAL", name="repotype"),
|
|
384
|
+
existing_nullable=False,
|
|
385
|
+
postgresql_using="type::VARCHAR::repotype",
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
with op.batch_alter_table("members", schema=None) as batch_op:
|
|
389
|
+
batch_op.alter_column(
|
|
390
|
+
"project_role",
|
|
391
|
+
existing_type=sa.String(length=100),
|
|
392
|
+
type_=postgresql.ENUM("ADMIN", "MANAGER", "USER", name="projectrole"),
|
|
393
|
+
existing_nullable=False,
|
|
394
|
+
postgresql_using="project_role::VARCHAR::projectrole",
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
with op.batch_alter_table("jobs", schema=None) as batch_op:
|
|
398
|
+
batch_op.alter_column(
|
|
399
|
+
"termination_reason",
|
|
400
|
+
existing_type=sa.String(length=100),
|
|
401
|
+
type_=postgresql.ENUM(
|
|
402
|
+
"FAILED_TO_START_DUE_TO_NO_CAPACITY",
|
|
403
|
+
"INTERRUPTED_BY_NO_CAPACITY",
|
|
404
|
+
"INSTANCE_UNREACHABLE",
|
|
405
|
+
"WAITING_INSTANCE_LIMIT_EXCEEDED",
|
|
406
|
+
"WAITING_RUNNER_LIMIT_EXCEEDED",
|
|
407
|
+
"TERMINATED_BY_USER",
|
|
408
|
+
"VOLUME_ERROR",
|
|
409
|
+
"GATEWAY_ERROR",
|
|
410
|
+
"SCALED_DOWN",
|
|
411
|
+
"DONE_BY_RUNNER",
|
|
412
|
+
"ABORTED_BY_USER",
|
|
413
|
+
"TERMINATED_BY_SERVER",
|
|
414
|
+
"INACTIVITY_DURATION_EXCEEDED",
|
|
415
|
+
"TERMINATED_DUE_TO_UTILIZATION_POLICY",
|
|
416
|
+
"CONTAINER_EXITED_WITH_ERROR",
|
|
417
|
+
"PORTS_BINDING_FAILED",
|
|
418
|
+
"CREATING_CONTAINER_ERROR",
|
|
419
|
+
"EXECUTOR_ERROR",
|
|
420
|
+
"MAX_DURATION_EXCEEDED",
|
|
421
|
+
name="jobterminationreason",
|
|
422
|
+
),
|
|
423
|
+
existing_nullable=True,
|
|
424
|
+
postgresql_using="termination_reason::VARCHAR::jobterminationreason",
|
|
425
|
+
)
|
|
426
|
+
batch_op.alter_column(
|
|
427
|
+
"status",
|
|
428
|
+
existing_type=sa.String(length=100),
|
|
429
|
+
type_=postgresql.ENUM(
|
|
430
|
+
"SUBMITTED",
|
|
431
|
+
"PROVISIONING",
|
|
432
|
+
"PULLING",
|
|
433
|
+
"RUNNING",
|
|
434
|
+
"TERMINATING",
|
|
435
|
+
"TERMINATED",
|
|
436
|
+
"ABORTED",
|
|
437
|
+
"FAILED",
|
|
438
|
+
"DONE",
|
|
439
|
+
name="jobstatus",
|
|
440
|
+
),
|
|
441
|
+
existing_nullable=False,
|
|
442
|
+
postgresql_using="status::VARCHAR::jobstatus",
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
with op.batch_alter_table("instances", schema=None) as batch_op:
|
|
446
|
+
batch_op.alter_column(
|
|
447
|
+
"status",
|
|
448
|
+
existing_type=sa.String(length=100),
|
|
449
|
+
type_=postgresql.ENUM(
|
|
450
|
+
"PENDING",
|
|
451
|
+
"PROVISIONING",
|
|
452
|
+
"IDLE",
|
|
453
|
+
"BUSY",
|
|
454
|
+
"TERMINATING",
|
|
455
|
+
"TERMINATED",
|
|
456
|
+
name="instancestatus",
|
|
457
|
+
),
|
|
458
|
+
existing_nullable=False,
|
|
459
|
+
postgresql_using="status::VARCHAR::instancestatus",
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
with op.batch_alter_table("gateways", schema=None) as batch_op:
|
|
463
|
+
batch_op.alter_column(
|
|
464
|
+
"status",
|
|
465
|
+
existing_type=sa.String(length=100),
|
|
466
|
+
type_=postgresql.ENUM(
|
|
467
|
+
"SUBMITTED", "PROVISIONING", "RUNNING", "FAILED", name="gatewaystatus"
|
|
468
|
+
),
|
|
469
|
+
existing_nullable=False,
|
|
470
|
+
postgresql_using="status::VARCHAR::gatewaystatus",
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
with op.batch_alter_table("fleets", schema=None) as batch_op:
|
|
474
|
+
batch_op.alter_column(
|
|
475
|
+
"status",
|
|
476
|
+
existing_type=sa.String(length=100),
|
|
477
|
+
type_=postgresql.ENUM(
|
|
478
|
+
"SUBMITTED", "ACTIVE", "TERMINATING", "TERMINATED", "FAILED", name="fleetstatus"
|
|
479
|
+
),
|
|
480
|
+
existing_nullable=False,
|
|
481
|
+
postgresql_using="status::VARCHAR::fleetstatus",
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
# ### end Alembic commands ###
|
|
@@ -7,7 +7,6 @@ from sqlalchemy import (
|
|
|
7
7
|
BigInteger,
|
|
8
8
|
Boolean,
|
|
9
9
|
DateTime,
|
|
10
|
-
Enum,
|
|
11
10
|
Float,
|
|
12
11
|
ForeignKey,
|
|
13
12
|
Index,
|
|
@@ -186,7 +185,7 @@ class UserModel(BaseModel):
|
|
|
186
185
|
token: Mapped[DecryptedString] = mapped_column(EncryptedString(200), unique=True)
|
|
187
186
|
# token_hash is needed for fast search by token when stored token is encrypted
|
|
188
187
|
token_hash: Mapped[str] = mapped_column(String(2000), unique=True)
|
|
189
|
-
global_role: Mapped[GlobalRole] = mapped_column(
|
|
188
|
+
global_role: Mapped[GlobalRole] = mapped_column(EnumAsString(GlobalRole, 100))
|
|
190
189
|
# deactivated users cannot access API
|
|
191
190
|
active: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
192
191
|
|
|
@@ -247,7 +246,7 @@ class MemberModel(BaseModel):
|
|
|
247
246
|
project: Mapped["ProjectModel"] = relationship()
|
|
248
247
|
user_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"))
|
|
249
248
|
user: Mapped[UserModel] = relationship(lazy="joined")
|
|
250
|
-
project_role: Mapped[ProjectRole] = mapped_column(
|
|
249
|
+
project_role: Mapped[ProjectRole] = mapped_column(EnumAsString(ProjectRole, 100))
|
|
251
250
|
# member_num defines members ordering
|
|
252
251
|
member_num: Mapped[Optional[int]] = mapped_column(Integer)
|
|
253
252
|
|
|
@@ -279,7 +278,7 @@ class RepoModel(BaseModel):
|
|
|
279
278
|
project: Mapped["ProjectModel"] = relationship()
|
|
280
279
|
# RepoModel.name stores repo_id
|
|
281
280
|
name: Mapped[str] = mapped_column(String(100))
|
|
282
|
-
type: Mapped[RepoType] = mapped_column(
|
|
281
|
+
type: Mapped[RepoType] = mapped_column(EnumAsString(RepoType, 100))
|
|
283
282
|
|
|
284
283
|
info: Mapped[str] = mapped_column(Text)
|
|
285
284
|
|
|
@@ -360,9 +359,9 @@ class RunModel(BaseModel):
|
|
|
360
359
|
submitted_at: Mapped[datetime] = mapped_column(NaiveDateTime)
|
|
361
360
|
last_processed_at: Mapped[datetime] = mapped_column(NaiveDateTime)
|
|
362
361
|
next_triggered_at: Mapped[Optional[datetime]] = mapped_column(NaiveDateTime)
|
|
363
|
-
status: Mapped[RunStatus] = mapped_column(
|
|
362
|
+
status: Mapped[RunStatus] = mapped_column(EnumAsString(RunStatus, 100), index=True)
|
|
364
363
|
termination_reason: Mapped[Optional[RunTerminationReason]] = mapped_column(
|
|
365
|
-
|
|
364
|
+
EnumAsString(RunTerminationReason, 100)
|
|
366
365
|
)
|
|
367
366
|
# resubmission_attempt counts consecutive transitions to pending without provisioning.
|
|
368
367
|
# Can be used to choose retry delay depending on the attempt number.
|
|
@@ -401,9 +400,9 @@ class JobModel(BaseModel):
|
|
|
401
400
|
submission_num: Mapped[int] = mapped_column(Integer)
|
|
402
401
|
submitted_at: Mapped[datetime] = mapped_column(NaiveDateTime)
|
|
403
402
|
last_processed_at: Mapped[datetime] = mapped_column(NaiveDateTime)
|
|
404
|
-
status: Mapped[JobStatus] = mapped_column(
|
|
403
|
+
status: Mapped[JobStatus] = mapped_column(EnumAsString(JobStatus, 100), index=True)
|
|
405
404
|
termination_reason: Mapped[Optional[JobTerminationReason]] = mapped_column(
|
|
406
|
-
|
|
405
|
+
EnumAsString(JobTerminationReason, 100)
|
|
407
406
|
)
|
|
408
407
|
termination_reason_message: Mapped[Optional[str]] = mapped_column(Text)
|
|
409
408
|
# `disconnected_at` stores the first time of connectivity issues with the instance.
|
|
@@ -446,7 +445,7 @@ class GatewayModel(BaseModel):
|
|
|
446
445
|
# Use `get_gateway_configuration` to construct `configuration` for old gateways.
|
|
447
446
|
configuration: Mapped[Optional[str]] = mapped_column(Text)
|
|
448
447
|
created_at: Mapped[datetime] = mapped_column(NaiveDateTime, default=get_current_datetime)
|
|
449
|
-
status: Mapped[GatewayStatus] = mapped_column(
|
|
448
|
+
status: Mapped[GatewayStatus] = mapped_column(EnumAsString(GatewayStatus, 100))
|
|
450
449
|
status_message: Mapped[Optional[str]] = mapped_column(Text)
|
|
451
450
|
last_processed_at: Mapped[datetime] = mapped_column(NaiveDateTime)
|
|
452
451
|
|
|
@@ -532,7 +531,7 @@ class FleetModel(BaseModel):
|
|
|
532
531
|
deleted: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
533
532
|
deleted_at: Mapped[Optional[datetime]] = mapped_column(NaiveDateTime)
|
|
534
533
|
|
|
535
|
-
status: Mapped[FleetStatus] = mapped_column(
|
|
534
|
+
status: Mapped[FleetStatus] = mapped_column(EnumAsString(FleetStatus, 100), index=True)
|
|
536
535
|
status_message: Mapped[Optional[str]] = mapped_column(Text)
|
|
537
536
|
|
|
538
537
|
spec: Mapped[str] = mapped_column(Text)
|
|
@@ -571,7 +570,7 @@ class InstanceModel(BaseModel):
|
|
|
571
570
|
fleet_id: Mapped[Optional[uuid.UUID]] = mapped_column(ForeignKey("fleets.id"))
|
|
572
571
|
fleet: Mapped[Optional["FleetModel"]] = relationship(back_populates="instances")
|
|
573
572
|
|
|
574
|
-
status: Mapped[InstanceStatus] = mapped_column(
|
|
573
|
+
status: Mapped[InstanceStatus] = mapped_column(EnumAsString(InstanceStatus, 100), index=True)
|
|
575
574
|
unreachable: Mapped[bool] = mapped_column(Boolean)
|
|
576
575
|
|
|
577
576
|
# VM
|
|
@@ -672,7 +671,7 @@ class VolumeModel(BaseModel):
|
|
|
672
671
|
deleted: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
673
672
|
deleted_at: Mapped[Optional[datetime]] = mapped_column(NaiveDateTime)
|
|
674
673
|
|
|
675
|
-
status: Mapped[VolumeStatus] = mapped_column(
|
|
674
|
+
status: Mapped[VolumeStatus] = mapped_column(EnumAsString(VolumeStatus, 100), index=True)
|
|
676
675
|
status_message: Mapped[Optional[str]] = mapped_column(Text)
|
|
677
676
|
|
|
678
677
|
configuration: Mapped[str] = mapped_column(Text)
|
|
@@ -152,7 +152,9 @@ def job_model_to_job_submission(
|
|
|
152
152
|
inactivity_secs=job_model.inactivity_secs,
|
|
153
153
|
status=job_model.status,
|
|
154
154
|
status_message=status_message,
|
|
155
|
-
termination_reason=job_model.termination_reason
|
|
155
|
+
termination_reason=job_model.termination_reason.value
|
|
156
|
+
if job_model.termination_reason
|
|
157
|
+
else None,
|
|
156
158
|
termination_reason_message=job_model.termination_reason_message,
|
|
157
159
|
exit_status=job_model.exit_status,
|
|
158
160
|
job_provisioning_data=job_provisioning_data,
|
|
@@ -714,7 +714,9 @@ def run_model_to_run(
|
|
|
714
714
|
last_processed_at=run_model.last_processed_at,
|
|
715
715
|
status=run_model.status,
|
|
716
716
|
status_message=status_message,
|
|
717
|
-
termination_reason=run_model.termination_reason
|
|
717
|
+
termination_reason=run_model.termination_reason.value
|
|
718
|
+
if run_model.termination_reason
|
|
719
|
+
else None,
|
|
718
720
|
run_spec=run_spec,
|
|
719
721
|
jobs=jobs,
|
|
720
722
|
latest_job_submission=latest_job_submission,
|