diff --git a/backend/fluksio/flow/provision.py b/backend/fluksio/flow/provision.py index 7b3362a..ea4520b 100644 --- a/backend/fluksio/flow/provision.py +++ b/backend/fluksio/flow/provision.py @@ -231,7 +231,6 @@ class SlurmProvisioner: worker = [ "exec fluksio-worker", f"--url {self.engine_url}", - f"--token {token}", f"--cpus {profile.cpus}", f"--gpus {profile.gpus}", f"--max-idle {self.max_idle_s:.0f}", @@ -248,6 +247,10 @@ class SlurmProvisioner: *[f"#SBATCH {option}" for option in profile.sbatch], "", *profile.prerun, + # Not `--token`: argv is in `ps` for every user of a shared node, + # the environment only for the job's owner. Exported after + # `prerun`, so nothing it starts inherits the token. + f"export FLUKSIO_WORKER_TOKEN={token}", " ".join(worker), "", ] diff --git a/backend/tests/flow/test_provision.py b/backend/tests/flow/test_provision.py index c86f736..966d54f 100644 --- a/backend/tests/flow/test_provision.py +++ b/backend/tests/flow/test_provision.py @@ -87,6 +87,9 @@ def test_the_script_starts_a_worker_that_dials_back_and_stops_when_done(monkeypa assert "--labels gpu" in script # Without this the job holds its allocation until the walltime. assert "--max-idle 120" in script + # The token travels in the environment: argv is in `ps` for anyone. + assert "--token" not in script + assert "\nexport FLUKSIO_WORKER_TOKEN=ey" in script def test_one_job_per_profile_however_often_it_is_asked_for(monkeypatch): diff --git a/docs/code/workers.md b/docs/code/workers.md index a62ae7b..3dc235b 100644 --- a/docs/code/workers.md +++ b/docs/code/workers.md @@ -240,6 +240,9 @@ When a node needs a machine nothing attached can give, and a profile fits, the engine `sbatch`es one over the system `ssh`, and the run waits meanwhile, saying so. `prerun` owns the environment: a `module load`, or a venv with `fluksio-worker` already in it. The generated script runs no `pip install`. +It hands the worker a token of its own, good for 24 hours, as +`FLUKSIO_WORKER_TOKEN` rather than `--token`, so other users of a shared +compute node cannot read it from `ps`. One outstanding request per profile, however often it is asked for. A job that never attaches within `provision_timeout_s` is `scancel`led, as is anything