Pin Docker desktop package versions

Pin the Python 3.13-compatible LibreOffice and Xpra releases used by the last successful multi-architecture build. Use Kali's last snapshot and remove beta probing so repository updates cannot pull Python 3.14 into ready images.

Alessandro committed Aug 19, 2026 at 13:30 UTC d52a1692c13993146b7673ef124a0f845567db8d
3 files changed +50 -65
docker/run/AGENTS.md
+1
@@ -19,6 +19,7 @@
19 - `BRANCH` is required for branch-based Docker builds.
20 - Preserve exposed ports for SSH, HTTP, and tunneled services unless docs and workflows are updated together.
21 - Keep the two-runtime Python model aligned with the root contract.
22 +- Keep runtime desktop packages on `kali-last-snapshot`; pin the verified Python 3.13-compatible LibreOffice and Xpra versions in `fs/ins/install_additional.sh` for both published architectures.
23 - Do not bake secrets, local `.env` values, or user data into the image.
24 - Runtime startup must ensure `/a0/usr/uploads` exists before supervised services start.
25 - Runtime startup raises the soft open-file limit toward `A0_NOFILE_LIMIT` (default `65535`) before supervisord starts, bounded by the container hard limit.
docker/run/fs/ins/install_additional.sh
+33 -64
@@ -12,80 +12,49 @@ if ! command -v apt-get >/dev/null 2>&1; then
12 exit 0
13 fi
14
15 -XPRA_PACKAGES=(xpra xpra-x11 xpra-html5)
15 +KALI_SUITE="kali-last-snapshot"
16 +LIBREOFFICE_VERSION="4:26.2.4.2-1"
17 +XPRA_VERSION="6.5.2-r0-1"
18 +arch="$(dpkg --print-architecture)"
19
17 -install_xpra_repo() {
18 - local os_id=""
19 - local codename=""
20 - local uri="https://xpra.org"
21 - local suite="trixie"
22 - local arch
23 -
24 - arch="$(dpkg --print-architecture 2>/dev/null || echo amd64)"
25 -
26 - if [ -r /etc/os-release ]; then
27 - # shellcheck disable=SC1091
28 - . /etc/os-release
29 - os_id="${ID:-}"
30 - codename="${VERSION_CODENAME:-}"
31 - fi
32 -
33 - if [ "$os_id" = "kali" ]; then
34 - uri="https://xpra.org/beta"
35 - suite="sid"
36 - elif [ "$codename" = "sid" ] || [ "$codename" = "forky" ]; then
37 - uri="https://xpra.org/beta"
38 - suite="$codename"
39 - elif [ -n "$codename" ]; then
40 - suite="$codename"
41 - fi
42 -
43 - apt-get update
44 - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates wget
45 - configure_xpra_repo "$uri" "$suite" "$arch"
46 - apt-get update
47 -
48 - if ! xpra_install_check; then
49 - echo "xpra packages are not installable from ${uri} ${suite} for ${arch}; falling back to https://xpra.org trixie"
50 - XPRA_PACKAGES=(xpra-server xpra-x11 xpra-html5)
51 - configure_xpra_repo "https://xpra.org" "trixie" "$arch"
52 - apt-get update
53 - if ! xpra_install_check; then
54 - cat /tmp/xpra-install-check.log
55 - exit 1
56 - fi
57 - fi
58 -}
20 +XPRA_HTML5_VERSION="19-r1-1"
21 +if [ "$arch" = "arm64" ]; then
22 + XPRA_HTML5_VERSION="21-r1-1"
23 +fi
24
60 -xpra_install_check() {
61 - DEBIAN_FRONTEND=noninteractive apt-get install -s --no-install-recommends "${XPRA_PACKAGES[@]}" >/tmp/xpra-install-check.log 2>&1
62 -}
25 +LIBREOFFICE_PACKAGES=(
26 + "libreoffice-core=$LIBREOFFICE_VERSION"
27 + "libreoffice-writer=$LIBREOFFICE_VERSION"
28 + "libreoffice-calc=$LIBREOFFICE_VERSION"
29 + "libreoffice-impress=$LIBREOFFICE_VERSION"
30 + "libreoffice-gtk3=$LIBREOFFICE_VERSION"
31 + "python3-uno=$LIBREOFFICE_VERSION"
32 +)
33 +XPRA_PACKAGES=(
34 + "xpra-common=$XPRA_VERSION"
35 + "xpra-server=$XPRA_VERSION"
36 + "xpra-x11=$XPRA_VERSION"
37 + "xpra-html5=$XPRA_HTML5_VERSION"
38 +)
39
64 -configure_xpra_repo() {
65 - local uri="$1"
66 - local suite="$2"
67 - local arch="$3"
40 +for source in /etc/apt/sources.list /etc/apt/sources.list.d/kali.sources; do
41 + [ ! -f "$source" ] || sed -i "s/kali-rolling/$KALI_SUITE/g" "$source"
42 +done
43
69 - wget -O /usr/share/keyrings/xpra.asc https://xpra.org/xpra.asc
70 - cat >/etc/apt/sources.list.d/xpra.sources <<EOF
44 +apt-get update
45 +DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates wget
46 +wget -O /usr/share/keyrings/xpra.asc https://xpra.org/xpra.asc
47 +cat >/etc/apt/sources.list.d/xpra.sources <<EOF
48 Types: deb
72 -URIs: ${uri}
73 -Suites: ${suite}
49 +URIs: https://xpra.org
50 +Suites: trixie
51 Components: main
52 Signed-By: /usr/share/keyrings/xpra.asc
76 -Architectures: ${arch}
53 +Architectures: $arch
54 EOF
78 -}
79 -
80 -install_xpra_repo
55 apt-get update
56 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
83 - libreoffice-core \
84 - libreoffice-writer \
85 - libreoffice-calc \
86 - libreoffice-impress \
87 - libreoffice-gtk3 \
88 - python3-uno \
57 + "${LIBREOFFICE_PACKAGES[@]}" \
58 "${XPRA_PACKAGES[@]}" \
59 xfce4-session \
60 xfwm4 \
tests/test_browser_agent_regressions.py
+16 -1
@@ -2356,10 +2356,25 @@ def test_browser_docker_installs_full_chromium_to_tmp_cache():
2356 assert '"windowState": "fullscreen"' not in runtime
2357 assert "self.interactive_view.ensure_display()" in runtime
2358 assert " xvfb \\" in install_additional
2359 - assert "XPRA_PACKAGES=(xpra xpra-x11 xpra-html5)" in install_additional
2359 assert " xdotool \\" in install_additional
2360
2361
2362 +def test_browser_docker_pins_python_313_compatible_desktop_packages():
2363 + install_additional = (
2364 + PROJECT_ROOT / "docker" / "run" / "fs" / "ins" / "install_additional.sh"
2365 + ).read_text(encoding="utf-8")
2366 +
2367 + assert 'KALI_SUITE="kali-last-snapshot"' in install_additional
2368 + assert 'LIBREOFFICE_VERSION="4:26.2.4.2-1"' in install_additional
2369 + assert 'XPRA_VERSION="6.5.2-r0-1"' in install_additional
2370 + assert 'XPRA_HTML5_VERSION="19-r1-1"' in install_additional
2371 + assert 'XPRA_HTML5_VERSION="21-r1-1"' in install_additional
2372 + assert '"python3-uno=$LIBREOFFICE_VERSION"' in install_additional
2373 + assert '"xpra-server=$XPRA_VERSION"' in install_additional
2374 + assert '"xpra-html5=$XPRA_HTML5_VERSION"' in install_additional
2375 + assert "https://xpra.org/beta" not in install_additional
2376 +
2377 +
2378 def test_browser_startup_migration_prepares_current_playwright_binary():
2379 extension = (
2380 PROJECT_ROOT