Install FreeBSD.app: Allow upgrades and/or clean installs preserving /home
Clean install (current behavior): On the selected disk, delete the partition table (using /sbin/gpart destroy -F "${INSTALLER_DEVICE}", and then create new partitions using bsdinstall zfsboot. As a result, the root filesystem will be mounted at FSMNT="/mnt" and the installation proceeds.
Clean install preserving /home: Like clean install, but do not delete the partition table, and leave /home alone but do delete all other partitions.
Upgrade: Check for existing disks that contain a helloSystem installation, delete all files that were previously installed there by the helloSystem installer, and then install the new helloSystem version there. (Actually, optimize for speed by only deleting the files that won't be overwritten.)
For Upgrade, idea:
- The installer installs
.spec"receipt" (BOM, manifest, list of installed files) files onto the system. Thespec.userandspec.developerfiles that are already being used in the ISO creation process can be used for this purpose - When the installer runs, it checks for existing
.specfiles and compares them with its own.specfile. It deletes all files that are contained in the old but not in the new.specfile usingmtree -f old.spec -f new.spec | grep -v $'^\t'; then it possibly also should delete all empty directories that are not contained in the new.specfile (or not?) - Then it installs (only) the files that are different in the new vs. the old
.specfiles, overwriting existing files (for this, we would need to put more information into our.specfiles, such as a checksum or at least size in bytes. Worth the effort?)
As a result, upgrade installations should be very quick if only a few files have changed. Files not originally installed by the installer (e.g., files created by users) should remain untouched. However, files originally created by the installer but then changed by users will get replaced by the new version. (I believe this is the only way we can ensure that the new system works as designed, and as tested - but it means that users need to re-apply changes they made to the system. Is that what we want?)
But: This alone would result in a totally messed up pkg database.
Hence, we would need to find a way to preserve the old pkg database but replace the entries that are also in the new pkg database with the new values.
Before the upgrade:
# Export the old package list
sqlite3 /var/db/pkg/local.sqlite "SELECT origin FROM packages ORDER BY origin" > old_pkg_list
# Preserve the old package database
sudo cp /var/db/pkg/local.sqlite /var/db/pkg/local.sqlite.old
After the upgrade, find the ports that were in the database before but are not there anymore:
sqlite3 /var/db/pkg/local.sqlite "SELECT origin FROM packages ORDER BY origin" > new_pkg_list
comm -2 -3 old_pkg_list new_pkg_list # ports in old but not in new
comm -1 -3 old_pkg_list new_pkg_list # ports in new but not in old (not needed here)
Then, we need to use sqlite3 to transfer the information about those packages from the old to the new database.
How to do this exactly?
Maybe this all is not really robust enough. E.g., what if the sqlite schema changes? Then it all breaks down,