Fixing a FreeBSD server with out of sync etcupdate status
A system with a clean /etc is a warm and welcoming system
Introduction
Let's say you have a FreeBSD server which you upgraded multiple times, but the last time you forgot to run the etcupdate migrations.
Reference system:
FreeBSD example.net 13.1-RELEASE-p2 FreeBSD 13.1-RELEASE-p2 752f813d6 GENERIC amd64
You can run etcupdate, but it's too late:
etcupdate extract etcupdate
etcupdate will only update the change for the current version now.
etcupdate diff
The diff command shows a lot a changes from the previous version.
Fixing the previous version
You can fix your system by patching files using the diff output and the current files in /var/db/etcupdate/current, but this is time consuming and error prone.
Instead, let's fix it properly.
First, we need to identify what was the version we missed the update from.
Let's say we went from 13.0-RELEASE to 13.1-RELEASE.
We need the source tree of the previous version:
fetch http://ftp.fr.freebsd.org/pub/FreeBSD/releases/amd64/13.0-RELEASE/src.txz -o src-13.0.txz
Extract it somewhere:
mkdir /usr/src.13.0/ tar --unlink -xvpJf src-13.0.txz -C /usr/src.13.0/ --strip-components=2
Build a etcupdate tarball for that specific version
etcupdate build -s /usr/src.13.0/ etcupdate-13.0.tgz
Now, clear the etcupdate database and extract the specific tarball we just built:
rm -r /var/db/etcupdate/* etcupdate extract -t etcupdate-13.0.tgz
Now we can run the updates from the old version:
etcupdate -p etcupdate etcupdate resolve
Running the update from the current version
Get the current updates from the current source tree:
etcupdate extract
If you don't have the current source tree, you can build the update database the same way we did the previous version.
Run etcupdate as usual
etcupdate -p etcupdate etcupdate resolve
Check that the diff now only shows local changes
etcupdate diff
All good!