feat(images): upgrade lsphp from the LiteSpeed repo at build time; label PHP version
cac-litespeed and cac-lsphp start FROM litespeedtech/openlitespeed:1.8.4-lsphpNN, which ships lsphp85 8.5.0 / lsphp84 8.4.15 (built 2025-12). lsphp only moved forward as a side effect of installing lsphpNN-ldap. lsphp-apt-upgrade.sh now sweeps every installed lsphpNN* package (and OS packages) to the repo's current release on every build and fails the build if the repo is unreachable or the result doesn't match what CI resolved from the repo index. CI passes a per-run CACHE_BUST so the upgrade layer is never a cache hit, and images carry org.whp.php-version / org.whp.lsphp-package-version labels. Tested on .148 (2026-10-21): cac-lsphp php85/php84 and cac-litespeed php85 built from this branch report the same PHP (8.5.11 / 8.4.26), identical module lists and OLS 1.8.4 as the current registry images; with the hardening flags each serves/runs PHP as the customer uid, restarts, and stops cleanly (exit 0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
74e12407f8
commit
71ca114529
6 files changed
+242
-10
No files matched your search
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
## lsphp-apt-upgrade.sh — BUILD-TIME ONLY. Brings every installed lsphp${PHPVER}*
|
||||
## package (and, by default, the Ubuntu OS packages) up to what the repos offer
|
||||
## RIGHT NOW, then proves it.
|
||||
##
|
||||
## Why this exists: cac-litespeed / cac-lsphp start FROM the LiteSpeed prebuilt
|
||||
## image litespeedtech/openlitespeed:<OLS>-lsphpNN, which LiteSpeed republishes
|
||||
## rarely (the 1.8.4 tags were built 2025-12-16 and ship lsphp85 8.5.0 /
|
||||
## lsphp84 8.4.15, measured 2026-10-21, while rpms.litespeedtech.com/debian
|
||||
## offers 8.5.11 / 8.4.26). The base image already carries that apt repo, so a
|
||||
## PHP security release reaches us the moment LiteSpeed publishes the .deb —
|
||||
## provided every build actually asks for it. Before this script the lsphp core
|
||||
## only moved forward as a SIDE EFFECT of `apt-get install lsphpNN-ldap` (whose
|
||||
## exact-version dependency on lsphpNN-common drags the family along); lsphp
|
||||
## extension packages without that coupling (e.g. lsphpNN-msgpack) and every
|
||||
## Ubuntu package stayed at the base image's December versions.
|
||||
##
|
||||
## Fails LOUDLY — never ships the base image's PHP by accident:
|
||||
## * `apt-get update --error-on=any`: plain `apt-get update` only WARNS when a
|
||||
## repo is unreachable and carries on with no/old lists, exit 0.
|
||||
## * the LiteSpeed repo must be the candidate source for lsphp${PHPVER}.
|
||||
## * after upgrading, no lsphp${PHPVER}* package may remain upgradable.
|
||||
## * if CI passed the version it resolved from the repo index (EXPECT_LSPHP_PKG,
|
||||
## EXPECT_PHP_VERSION), the installed package / running PHP must match it;
|
||||
## that same value becomes the image LABEL, so the label cannot lie.
|
||||
##
|
||||
## Usage: lsphp-apt-upgrade.sh [--no-os-upgrade] PHPVER [extra apt packages / pkg=ver pins...]
|
||||
## Extra packages are installed in the same transaction set (after the OS
|
||||
## upgrade, before the lsphp sweep). Does NOT clean apt lists — the caller
|
||||
## decides (multi-stage builders want them; shipped layers delete them).
|
||||
set -euo pipefail
|
||||
|
||||
OS_UPGRADE=1
|
||||
if [ "${1:-}" = "--no-os-upgrade" ]; then OS_UPGRADE=0; shift; fi
|
||||
PHPVER="${1:?usage: lsphp-apt-upgrade.sh [--no-os-upgrade] PHPVER [pkgs...]}"
|
||||
shift
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
APT=(apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold)
|
||||
LSPHP="/usr/local/lsws/lsphp${PHPVER}/bin/lsphp"
|
||||
PHPCLI="/usr/local/lsws/lsphp${PHPVER}/bin/php"
|
||||
|
||||
die() { echo "FATAL(lsphp-apt-upgrade): $*" >&2; exit 1; }
|
||||
|
||||
echo "lsphp-apt-upgrade: PHPVER=${PHPVER} os_upgrade=${OS_UPGRADE} cache_bust=${CACHE_BUST:-<none>}"
|
||||
echo "lsphp-apt-upgrade: base image lsphp${PHPVER}=$(dpkg-query -W -f='${Version}' "lsphp${PHPVER}" 2>/dev/null || echo none)"
|
||||
|
||||
"${APT[@]}" update --error-on=any || die "apt-get update failed (repo unreachable?). Refusing to build with stale package lists."
|
||||
|
||||
# The candidate for lsphpNN must come from the LiteSpeed repo — not "none", and
|
||||
# not merely whatever is already installed.
|
||||
if ! apt-cache madison "lsphp${PHPVER}" | grep -q 'rpms.litespeedtech.com'; then
|
||||
apt-cache policy "lsphp${PHPVER}" >&2 || true
|
||||
die "the LiteSpeed apt repo does not offer lsphp${PHPVER} (repo missing from sources, or its index is empty)."
|
||||
fi
|
||||
CAND=$(apt-cache policy "lsphp${PHPVER}" | awk '/Candidate:/ {print $2; exit}')
|
||||
echo "lsphp-apt-upgrade: repo candidate lsphp${PHPVER}=${CAND}"
|
||||
|
||||
if [ "$OS_UPGRADE" = 1 ]; then
|
||||
# --with-new-pkgs: let an upgrade pull in a new dependency instead of being
|
||||
# silently "kept back". Never removes packages (that would be dist-upgrade).
|
||||
"${APT[@]}" upgrade --with-new-pkgs
|
||||
fi
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
"${APT[@]}" install --no-install-recommends "$@"
|
||||
fi
|
||||
|
||||
# Sweep EVERY installed lsphpNN* package (core + all extensions) to the candidate.
|
||||
mapfile -t PKGS < <(dpkg-query -W -f='${db:Status-Abbrev} ${Package}\n' "lsphp${PHPVER}*" 2>/dev/null | awk '$1 == "ii" {print $2}')
|
||||
[ "${#PKGS[@]}" -gt 0 ] || die "no lsphp${PHPVER}* packages installed — wrong base image?"
|
||||
"${APT[@]}" install --only-upgrade --no-install-recommends "${PKGS[@]}"
|
||||
|
||||
LEFT=$(apt list --upgradable 2>/dev/null | grep "^lsphp${PHPVER}" || true)
|
||||
[ -z "$LEFT" ] || die "lsphp packages still upgradable after the sweep:
|
||||
$LEFT"
|
||||
|
||||
INST=$(dpkg-query -W -f='${Version}' "lsphp${PHPVER}")
|
||||
RUNV=$("$PHPCLI" -r 'echo PHP_VERSION;') || die "lsphp${PHPVER} CLI does not run"
|
||||
|
||||
if [ -n "${EXPECT_LSPHP_PKG:-}" ] && [ "$INST" != "$EXPECT_LSPHP_PKG" ]; then
|
||||
die "installed lsphp${PHPVER}=$INST but CI resolved $EXPECT_LSPHP_PKG from the repo index (repo changed mid-build? re-run)."
|
||||
fi
|
||||
if [ -n "${EXPECT_PHP_VERSION:-}" ] && [ "$RUNV" != "$EXPECT_PHP_VERSION" ]; then
|
||||
die "lsphp${PHPVER} reports PHP $RUNV but the image will be labelled $EXPECT_PHP_VERSION."
|
||||
fi
|
||||
if [ -z "${EXPECT_PHP_VERSION:-}" ]; then
|
||||
echo "lsphp-apt-upgrade: WARNING no EXPECT_PHP_VERSION build-arg — image label will read 'unverified' (fine for local builds; CI always sets it)." >&2
|
||||
fi
|
||||
|
||||
printf '%s\n' "$RUNV" > /etc/cac-php-version
|
||||
|
||||
echo "lsphp-apt-upgrade: ===== version report ====="
|
||||
dpkg-query -W -f=' ${Package} ${Version}\n' "lsphp${PHPVER}*"
|
||||
echo " lsphp -v: $("$LSPHP" -v | head -n1)"
|
||||
echo " OS packages still upgradable: $(apt list --upgradable 2>/dev/null | grep -vc '^Listing' || true)"
|
||||
echo "lsphp-apt-upgrade: OK lsphp${PHPVER}=${INST} (PHP ${RUNV})"
|
||||
Reference in new issue
Block a user