Skip to content

Commit c876047

Browse files
authored
Rolling deployments for files (#2862)
Support rolling deployments for services when the `files` property is updated or the contents of file archives change. Currently, `dstack` always detects phantom changes to file archive contents, since file archives are omitted when getting the run plan. Addressing this is out of scope for this PR. This PR does not address compatibility with previously submitted jobs that are using files, because the files feature has not been released yet, so no users have such jobs.
1 parent b2a28f5 commit c876047

File tree

9 files changed

+14
-6
lines changed

9 files changed

+14
-6
lines changed

runner/internal/executor/files.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (ex *RunExecutor) setupFiles(ctx context.Context) error {
5151
}
5252
}
5353

54-
for _, fa := range ex.run.RunSpec.FileArchives {
54+
for _, fa := range ex.jobSpec.FileArchives {
5555
log.Trace(ctx, "Extracting file archive", "id", fa.Id, "path", fa.Path)
5656

5757
p := path.Clean(fa.Path)

runner/internal/schemas/schemas.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ type RunSpec struct {
4747
RunName string `json:"run_name"`
4848
RepoId string `json:"repo_id"`
4949
RepoData RepoData `json:"repo_data"`
50-
FileArchives []FileArchive `json:"file_archives"`
5150
Configuration Configuration `json:"configuration"`
5251
ConfigurationPath string `json:"configuration_path"`
5352
}
@@ -71,7 +70,8 @@ type JobSpec struct {
7170
// `RepoData` is optional for compatibility with jobs submitted before 0.19.17.
7271
// Use `RunExecutor.getRepoData()` to get non-nil `RepoData`.
7372
// TODO: make required when supporting jobs submitted before 0.19.17 is no longer relevant.
74-
RepoData *RepoData `json:"repo_data"`
73+
RepoData *RepoData `json:"repo_data"`
74+
FileArchives []FileArchive `json:"file_archives"`
7575
}
7676

7777
type ClusterInfo struct {

src/dstack/_internal/core/compatibility/runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ def get_job_spec_excludes(job_specs: list[JobSpec]) -> Optional[dict]:
138138
spec_excludes["repo_code_hash"] = True
139139
if all(s.repo_data is None for s in job_specs):
140140
spec_excludes["repo_data"] = True
141+
if all(not s.file_archives for s in job_specs):
142+
spec_excludes["file_archives"] = True
141143

142144
if spec_excludes:
143145
return spec_excludes

src/dstack/_internal/core/models/runs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class JobSpec(CoreModel):
226226
# submitted before 0.19.17. See `_get_repo_code_hash` on how to get the correct `repo_code_hash`
227227
# TODO: drop this comment when supporting jobs submitted before 0.19.17 is no longer relevant.
228228
repo_code_hash: Optional[str] = None
229+
file_archives: list[FileArchiveMapping] = []
229230

230231

231232
class JobProvisioningData(CoreModel):

src/dstack/_internal/server/background/tasks/process_running_jobs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ async def _process_running_job(session: AsyncSession, job_model: JobModel):
244244
# the runner is not ready yet
245245
file_archives = await _get_job_file_archives(
246246
session=session,
247-
archive_mappings=run.run_spec.file_archives,
247+
archive_mappings=job.job_spec.file_archives,
248248
user=run_model.user,
249249
)
250250
code = await _get_job_code(
@@ -296,7 +296,7 @@ async def _process_running_job(session: AsyncSession, job_model: JobModel):
296296
# the runner is not ready yet
297297
file_archives = await _get_job_file_archives(
298298
session=session,
299-
archive_mappings=run.run_spec.file_archives,
299+
archive_mappings=job.job_spec.file_archives,
300300
user=run_model.user,
301301
)
302302
code = await _get_job_code(

src/dstack/_internal/server/schemas/runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class SubmitBody(CoreModel):
5757
"repo_data",
5858
"configuration",
5959
"configuration_path",
60-
"file_archives",
6160
},
6261
}
6362
),
@@ -79,6 +78,7 @@ class SubmitBody(CoreModel):
7978
"ssh_key",
8079
"working_dir",
8180
"repo_data",
81+
"file_archives",
8282
}
8383
),
8484
]

src/dstack/_internal/server/services/jobs/configurators/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ async def _get_job_spec(
151151
ssh_key=self._ssh_key(jobs_per_replica),
152152
repo_data=self.run_spec.repo_data,
153153
repo_code_hash=self.run_spec.repo_code_hash,
154+
file_archives=self.run_spec.file_archives,
154155
)
155156
return job_spec
156157

src/dstack/_internal/server/services/runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ def _validate_run_spec_and_set_defaults(run_spec: RunSpec):
918918
# rolling deployment
919919
"repo_data",
920920
"repo_code_hash",
921+
"file_archives",
921922
],
922923
}
923924
_CONF_UPDATABLE_FIELDS = ["priority"]
@@ -930,6 +931,7 @@ def _validate_run_spec_and_set_defaults(run_spec: RunSpec):
930931
# rolling deployment
931932
"resources",
932933
"volumes",
934+
"files",
933935
"image",
934936
"user",
935937
"privileged",

src/tests/_internal/server/routers/test_runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def get_dev_env_run_plan_dict(
246246
"working_dir": ".",
247247
"repo_code_hash": None,
248248
"repo_data": {"repo_dir": "/repo", "repo_type": "local"},
249+
"file_archives": [],
249250
},
250251
"offers": [json.loads(o.json()) for o in offers],
251252
"total_offers": total_offers,
@@ -440,6 +441,7 @@ def get_dev_env_run_dict(
440441
"working_dir": ".",
441442
"repo_code_hash": None,
442443
"repo_data": {"repo_dir": "/repo", "repo_type": "local"},
444+
"file_archives": [],
443445
},
444446
"job_submissions": [
445447
{

0 commit comments

Comments
 (0)