LAPP as a child of apache-php, in two content variants #2
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Keel-Linux/keel-lapp!2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/lapp-on-apache-php"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1.
LAPP is now a child of the
apache-phplayer carrying thepostgresqlunit,with two artefacts split by content rather than by topology. This is
Keel-Linux/keel-lamp#2with the database named differently, which is theclaim the issue asked to be tested, so most of this description is the
difference between the two recipes and the numbers behind it.
The two artefacts
lappapache-phppostgresql@1.0.0lapp-clientapache-phpBoth built from one commit of this repository, in two product directories whose
only difference is whether
unit.d/postgresqlwas cloned into it.lapp-clientis a strict subset: 10 packages fewer and none of its own, all 10the server closure (
postgresql,postgresql-17,postgresql-common,postgresql-common-dev,webmin-postgresql,ssl-cert,libipc-run-perl,libjson-perl,libllvm19,libz3-4).How much of this recipe is keel-lamp's
Makefileandplan/mainare the same files once the four database packagesare named by their role. Diffed after substituting the engine names, every
substantive line is identical and only comments differ; the plans reduce to the
same seven entries, four of them the client, the PHP driver, the Perl DBI
driver and the Python driver.
conf.d/mainis the same script with the same skeleton and exactly twoblocks that are not the same. Both are asymmetries between the two
components, neither between the two stacks:
unit-postgresqlwrites them inside its own confscript, because the addresses a server answers on belong to whoever installs
the server, so this recipe only checks the line is there.
unit-mariadbdoes not, so
keel-lamphas to write99-keel-bind.cnfitself, andkeel-mariadbalready carries the same file in its overlay: the settingexists twice on the MariaDB side and zero times here.
unit-postgresql's conf script opens withset ${PGSQL_PASS:=postgres}, so a build naming noPGSQL_PASSgives thesuperuser a known password and every consumer has to undo it, as
keel-postgresqland this recipe both do. The shared tree'sconf/adminer-mysqluses a value frommcookiethat nobody records, sokeel-lamphas nothing to undo.A third difference belongs to the shared tree and not to the components:
conf/adminer-mysqlstarts the database to create an account, sokeel-lampcan only run it in the artefact that has a server, while
conf/adminer-pgsqlis two
sedlines and could run in both. It is kept to the server artefacthere anyway, so that the two Makefiles stay the same shape and the client
artefact gets the same result from
conf.d/main. Splittingconf/adminer-mysqlinto a driver half and an account half would remove thelast structural difference between the two recipes;
commonis shared, so thatis proposed and not done.
None of the three argues against the composition. All three say the same
thing: the two components were extracted to different depths and the recipes
are carrying the difference.
Equivalence against a monolithic build
Measured the way decision 0010 measured the unit extraction, on the assembled
root and not on the delta: a scratch product
lapp-monoexpressing the samestack as one recipe on
core, built twice for the noise floor. All builds atSOURCE_DATE_EPOCH=1700000000,common6803422, fab 1.1.1+keel2,core7acf2c53,
apache-phpb9dd64db.The control needed one line that the shared tree does not have:
unit-postgresqlis not a verbatim extraction ofcommon/conf/pgsql, it alsosets the cluster's listen addresses. Without that line the control would be a
different stack, listening on IPv4 only, and the comparison would measure that
improvement instead of the composition. The line is applied in the control and
nothing else about the shared tree is touched.
Every version of every shared package is identical, all 510.
The five extra packages, and none of them is the unit's:
turnkey-apache-php-19.0, the parent layer's own release record. A chainrecords every layer it is made of and a monolith records one.
php-jsonandphp8.4-phpdbg, the parent's composer closure. Inkeel-lampthe control-vs-control run showed these two arriving and leaving between two
runs of the identical recipe, so they are not deterministic; here the control
happened to be stable and the composed build inherits them from the published
parent, where they are installed.
php-mysqlandphp8.4-mysql, a MariaDB driver in a PostgreSQL stack.adminerdepends onphp-mysql | php-mysqli | php-pdo-mysql | php-sqlite3 | php-pgsqland apt takes the first alternative. The publishedapache-phplayer installs Adminer before either stack's packages exist, so it resolves
to MySQL's driver and every child inherits it. The monolithic LAPP already
had
php-pgsqlin its plan, which satisfied the same alternative, so itinstalled no MySQL driver at all.
This is the one finding of the measurement that is worth acting on, and it is
apache-php's: putting Adminer in the shared layer forces a database driverinto the shared layer, and the alternative decides which.
apache-phpshouldname the driver it wants.
Differences attributable to the unit form, the control-vs-composed set
minus the control-vs-control set: 20 paths, and every one of them records
the package set or the order it was installed in:
/etc/hostnameand/etc/hosts, the product's own name; the control has tobe a differently named product to exist beside the real one (
lapp-monoagainst
lapp, read out of both trees)./var/lib/dpkg/statusandstatus-old: the five extra stanzas above andnothing else, checked by diffing the
Package:lines./var/lib/ucf/{registry,hashfile}*: thephp8.4-mysqlandphp8.4-phpdbg.inilines and nothing else./var/lib/apt/extended_states,/var/lib/dpkg/triggers/File,/var/cache/man/index.db(identical size, a cache), and/etc/webmin/webmin.acl, which differs only in the order of the module list(
apache postgresql phpiniagainstapache phpini postgresql).So the count attributable to the unit form is zero. The 16 the control
differs from itself by are the self-signed certificate and key, the webmin
caches and logs,
alternatives.log,aux-cacheand the dpkg and aptregistries: install-time state of the kind the M0 allow-list already freezes.
The boot test, which proves the stack rather than the ports
lapp:lapp-client, same web verdicts, and the absence in place of the database:The absence is asked four ways because each can be true while the others are
false. The data directory verdict reads the directory's contents rather than
its existence, because
postgresql-clientcreates/var/lib/postgresqlas therole's home and leaves it empty.
Coverage
67 bats tests, 100 percent (284/284) of
tests/lib/boot-test-lib.shunderkcov, the threshold the workflow enforces. The 67th runs the artefact helpers
in a script with
set -euo pipefail, becausebats runturns errexit off andthe first
lamp-clientboot test died silently on exactly that: a helper thatreturns 1 to mean "this artefact has no server" killed its caller. See
Keel-Linux/keel-lamp#2.Why
package / changelogis redrequire-changelogcompares only the Debian revision inside the parentheses.master's top entry isturnkey-lapp-18.1 (1)and the new one isturnkey-lapp-19.0 (1), so it reports "1 is not greater than 1". The versiondid increase, from 18.1 to 19.0; the checker cannot see it, and a fork's first
entry under a new upstream version can never pass. Fixing it is a change to
keel-linux/.github, which the 2026-09-26 audit called the highest blastradius in the organization, so it is reported rather than made, and the entry
is left honest at revision 1.
appliance / build-and-bootandappliance-client / build-and-bootstay redor skipped until the layers are on the mirror. Nothing has been published.