360 Secure SkillHub
360 安全技能中心

rez-suites-bundles

介绍 Rez 3.4 的 suite 与 context bundle。rez-suite 把多个 resolve 的上下文及包装脚本组织成一个 bin 目录,通过别名、前后缀、隐藏和 bump 处理工具冲突,支持 ++help、++patch 等控制参数,并提供 Suite API。rez-bundle / bundle_context() 将上下文及其包仓库复制为可相对引用的目录,便于分发到渲染农场、容器或离线机器。输入为 .rxt 文件,输出为 suite 目录或 bundle 目录。

loonghao
loonghao
热度 13.68
最近更新 2026-10-02 04:58:23
分类:开发依赖:代码执行 / 读写文件应用场景:DevOps / 工作流

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add rez-suites-bundles
Metadata
name
rez-suites-bundles
description
Rez suites and context bundles — rez-suite to expose tools from several contexts behind one PATH entry, suite tool aliasing, prefixing, hiding, bumping and control arguments (++help, ++about, ++patch, ++peek), and rez-bundle / bundle_context() to package a resolve with its packages into a relocatable directory. Use when the user wants to ship a resolved environment to artists, a render farm, a container or another machine. Covers Rez 3.4.0.

Rez suites and context bundles

One-sentence summary: a suite is a directory of contexts plus wrapper scripts that makes tools from different resolves look like one PATH entry; a context bundle is a directory that carries the context and its packages, so the whole thing can be moved somewhere else.

Skill scope: delivering a resolve to somewhere other than your own shell. For the resolve itself see rez-resolve; for the objects these commands are built on see rez-python-api; for the command reference see rez-cli.

Which one do I want?

Suite Context bundle
Holds contexts + wrapper scripts one context + its packages
Packages stay where they are yes — absolute refs to shared repos no — copied into the bundle, refs become relative
Relocatable no yes
Typical use artist workstations, PATH entry farm, container, server, air-gapped copy
Built by rez-suite rez-bundle

Suites

A suite is a directory containing a set of contexts and wrapper scripts that run tools within those contexts. Put its bin directory on PATH and foo resolves to the wrapper, which resolves to the right context — the artist never has to know.

Building one

rez-env foo -o foo.rxt
rez-suite --create mysuite
rez-suite --add foo.rxt --context fooCtx mysuite
export PATH=$PWD/mysuite/bin:$PATH

--add copies the context into mysuite/contexts/<name>.rxt, and --context is the label it gets inside the suite. The label is what every other context-scoped option refers to, so name it after what the context is for, not after the file you happened to save it as.

rez-suite flags

Flag Effect
--create create an empty suite at DIR
-a, --add RXT add a context to the suite (needs --context)
-c, --context NAME which context a context-scoped option applies to
-r, --remove NAME remove a context
-d, --description DESC set a context's description
-p, --prefix PREFIX / -s, --suffix SUFFIX prefix/suffix every tool in the context
--hide TOOL / --unhide TOOL hide or expose one tool
--alias TOOL ALIAS / --unalias TOOL give one tool a different name
-b, --bump NAME raise a context's priority so its tools win
-P, --prefix-char CHAR change the control-argument prefix (default +; "" disables)
-t, --tools list the tools the suite exposes
--which TOOL print the path of a suite wrapper
-l, --list list visible suites
--validate check the suite is internally consistent
--find-request PKG / --find-resolve PKG which contexts contain PKG in the request / the resolve
-i, --interactive open a shell in a suite context (needs --context)

Which tools get exposed

A suite exposes the tools attribute of the packages in a context's requests. Three rules follow from that, and they explain most "my tool is missing" reports:

  • Packages pulled in as dependencies do not expose their tools.
  • Weak references (~foo-1) and conflict requests (!foo) do not expose their tools.
  • If two contexts expose the same tool name, one is a conflict; --bump, aliasing or prefixing resolves it.

Prefixing and suffixing are the cheap way to offer the same tool from two contexts at once:

rez-suite --add foo2017.rxt --context foo2017 mysuite
rez-suite --suffix _beta --context foo2017 mysuite
rez-suite --tools mysuite

That gives you foo from the stable context and foo_beta from the new one.

Control arguments

Suite wrappers pass their arguments through to the real tool, except for rez's own control arguments, which use + instead of -:

foo ++help
foo ++about
foo ++versions
foo +i
foo +p bar-2
foo ++peek
foo ++command 'printenv FOO_VERSION'
foo ++no-rez-args --not-a-rez-flag
Control arg Meaning
+h, ++help wrapper usage
+a, ++about which suite, context and package the wrapper comes from
++versions versions of the package providing the tool
+i, ++interactive interactive shell in the tool's environment
+p, ++patch PKG... run the tool in a patched environment
++strict strict patching (ignored without ++patch)
++nl, ++no-local do not load local packages when patching
++command, ++stdin run commands instead of the tool
++peek diff the tool's context against a re-resolve — how stale it is
++verbose, ++quiet output control
++no-rez-args pass everything through, even + args

If a target tool uses + for its own arguments, change rez's prefix with --prefix-char.

The Suite object

from rez.suite import Suite
from rez.resolved_context import ResolvedContext

suite = Suite()
suite.add_context(name="fooCtx", context=ResolvedContext.load("foo.rxt"))
suite.save("mysuite")

reloaded = Suite.load("mysuite")
reloaded.context_names                 # ['fooCtx']
reloaded.set_context_suffix("fooCtx", "_beta")
reloaded.validate()                    # raises rez.exceptions.SuiteError when broken

context_names lists the labels, tools_path is the bin directory to put on PATH, get_tools() is the alias-to-tool mapping, and Suite.print_info() dumps the whole thing.

Context bundles

A context bundle is a directory holding a context and a package repository containing every package the context uses. Package references in the .rxt become relative, which is what makes the bundle relocatable — copy it to a server, a container or a USB stick and nothing points back at your shared storage.

rez-env foo -o foo.rxt
rez-bundle foo.rxt ./mybundle

The result:

.../mybundle/
   ./context.rxt
   ./packages/
      <standard package repository layout>

Run something out of it by pointing rez-env at the bundled context:

rez-env -i ./mybundle/context.rxt -- foo-tool

rez-bundle flags

Flag Effect
-s, --skip-non-relocatable leave non-relocatable packages where they are instead of failing
-f, --force bundle anyway, even when a package says it cannot be relocated
-n, --no-lib-patch skip the library-patching step
-v, --verbose verbose mode

-s, -f and -n all sit in one mutually exclusive group: pass at most one of them.

Library patching

A compiled library inside a package can carry an absolute rpath/runpath to a library in another package, which would silently resolve outside the bundle. Bundling rewrites those references to $ORIGIN-relative paths pointing at the copy inside the bundle, and the step is platform-specific (linux rewrites ELF headers with patchelf). References that have no equivalent inside the bundle — a system library, say — are left alone, which is why a bundle is rarely completely hermetic.

The bundle API

from rez.bundle_context import bundle_context
from rez.resolved_context import ResolvedContext

context = ResolvedContext(["foo-1"])
bundle_context(context, "./mybundle", force=True)

bundle_context(context, dest_dir, force=False, skip_non_relocatable=False, quiet=False, patch_libs=False, verbose=False) is the same operation as rez-bundle; note that the CLI passes patch_libs=True unless you give it --no-lib-patch, while the API default is off.

Troubleshooting

Symptom Check
A tool is missing from the suite was it in the request? dependencies and weak refs expose nothing
Two tools fight rez-suite --tools; fix with --bump, --alias or --prefix/--suffix
Wrappers ignore your suite after an edit re-run rez-suite --validate; wrappers are regenerated on save
The tool uses + itself rez-suite --prefix-char
rez-bundle refuses a package relocatable is off; decide between -s (skip it) and -f (force it)
A bundled tool loads a library from outside library patching; check the platform and drop -n
Bundle works here, not there the bundle is only as portable as its payloads; check --validate and --peek

Agent workflow

  1. Decide first: shared disk and many tools means a suite; anywhere-but-here means a bundle.
  2. For a suite, build the contexts with rez-env ... -o, then add them one at a time with rez-suite --add ... --context <name>.
  3. Confirm exposure with rez-suite --tools before telling anyone to put bin on PATH.
  4. For a bundle, resolve, bundle, then run the bundled context — a bundle you have not executed is a guess.
  5. Re-check both with rez-suite --validate and rez-context context.rxt --so after a package changes.