Applies a resolved Rez context to each task through per-tool shim scripts that run each tool inside that context.
No longer recommended. rez_queue_env.yaml now runs each task in the resolved context with Open Job Description wrap actions, which gives the same result without shims. This environment predates wrap actions and is kept for reference.
It targets Rez packages that configure software with anything other than plain environment variables. Studios commonly hit this when a package defines an alias for a launcher, relies on a shell function, or prepends to PATH expecting its own binary to shadow a system one.
| File | Purpose |
|---|---|
rez_queue_env_shim.yaml |
The queue environment to deploy on a farm |
rez_demo_setup_queue_env.yaml |
Test scaffolding: installs Rez and builds a demo package so the shim environment can run on a worker that has neither |
demo_job_bundle/template.yaml |
A job that calls a Rez tool by bare name and verifies environment fidelity |
Only the first file belongs on a production queue. The other two exist to demonstrate and test it.
The limitation is structural. A queue environment action runs in its own subprocess, so without wrap actions the only way it can affect later actions is by printing openjd_env: NAME=value directives. An environment that works within that activates a context and then replays the difference between the environment before and after. That round trip drops anything that is not a name-value pair.
A Rez alias is the clearest casualty. Rez implements it as an exported shell function, which Bash exports under a name like BASH_FUNC_launch%% with a multi-line value. The session runtime rejects that assignment outright:
openjd_env: "BASH_FUNC_demoalias%%=() { demorender --via-alias \"$@\"\n}"
-- ERROR: Failed to parse environment variable assignment.
The alias is gone before any task runs.
onEnter resolves the requested packages once and saves the context to a .rxt file in the session directory. It then asks Rez which executables those packages provide and writes one small shim per tool, prepending the shim directory to PATH:
#!/usr/bin/env bash
exec rez env --input "$REZ_CONTEXT_FILE" --shell bash -- "/abs/path/to/tool" "$@"Job templates keep calling tools by bare name, such as command: mayapy, so each call re-enters the saved context in its own shell and Rez applies the full context inside the task's own process. Job bundles don't need changes.
Tool names come from rez context -t on the saved context, so no list of executables is hard-coded. Set RezExtraTools for commands a package provides without declaring them in its tools list.
When the environment writes a tool's shim, it resolves the tool to an absolute path with command -v inside the context, and the shim calls that path at task time. The reason is a recursion risk. By default Rez rebuilds PATH from the context and drops the shim directory, so a bare name is safe. On a farm whose Rez config lists PATH in parent_variables, though, the shim directory stays ahead of the package's own bin, and a bare name would find the shim again and fork until the worker ran out of processes. Resolving once up front removes that risk whatever the Rez configuration.
The environment skips the shim for a tool that resolves back into the shim directory or that the context cannot resolve. The environment reports it at startup and tasks fall back to whatever the worker provides.
The shim environment defines these:
| Parameter | Default | Purpose |
|---|---|---|
RezPackages |
"" |
Space-separated packages to resolve. Empty skips the environment |
RezRepositories |
REZ_REPOSITORY_PATH |
Colon-separated package search path. Edit the per-platform defaults in the script for your farm |
RezExtraTools |
"" |
Extra command names to shim, for tools a package does not declare |
The demo setup environment and job add these:
| Parameter | Default | Purpose |
|---|---|---|
RezDemoRepository |
/tmp/rez-demo-repository |
Where to build the demo package. Pass the same value as RezRepositories |
ToolName |
demorender |
The command the first demo step invokes by bare name |
CancelSleepSeconds |
600 |
How long CancelThroughShim sleeps while you cancel the job |
Edit LINUX_REZ_REPOSITORY_PATH and MACOS_REZ_REPOSITORY_PATH in rez_queue_env_shim.yaml to your repository location, then create the queue environment:
aws deadline create-queue-environment \
--farm-id FARM_ID \
--queue-id QUEUE_ID \
--priority 2 \
--template-type YAML \
--template file://queue_environments/rez_shim/rez_queue_env_shim.yamlGive it a higher priority number than any other environment that edits PATH, such as a Conda environment, because the environment entered last makes the final change to PATH.
Workers need Rez installed and read access to the package repository. Service-managed fleet images don't include either by default.
rez_demo_setup_queue_env.yaml installs Rez and builds a demotool package into the session. The shim environment then runs against it unmodified. Apply both environments in order:
openjd run queue_environments/rez_shim/demo_job_bundle/template.yaml \
--environment queue_environments/rez_shim/rez_demo_setup_queue_env.yaml \
--environment queue_environments/rez_shim/rez_queue_env_shim.yaml \
-p RezDemoRepository=/tmp/rez-demo-repository \
-p RezPackages=demotool \
-p RezRepositories=/tmp/rez-demo-repository \
--step VerifyEnvironmentPass the same directory as the setup environment's RezDemoRepository and the shim environment's RezRepositories.
To run it on a queue, attach the setup environment at a lower priority number than the shim environment and submit with the same parameters:
deadline bundle submit queue_environments/rez_shim/demo_job_bundle \
-p RezDemoRepository=/tmp/rez-demo-repository \
-p RezPackages=demotool \
-p RezRepositories=/tmp/rez-demo-repositoryThe demo needs a fleet of Linux or macOS workers with python3 and network access to PyPI. A production farm provides Rez on the worker image and does not need the setup environment at all.
RunRezTool calls demorender by bare name, so the shim is what runs. VerifyEnvironment then runs three checks and fails the task if any regress:
| Check | State under test | Under harvest-and-replay |
|---|---|---|
| 1 | A plain variable, DEMOTOOL_VERSION |
Survives |
| 2 | A Rez alias, which becomes an exported shell function |
Lost, rejected by the runtime |
| 3 | A PATH prepend where the package provides its own sort |
Depends on environment order rather than the resolved context |
All three checks read their results from a tool called by bare name. That tests the shim mechanism end to end, not only the saved context. Deleting the PATH injection from the environment fails all three, which is how the checks were confirmed to test what they claim.
A third step, CancelThroughShim, is a manual check rather than an automatic one. It sleeps inside a shimmed tool for CancelSleepSeconds so you can cancel the job and watch the signal arrive. The tool reports the signal it caught before exiting. Cancel it from the monitor or with:
aws deadline update-job --farm-id FARM_ID --queue-id QUEUE_ID \
--job-id JOB_ID --target-task-run-status CANCELEDExpect the step to end as CANCELED with demosleep: caught SIGTERM, exiting in the session log. Left alone it simply runs to completion.
A successful session log shows the variable absent from the session but present inside the tool, then all three checks passing:
=== DEMOTOOL_VERSION as seen by the session (expected UNSET) ===
DEMOTOOL_VERSION=UNSET
=== DEMOTOOL_VERSION as seen inside the tool (expected 1.0.0) ===
demorender: DEMOTOOL_VERSION=1.0.0
=== Check 1: plain variable reaches the tool ===
PASS: variable visible inside the tool
=== Check 2: Rez alias survives into the task ===
PASS: alias is callable
=== Check 3: package PATH prepend shadows the system command ===
PASS: package command shadows the system one
All 3 environment fidelity checks passed.
An environment that copies variables with openjd_env instead shows the runtime refusing the alias, which is the failure this environment avoids.
- Only bare command names are intercepted. A template invoking an absolute path bypasses the shims.
- Linux and macOS workers only. The shims are POSIX shell scripts that depend on a shebang line, which does not work on Windows. On Windows the environment fails immediately with a message pointing at the alternative. rez_queue_env.yaml supports Windows workers.
- Each task pays a context re-entry. Rez's resolve cache reduces this cost but doesn't remove it.
Cancelation does reach through a shim. Rez runs the tool in a shell of its own, so the process tree is shim → rez env → shell → tool rather than flat, but a SIGTERM sent to the top process propagates to the tool and no orphans are left behind. Verified on a Linux service-managed fleet worker: canceling the CancelThroughShim step below produced
INTERRUPT: Sending signal "term" to process 39247
demosleep: caught SIGTERM, exiting
Applications that install their own signal handlers still get the chance to shut down cleanly. Give cancelation a NOTIFY_THEN_TERMINATE mode in your step if a tool needs a grace period.
This environment was a workaround from before the WRAP_ACTIONS extension in RFC 0008: Environment Wrap Actions. With that extension, a queue environment wraps each task's command directly instead of exporting variables to it, which removes the shim directory, the PATH manipulation, and the tradeoffs above. rez_queue_env.yaml takes that approach.
The Rez installation, the .rxt context, and the shims are written under the session working directory and removed with the session. The demo package repository is not: it is created at RezDemoRepository, which defaults to /tmp/rez-demo-repository and persists on the worker until the instance is replaced. Delete it if you are testing on a long-lived worker, and detach the setup environment when finished.