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 */