From 084dec84b06f948b17338876db5394e11778dcf7 Mon Sep 17 00:00:00 2001 From: Dmitry Meyer Date: Tue, 2 Sep 2025 09:19:24 +0000 Subject: [PATCH 1/2] Expose job working dir via environment variable * Expose the job's working dir via `DSTACK_WORKING_DIR` environment variable * Automatically `cd` to `DSTACK_WORKING_DIR` on login Closes: https://github.com/dstackai/dstack/issues/3045 --- runner/internal/executor/executor.go | 4 ++++ .../server/services/jobs/configurators/base.py | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/runner/internal/executor/executor.go b/runner/internal/executor/executor.go index 39999156c2..fdc20d52f8 100644 --- a/runner/internal/executor/executor.go +++ b/runner/internal/executor/executor.go @@ -394,6 +394,7 @@ func (ex *RunExecutor) execJob(ctx context.Context, jobLogFile io.Writer) error "DSTACK_RUN_NAME": ex.run.RunSpec.RunName, "DSTACK_REPO_ID": ex.run.RunSpec.RepoId, "DSTACK_REPO_DIR": ex.repoDir, + "DSTACK_WORKING_DIR": ex.jobWorkingDir, "DSTACK_NODES_IPS": strings.Join(ex.clusterInfo.JobIPs, "\n"), "DSTACK_MASTER_NODE_IP": ex.clusterInfo.MasterJobIP, "DSTACK_NODE_RANK": strconv.Itoa(node_rank), @@ -864,6 +865,9 @@ func writeDstackProfile(env map[string]string, pth string) error { return err } } + if _, err = file.WriteString("cd \"$DSTACK_WORKING_DIR\"\n"); err != nil { + return err + } if err = os.Chmod(pth, 0o644); err != nil { return err } diff --git a/src/dstack/_internal/server/services/jobs/configurators/base.py b/src/dstack/_internal/server/services/jobs/configurators/base.py index 7eb469865f..039965209c 100644 --- a/src/dstack/_internal/server/services/jobs/configurators/base.py +++ b/src/dstack/_internal/server/services/jobs/configurators/base.py @@ -218,7 +218,15 @@ def _dstack_image_commands(self) -> List[str]: ): return [] return [ - f"uv venv -q --prompt $DSTACK_RUN_NAME --seed -p {self._python()} {DSTACK_DIR}/venv", + # `uv` may emit: + # > warning: `VIRTUAL_ENV=/dstack/venv` does not match the project environment path + # > `.venv` and will be ignored; use `--active` to target the active environment + # > instead + # Safe to ignore, reusing dstack's venv for `uv` is discouraged (it should only be + # used for legacy `pip`-based configurations). `--no-active` suppresses the warning. + # Alternatively, the user can call `deactivate` once before using `uv`. + # If the user really wants to reuse dstack's venv, they must spefify `--active`. + f"uv venv -q --prompt dstack -p {self._python()} --seed {DSTACK_DIR}/venv", f"echo '. {DSTACK_DIR}/venv/bin/activate' >> {DSTACK_PROFILE_PATH}", f". {DSTACK_DIR}/venv/bin/activate", ] From 45102d98de3c6573f14ab5a72b634ac1211a4809 Mon Sep 17 00:00:00 2001 From: Dmitry Meyer Date: Tue, 2 Sep 2025 09:32:00 +0000 Subject: [PATCH 2/2] Fix tests --- src/tests/_internal/server/routers/test_runs.py | 4 ++-- .../_internal/server/services/jobs/configurators/test_task.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/_internal/server/routers/test_runs.py b/src/tests/_internal/server/routers/test_runs.py index c28f5458cd..3361f49e47 100644 --- a/src/tests/_internal/server/routers/test_runs.py +++ b/src/tests/_internal/server/routers/test_runs.py @@ -110,7 +110,7 @@ def get_dev_env_run_plan_dict( "-i", "-c", ( - "uv venv -q --prompt $DSTACK_RUN_NAME --seed -p 3.13 /dstack/venv" + "uv venv -q --prompt dstack -p 3.13 --seed /dstack/venv" " && echo '. /dstack/venv/bin/activate' >> /dstack/profile" " && . /dstack/venv/bin/activate" " && (echo 'pip install ipykernel...'" @@ -314,7 +314,7 @@ def get_dev_env_run_dict( "-i", "-c", ( - "uv venv -q --prompt $DSTACK_RUN_NAME --seed -p 3.13 /dstack/venv" + "uv venv -q --prompt dstack -p 3.13 --seed /dstack/venv" " && echo '. /dstack/venv/bin/activate' >> /dstack/profile" " && . /dstack/venv/bin/activate" " && (echo 'pip install ipykernel...'" diff --git a/src/tests/_internal/server/services/jobs/configurators/test_task.py b/src/tests/_internal/server/services/jobs/configurators/test_task.py index 8e70b2e0d3..6397c40e2c 100644 --- a/src/tests/_internal/server/services/jobs/configurators/test_task.py +++ b/src/tests/_internal/server/services/jobs/configurators/test_task.py @@ -98,7 +98,7 @@ async def test_with_commands_no_image(self, shell: Optional[str], expected_shell expected_shell, "-i", "-c", - "uv venv -q --prompt $DSTACK_RUN_NAME --seed -p 3.12 /dstack/venv" + "uv venv -q --prompt dstack -p 3.12 --seed /dstack/venv" " && echo '. /dstack/venv/bin/activate' >> /dstack/profile" " && . /dstack/venv/bin/activate" " && sleep inf",