Skip to content

Commit 18639f1

Browse files
committed
fix: keep the Blender prefix world-readable, and report what actually failed
Three findings from running the sample end to end in a container, which is what the new workflow does. All three were caught by that workflow rather than reasoned about, which is the argument for having it. The staged extraction introduced earlier in this branch made the prefix root-only. mktemp -d creates a directory 0700 and mv preserves that, where the mkdir it replaced took 0755 from the umask, so the artist could not traverse /opt/blender and the add-on step failed with "Permission denied". Blender is a system-wide install every user runs, so the staging directory is widened before the move. The add-on step then discarded Blender's output and reported only "failed to enable the Blender add-on", which is how the permission error stayed invisible for a run. Both the enable and the verify step now report what Blender said. The library list the workflow installs was derived rather than guessed, and the last of it took four rounds to find, because qtpy reports any failure to import PySide6 as "No Qt bindings could be found" -- so a missing libglib, then a missing libfontconfig, then the missing xcb platform libraries all present as a missing PySide6 that is in fact bundled and present. The final list comes from the closure of unresolved libraries across the installed tree under ldd. The sample's README documents the whole set and how to diagnose it, since a customer on a minimal image hits exactly this and the message points the wrong way. Verified: exit 0 with all eight independent assertions passing -- Blender runs, the add-on reads back from Blender's preferences as the artist, the CLI is on the artist's login PATH, the profile has the right region, a non-empty monitor_id and artist ownership, and auth status reports NEEDS_LOGIN -- and a second run also exits 0, which exercises the prefix guard and staged extract on a re-run. Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
1 parent a00b7fb commit 18639f1

3 files changed

Lines changed: 57 additions & 12 deletions

File tree

.github/workflows/virtual_workstation_checks.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,22 @@ jobs:
7171
steps:
7272
# A container job has no git for actions/checkout, and the sample documents
7373
# a desktop environment as a prerequisite it deliberately does not install.
74-
# Blender's X11 and GL libraries stand in for that here: this is CI setup,
75-
# not something the sample should be doing on a real workstation.
74+
# These libraries stand in for that desktop: this is CI setup, not something
75+
# the sample should be doing on a real workstation.
76+
#
77+
# The list was derived empirically -- run the script, read what failed, and
78+
# take the closure of unresolved libraries across the installed tree with
79+
# ldd -- rather than guessed. Three groups, for two different consumers:
80+
#
81+
# * Blender's own X11 and GL dependencies, without which it cannot exec.
82+
# * GLib, fontconfig, and freetype, for the PySide6 the submitter bundles.
83+
# * The xcb platform libraries that PySide6's Qt platform plugin needs.
84+
#
85+
# The Qt group is worth knowing about beyond CI: when any of it is missing,
86+
# the add-on's import chain reaches qtpy, which reports the underlying
87+
# ImportError as "No Qt bindings could be found" -- a message that sends you
88+
# looking for a missing PySide6 that is in fact present and bundled. The
89+
# sample's README documents this under Troubleshooting.
7690
- name: Install the prerequisites the sample documents
7791
run: |
7892
set -euo pipefail
@@ -81,7 +95,11 @@ jobs:
8195
apt-get install -y -qq --no-install-recommends \
8296
git sudo ca-certificates \
8397
libx11-6 libxi6 libxxf86vm1 libxfixes3 libxrender1 libxext6 \
84-
libxkbcommon0 libsm6 libice6 libgl1 libegl1 libglu1-mesa libdbus-1-3
98+
libxkbcommon0 libsm6 libice6 libgl1 libegl1 libglu1-mesa libdbus-1-3 \
99+
libglib2.0-0 libfontconfig1 libfreetype6 \
100+
libxkbcommon-x11-0 libxcb-cursor0 libxcb-icccm4 libxcb-image0 \
101+
libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 \
102+
libxcb-xkb1
85103
86104
- name: Check out repository
87105
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

utility_scripts/virtual_workstation/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,22 @@ Remove-Item -Recurse -Force "C:\Program Files\Blender"
174174

175175
Runs interrupted after this point do not recur: Blender is now unpacked to a staging directory beside the prefix and moved into place, so the prefix only ever exists complete.
176176

177+
**The add-on step fails with `qtpy.QtBindingsNotFoundError: No Qt bindings could be found`.** The bindings are present: the submitter bundles PySide6. That message is `qtpy` reporting an `ImportError` it could not attribute, and the real cause is a system library that PySide6 links against and this image does not have. On a minimal Ubuntu 22.04 image, this is the set:
178+
179+
```console
180+
sudo apt-get install -y libglib2.0-0 libfontconfig1 libfreetype6 \
181+
libxkbcommon-x11-0 libxcb-cursor0 libxcb-icccm4 libxcb-image0 \
182+
libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xkb1
183+
```
184+
185+
To see the actual cause rather than the `qtpy` summary, run `ldd` over the bundled Qt and look for `not found`:
186+
187+
```console
188+
ldd /opt/DeadlineCloudSubmitter/Submitters/Blender/python/modules/PySide6/QtCore.abi3.so | grep "not found"
189+
```
190+
191+
Ignore the `libQt6*.so.6` entries there: those resolve within the bundle at load time. A full desktop environment provides all of these, which is why this only appears on an image that has none. It is the same class of failure as Blender's own missing X11 and GL libraries, which the script reports directly.
192+
177193
**The Deadline Cloud menu is missing in Blender.** Add-ons register per user, so confirm the script ran for the account that is signing in. On Linux that is the second argument. On Windows it is the account that ran the script. To check, as that same user:
178194

179195
```console

utility_scripts/virtual_workstation/setup_workstation_linux.sh

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ tar -xJf "$WORK_DIR/$blender_archive" -C "$blender_staging" --strip-components=1
254254
[[ -x "$blender_staging/blender" ]] \
255255
|| die "the Blender archive did not contain a blender executable"
256256

257+
# mktemp -d creates the directory 0700 and mv preserves that, which would leave
258+
# every account but root unable to even traverse the prefix -- so the artist's
259+
# add-on step would fail with "Permission denied". Blender is a system-wide
260+
# install that every user runs, so widen it to the 0755 that mkdir would have
261+
# produced under the usual umask.
262+
chmod 755 "$blender_staging"
263+
257264
# Replace any previous install so re-runs are clean. Only ever delete a directory
258265
# this script created: BLENDER_PREFIX is a constant an administrator edits, and
259266
# removing it unconditionally as root would destroy whatever it names.
@@ -340,18 +347,22 @@ log "submitter installed at $SUBMITTER_PREFIX"
340347
addon_script="$SUBMITTER_PREFIX/Submitters/Blender/add_submitter_to_pref.py"
341348
addon_path="$SUBMITTER_PREFIX/Submitters/Blender/python"
342349

350+
# Capture the output and report it on failure. Discarding it leaves the operator
351+
# with "failed to enable the Blender add-on" and nothing to act on, when the
352+
# actual cause is in the message -- a prefix the artist cannot execute, say.
343353
log "enabling the Blender add-on for $WORKSTATION_USER"
344-
runuser -u "$WORKSTATION_USER" -- env HOME="$USER_HOME" \
345-
"$BLENDER_PREFIX/blender" --background --python "$addon_script" \
346-
-- --deadline_cloud_install_path "$addon_path" >/dev/null \
347-
|| die "failed to enable the Blender add-on"
354+
addon_output="$(
355+
runuser -u "$WORKSTATION_USER" -- env HOME="$USER_HOME" \
356+
"$BLENDER_PREFIX/blender" --background --python "$addon_script" \
357+
-- --deadline_cloud_install_path "$addon_path" 2>&1
358+
)" || die "failed to enable the Blender add-on: $addon_output"
348359

349360
# Confirm from Blender's preferences rather than trusting the exit code.
350-
runuser -u "$WORKSTATION_USER" -- env HOME="$USER_HOME" \
351-
"$BLENDER_PREFIX/blender" --background --python-expr \
352-
'import bpy, sys; sys.exit(0 if "deadline_cloud_blender_submitter" in bpy.context.preferences.addons.keys() else 1)' \
353-
>/dev/null 2>&1 \
354-
|| die "the Blender add-on did not register in $WORKSTATION_USER's preferences"
361+
verify_output="$(
362+
runuser -u "$WORKSTATION_USER" -- env HOME="$USER_HOME" \
363+
"$BLENDER_PREFIX/blender" --background --python-expr \
364+
'import bpy, sys; sys.exit(0 if "deadline_cloud_blender_submitter" in bpy.context.preferences.addons.keys() else 1)' 2>&1
365+
)" || die "the Blender add-on did not register in $WORKSTATION_USER's preferences: $verify_output"
355366
log "Blender add-on enabled"
356367

357368
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)