Dockerfile.litespeed / Dockerfile.lsphp: one global
ARG BASE_IMAGE=litespeedtech/openlitespeed:${OLS_VERSION}-lsphp${PHPVER}
used by every stage (incl. the emergency lsphp-src stage, which stays on
upstream repos). The stages that run lsphp-apt-upgrade.sh (litespeed final,
lsphp ext-build + final) take ARG PKG_CACHE=, ship pkg-cache-repos.sh +
keys/pkg-cache/, and wrap the upgrade in `pkg-cache-repos.sh apt` ...
`pkg-cache-repos.sh restore`. Without PKG_CACHE both are no-ops.
lsphp-apt-upgrade.sh: the madison gate also accepts ${PKG_CACHE}/litespeed/
as the lsphp source, but only when PKG_CACHE is set.
build-push.yaml: Build-LiteSpeed-Images and Build-LSPHP-Images resolve the
base digest directly from Docker Hub, probe the cache, set up buildx with
the registry mirror only for a pinned base, and pass BASE_IMAGE + PKG_CACHE.
OLS_VERSION (1.8.4) is now a job-level env read by both the digest lookup
and the build-arg.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
114 lines
6.0 KiB
Bash
Executable File
114 lines
6.0 KiB
Bash
Executable File
#!/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}
|
|
## (rpms.litespeedtech.com, or ${PKG_CACHE}/litespeed/ when PKG_CACHE is set).
|
|
## * 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.
|
|
# Read each output into a variable and match in the shell: piping into an
|
|
# early-exit reader (grep -q, awk ... exit) under pipefail can SIGPIPE the writer
|
|
# and report "missing" for a package that is there (scripts/tests/lsphp-info-probe.test.sh).
|
|
# With the internal package cache (PKG_CACHE build-arg, scripts/pkg-cache-repos.sh
|
|
# apt) the LiteSpeed source reads ${PKG_CACHE}/litespeed/... instead; that URL is
|
|
# accepted ONLY when PKG_CACHE is set, and only under its /litespeed/ path.
|
|
MADISON=$(apt-cache madison "lsphp${PHPVER}")
|
|
LS_REPO_OK=0
|
|
if [[ "$MADISON" == *rpms.litespeedtech.com* ]]; then
|
|
LS_REPO_OK=1
|
|
elif [ -n "${PKG_CACHE:-}" ] && [[ "$MADISON" == *"${PKG_CACHE%/}/litespeed/"* ]]; then
|
|
LS_REPO_OK=1
|
|
echo "lsphp-apt-upgrade: LiteSpeed repo via package cache ${PKG_CACHE%/}/litespeed/"
|
|
fi
|
|
if [ "$LS_REPO_OK" != 1 ]; 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
|
|
POLICY=$(apt-cache policy "lsphp${PHPVER}")
|
|
CAND=$(awk '/Candidate:/ {print $2; exit}' <<<"$POLICY")
|
|
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})"
|