Utilities icon indicating copy to clipboard operation
Utilities copied to clipboard

Install FreeBSD.app: Allow upgrades and/or clean installs preserving /home

Open probonopd opened this issue 2 years ago • 1 comments

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.)

probonopd avatar Jan 22 '23 11:01 probonopd

For Upgrade, idea:

  1. The installer installs .spec "receipt" (BOM, manifest, list of installed files) files onto the system. The spec.user and spec.developer files that are already being used in the ISO creation process can be used for this purpose
  2. When the installer runs, it checks for existing .spec files and compares them with its own .spec file. It deletes all files that are contained in the old but not in the new .spec file using mtree -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 .spec file (or not?)
  3. Then it installs (only) the files that are different in the new vs. the old .spec files, overwriting existing files (for this, we would need to put more information into our .spec files, 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,

probonopd avatar Jan 22 '23 11:01 probonopd