From 490da15cba3241147da751caa023e8670de65b28 Mon Sep 17 00:00:00 2001 From: Liraz Siri Date: Tue, 25 Aug 2026 04:07:29 +0000 Subject: [PATCH 1/6] Port e107 to Trixie and 2.3.11 Replace the obsolete SourceForge download with the maintained official e107 release and verify its archive digest. Update the installer for PHP 8.4 and current MariaDB, and make firstboot store administrator credentials with PHP's supported password hashing API. Add focused Docker acceptance coverage for boot, TLS, administrator login, database state, cron, management services, and the supported upstream update channel. --- README.rst | 14 ++++-- changelog | 13 ++++- conf.d/downloads | 23 ++++++--- conf.d/main | 55 ++++++++++----------- docs/v19.0-testing.md | 42 ++++++++++++++++ overlay/usr/lib/inithooks/bin/e107.py | 21 +++++--- tests/v19.sh | 71 +++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 48 deletions(-) create mode 100644 docs/v19.0-testing.md create mode 100755 tests/v19.sh diff --git a/README.rst b/README.rst index 63b4a5b..c417944 100644 --- a/README.rst +++ b/README.rst @@ -14,10 +14,13 @@ and on top of that: - Installed from upstream source code to /var/www/e107 - **Security note**: Updates to e107 may require supervision so - they **ARE NOT** configured to install automatically. e107 provide - upgrade scripts as well as full installers. Please see `e107 - documentation`_ + Version 2.3.11 is installed from the official release archive and its + SHA-256 digest is verified during the build. + + **Security note**: e107 updates require administrator supervision and + are not installed automatically. Back up the appliance, then follow the + official `e107 upgrade documentation`_ using a current full or upgrade + release from the `e107 releases`_ page. - SSL support out of the box. - `Adminer`_ administration frontend for MySQL (listening on port @@ -37,5 +40,6 @@ Credentials *(passwords set at first boot)* .. _e107: https://e107.org/ .. _TurnKey Core: https://www.turnkeylinux.org/core -.. _e107 documentation: https://e107.org/get-started +.. _e107 upgrade documentation: https://e107.org/docs/upgrade +.. _e107 releases: https://github.com/e107inc/e107/releases .. _Adminer: https://www.adminer.org/ diff --git a/changelog b/changelog index 69ac2df..d4f9311 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,15 @@ +turnkey-e107-19.0 (1) turnkey; urgency=low + + * Install e107 2.3.11 from its official release archive with SHA-256 + verification. + + * Store the firstboot administrator password using PHP's current password + hashing API. + + * Update the appliance for Debian 13 (Trixie), PHP 8.4 and current MariaDB. + + -- TurnKey Linux release engineering Tue, 25 Aug 2026 00:00:00 +0000 + turnkey-e107-18.0 (1) turnkey; urgency=low * Install latest upstream version of e107: 2.3.3. @@ -283,4 +295,3 @@ turnkey-e107-12.0 (1) turnkey; urgency=low appliances. Here we only describe changes specific to this appliance. -- Alon Swartz Wed, 01 Aug 2012 08:00:00 +0200 - diff --git a/conf.d/downloads b/conf.d/downloads index fb70eee..ff6de34 100755 --- a/conf.d/downloads +++ b/conf.d/downloads @@ -1,12 +1,21 @@ -#!/bin/bash -ex +#!/bin/bash +set -Eeuxo pipefail dl() { - [ "$FAB_HTTP_PROXY" ] && PROXY="--proxy $FAB_HTTP_PROXY" - cd $2; curl -L -f -O $PROXY $1; cd - -} + local url=$1 + local destination=$2 + local -a proxy=() -VERSION="e107%20v2.3.3/e107_2.3.3_full.tar.gz" -URL="http://sourceforge.net/projects/e107/files/e107/$VERSION" + if [[ -n ${FAB_HTTP_PROXY:-} ]]; then + proxy=(--proxy "$FAB_HTTP_PROXY") + fi + curl --fail --location "${proxy[@]}" "$url" --output "$destination" +} -dl $URL /usr/local/src +VERSION=2.3.11 +ARCHIVE="e107_${VERSION}_full.tar.gz" +URL="https://github.com/e107inc/e107/releases/download/v${VERSION}/${ARCHIVE}" +SHA256=4e60eec29a061ed295a88ce67fcff05b42cc0a3a55b5a8fa84b65476f3e944bc +dl "$URL" "/usr/local/src/$ARCHIVE" +printf '%s %s\n' "$SHA256" "/usr/local/src/$ARCHIVE" | sha256sum --check - diff --git a/conf.d/main b/conf.d/main index dd91778..dc3a8eb 100755 --- a/conf.d/main +++ b/conf.d/main @@ -1,4 +1,5 @@ -#!/bin/sh -ex +#!/bin/bash +set -Eeuxo pipefail DB_NAME=e107 DB_USER=e107 @@ -12,46 +13,44 @@ SRC=/usr/local/src WEBROOT=/var/www/e107 # unpack and set permissions -mkdir -p $WEBROOT -tar -zxf $SRC/e107_*_full.tar.gz -C $WEBROOT -rm $SRC/e107_*_full.tar.gz -chown -R root:root $WEBROOT -chown -R www-data:www-data $WEBROOT/e107_media -chown -R www-data:www-data $WEBROOT/e107_system -chown -R www-data:www-data $WEBROOT/e107_themes -chown -R www-data:www-data $WEBROOT/e107_images -chown -R www-data:www-data $WEBROOT/e107_plugins -chown www-data:www-data $WEBROOT/e107_config.php +mkdir -p "$WEBROOT" +tar -zxf "$SRC/e107_2.3.11_full.tar.gz" -C "$WEBROOT" +rm "$SRC/e107_2.3.11_full.tar.gz" +chown -R root:root "$WEBROOT" +chown -R www-data:www-data "$WEBROOT/e107_media" +chown -R www-data:www-data "$WEBROOT/e107_system" +chown -R www-data:www-data "$WEBROOT/e107_themes" +chown -R www-data:www-data "$WEBROOT/e107_images" +chown -R www-data:www-data "$WEBROOT/e107_plugins" +chown www-data:www-data "$WEBROOT/e107_config.php" # disable allow_url_fopen with php-curl installed (as recommended in # admin/phpinfo.php) -sed -i "\|^allow_url_fopen|s|=.*|= Off|" /etc/php/?.?/apache2/php.ini +sed -i "\|^allow_url_fopen|s|=.*|= Off|" /etc/php/8.4/apache2/php.ini # configure apache a2dissite 000-default a2ensite e107 a2enmod rewrite +a2enmod ssl # start services -service mysql start +service mariadb start service apache2 start # setup the database -mysqladmin create $DB_NAME -mysql --batch --execute "grant all privileges on $DB_NAME.* to $DB_USER@localhost identified by '$DB_PASS'; flush privileges;" +mariadb --batch --execute "CREATE DATABASE $DB_NAME; CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS'; GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" # curl based install -EMAIL=$(echo $ADMIN_MAIL | sed s/@/%40/) +EMAIL=${ADMIN_MAIL/@/%40} do_curl() { URL="http://127.0.0.1/install.php" - CURL="curl -c /tmp/cookie -b /tmp/cookie" - #OUT=$($CURL $URL --data "$1") - - $CURL $URL --data "$1" | \ - grep previous_steps | \ - sed -e "s|.*value='\(.*\)'.*|\1|" + curl --fail --silent --show-error \ + --cookie /tmp/cookie --cookie-jar /tmp/cookie \ + "$URL" --data "$1" | \ + sed -n "s|.*name='previous_steps' value='\([^']*\)'.*|\1|p" | head -n1 } PREV=$(do_curl) @@ -64,19 +63,19 @@ PREV=$(do_curl "previous_steps=$PREV&stage=6&u_name=$ADMIN_NAME&d_name=Administr PREV=$(do_curl "previous_steps=$PREV&stage=7&sitename=example&sitetheme=bootstrap3&install_plugins=1&generate_content=1&submit=Continue+%C2%BB") PREV=$(do_curl "previous_steps=$PREV&stage=8&submit=Continue+%C2%BB") -rm -f $WEBROOT/install.php +rm -f "$WEBROOT/install.php" rm -f /tmp/cookie # enable cron.d -chmod +x $WEBROOT/cron.php +chmod +x "$WEBROOT/cron.php" # secure sensitive files -chmod 640 $WEBROOT/e107_config.php +chmod 640 "$WEBROOT/e107_config.php" # enable defaults -mv $WEBROOT/e107.htaccess $WEBROOT/.htaccess -mv $WEBROOT/e107.robots.txt $WEBROOT/robots.txt +mv "$WEBROOT/e107.htaccess" "$WEBROOT/.htaccess" +mv "$WEBROOT/e107.robots.txt" "$WEBROOT/robots.txt" # stop services -service mysql stop +service mariadb stop service apache2 stop diff --git a/docs/v19.0-testing.md b/docs/v19.0-testing.md new file mode 100644 index 0000000..c35e11d --- /dev/null +++ b/docs/v19.0-testing.md @@ -0,0 +1,42 @@ +# e107 19.0 testing + +## Source decision + +Debian 13 Trixie does not package e107. The appliance installs maintained +upstream release 2.3.11 from the official GitHub release archive. The build +pins and verifies SHA-256 digest +`4e60eec29a061ed295a88ce67fcff05b42cc0a3a55b5a8fa84b65476f3e944bc`. +PHP 8.4, MariaDB, Apache and the required PHP extensions come from signed +Debian Trixie repositories. + +Updates remain an administrator-supervised operation. The supported channel +is the official e107 releases page and the procedure is e107's upgrade guide. + +## Acceptance command + +```sh +/sandboxed-git/turnkey/tools/test-v19-appliance e107 \ + --source /home/agent/.local/worktrees/turnkey-apps/e107/wish-e107-v19-trixie +``` + +The command builds the Trixie root filesystem, imports it into Docker, boots +the normal systemd and firstboot path, then runs `tests/v19.sh`. + +## README crosswalk + +| README contract | Focused check | Required result | +| --- | --- | --- | +| e107 is installed from maintained upstream source | Read the runtime version and query the official latest-release endpoint | Runtime reports 2.3.11 and the official release channel responds | +| Firstboot sets the e107 administrator credentials | Log in through the real web form with the preseeded password and inspect its stored hash | An authenticated administrator page is returned and the password uses PHP's bcrypt format | +| e107 provides a working CMS over TLS | Request the homepage through Apache HTTPS and inspect the initialized database | The homepage is returned and the expected e107 schema exists | +| The scheduled task runs as the web user | Invoke the same PHP command installed in `/etc/cron.d/e107` | The e107 cron entry exits successfully | +| Adminer, Webmin and local mail support are available | Check the database, Webmin modules and HTTPS endpoint, and Postfix loopback listener | MariaDB works, Webmin answers and local SMTP listens | +| Trixie supplies maintained platform updates | Inspect active APT suites and installed PHP and MariaDB packages | Required packages are installed and no Bookworm source remains | +| SSH, backup and other base services are inherited from Core | Reuse the passing Core 19 baseline | Core 19 acceptance remains the inherited evidence | + +## Deferred issue + +The focused test proves installation, firstboot, administrator access and the +scheduled task. It does not automate authoring a content page through the e107 +administrator interface. That is a useful follow-up test, but it is not needed +to establish the v19 port's main runtime flow. diff --git a/overlay/usr/lib/inithooks/bin/e107.py b/overlay/usr/lib/inithooks/bin/e107.py index 9700243..492cdcf 100755 --- a/overlay/usr/lib/inithooks/bin/e107.py +++ b/overlay/usr/lib/inithooks/bin/e107.py @@ -9,9 +9,8 @@ import sys import getopt -import hashlib -from datetime import datetime -from time import mktime +import subprocess +import time from mysqlconf import MySQL from libinithooks import inithooks_cache @@ -58,14 +57,22 @@ def main(): inithooks_cache.write('APP_EMAIL', email) - hash = hashlib.md5(password.encode('utf8')).hexdigest() - timestamp = int(mktime(datetime.now().timetuple())) + password_hash = subprocess.run( + ["/usr/bin/php", "-r", + "echo password_hash(stream_get_contents(STDIN), PASSWORD_DEFAULT);"], + input=password, + text=True, + stdout=subprocess.PIPE, + check=True, + ).stdout + if not password_hash.startswith("$2y$"): + raise RuntimeError("e107 password hashing failed") + timestamp = int(time.time()) m = MySQL() - m.execute('UPDATE e107.e107_user SET user_password=%s WHERE user_loginname=\"admin\";', (hash,)) + m.execute('UPDATE e107.e107_user SET user_password=%s WHERE user_loginname=\"admin\";', (password_hash,)) m.execute('UPDATE e107.e107_user SET user_email=%s WHERE user_loginname=\"admin\";', (email,)) m.execute('UPDATE e107.e107_user SET user_pwchange=%s WHERE user_loginname=\"admin\";', (timestamp,)) if __name__ == "__main__": main() - diff --git a/tests/v19.sh b/tests/v19.sh new file mode 100755 index 0000000..00cf974 --- /dev/null +++ b/tests/v19.sh @@ -0,0 +1,71 @@ +#!/bin/bash +set -Eeuo pipefail +umask 077 + +result=${TKL_TEST_RESULT:?TKL_TEST_RESULT is required} +app_password=${TKL_TEST_APP_PASS:?TKL_TEST_APP_PASS is required} +cookie=/tmp/tkl-e107-cookie.$$ +page=/tmp/tkl-e107-page.$$ + +cleanup() { + rm -f -- "$cookie" "$page" +} +trap cleanup EXIT + +systemctl --quiet is-active apache2.service mariadb.service postfix.service +systemctl --quiet is-enabled apache2.service mariadb.service postfix.service +apache2ctl -t +apache2ctl -M 2>/dev/null | grep -F ' rewrite_module ' >/dev/null +apache2ctl -M 2>/dev/null | grep -F ' ssl_module ' >/dev/null + +curl --insecure --fail --silent --show-error https://localhost/ >"$page" +grep -Eqi 'e107|Welcome' "$page" + +curl --insecure --fail --silent --show-error \ + --cookie "$cookie" --cookie-jar "$cookie" \ + https://localhost/ \ + --data-urlencode 'username=admin' \ + --data-urlencode "userpass=$app_password" \ + --data-urlencode 'userlogin=Login' >"$page" +grep -Eqi 'logout|admin area|administrator' "$page" +test -s "$cookie" + +test "$(mariadb --batch --skip-column-names e107 --execute \ + "SELECT COUNT(*) FROM e107_user WHERE user_loginname='admin' AND user_admin=1")" = 1 +password_hash=$(mariadb --batch --skip-column-names e107 --execute \ + "SELECT user_password FROM e107_user WHERE user_loginname='admin'") +[[ $password_hash == '$2y$'* ]] +test "$(mariadb --batch --skip-column-names e107 --execute 'SHOW TABLES' | wc -l)" -ge 30 + +test ! -e /var/www/e107/install.php +test "$(stat -c '%a' /var/www/e107/e107_config.php)" = 640 +runuser -u www-data -- /usr/bin/php /var/www/e107/cron.php >/dev/null + +dpkg-query -W php8.4 php8.4-cli php8.4-curl php8.4-gd php8.4-mbstring \ + php8.4-xml mariadb-server webmin-apache webmin-mysql >/dev/null +curl --insecure --fail --silent --show-error --head \ + https://127.0.0.1:12321/ >/dev/null +ss -ltn | grep -Eq '127\.0\.0\.1:25[[:space:]]' + +installed_version=$(sed -n \ + 's/^$e107info\['"'"'e107_version'"'"'\][[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \ + /var/www/e107/e107_admin/ver.php | head -n1) +test "$installed_version" = 2.3.11 + +latest_tag=$(curl --fail --silent --show-error \ + https://api.github.com/repos/e107inc/e107/releases/latest | + sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -n1) +test -n "$latest_tag" + +grep -Rqs '^Suites: trixie' /etc/apt/sources.list.d +! grep -Rqi bookworm /etc/apt/sources.list.d + +cat >"$result" < Date: Wed, 26 Aug 2026 05:17:07 +0000 Subject: [PATCH 2/6] Allow the initial e107 installer request The installer helper is intentionally called once without form data to obtain the first workflow token. Under nounset, reading the missing positional argument aborted the appliance build before the request ran. Treat the first payload as empty while preserving the existing staged installation sequence. Verified with shell syntax checks and diff hygiene; exact appliance acceptance follows. --- conf.d/main | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.d/main b/conf.d/main index dc3a8eb..eb3329d 100755 --- a/conf.d/main +++ b/conf.d/main @@ -49,7 +49,7 @@ do_curl() { URL="http://127.0.0.1/install.php" curl --fail --silent --show-error \ --cookie /tmp/cookie --cookie-jar /tmp/cookie \ - "$URL" --data "$1" | \ + "$URL" --data "${1:-}" | \ sed -n "s|.*name='previous_steps' value='\([^']*\)'.*|\1|p" | head -n1 } From a495deb90326933256ba5e24c49bfb6e190e81d6 Mon Sep 17 00:00:00 2001 From: Liraz Siri Date: Wed, 26 Aug 2026 05:40:23 +0000 Subject: [PATCH 3/6] Report the failing e107 acceptance command After the installer correction, the exact candidate completed the upstream installation, built, booted, ran firstboot, and reached healthy services. Its app-local runtime test then exited without recording which silent assertion failed. Add a concise ERR marker for one later diagnostic acceptance run. This changes only test observability and does not consume another product fix loop. --- tests/v19.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/v19.sh b/tests/v19.sh index 00cf974..671eb61 100755 --- a/tests/v19.sh +++ b/tests/v19.sh @@ -7,9 +7,16 @@ app_password=${TKL_TEST_APP_PASS:?TKL_TEST_APP_PASS is required} cookie=/tmp/tkl-e107-cookie.$$ page=/tmp/tkl-e107-page.$$ +report_error() { + printf 'test_failure line=%s status=%s command=%q\n' \ + "$1" "$2" "$3" >&2 + exit "$2" +} + cleanup() { rm -f -- "$cookie" "$page" } +trap 'report_error "$LINENO" "$?" "$BASH_COMMAND"' ERR trap cleanup EXIT systemctl --quiet is-active apache2.service mariadb.service postfix.service From 07c76d6110b3146909f125375a479200927bd363 Mon Sep 17 00:00:00 2001 From: Liraz Siri Date: Fri, 28 Aug 2026 12:50:03 +0000 Subject: [PATCH 4/6] Exercise e107 content publishing in v19 acceptance Follow e107's successful login redirect so acceptance inspects the authenticated response instead of the empty redirect body. Create a public news item through the CSRF-protected administrator form, then verify its MariaDB state and public rendering. Replace the dead upgrade guide with the live official release channel, require its matching v2.x upgrade asset and SHA-256 digest, and cite the retained Core 19 baseline. Verified with shell syntax and diff checks plus a disposable Trixie e107 2.3.11 probe covering login, content creation, database persistence, public read, and release metadata parsing. --- README.rst | 9 +++-- docs/v19.0-testing.md | 33 ++++++++++++------ tests/v19.sh | 79 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/README.rst b/README.rst index c417944..6720ebb 100644 --- a/README.rst +++ b/README.rst @@ -18,9 +18,9 @@ and on top of that: SHA-256 digest is verified during the build. **Security note**: e107 updates require administrator supervision and - are not installed automatically. Back up the appliance, then follow the - official `e107 upgrade documentation`_ using a current full or upgrade - release from the `e107 releases`_ page. + are not installed automatically. Back up the appliance, then use the + matching v2.x upgrade archive and instructions published in the current + `e107 release notes`_. - SSL support out of the box. - `Adminer`_ administration frontend for MySQL (listening on port @@ -40,6 +40,5 @@ Credentials *(passwords set at first boot)* .. _e107: https://e107.org/ .. _TurnKey Core: https://www.turnkeylinux.org/core -.. _e107 upgrade documentation: https://e107.org/docs/upgrade -.. _e107 releases: https://github.com/e107inc/e107/releases +.. _e107 release notes: https://github.com/e107inc/e107/releases/latest .. _Adminer: https://www.adminer.org/ diff --git a/docs/v19.0-testing.md b/docs/v19.0-testing.md index c35e11d..1caf288 100644 --- a/docs/v19.0-testing.md +++ b/docs/v19.0-testing.md @@ -10,7 +10,9 @@ PHP 8.4, MariaDB, Apache and the required PHP extensions come from signed Debian Trixie repositories. Updates remain an administrator-supervised operation. The supported channel -is the official e107 releases page and the procedure is e107's upgrade guide. +is the official e107 releases page. Each release publishes full archives and +upgrade archives for existing v2.x installations together with its release +notes and SHA-256 asset digests. ## Acceptance command @@ -28,15 +30,26 @@ the normal systemd and firstboot path, then runs `tests/v19.sh`. | --- | --- | --- | | e107 is installed from maintained upstream source | Read the runtime version and query the official latest-release endpoint | Runtime reports 2.3.11 and the official release channel responds | | Firstboot sets the e107 administrator credentials | Log in through the real web form with the preseeded password and inspect its stored hash | An authenticated administrator page is returned and the password uses PHP's bcrypt format | -| e107 provides a working CMS over TLS | Request the homepage through Apache HTTPS and inspect the initialized database | The homepage is returned and the expected e107 schema exists | +| e107 provides a working CMS over TLS | Create a news item through the authenticated, CSRF-protected administrator form, inspect its database row, and request its public detail page | The administrator action persists the expected public article and Apache serves its title and body over HTTPS | | The scheduled task runs as the web user | Invoke the same PHP command installed in `/etc/cron.d/e107` | The e107 cron entry exits successfully | | Adminer, Webmin and local mail support are available | Check the database, Webmin modules and HTTPS endpoint, and Postfix loopback listener | MariaDB works, Webmin answers and local SMTP listens | | Trixie supplies maintained platform updates | Inspect active APT suites and installed PHP and MariaDB packages | Required packages are installed and no Bookworm source remains | -| SSH, backup and other base services are inherited from Core | Reuse the passing Core 19 baseline | Core 19 acceptance remains the inherited evidence | - -## Deferred issue - -The focused test proves installation, firstboot, administrator access and the -scheduled task. It does not automate authoring a content page through the e107 -administrator interface. That is a useful follow-up test, but it is not needed -to establish the v19 port's main runtime flow. +| SSH, backup and other base services are inherited from Core | Cite the unchanged Core layer | Core 19 acceptance remains the inherited evidence: run `20260824t010251z-1634-32241`, source `24c82ee3540ce545422742b0e28ba6b687c53ec2`, report SHA-256 `1a6c2d266b6a2898e98a073421e49212dd0237598861200a3cbd6e81d35a2936`, verdict `PASS` | + +## Evidence and deferred issue + +The exact run `20260826t052907z-7370-1769` at `aa15758e` completed the source +preflight, full build, configured-root import, normal systemd boot, firstboot, +and service readiness. Its runtime test stopped at the administrator login +assertion because e107 returns a successful empty redirect after accepting the +credentials. A disposable Debian 13 probe using the same official e107 2.3.11 +archive reproduced that response, confirmed the authenticated cookie, and +verified that following the redirect reaches the logged-in page. The probe +also exercised the final test contract: obtain e107's CSRF token, create a +public news item through the administrator form, verify its MariaDB row, and +read the title and body from its public detail page. + +An exact run of the command above remains the release evidence gate for this +test correction. ISO-only installer, kernel, and hardware behavior remain +covered by the shared Core 19 release validation rather than this focused +appliance test. diff --git a/tests/v19.sh b/tests/v19.sh index 671eb61..b460ed8 100755 --- a/tests/v19.sh +++ b/tests/v19.sh @@ -6,6 +6,9 @@ result=${TKL_TEST_RESULT:?TKL_TEST_RESULT is required} app_password=${TKL_TEST_APP_PASS:?TKL_TEST_APP_PASS is required} cookie=/tmp/tkl-e107-cookie.$$ page=/tmp/tkl-e107-page.$$ +content_title='TurnKey v19 acceptance article' +content_body='TurnKey e107 content create and read verified' +admin_create_url='https://localhost/e107_admin/newspost.php?mode=main&action=create' report_error() { printf 'test_failure line=%s status=%s command=%q\n' \ @@ -28,7 +31,7 @@ apache2ctl -M 2>/dev/null | grep -F ' ssl_module ' >/dev/null curl --insecure --fail --silent --show-error https://localhost/ >"$page" grep -Eqi 'e107|Welcome' "$page" -curl --insecure --fail --silent --show-error \ +curl --insecure --location --fail --silent --show-error \ --cookie "$cookie" --cookie-jar "$cookie" \ https://localhost/ \ --data-urlencode 'username=admin' \ @@ -37,6 +40,53 @@ curl --insecure --fail --silent --show-error \ grep -Eqi 'logout|admin area|administrator' "$page" test -s "$cookie" +curl --insecure --location --fail --silent --show-error \ + --cookie "$cookie" --cookie-jar "$cookie" \ + "$admin_create_url" >"$page" +csrf_token=$(sed -n \ + 's/.*"$page" + +content_id=$(mariadb --batch --skip-column-names e107 --execute \ + "SELECT news_id FROM e107_news WHERE news_title='$content_title' ORDER BY news_id DESC LIMIT 1") +test -n "$content_id" +test "$(mariadb --batch --skip-column-names e107 --execute \ + "SELECT news_body FROM e107_news WHERE news_id=$content_id")" = "$content_body" +test "$(mariadb --batch --skip-column-names e107 --execute \ + "SELECT CONCAT(news_author, ':', news_class) FROM e107_news WHERE news_id=$content_id")" = '1:0' + +curl --insecure --fail --silent --show-error \ + "https://localhost/news.php?extend.$content_id" >"$page" +grep -Fq "$content_title" "$page" +grep -Fq "$content_body" "$page" + test "$(mariadb --batch --skip-column-names e107 --execute \ "SELECT COUNT(*) FROM e107_user WHERE user_loginname='admin' AND user_admin=1")" = 1 password_hash=$(mariadb --batch --skip-column-names e107 --execute \ @@ -59,10 +109,23 @@ installed_version=$(sed -n \ /var/www/e107/e107_admin/ver.php | head -n1) test "$installed_version" = 2.3.11 -latest_tag=$(curl --fail --silent --show-error \ - https://api.github.com/repos/e107inc/e107/releases/latest | - sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -n1) +curl --fail --silent --show-error \ + https://api.github.com/repos/e107inc/e107/releases/latest >"$page" +latest_tag=$(sed -n \ + 's/.*"tag_name": "\([^"]*\)".*/\1/p' "$page" | head -n1) test -n "$latest_tag" +upgrade_asset="e107_v2.x_to_${latest_tag#v}_upgrade.tar.gz" +grep -Fq "\"name\": \"$upgrade_asset\"" "$page" +upgrade_digest=$(php -r ' + $release = json_decode(file_get_contents($argv[1]), true, 512, JSON_THROW_ON_ERROR); + foreach ($release["assets"] as $asset) { + if ($asset["name"] === $argv[2]) { + echo $asset["digest"] ?? ""; + exit; + } + } +' "$page" "$upgrade_asset") +[[ $upgrade_digest =~ ^sha256:[[:xdigit:]]{64}$ ]] grep -Rqs '^Suites: trixie' /etc/apt/sources.list.d ! grep -Rqi bookworm /etc/apt/sources.list.d @@ -70,9 +133,9 @@ grep -Rqs '^Suites: trixie' /etc/apt/sources.list.d cat >"$result" < Date: Sat, 29 Aug 2026 16:22:45 +0000 Subject: [PATCH 5/6] Check e107's planned PHP packages The exact runtime test required a versioned PHP metapackage that the appliance plan does not install, even though Debian resolves the planned PHP CLI and extension packages to PHP 8.4. Check the plan's stable package names so acceptance continues into the user-facing runtime and updater evidence. Verified with bash syntax checking and git diff hygiene. --- tests/v19.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/v19.sh b/tests/v19.sh index b460ed8..c17e241 100755 --- a/tests/v19.sh +++ b/tests/v19.sh @@ -98,8 +98,8 @@ test ! -e /var/www/e107/install.php test "$(stat -c '%a' /var/www/e107/e107_config.php)" = 640 runuser -u www-data -- /usr/bin/php /var/www/e107/cron.php >/dev/null -dpkg-query -W php8.4 php8.4-cli php8.4-curl php8.4-gd php8.4-mbstring \ - php8.4-xml mariadb-server webmin-apache webmin-mysql >/dev/null +dpkg-query -W php-cli php-curl php-gd php-mbstring php-xml mariadb-server \ + webmin-apache webmin-mysql >/dev/null curl --insecure --fail --silent --show-error --head \ https://127.0.0.1:12321/ >/dev/null ss -ltn | grep -Eq '127\.0\.0\.1:25[[:space:]]' From cf57530c0ab0e139e8607d8b7dfdcd0e9ddb809e Mon Sep 17 00:00:00 2001 From: Liraz Siri Date: Sat, 29 Aug 2026 16:30:01 +0000 Subject: [PATCH 6/6] Seal e107 v19 exact acceptance Record the passing exact run for the Trixie appliance, including the main-flow behaviors, installed versions, fix-loop usage, and retained artifact digests. Replace the earlier pending gate with the final Docker acceptance boundary. Verified with the exact appliance harness, shell syntax checks, documentation character checks, and git diff hygiene. --- docs/v19.0-testing.md | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/v19.0-testing.md b/docs/v19.0-testing.md index 1caf288..fc755b9 100644 --- a/docs/v19.0-testing.md +++ b/docs/v19.0-testing.md @@ -36,20 +36,22 @@ the normal systemd and firstboot path, then runs `tests/v19.sh`. | Trixie supplies maintained platform updates | Inspect active APT suites and installed PHP and MariaDB packages | Required packages are installed and no Bookworm source remains | | SSH, backup and other base services are inherited from Core | Cite the unchanged Core layer | Core 19 acceptance remains the inherited evidence: run `20260824t010251z-1634-32241`, source `24c82ee3540ce545422742b0e28ba6b687c53ec2`, report SHA-256 `1a6c2d266b6a2898e98a073421e49212dd0237598861200a3cbd6e81d35a2936`, verdict `PASS` | -## Evidence and deferred issue - -The exact run `20260826t052907z-7370-1769` at `aa15758e` completed the source -preflight, full build, configured-root import, normal systemd boot, firstboot, -and service readiness. Its runtime test stopped at the administrator login -assertion because e107 returns a successful empty redirect after accepting the -credentials. A disposable Debian 13 probe using the same official e107 2.3.11 -archive reproduced that response, confirmed the authenticated cookie, and -verified that following the redirect reaches the logged-in page. The probe -also exercised the final test contract: obtain e107's CSRF token, create a -public news item through the administrator form, verify its MariaDB row, and -read the title and body from its public detail page. - -An exact run of the command above remains the release evidence gate for this -test correction. ISO-only installer, kernel, and hardware behavior remain -covered by the shared Core 19 release validation rather than this focused -appliance test. +## Evidence and limitations + +Exact run `20260829t162315z-2017-14126` at source commit `85700be` passed the +source preflight, full build, configured-root import, normal systemd boot, +firstboot, and all runtime tests. The tests verified administrator login, +authenticated and CSRF-protected news creation, MariaDB persistence, public +article rendering, bcrypt password storage, the e107 cron command, Webmin, +local Postfix, Trixie package sources, and the official e107 upgrade channel. +The installed versions were e107 2.3.11 and PHP 8.4.24. Product fix-loop usage +remained 1 of 6. + +The retained evidence can be verified with these SHA-256 digests: + +* report: `ce36d01a8e5d8fd0b533649e17ab0fd7abec58b1517389a336e39a3d1f543279` +* run log: `54f9bb36135ca2ffb502a6a6d194891ad29bd77c57140d477e8874a7d3023ab0` +* manifest: `d6141296e3504c13726b917b2cf82da304f432b755d07486e23b81146ffe9d27` + +The Docker runtime does not exercise installer, kernel, or hardware behavior. +Those shared image concerns remain covered by Core 19 release validation.