A necessary part of directory server is the ability to upgrade instances to use new features that we have developed and provide to our users. However this problem space is far larger than traditionally we have implemented for.
Previously, directory server has a strong relationship between the application (rpms and the binaries they provide) and the state (the database, the configuration in /etc). This mean that changes in the application could be assumed to occur with the state of the instance. Tools like setup-ds.pl -u certainly did this, to upgrade instance configuration on upgrade of the rpm. We also provided entries in template-dse.ldif and such to achieve this.
However, that’s not sufficent today. Two scenarioes exist that complicate this. One is when you restore your state (db, config) from a backup to a server that has already completed the rpm upgrade process. This now relies on the administrator to manually run setup-ds.pl - something we can not guarantee and poses a risk to stability of the service. The second scenario is containers - containers by their nature seperate the application (the container image) from the state (the data volume attached at runtime). In containers, the application may be upgrade in the image, but this occurs seperate to the state - an administrator would “pull” the new image and run it attached to the state, with no upgrade process in place.
With this in mind we must consider that as application and state are seperated, the only time our application can affect the data state and perform an upgrade, is at the time they are first attached
This is the first strategy - we do not need to migrate anything that does not exist. Having features that are switched at compile time through define flags, means we have a path to enable and disable features for development and release, and a path to “rollback” for customers. It also helps that when we enable features, we guarantee that all upgrades will be consuming these changes in a consitent and uniform manner.
If we can not avoid configuration, we should use the configuration reset mechanism. This is where we ship “default” values in libglobs.c, that do not need to be in cn=config. This allows admins to override defaults if they wish, means we do not require any migrations, and can change the default progressively over time where the upgrade will “take effect” unless an override has been provided. For more information see:
If we have a configuration entry that requires creation such as a plugin definition, or some other
more complex change, we should migrate these on start up using the mechanisms in
config.c slapd_bootstrap_config(). An example of this is the creation of the PBKDF2 plugin on start