Skip to content
Merged
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
55 changes: 50 additions & 5 deletions COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,58 @@ Measured on 2026-09-24 against upstream 19.x (b60dd23), following the
project decision 0003 (90 percent floor per repository, 95 percent for every
file our changes touch).

## Measured baseline on the default branch: 100 percent (2026-09-26)
## Measured baseline on the default branch: 100 percent (2026-09-28)

Pull request #2 merged on 2026-09-26 (merge commit 5a0a381) and brought
`tests/coverage.sh` with it: conf/turnkey.d/postfix-local 17 of 17 lines under kcov, 100 percent, 7 bats. The gate in
`.github/workflows/tests.yml` is set to 100, the measured number rounded
down, and is only ever raised. The sections that follow record the state
before the merge.
`tests/coverage.sh` with it. Every file it measures is at 100 percent:

| File | What it is | Measured |
| --- | --- | --- |
| `conf/turnkey.d/postfix-local` | the build-time postfix configuration | 100 percent, 17 of 17 lines, 7 bats |
| `conf/turnkey.d/dpkg-vendor` | points the dpkg vendor at Keel, and removes an inherited TurnKey origin | 100 percent, 7 of 7 lines, 16 bats |
| `conf/turnkey.d/apt-identity` | keeps the shipped apt User-Agent the one in force | 100 percent, 4 of 4 lines, 11 bats |

34 bats, measured on 2026-09-29 with kcov 43 and bats 1.11. The gate in
`.github/workflows/tests.yml` is set to 100, the measured number, and is
only ever raised. The sections that follow record the state before the
first merge.

## The apt and vendor identity of an image

Three things used to tell an archive, or a bug reporting tool, that this
machine is a TurnKey appliance (Keel-Linux/common#6). None of the
assertions below reads back a file the code under test wrote:

- **the vendor.** `conf/turnkey.d/dpkg-vendor` points the origins `default`
entry at the `Keel` file the matching overlay ships. Every verdict in
`tests/dpkg-vendor.bats` is an answer from the real `dpkg-vendor`, pointed
at the tree the script produced through dpkg's own `DPKG_ORIGINS_DIR`:
`--query Vendor`, `--query Bugs`, `--is`, `--derives-from`. The `Keel`
file keeps `Parent: Debian`, so `dpkg-dev` resolves the same vendor object
it did before and package building is unaffected. A `TurnKey` origin file
inherited from a parent layer is removed, so dpkg no longer knows that
vendor by name.
- **the apt User-Agent.** The header is a fixed file the overlay ships,
`/etc/apt/apt.conf.d/01keel`; `mk/turnkey.mk` and `mk/turnkey-desktop.mk`
no longer write a per-appliance `01turnkey`. Every verdict in
`tests/apt-identity.bats` is read off the wire: `tests/ua-recorder.py`
records the header a real `apt-get update` sent, over http and over TLS.
One test measures the hazard the conf script exists for: with a stale
`01turnkey` beside `01keel`, apt sends TurnKey's header, because
`apt.conf.d` is read in lexical order and the last assignment wins.
- **the source URIs.** The stanzas are extracted from `conf/bootstrap_apt`
itself, rendered with a build's variables and handed to apt, which is
asked with `apt-get indextargets` what it would fetch. No network.

Refutations in both suites are written `run ! cmd`, never a bare `! cmd`.
bash does not apply errexit to a negated command, so a bare one that is
not the last command of its test passes whatever happens; as the last
command it does decide the test, because bats takes the last status as the
verdict. `run !` asserts wherever it stands, which is why it is the
convention. shellcheck grades the two cases differently: SC2314 is an error
for the inert one and a note otherwise. Of the three bare negations in
`tests/postfix-local.bats`, only line 96 is inert; lines 66 and 97 are last
in their tests. It is left for the pull request that owns that file.

## Baseline before the merge: 0 percent, nothing measured

Expand Down
17 changes: 17 additions & 0 deletions changes/turnkey.changelog
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
turnkey-core-19.0 (1) turnkey; urgency=low

* apt no longer announces the appliance to every archive it contacts. The
per-appliance '/etc/apt/apt.conf.d/01turnkey', which carried a User-Agent
of 'TurnKey APT-HTTP/1.3 (turnkey-<app>-<version>-<codename>-<arch>)', is
replaced by a fixed '/etc/apt/apt.conf.d/01keel' naming the distribution
and nothing else. A stale 01turnkey inherited from a parent layer would
win on lexical order, so conf/turnkey.d/apt-identity removes it.

* 'dpkg-vendor' answers Keel, and bug reporting tools address
Keel-Linux/tracker rather than turnkeylinux/tracker. The TurnKey origin
file is no longer shipped, and one inherited from a parent layer is
removed; the new Keel one keeps 'Parent: Debian', so dpkg-dev behaves
exactly as before.

* The TurnKey archive is fetched over https rather than plain http, in all
three suites and in the legacy sources.list written for pre-Trixie
releases. The Debian sources are unchanged.

* Upgraded base distribution to Debian 13.x/Trixie.

* Replace TurnKey custom Debian-Installer based 'di-live' with new custom
Expand Down
12 changes: 6 additions & 6 deletions conf/bootstrap_apt
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ if [[ $deb_ver -ge 13 ]]; then
# Main repos
cat > $SOURCES_LIST/sources.sources <<EOF
Types: deb
URIs: http://archive.turnkeylinux.org/debian
URIs: https://archive.turnkeylinux.org/debian
Suites: $KEY_CODENAME
Components: main
Architectures: ${SUPPORTED_ARCH[*]}
Expand All @@ -222,7 +222,7 @@ EOF
# Security repos
cat > $SOURCES_LIST/security.sources.sources <<EOF
Types: deb
URIs: http://archive.turnkeylinux.org/debian
URIs: https://archive.turnkeylinux.org/debian
Suites: $KEY_CODENAME-security
Components: main
Enabled: $tkl_apt_repo_enabled
Expand All @@ -248,7 +248,7 @@ EOF
# TurnKey testing repo
cat > $SOURCES_LIST/turnkey-testing.sources <<EOF
Types: deb
URIs: http://archive.turnkeylinux.org/debian
URIs: https://archive.turnkeylinux.org/debian
Suites: $KEY_CODENAME-testing
Components: main
Enabled: $tkl_apt_testing_enabled
Expand All @@ -258,14 +258,14 @@ EOF
else
# legacy sources.list files for bookworm and earlier
cat > $SOURCES_LIST/sources.list <<EOF
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-main.gpg] http://archive.turnkeylinux.org/debian $KEY_CODENAME main
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-main.gpg] https://archive.turnkeylinux.org/debian $KEY_CODENAME main

deb $MIRROR_URL $CODENAME ${MAIN[*]}
deb $MIRROR_URL $CODENAME ${CONTRIB[*]}
#deb $MIRROR_URL $CODENAME ${NON_FREE[*]}
EOF
cat > $SOURCES_LIST/security.sources.list <<EOF
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-security.gpg] http://archive.turnkeylinux.org/debian $KEY_CODENAME-security main
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-security.gpg] https://archive.turnkeylinux.org/debian $KEY_CODENAME-security main

deb $SEC_MIRROR $sec_repo ${MAIN[*]}
deb $MIRROR_URL $CODENAME ${CONTRIB[*]}
Expand All @@ -276,7 +276,7 @@ EOF
TKL_TESTING_LIST=$TKL_TESTING_LIST.disabled
fi
cat > $SOURCES_LIST/$TKL_TESTING_LIST <<EOF
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-testing.gpg] http://archive.turnkeylinux.org/debian $KEY_CODENAME-testing main
deb [signed-by=$key_dir/tkl-$KEY_CODENAME-testing.gpg] https://archive.turnkeylinux.org/debian $KEY_CODENAME-testing main
EOF
DEB_BACKPORT_LIST=$SOURCES_LIST/debian-backports.list
if [[ -z "$BACKPORTS" ]]; then
Expand Down
22 changes: 22 additions & 0 deletions conf/turnkey.d/apt-identity
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash -e
#
# Keeps the apt User-Agent of the image the one the overlay ships.
#
# The header itself is overlays/turnkey.d/apt-identity's 01keel. This exists
# because apt reads /etc/apt/apt.conf.d in lexical order and the last
# assignment of a scalar wins, so a 01turnkey inherited from a parent layer
# built before Keel-Linux/common#6 silently beats the 01keel beside it and the
# appliance goes back to announcing which appliance and which version it is.
# Measured: with both files in place apt sends TurnKey's header, and
# tests/apt-identity.bats takes that verdict off the wire.
#
# APT_CONF_DIR is a test hook; a build leaves it unset.

fatal() { echo "'$(basename "$0")' Error: $*" >&2; exit 1; }

conf_dir="${APT_CONF_DIR:-/etc/apt/apt.conf.d}"

[ -d "$conf_dir" ] || fatal "the apt configuration directory '$conf_dir' does not exist"
[ -f "$conf_dir/01keel" ] || fatal "'$conf_dir/01keel' is missing - it is shipped by overlays/turnkey.d/apt-identity"

rm -f "$conf_dir/01turnkey"
39 changes: 35 additions & 4 deletions conf/turnkey.d/dpkg-vendor
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
#!/bin/bash -e
#
# Creates required symlink so dpkg-vendor --query vendor
# returns the correct string
# Makes a vendor query answer Keel.
#
# dpkg reads the vendor of the running system from the 'default' entry of the
# origins directory (Dpkg::Vendor), which has to resolve to one of the files
# beside it. The Keel file itself is shipped by the matching overlay,
# overlays/turnkey.d/dpkg-vendor. Everything a vendor query answers comes out
# of the file this points at: the name dpkg-vendor reports, and the tracker
# that bug reporting tools address. It used to point at TurnKey, so both
# named TurnKey (Keel-Linux/common#6).
#
# The Keel file keeps "Parent: Debian", and that line is not decoration.
# There is no Dpkg::Vendor::Keel perl module, so Dpkg::Vendor falls back to
# the parent's object, Dpkg::Vendor::Debian, the one TurnKey resolved to:
# Debian's hardening defaults, update-buildflags hook and changelog
# handling. Without Parent it would fall to Dpkg::Vendor::Default instead.
#
# DPKG_ORIGINS_DIR is dpkg's own override of that directory, honoured here so
# tests/dpkg-vendor.bats can arrange a tree and then ask the real dpkg-vendor
# what it makes of it, rather than reading back the link this wrote. A build
# leaves it unset and the directory is /etc/dpkg/origins.

fatal() { echo "'$(basename "$0")' Error: $*" >&2; exit 1; }

origins="${DPKG_ORIGINS_DIR:-/etc/dpkg/origins}"
vendor="Keel"

[ -d "$origins" ] || fatal "the dpkg origins directory '$origins' does not exist"
[ -f "$origins/$vendor" ] || fatal "'$origins/$vendor' is missing - it is shipped by overlays/turnkey.d/dpkg-vendor"

rm -rf "$origins/default"
ln -s "$origins/$vendor" "$origins/default"

rm -rf /etc/dpkg/origins/default
ln -s /etc/dpkg/origins/TurnKey /etc/dpkg/origins/default
# An overlay only adds files, so a parent layer built before this change
# leaves its TurnKey origin file behind, and dpkg keeps knowing that vendor
# by name. Remove it, as apt-identity removes a stale 01turnkey.
rm -f "$origins/TurnKey"
13 changes: 7 additions & 6 deletions mk/turnkey-desktop.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ endef
bootstrap/post += $(_bootstrap/post)

# tag package management system with release package
# set /etc/turnkey_version and apt user-agent
# set /etc/turnkey_version
#
# The apt User-Agent is no longer written here, for the reason given in
# mk/turnkey.mk: overlays/turnkey.d/apt-identity ships it (Keel-Linux/common#6).
define _root.patched/post
#

#
# tagging package management system with release package
# setting /etc/turnkey_version and apt user-agent
# setting /etc/turnkey_version
#
@if [ -f $(FAB_PATH)/products/core/changelog ]; then \
echo $(FAB_SHARE_PATH)/make-release-deb.py $(FAB_PATH)/products/core/changelog $O/root.patched; \
Expand All @@ -62,9 +65,7 @@ define _root.patched/post
echo $(FAB_SHARE_PATH)/make-release-deb.py ./changelog $O/root.patched; \
$(FAB_SHARE_PATH)/make-release-deb.py ./changelog $O/root.patched; \
turnkey_version=$$($(FAB_SHARE_PATH)/turnkey-version.py --dist=$(CODENAME) --tag=$(VERSION_TAG) ./changelog $(FAB_ARCH)); \
turnkey_aptconf="Acquire::http::User-Agent \"TurnKey APT-HTTP/1.3 ($$turnkey_version)\";"; \
echo $$turnkey_version > $O/root.patched/etc/turnkey_version; \
echo $$turnkey_aptconf > $O/root.patched/etc/apt/apt.conf.d/01turnkey; \
else \
echo; \
echo "WARNING: can't tag local release (./changelog doesn't exist)"; \
Expand Down
16 changes: 10 additions & 6 deletions mk/turnkey.mk
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,24 @@ endef
bootstrap/post += $(_bootstrap/post)

# tag package management system with release package
# set /etc/turnkey_version and apt user-agent
# set /etc/turnkey_version
#
# The apt User-Agent is no longer written here. It used to carry the appliance
# and its version to every archive the machine ever contacted; it is now a
# fixed header naming the distribution and nothing else, shipped by
# overlays/turnkey.d/apt-identity as /etc/apt/apt.conf.d/01keel
# (Keel-Linux/common#6).
define _root.patched/post
#

#
# tagging package management system with release package
# setting /etc/turnkey_version and apt user-agent
# setting /etc/turnkey_version
#
@if [ -f ./changelog ]; then \
echo $(FAB_SHARE_PATH)/make-release-deb.py ./changelog $O/root.patched; \
$(FAB_SHARE_PATH)/make-release-deb.py ./changelog $O/root.patched; \
turnkey_version=$$($(FAB_SHARE_PATH)/turnkey-version.py --dist=$(CODENAME) --tag=$(VERSION_TAG) ./changelog $(FAB_ARCH)); \
turnkey_aptconf="Acquire::http::User-Agent \"TurnKey APT-HTTP/1.3 ($$turnkey_version)\";"; \
echo $$turnkey_version > $O/root.patched/etc/turnkey_version; \
echo $$turnkey_aptconf > $O/root.patched/etc/apt/apt.conf.d/01turnkey; \
else \
echo; \
echo "WARNING: can't tag local release (./changelog doesn't exist)"; \
Expand Down
13 changes: 13 additions & 0 deletions overlays/turnkey.d/apt-identity/etc/apt/apt.conf.d/01keel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// The User-Agent apt announces to every archive it contacts.
//
// It names the distribution and nothing else. What used to stand here was
// /etc/apt/apt.conf.d/01turnkey, written per appliance by mk/turnkey.mk:
//
// Acquire::http::User-Agent "TurnKey APT-HTTP/1.3 (turnkey-wordpress-19.0-trixie-amd64)";
//
// so deb.debian.org, security.debian.org, every mirror in between and anyone
// watching the connection were told which appliance this machine is and which
// version it runs, on every apt run it ever made. Keel-Linux/common#6.
//
// The https method of apt reads this same setting, so one line covers both.
Acquire::http::User-Agent "Keel APT-HTTP/1.3";
4 changes: 4 additions & 0 deletions overlays/turnkey.d/dpkg-vendor/etc/dpkg/origins/Keel
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Vendor: Keel
Vendor-URL: https://keellinux.org/
Bugs: https://github.com/Keel-Linux/tracker/issues
Parent: Debian
4 changes: 0 additions & 4 deletions overlays/turnkey.d/dpkg-vendor/etc/dpkg/origins/TurnKey

This file was deleted.

Loading
Loading