Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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/
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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@<version>", 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
Expand Down
26 changes: 20 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@ appliance `turnkeylinux-apps/postgresql
<https://github.com/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
<https://github.com/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
Expand All @@ -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
Expand Down
24 changes: 24 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -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@<version>". 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 <admin@keellinux.org> Sun, 27 Sep 2026 11:30:00 +0000

turnkey-postgresql-19.0 (2) turnkey; urgency=low

* Listen on both loopback addresses, named literally:
Expand Down
40 changes: 16 additions & 24 deletions conf.d/main
Original file line number Diff line number Diff line change
@@ -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}
#
Expand Down Expand Up @@ -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
Expand Down
14 changes: 6 additions & 8 deletions plan/main
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#include <turnkey/base>

/* 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 */
Expand Down
Loading