From 82f70bc0e955b9ed3d55b76da6620f9c2ab96573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20M=C3=A9ndez?= Date: Sun, 27 Sep 2026 18:09:23 +0000 Subject: [PATCH] Compose the PostgreSQL component instead of including the shared tree The recipe stops including mk/turnkey/pgsql.mk, stops naming the server packages, and composes keel-linux/unit-postgresql as unit.d/postgresql. fab resolves the component's plan with this one, applies its overlay, runs its conf script with the PGSQL_PASS its conf-vars asks for, and bt-layer records it in the layer manifest as "units postgresql@1.0.0". Decision 0013 is why: a database is a component and not a parent layer, so LAMP and LAPP can share one apache-php layer instead of being children of two different database layers. Decision 0010 is how, and it asks for the proof to be a comparison rather than a claim. listen_addresses = '::1,127.0.0.1' moves with the server. The line was written here last night, when the layer was found binding the IPv4 loopback alone because Debian's /etc/hosts never maps ::1 to localhost. It belongs to whoever installs the server: LAPP will carry the component without carrying this recipe, and a fix that lives here would have to be copied there. What stays here is the check that the built image has the line, so the component is verified by the recipe rather than trusted, and the boot test still proves what the cluster actually binds on a running machine. unit.d/ is ignored by git. Materialising it from the pin is the assembly step decision 0010 names as work of the project, and it does not exist yet: the clone in README.rst is that step today, and the layer manifest is the record of what a build applied. --- .gitignore | 5 +++++ Makefile | 17 ++++++++++++++--- README.rst | 26 ++++++++++++++++++++------ changelog | 24 ++++++++++++++++++++++++ conf.d/main | 40 ++++++++++++++++------------------------ plan/main | 14 ++++++-------- 6 files changed, 85 insertions(+), 41 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be14f7b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# The components this recipe composes are materialised here before a build, +# one directory per unit, each a checkout of its own repository at the version +# the build pins (README.rst). They are not part of this repository: the layer +# manifest bt-layer writes is the record of which ones were applied. +/unit.d/ diff --git a/Makefile b/Makefile index 364fb9e..bb32239 100644 --- a/Makefile +++ b/Makefile @@ -4,15 +4,26 @@ # any other appliance that needs PostgreSQL is built on it instead of # installing its own. # +# git clone --branch v1.0.0 \ +# https://github.com/keel-linux/unit-postgresql.git unit.d/postgresql # bt-layer postgresql --parent core # # What it deliberately leaves out, and why, is in README.rst: Adminer needs # a web server, and which web server differs by context (lighttpd upstream, # Apache in LAPP), so it arrives with the web stack, not with the database. +# +# The server itself is not included from the shared tree any more. It is the +# unit.d/postgresql component (keel-linux/unit-postgresql), which fab resolves +# and applies on its own and bt-layer records in the layer manifest as +# "units postgresql@", so a layer built on this one applies it once +# and a layer built on that one does not apply it again. Decision 0013 is why: +# a database is a component, LAMP and LAPP share apache-php, and a database +# that is a parent layer cannot be shared that way. -include $(FAB_PATH)/common/mk/turnkey/pgsql.mk - -# After pgsql.mk, so a file of this overlay wins over the shared one. +# The recipe's own overlay reaches the tree twice, here and again as +# ROOT_OVERLAY after the units, so a file of this overlay still wins over a +# file of the component. No path is in both today, and tests/unit.bats of +# unit-postgresql lists what the component ships. COMMON_OVERLAYS += $(CURDIR)/overlay # Webmin comes from core and answers on 12321; plan/main adds the database diff --git a/README.rst b/README.rst index 4c23b7f..e64e18d 100644 --- a/README.rst +++ b/README.rst @@ -7,8 +7,19 @@ appliance `turnkeylinux-apps/postgresql `_ for the database half of what that appliance is:: + git clone --branch v1.0.0 \ + https://github.com/keel-linux/unit-postgresql.git unit.d/postgresql bt-layer postgresql --parent core +The server comes from the ``unit.d/postgresql`` component, not from the +shared tree: `keel-linux/unit-postgresql +`_ carries its plan, its +overlay, its conf script and the ``PGSQL_PASS`` it reads, fab applies it, and +``bt-layer`` records it in the layer manifest as ``units postgresql@1.0.0``. +Materialising ``unit.d`` from the pin is the assembly step decision 0010 names +as work of the project and does not exist yet, so the clone above is that step +for now; ``unit.d/`` is ignored by git here. + It is a layer, not a product: LAPP and any other appliance that needs PostgreSQL is built on it, so the cluster is created, secured and measured once. Nothing is stopping it being run on its own; it boots, it listens on @@ -18,18 +29,21 @@ What is in it ------------- ====================================== ==================================== -``Makefile`` ``mk/turnkey/pgsql.mk`` of ``common``, this overlay, the firewall ports -``plan/main`` postgresql, webmin-postgresql, the client, the project packages +``Makefile`` the component under ``unit.d``, this overlay, the firewall ports +``plan/main`` the client and the project packages; the server and webmin-postgresql are the component's plan ``conf.d/main`` the build time password removed; the checks; the project package upgrade ``overlay/usr/lib/inithooks/`` the verification hook and its library ``keel/instance.example.yaml`` the instance description an operator starts from ``tests/`` bats for the shell, ``boot-test.sh`` for the machine ====================================== ==================================== -``mk/turnkey/pgsql.mk`` brings ``conf/pgsql`` (the UTF-8 cluster, password -encryption, the root superuser) and the ``pgsql`` overlay, which carries -``bin/pgsqlconf.py`` and ``firstboot.d/35pgsqlpass``. Those are used as -they are, not rewritten. +The component brings the UTF-8 cluster, password encryption, the bind +addresses, the root superuser, ``bin/pgsqlconf.py`` and +``firstboot.d/35pgsqlpass``. Those are used as they are, not rewritten. The +bind addresses used to be set here, in ``conf.d/main``; they moved into the +component because binding is what whoever installs the server decides and LAPP +will carry the component without carrying this recipe. What stayed here is the +check that the line is in the built image. Webmin comes from ``core`` and answers on 12321; this layer adds ``webmin-postgresql``, the module that puts the database in it. Batteries diff --git a/changelog b/changelog index 5ca7b24..393fc02 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,27 @@ +turnkey-postgresql-19.0 (3) turnkey; urgency=low + + * The PostgreSQL server is a component instead of a piece of the shared + tree. The recipe no longer includes mk/turnkey/pgsql.mk and no longer + names the server packages; it composes keel-linux/unit-postgresql as + unit.d/postgresql, which fab resolves and applies and bt-layer records in + the layer manifest as "units postgresql@". Decision 0013 is the + reason: a database is a component, so LAMP and LAPP can share one + apache-php layer instead of being children of two different databases. + + * listen_addresses = '::1,127.0.0.1' is set by the component now, not by + conf.d/main. It is the same line for the same reason, in the place that + owns it: LAPP will carry the component without carrying this recipe, and a + fix living here would have to be copied there. conf.d/main keeps the check + that the built image has it, so the component is verified rather than + trusted, and the boot test still proves what the cluster binds. + + * No other change to what the image gets. The layer built this way was + compared to a layer built from the shared tree the way decision 0010 + compares them, with a second build of the shared tree to measure the noise + the comparison is read against. + + -- Keel Linux maintainers Sun, 27 Sep 2026 11:30:00 +0000 + turnkey-postgresql-19.0 (2) turnkey; urgency=low * Listen on both loopback addresses, named literally: diff --git a/conf.d/main b/conf.d/main index 5908c2a..620be01 100755 --- a/conf.d/main +++ b/conf.d/main @@ -1,12 +1,13 @@ #!/bin/bash -ex # PostgreSQL, and nothing that serves a web page. # -# common's conf/pgsql has already run (COMMON_CONF of mk/turnkey/pgsql.mk): -# it recreated the cluster as UTF-8, turned on password encryption, reduced -# shared_buffers, gave root a superuser role, and set the postgres role's -# password. That last step is the one thing this layer has to undo. +# The conf script of the unit.d/postgresql component has already run (fab runs +# the units after the common conf scripts and before this one): it recreated +# the cluster as UTF-8, turned on password encryption, reduced shared_buffers, +# set the bind addresses, gave root a superuser role, and set the postgres +# role's password. That last step is the one thing this layer has to undo. # -# conf/pgsql opens with +# The component's conf script opens with # # set ${PGSQL_PASS:=postgres} # @@ -41,25 +42,16 @@ EOF systemctl stop postgresql -# The cluster listens on the loopback of both families and nowhere else, -# and both are named as literal addresses. -# -# Debian's default is listen_addresses = 'localhost', and that was taken -# for "the loopback of both families" when this layer was written. It is -# not. Debian's /etc/hosts maps ::1 to ip6-localhost and ip6-loopback and -# never to localhost, so getaddrinfo("localhost") answers 127.0.0.1 alone -# and the cluster binds the IPv4 loopback only. Measured on the booted -# layer: "LISTEN 127.0.0.1:5432" and nothing on [::1]:5432, with ::1 up on -# lo and pg_hba.conf already holding its scram-sha-256 line for ::1/128. -# An appliance built on this layer and reaching its database over IPv6, -# which is the default this project builds for (brief section 10), found -# nothing listening. -# -# Two literal addresses cannot resolve into something else, which is the -# whole point of writing them out; what they bind to is then proved on the -# booted machine by the boot test rather than assumed here. -sed -i "s|^#\?listen_addresses = .*|listen_addresses = '::1,127.0.0.1'\t\t# set by conf.d/main of keel-postgresql: see the comment there|" \ - "$CONF_DIR/postgresql.conf" +# The cluster listens on the loopback of both families and nowhere else, and +# both are named as literal addresses. The component wrote that line, because +# binding is what whoever installs the server decides and LAPP will carry the +# component without carrying this recipe. This is the check on what it wrote: +# Debian's default, listen_addresses = 'localhost', binds the IPv4 loopback +# only, since /etc/hosts maps ::1 to ip6-localhost and ip6-loopback and never +# to localhost, and an appliance reaching its database over IPv6, which is the +# default this project builds for (brief section 10), then finds nothing +# listening. What the two addresses bind to is proved on the booted machine by +# the boot test; this fails the build if the line is not there at all. grep -qE "^listen_addresses = '::1,127\.0\.0\.1'" "$CONF_DIR/postgresql.conf" # Upstream's postgresql appliance replaces listen_addresses with '*' and diff --git a/plan/main b/plan/main index 743f6be..a0332b7 100644 --- a/plan/main +++ b/plan/main @@ -1,13 +1,11 @@ #include -/* There is no plans/turnkey/pgsql in common, so the packages are named - here. mk/turnkey/pgsql.mk brings the conf script and the overlay that - carries bin/pgsqlconf.py and firstboot.d/35pgsqlpass. */ -postgresql - -/* webmin-postgresql (2.660.turnkey0) is the module that puts the database - in the panel core already carries */ -webmin-postgresql +/* The server and webmin-postgresql (2.660.turnkey0), the module that puts + the database in the panel core already carries, are the plan of the + unit.d/postgresql component, together with the overlay that carries + bin/pgsqlconf.py and firstboot.d/35pgsqlpass and the conf script that + creates the cluster. fab resolves every unit's plan with this one, so they + are not named here. */ /* the command line client: the appliance talks to its own database over loopback, and firstboot.d/36pgsqlverify proves the declared password */