Skip to content

Commit 2be4c1b

Browse files
78cursoragent
andauthored
Fix reproducibility issues with libyuv and improve tenboxd installation (#117)
* fix: pin libyuv to a specific commit to ensure reproducibility - Updated the LIBYUV_REF argument in Dockerfile.jammy to a specific commit to avoid issues with NEON inline assembly in the stable branch that breaks the arm64 build-base. - Modified the git clone command to check out the specified commit, ensuring consistent build outputs across runs. * fix(linux): reload env file on re-install and clean enabled state on remove Two reinforcing bugs prevented `install-linux.sh` from reliably applying /etc/tenbox/tenboxd.env on a re-install: 1. prerm did not call `systemctl disable tenboxd`, so the [Install] symlink under /etc/systemd/system/multi-user.target.wants/ survived `apt-get remove`. The next `apt-get install tenbox` therefore saw is-enabled=true in postinst and ran `deb-systemd-invoke restart` *before* install-linux.sh had a chance to write the env file, leaving the daemon running with empty TENBOX_CLOUD_URL / TENBOX_DATA_DIR and disconnected from the cloud tunnel. 2. install-linux.sh used `systemctl enable --now tenboxd`, which no-ops the start when the daemon is already active — so even after the env file landed, systemd never re-read it. Switched to an explicit `enable + restart` so the freshly written env always wins. Verified end-to-end: purge -> reinstall -> install-linux.sh now prints the my.tenbox.ai/pair?code=... URL on the first try, and the daemon's cmdline carries the correct --cloud-url and --data-dir. docs/linux-update.md documents the new flow plus the existing /run/tenbox/tenbox.sock + tenbox-group permission model. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 8f8748d commit 2be4c1b

5 files changed

Lines changed: 58 additions & 5 deletions

File tree

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.7.8
1+
0.7.9

docs/linux-update.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,36 @@ sudo apt-get install tenbox=0.7.5
7676
The package's `postinst` reloads systemd and bounces `tenboxd` only if
7777
the unit was already enabled — fresh installs are still gated on
7878
`scripts/install-linux.sh` writing `/etc/tenbox/tenboxd.env` and calling
79-
`systemctl enable --now tenboxd`.
79+
`systemctl enable + restart tenboxd` (note: not `enable --now`, because
80+
on a re-install `--now` would no-op when the daemon is already active
81+
and the freshly written env file would never be loaded). Symmetrically,
82+
`prerm` runs `systemctl disable tenboxd` so a subsequent
83+
`apt install tenbox` doesn't see a stale enabled state and start the
84+
daemon before the env file lands.
85+
86+
## Socket permissions and the `tenbox` group
87+
88+
`tenboxd` listens on `/run/tenbox/tenbox.sock`. The deb's `postinst`
89+
creates a system group `tenbox` and a system user `tenbox` (the user
90+
is reserved for a future drop-priv step; today the daemon still runs
91+
as root for `/dev/kvm` and `apt-get`). At startup the daemon:
92+
93+
1. Lets systemd create `/run/tenbox/` mode `0755` (owned `root:root`).
94+
2. After `Listen()` succeeds, reads `TENBOX_SOCKET_GROUP` from the
95+
environment (set to `tenbox` by the unit file), and `chown :tenbox`
96+
+ `chmod 0660` on the socket file itself.
97+
98+
The result mirrors libvirt and docker: the directory is
99+
world-traversable so any user can `stat(2)` the socket and the CLI
100+
can give an honest `permission denied` error rather than a misleading
101+
`no such file`, but only members of the `tenbox` group can `connect(2)`.
102+
The installer adds `$SUDO_USER` to the group automatically; new
103+
shells (or `newgrp tenbox`) pick up the membership.
104+
105+
CLI default-socket lookup is in `client.cpp:DefaultSocketPath()` and
106+
goes: `$TENBOX_SOCK``/run/tenbox/tenbox.sock` (if `/run/tenbox`
107+
exists) → `$XDG_RUNTIME_DIR/tenbox.sock` (per-user dev daemon) →
108+
`/tmp/tenbox-<uid>.sock` (last-resort fallback).
80109

81110
## Stop all VMs first
82111

packaging/build-base/Dockerfile.jammy

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ ENV CXXFLAGS="-O2 -fPIC"
5656
# Pin upstream versions so build outputs are reproducible across runs.
5757
ARG X264_REF=stable
5858
ARG OPUS_VERSION=1.5.2
59-
ARG LIBYUV_REF=stable
59+
# libyuv: pin to a specific commit on main rather than tracking the
60+
# `stable` branch. The stable branch occasionally ships NEON inline
61+
# assembly that jammy's binutils 2.38 rejects (e.g. `ld1 {v4.16b},
62+
# [x3, 80]` without the required `#` on the immediate offset), which
63+
# breaks the arm64 build-base. Pinning a known-good main commit also
64+
# makes the static archive bit-for-bit reproducible across runs.
65+
ARG LIBYUV_REF=b438739c8b08eba2c562a62ea5961f6215d525ed
6066
ARG FFMPEG_VERSION=6.1.1
6167
# libcurl is statically linked into tenboxd. Pinning the version here
6268
# (instead of pulling whatever apt has) means the LLM proxy's HTTP
@@ -94,7 +100,8 @@ RUN curl -fsSL "https://downloads.xiph.org/releases/opus/opus-${OPUS_VERSION}.ta
94100
# cmake_minimum_required is older than what cmake 4 will accept by
95101
# default. The flag tells cmake "treat this project as if it asked for
96102
# at least 3.5 policy semantics" without us having to fork upstream.
97-
RUN git clone --depth 1 --branch ${LIBYUV_REF} https://chromium.googlesource.com/libyuv/libyuv \
103+
RUN git clone https://chromium.googlesource.com/libyuv/libyuv \
104+
&& git -C libyuv checkout ${LIBYUV_REF} \
98105
&& cmake -S libyuv -B libyuv/build -G Ninja \
99106
-DCMAKE_BUILD_TYPE=Release \
100107
-DCMAKE_INSTALL_PREFIX=$DEPS_PREFIX \

packaging/debian/prerm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ case "$1" in
1111
if systemctl is-active --quiet tenboxd 2>/dev/null; then
1212
deb-systemd-invoke stop tenboxd || true
1313
fi
14+
# Drop the [Install] symlinks too. Without this, the unit
15+
# remains `enabled` after `apt-get remove tenbox`, and a
16+
# subsequent fresh `apt install tenbox` would have postinst
17+
# see is-enabled=true and call `deb-systemd-invoke restart`
18+
# *before* install-linux.sh has had a chance to write
19+
# /etc/tenbox/tenboxd.env, leaving the daemon running with
20+
# empty TENBOX_CLOUD_URL / TENBOX_DATA_DIR.
21+
if systemctl is-enabled --quiet tenboxd 2>/dev/null; then
22+
systemctl disable tenboxd >/dev/null 2>&1 || true
23+
fi
1424
;;
1525
esac
1626

scripts/install-linux.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,15 @@ enable_systemd() {
179179
# but deliberately does not enable it, because the env file above
180180
# is what makes the unit actually safe to launch with the right
181181
# cloud URL / data dir.
182+
#
183+
# `enable --now` would only `start` (not `restart`) the service,
184+
# which is fine on a brand-new install. But on a re-install the
185+
# daemon may already be active from a previous run; in that case
186+
# `--now` becomes a no-op and the freshly written env file is
187+
# ignored. Force a restart so the new env always wins.
182188
systemctl daemon-reload
183-
systemctl enable --now tenboxd
189+
systemctl enable tenboxd >/dev/null
190+
systemctl restart tenboxd
184191
}
185192

186193
await_pair_url() {

0 commit comments

Comments
 (0)