Don't do app upgrades in the background

This removes the logic for transparently upgrading apps and moves it to the same system we use for core upgrades.
Transparent app upgrades can leave the instance in a broken state when requests are being processed in parallel.

Only doing the upgrades in the foreground prevents this and provide a way for users to know when an upgrade failed.

cc @DeepDiver1975 @PVince81 
Compatibility check algo was changed during refactoring: needs retest