mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-08-22 12:53:32 +02:00
fix(collabora): pin BUILD_FROM per arch and restore the payload capabilities
build.json named the multi-arch collabora/code:latest for both architectures. The builder never passes --platform -- it runs each architecture on its own native runner -- so BUILD_FROM is the only thing selecting which binaries end up in the add-on. That resolves correctly today only because the runner architecture happens to match the target. Name collabora/code:latest-amd64 and collabora/code:latest-arm64, which are published in lockstep with latest. The official image sets file capabilities on two binaries, and COPY --from does not carry extended attributes, so they arrived stripped: coolforkit-caps cap_chown,cap_fowner,cap_sys_chroot=ep coolmount cap_sys_admin=ep Without them coolwsd starts and serves the admin console, but cannot chroot a kit process, so no document ever opens. Reapply and verify them. Replace the smoke test, which is why the build is currently red: coolwsd refuses to run as root (exit 78), and --version does not exit anyway, since the official entrypoint passes it to the long-running server. Check instead that every binary resolves its libraries against the Debian base. For ssl: true, hand Collabora the certificate copies in /etc/coolwsd rather than /ssl. coolwsd runs as uid 1001 and a private key in /ssl is commonly root-only, so it could not be read; the copies were already being made and chowned, but nothing pointed at them. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
|
||||
## 26.04.2.4.1 (2026-07-26)
|
||||
- Rebuild on a Debian base: upstream turned collabora/code into a distroless image with no shell, which broke the addon build entirely. collabora/code:latest stays the tracked upstream image in build.json, but is now a build stage whose payload is copied onto ghcr.io/hassio-addons/debian-base, and the addon ships its own launcher in place of the removed /start-collabora-online.sh
|
||||
- Rebuild on a Debian base: upstream turned collabora/code into a distroless image with no shell, which broke the addon build entirely. collabora/code stays the tracked upstream image in build.json, but is now a build stage whose payload is copied onto ghcr.io/hassio-addons/debian-base, and the addon ships its own launcher in place of the removed /start-collabora-online.sh
|
||||
- build.json names the architecture explicitly again (`collabora/code:latest-amd64` and `collabora/code:latest-arm64`). The builder never passes `--platform`, so the tag is the only thing that decides which binaries land in the addon
|
||||
- Restore the file capabilities on `coolforkit-caps` and `coolmount`. The official image carries them as extended attributes, which `COPY --from` does not transfer, and without them Collabora starts but cannot open any document
|
||||
- The certificates for `ssl: true` are read from the copies in /etc/coolwsd rather than from /ssl directly, which Collabora could not read as uid 1001 when the private key is root-only
|
||||
- Fix version numbering: releases on CollaboraOnline/online are now Helm charts only, which had renumbered the addon from 25.4.9.2 down to 1.3.0 and hid updates. The version is tracked from the collabora/code Docker Hub tags again
|
||||
- `server_name` is now passed to Collabora, fixing `Your browser has been unable to connect to the Collabora server` behind a reverse proxy
|
||||
- `domain1` was never passed to Collabora at all (the script read a `domain` option that does not exist, and recent Collabora releases dropped that variable). It is now deprecated and applied as `server_name`
|
||||
|
||||
@@ -20,6 +20,16 @@ ARG BUILD_VERSION
|
||||
###############################################################################
|
||||
# Get Collabora Online from the official image (BUILD_FROM, see build.json)
|
||||
#
|
||||
# build.json pins the architecture explicitly, collabora/code:latest-amd64 and
|
||||
# collabora/code:latest-arm64, rather than the multi-arch collabora/code:latest.
|
||||
# The builder never passes --platform: it runs the amd64 build on a native amd64
|
||||
# runner and the aarch64 build on a native arm runner, so the only thing that
|
||||
# decides which Collabora binaries end up in the add-on is this tag. With the
|
||||
# multi-arch tag that happens to resolve correctly, but only for as long as the
|
||||
# runner architecture keeps matching the target, and a mismatch would silently
|
||||
# produce an image full of foreign-architecture binaries. The per-arch tags are
|
||||
# published in lockstep with latest, so nothing is lost by naming them.
|
||||
#
|
||||
# Upstream rebuilt collabora/code as a Nix-based distroless image: /bin and
|
||||
# /sbin are empty, so it can no longer be the base of the add-on itself, as s6,
|
||||
# bashio and every RUN need a shell. It stays the tracked upstream image, and
|
||||
@@ -38,8 +48,12 @@ FROM ${BUILD_FROM} AS collabora
|
||||
###############################################################################
|
||||
FROM ghcr.io/hassio-addons/debian-base:9.3.0
|
||||
|
||||
# Inherited from the base, but declared explicitly: the linkage check below
|
||||
# relies on pipefail to notice a failing ldd.
|
||||
# Inherited from the base, declared here so it is visible to hadolint and to
|
||||
# anyone adding a pipe below. Note that the linkage check does NOT pipe into
|
||||
# grep: with pipefail an ldd that exits non-zero (a binary it cannot handle at
|
||||
# all) would make the pipeline fail even though grep matched, and "if" would
|
||||
# then read that as "no unresolved libraries" -- the one case worth catching.
|
||||
# Capturing the output and matching it with case avoids the question entirely.
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
##################
|
||||
@@ -111,18 +125,55 @@ RUN \
|
||||
rm -rf /etc/coolwsd/proof_key* && \
|
||||
fc-cache /opt/collaboraoffice/share/fonts/truetype > /dev/null 2>&1 || true
|
||||
|
||||
# Fail the build rather than ship an image that cannot start. ha_autoapps.sh is
|
||||
# invoked with "|| true", so a missing package would go unnoticed, and the
|
||||
# binaries were built inside the upstream Nix image against a different libc.
|
||||
# ldd is the right check here: it resolves every NEEDED library against this
|
||||
# base without booting Collabora, which would try to build a jail.
|
||||
# Restore the file capabilities. The official image carries them as extended
|
||||
# attributes on two binaries:
|
||||
# coolforkit-caps cap_chown,cap_fowner,cap_sys_chroot=ep
|
||||
# coolmount cap_sys_admin=ep
|
||||
# COPY --from does not transfer extended attributes, so both arrive stripped.
|
||||
# Nothing about the build notices: coolwsd starts and serves the admin console,
|
||||
# but every document fails to open because it cannot chroot a kit process. Set
|
||||
# them again and check they stuck, so a builder without xattr support fails here
|
||||
# instead of shipping an add-on that only looks like it works.
|
||||
#
|
||||
# cap_sys_admin on coolmount only takes effect if the container is given
|
||||
# SYS_ADMIN, which the add-on does not request; without it Collabora copies its
|
||||
# child roots instead of bind-mounting them, which is slower but works.
|
||||
RUN \
|
||||
setcap "cap_chown,cap_fowner,cap_sys_chroot=ep" /usr/bin/coolforkit-caps && \
|
||||
setcap "cap_sys_admin=ep" /usr/bin/coolmount && \
|
||||
caps="$(getcap /usr/bin/coolforkit-caps /usr/bin/coolmount)" && \
|
||||
case "$caps" in \
|
||||
*cap_sys_chroot*) ;; \
|
||||
*) echo "coolforkit-caps lost its capabilities: ${caps}"; exit 1 ;; \
|
||||
esac && \
|
||||
case "$caps" in \
|
||||
*cap_sys_admin*) ;; \
|
||||
*) echo "coolmount lost its capabilities: ${caps}"; exit 1 ;; \
|
||||
esac
|
||||
|
||||
# Fail the build rather than ship an image that cannot start: ha_autoapps.sh is
|
||||
# invoked with "|| true", and the payload was linked against the libraries of
|
||||
# the distroless image, so both are worth proving here.
|
||||
#
|
||||
# coolwsd itself cannot be executed as a smoke test. It refuses to run as root
|
||||
# ("Do not run as root. Please run as cool user.", exit 78), and --version does
|
||||
# not exit either -- the official entrypoint passes it to the long-running
|
||||
# server to get the version into the log. Checking that every binary resolves
|
||||
# its libraries proves the same thing and terminates.
|
||||
RUN \
|
||||
command -v openssl > /dev/null && \
|
||||
command -v su > /dev/null && \
|
||||
for binary in /usr/bin/coolwsd /usr/bin/coolforkit-ns /usr/bin/coolmount; do \
|
||||
if ldd "$binary" | grep "not found"; then \
|
||||
echo "unresolved shared libraries in $binary" && exit 1; \
|
||||
fi; \
|
||||
for binary in \
|
||||
/usr/bin/coolwsd \
|
||||
/usr/bin/coolforkit-caps \
|
||||
/usr/bin/coolforkit-ns \
|
||||
/usr/bin/coolmount \
|
||||
/opt/collaboraoffice/program/soffice.bin \
|
||||
/opt/collaboraoffice/program/libmergedlo.so; do \
|
||||
libs="$(ldd "$binary" 2>&1)"; \
|
||||
case "$libs" in \
|
||||
*"not found"*) echo "Unresolved libraries in ${binary}:"; echo "$libs"; exit 1 ;; \
|
||||
esac; \
|
||||
done
|
||||
|
||||
################
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"build_from": {
|
||||
"aarch64": "collabora/code:latest",
|
||||
"amd64": "collabora/code:latest"
|
||||
"aarch64": "collabora/code:latest-arm64",
|
||||
"amd64": "collabora/code:latest-amd64"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,16 +94,21 @@ if bashio::config.true 'ssl'; then
|
||||
bashio::log.error "Key file /ssl/${keyfile} not found"
|
||||
exit 1
|
||||
fi
|
||||
# Point Collabora at the copies rather than at /ssl. coolwsd runs as uid
|
||||
# 1001 and /ssl is mounted read-only with whatever ownership the certificate
|
||||
# tooling left behind, which for a private key is commonly root-only. These
|
||||
# copies are picked up by the chown below, so they are readable regardless.
|
||||
cp -f "/ssl/${keyfile}" /etc/coolwsd/key.pem
|
||||
cp -f "/ssl/${certfile}" /etc/coolwsd/cert.pem
|
||||
cp -f "/ssl/${certfile}" /etc/coolwsd/ca-chain.cert.pem
|
||||
chmod 600 /etc/coolwsd/key.pem
|
||||
extra_params="${extra_params/--o:ssl.enable=false/}"
|
||||
extra_params="${extra_params} \
|
||||
--o:ssl.enable=true \
|
||||
--o:ssl.termination=false \
|
||||
--o:ssl.cert_file_path=/ssl/${certfile} \
|
||||
--o:ssl.key_file_path=/ssl/${keyfile} \
|
||||
--o:ssl.ca_file_path=/ssl/${certfile}"
|
||||
--o:ssl.cert_file_path=/etc/coolwsd/cert.pem \
|
||||
--o:ssl.key_file_path=/etc/coolwsd/key.pem \
|
||||
--o:ssl.ca_file_path=/etc/coolwsd/ca-chain.cert.pem"
|
||||
elif [[ "$extra_params" != *ssl.termination* ]]; then
|
||||
# coolwsd defaults ssl.termination to false, so with ssl disabled it builds
|
||||
# http:// and ws:// URLs even when the browser reached it over https through
|
||||
|
||||
Reference in New Issue
Block a user