I recommend to keep the base functionality and all its involved components as static as possible (only upgradable as a full, robust OS update):
- Mender client for robust A/B update.
- Connectivity setup towards vital backend system(s) (e.g. hosted Mender).
- Linux kernel.
- Rootfs with base user space functionality.
- Ansible or CFEngine (it should not update itself dynamically).
- …
The dynamic part could include the following use cases:
- Configure LAN ports of an IoT gateway (without modifying the WAN setup).
- Add some software containing intellectual property that can only be shipped to certain countries.
- Enable extra features that some customers are paying for.
- Fix issues of the system in an incremental way. Of course such modifications should not have a harmful effect on the base functionality.
- …
So Mender makes sure that the base functionality works while Ansible or CFEngine dynamically modifies the “nice to have” part that actually provides the features requested by a certain installation. The “nice to have” part can be very dynamic and depend upon facts that need to be gathered from the given device instance.