fd11aa716c
redbear-ci / check (push) Has been cancelled
Unblocks plasma-workspace/plasma-desktop, which required 14 packages that had
no in-tree recipe. Sources are reproducible from each recipe's tar= + blake3;
the vendored source/ trees are deliberately not committed here (212M).
New recipes:
KF6 6.28.0 kf6-kholidays, kf6-krunner, kf6-kstatusnotifieritem,
kf6-kunitconversion
Plasma 6.7.2 knighttime, layer-shell-qt, libkscreen, libksysguard,
plasma-activities-stats, plasma5support, kscreenlocker
Qt 6.11.1 qtpositioning, qtspeech, qttools
libksysguard carries P0-redox-process-backend.patch: processes_local_p.cpp
dispatches on platform macros and had no __redox__ arm, so ProcessesLocal was
entirely undefined. Adds a real backend reading /scheme/proc/ps (pid, ppid,
real+effective ids, thread count, state) and /scheme/sys/mem, with kill() for
signals. Upstream's generic fallback is a pure stub and was not used. Absent
facilities (no setpriority/sched_setscheduler/ioprio on a microkernel) report
NotSupported rather than pretending.
Restored, no longer disabled:
- night colour: kcms/nighttime + kwin's nightlight plugin, now that
KNightTime/Qt6Positioning/KF6Holidays exist
- KIO FileWidgets (file dialog, places model), wrongly swept in with the
unportable kiod/kssld/kioworkers subdirs
- kf6-ktexteditor text-to-speech: removes a disguised stub that rewrote
speechEngine() to return nullptr and mangled call sites into invalid C++
- kwin KWIN_BUILD_SCREENLOCKER=ON (needs kscreenlocker; see below)
Toolchain and recipe fixes:
- redox-toolchain.cmake: append -lgcc. __extendhfsf2/__extendbfsf2 are
global in libgcc.a but hidden in libgcc_s.so (the Redox libgcc version map
stops at GCC_7.0.0 and never emits the GCC_12/13 nodes upstream exports),
and GCC omits -lgcc for -shared, so no C++23 shared library using
std::format<_Float16|bfloat16_t> could link.
- qtmultimedia: rewrite /usr/src/.../meta_types paths and stage metatypes,
so consumers using qt_internal_add_qml_module can configure.
- qtspeech: qtmultimedia is mandatory, not optional -- upstream return()s
with only a NOTICE without it, yielding a green build over an empty
package. Asserts its own output so that cannot recur.
- narrow Linux-only guards with AND NOT REDOX where the toolchain sets
CMAKE_SYSTEM_NAME=Linux purely to get UNIX=TRUE (kio LibMount,
libksysguard NL/Sensors, plasma-workspace NetworkManagerQt).
- drop REQUIRED components that are declared but referenced nowhere
(Location, QCoro6, Qt6 Test) -- verified by exhaustive grep.
- DESTDIR installs where KDE emits absolute KDE_INSTALL_FULL_* paths that
--prefix cannot re-root, which otherwise write into the build host.
Auth stack:
- pam-redbear: add PAM_MODULE_UNKNOWN (28), missing from both the header and
lib.rs; realign 30/31 to Linux-PAM's PAM_CONV_AGAIN/PAM_INCOMPLETE, which
previously held Red Bear-only names on standard values, so anything built
against stock PAM headers mis-decoded them.
- redbear-authd: support yescrypt ($y$ -- the default shadow format on
current Debian/Ubuntu/Fedora, previously an unexplained login failure),
bcrypt and md5-crypt. Plaintext shadow entries now require the
/etc/redbear/allow-plaintext-passwords sentinel and warn on every use,
instead of being compared silently. 19/19 host tests pass.
Build-system hardening:
- verify-tracked-sources.sh, wired into preflight: fails on deletion of any
tracked vendored source, and on modifications with no baseline entry.
local/sources/ had a dirty gate and version checks; local/recipes/*/source/
had none, which allowed an rm -rf to delete 7958 tracked files and a
pristine re-extract to silently overwrite committed fixes (kwin's
std::expected/vulkan-hpp and X11 gating, kio's Q_OS_REDOX resolver guards).
- validate-source-trees.py: resolve recipe.toml through the overlay symlink;
it reported false MISSING for symlinked recipes.
- test-sddm-virgl-qemu.sh: the null-proxy check used report(), which PASSES
on regex match -- so the known Qt6 Wayland null+8 fault would report PASS
when present. Added report_absent().
kscreenlocker builds only its cmake-level Wayland-only changes so far; the
C++ X11 removal (61 call sites) is not yet applied, so kwin's screenlocker
flag is blocked on it.
223 lines
9.3 KiB
Bash
Executable File
223 lines
9.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# verify-tracked-sources.sh — integrity gate for git-tracked vendored source trees.
|
|
#
|
|
# WHY THIS EXISTS
|
|
# ---------------
|
|
# Several recipes under local/recipes/ are "vendored forks": their source/ tree
|
|
# is committed to git and carries real Red Bear work baked directly into files
|
|
# that also exist upstream (see local/docs/VERSIONING.md, "baked shim"). That
|
|
# tree is durable state, but nothing guarded it, and two failure modes have
|
|
# actually happened:
|
|
#
|
|
# 1. DELETION. An ad-hoc `rm -rf <recipe>/source` (to force a clean
|
|
# re-extract) removes thousands of tracked files. AGENTS.md already warns
|
|
# that this "has wiped tracked local/recipes/*/source/ trees in the past".
|
|
#
|
|
# 2. SILENT OVERWRITE. For a `tar` recipe, deleting source/ makes the
|
|
# cookbook re-extract PRISTINE upstream over it. Files that exist upstream
|
|
# get their committed Red Bear edits replaced with upstream content. No
|
|
# error is raised -- the package may even still build -- so the loss ships
|
|
# as a silent regression. This is how kwin lost its std::expected /
|
|
# vulkan-hpp and X11-gating fixes, and kio lost the Q_OS_REDOX guards in
|
|
# hostinfo.cpp.
|
|
#
|
|
# Neither mode is detectable by the existing gates: verify-fork-versions.sh
|
|
# covers local/sources/ (the submodule forks), and the build-redbear.sh
|
|
# dirty-source gate likewise only looks at local/sources/. The vendored recipe
|
|
# trees carry equally durable work and had no equivalent check.
|
|
#
|
|
# WHAT IT CHECKS
|
|
# --------------
|
|
# Recipe seds legitimately rewrite tracked source files on every build (that is
|
|
# the current in-tree build model), so "modified" alone cannot mean "damaged".
|
|
# The gate therefore separates three cases:
|
|
#
|
|
# DELETED tracked file under */source/ -> ERROR, always. A build never
|
|
# legitimately deletes tracked
|
|
# source.
|
|
# MODIFIED, not in the baseline -> ERROR. Something changed a
|
|
# tracked source file that no
|
|
# recorded recipe sed accounts
|
|
# for -- the overwrite signature.
|
|
# MODIFIED, listed in the baseline -> known churn. Reported as a
|
|
# durability WARNING (this is
|
|
# uncommitted work living in a
|
|
# durable tree); escalate to an
|
|
# error with
|
|
# REDBEAR_STRICT_TRACKED_SOURCES=1.
|
|
#
|
|
# The baseline (local/tracked-source-baseline.txt) is itself tracked, so the set
|
|
# of "expected to be dirty" files is reviewable in git rather than invisible.
|
|
#
|
|
# USAGE
|
|
# verify-tracked-sources.sh [--quiet] # check (preflight mode)
|
|
# verify-tracked-sources.sh --update # regenerate the baseline
|
|
# verify-tracked-sources.sh --list # show current dirty tracked sources
|
|
#
|
|
# Bypass: REDBEAR_SKIP_TRACKED_SOURCE_CHECK=1 (emergency only).
|
|
# Escalate baseline churn to an error: REDBEAR_STRICT_TRACKED_SOURCES=1.
|
|
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
BASELINE="$ROOT/local/tracked-source-baseline.txt"
|
|
|
|
QUIET=0
|
|
MODE=check
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--quiet) QUIET=1 ;;
|
|
--update) MODE=update ;;
|
|
--list) MODE=list ;;
|
|
-h|--help)
|
|
sed -n '2,60p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
|
|
exit 0 ;;
|
|
*) echo "verify-tracked-sources.sh: unknown argument '$arg'" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
say() { [ "$QUIET" -eq 1 ] || echo "$@"; }
|
|
|
|
cd "$ROOT" || exit 2
|
|
|
|
# Collect tracked files under any local/recipes/**/source/ that git reports as
|
|
# changed. -z keeps paths with spaces intact (several KDE avatar assets have
|
|
# them, which is exactly where a naive `xargs` split goes wrong).
|
|
collect() { # $1 = status filter letter (M or D)
|
|
local want="$1"
|
|
git status --porcelain -z -- local/recipes 2>/dev/null \
|
|
| while IFS= read -r -d '' entry; do
|
|
local st="${entry:0:2}" path="${entry:3}"
|
|
case "$st" in
|
|
*"$want"*) [[ "$path" == */source/* ]] && printf '%s\n' "$path" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
mapfile -t DELETED < <(collect D | LC_ALL=C sort)
|
|
mapfile -t MODIFIED < <(collect M | LC_ALL=C sort)
|
|
|
|
if [ "$MODE" = list ]; then
|
|
printf '%s\n' "${MODIFIED[@]}" | sed '/^$/d'
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$MODE" = update ]; then
|
|
{
|
|
echo "# tracked-source-baseline.txt"
|
|
echo "#"
|
|
echo "# Tracked files under local/recipes/*/source/ that are EXPECTED to differ"
|
|
echo "# from HEAD during a normal build -- almost all of it recipe-sed churn."
|
|
echo "# Consumed by local/scripts/verify-tracked-sources.sh."
|
|
echo "#"
|
|
echo "# A file listed here is uncommitted work sitting in a DURABLE tree. That is"
|
|
echo "# tolerated, not endorsed: commit it, or convert the change into a recipe sed"
|
|
echo "# or a patch, so a clean re-extract cannot lose it."
|
|
echo "#"
|
|
echo "# A line prefixed 'D ' records an INTENTIONAL deletion of a tracked source"
|
|
echo "# file (e.g. removing a vendored stub). Without an entry, any deletion is"
|
|
echo "# treated as damage."
|
|
echo "#"
|
|
echo "# Regenerate with: ./local/scripts/verify-tracked-sources.sh --update"
|
|
printf '%s\n' "${MODIFIED[@]}" | sed '/^$/d'
|
|
printf 'D %s\n' "${DELETED[@]}" | sed '/^D $/d'
|
|
} > "$BASELINE"
|
|
echo ">>> baseline updated: $(printf '%s\n' "${MODIFIED[@]}" | sed '/^$/d' | wc -l) modified," \
|
|
"$(printf '%s\n' "${DELETED[@]}" | sed '/^$/d' | wc -l) deleted -> $BASELINE"
|
|
exit 0
|
|
fi
|
|
|
|
# ---- check mode ----------------------------------------------------------
|
|
rc=0
|
|
|
|
if [ "${REDBEAR_SKIP_TRACKED_SOURCE_CHECK:-0}" = "1" ]; then
|
|
echo ">>> WARNING: tracked-source integrity check bypassed via REDBEAR_SKIP_TRACKED_SOURCE_CHECK=1." >&2
|
|
exit 0
|
|
fi
|
|
|
|
# Load the baseline first: it records both expected modifications (plain lines)
|
|
# and intentional deletions ("D <path>").
|
|
declare -A known=()
|
|
declare -A known_del=()
|
|
if [ -f "$BASELINE" ]; then
|
|
while IFS= read -r line; do
|
|
[[ -z "$line" || "$line" == \#* ]] && continue
|
|
if [[ "$line" == "D "* ]]; then
|
|
known_del["${line:2}"]=1
|
|
else
|
|
known["$line"]=1
|
|
fi
|
|
done < "$BASELINE"
|
|
fi
|
|
|
|
# 1. Deletions are damage unless explicitly recorded as intentional.
|
|
unexpected_del=()
|
|
for f in "${DELETED[@]}"; do
|
|
[ -z "$f" ] && continue
|
|
[ -n "${known_del[$f]:-}" ] || unexpected_del+=("$f")
|
|
done
|
|
DELETED=("${unexpected_del[@]}")
|
|
|
|
if [ "${#DELETED[@]}" -gt 0 ] && [ -n "${DELETED[0]:-}" ]; then
|
|
echo "" >&2
|
|
echo ">>> ERROR: ${#DELETED[@]} git-tracked file(s) under a vendored source/ tree are DELETED." >&2
|
|
echo " A build never legitimately deletes tracked source. This is the signature of an" >&2
|
|
echo " ad-hoc 'rm -rf <recipe>/source'." >&2
|
|
printf ' %s\n' "${DELETED[@]:0:15}" >&2
|
|
[ "${#DELETED[@]}" -gt 15 ] && echo " ... and $(( ${#DELETED[@]} - 15 )) more" >&2
|
|
echo "" >&2
|
|
echo " Restore with: git checkout -- local/recipes/<recipe>/source" >&2
|
|
echo " To force a clean re-extract of a tracked tree, restore it from git afterwards;" >&2
|
|
echo " never delete it." >&2
|
|
rc=1
|
|
fi
|
|
|
|
# 2. Modifications the baseline does not account for.
|
|
unexpected=()
|
|
for f in "${MODIFIED[@]}"; do
|
|
[ -z "$f" ] && continue
|
|
[ -n "${known[$f]:-}" ] || unexpected+=("$f")
|
|
done
|
|
|
|
if [ "${#unexpected[@]}" -gt 0 ]; then
|
|
echo "" >&2
|
|
echo ">>> ERROR: ${#unexpected[@]} tracked source file(s) changed with no baseline entry." >&2
|
|
echo " Either a recipe gained a new sed, or committed Red Bear work was overwritten" >&2
|
|
echo " (e.g. a pristine tarball re-extract replacing baked-in fixes)." >&2
|
|
printf ' %s\n' "${unexpected[@]:0:15}" >&2
|
|
[ "${#unexpected[@]}" -gt 15 ] && echo " ... and $(( ${#unexpected[@]} - 15 )) more" >&2
|
|
echo "" >&2
|
|
echo " Inspect: git diff -- <path>" >&2
|
|
echo " If the change is LOST WORK: git checkout -- <path>" >&2
|
|
echo " If the change is EXPECTED: ./local/scripts/verify-tracked-sources.sh --update" >&2
|
|
rc=1
|
|
fi
|
|
|
|
# 3. Baseline churn: uncommitted work in a durable tree. Visible, not fatal by
|
|
# default -- this is the local/recipes/ counterpart of the local/sources/
|
|
# dirty gate in build-redbear.sh.
|
|
baseline_dirty=0
|
|
for f in "${MODIFIED[@]}"; do
|
|
[ -z "$f" ] && continue
|
|
[ -n "${known[$f]:-}" ] && baseline_dirty=$(( baseline_dirty + 1 ))
|
|
done
|
|
|
|
if [ "$baseline_dirty" -gt 0 ]; then
|
|
if [ "${REDBEAR_STRICT_TRACKED_SOURCES:-0}" = "1" ]; then
|
|
echo ">>> ERROR: $baseline_dirty uncommitted change(s) in tracked source trees" \
|
|
"(REDBEAR_STRICT_TRACKED_SOURCES=1)." >&2
|
|
rc=1
|
|
else
|
|
say ">>> Preflight note: $baseline_dirty uncommitted change(s) in tracked vendored" \
|
|
"source trees (baseline-known)."
|
|
say " These live in a DURABLE tree but are not committed; a clean re-extract would" \
|
|
"lose them. Commit them, or move them into a recipe sed / patch."
|
|
fi
|
|
fi
|
|
|
|
if [ "$rc" -eq 0 ]; then
|
|
say ">>> Preflight: tracked vendored source trees intact (no deletions, no unexplained edits)."
|
|
fi
|
|
exit "$rc"
|