- 2022-12-07: @thalesmg Initial draft
- 2022-12-13: @thalesmg Added comment about downgrading
This proposes a way to circumvent the limitation that the hot upgrade installation scripts that are executed cannot be changed after a package is released, making it impossible to fix bugs or change upgrade logic.
This section should clearly explain why the functionality proposed by this EIP is necessary. EIP submissions without sufficient motivation may be rejected outright.
Currently, when performing a hot upgrade, the scripts that are run are those from the currently installed EMQX version. It has a validation that prevents upgrade between different minor versions. If we want to allow an upgrade from, say, 5.0.x to 5.1.y, then the scripts in already released packages will deny such operation. Also, if an upgrade installation script contains a bug in the current, it will never be able to execute properly without manual patching.
By attempting to execute the scripts from the target version, we may add fixes and new validations to new EMQX versions and have them executed by older versions.
- A zip file with a conventional filename format
(
<relname>-<version>.tar.gz) is placed in thereleasesdirectory of the currently running EMQX installation. Typically this means/usr/lib/emqx/releases. - The user runs
emqx {install,upgrade,unpack} <relname>-<version>. - The
emqxscript then callsinstall_upgrade.escriptfrom the currently running version with some info alongside the desired operation and new version. - The script then processes the desired operation.
Currently, a versioned copy of install_upgrade.escript and emqx
are already installed with EMQX in the bin directory. That means
install_upgrade.escript-<version> and emqx-<version>,
respectively.
- First of all, we check if the currently installed and the target
release profiles match. For example, if the enterprise edition is
currently installed and the user attempts to hot-upgrade using a
community edition package (
emqx-<version>.tar.gz) or vice-versa, the operation should abort.- This can be done by checking the
$IS_ENTERPRISEvariable that is set inemqx_varsand loaded bybin/emqxagainst the package filename:emqx-<version>.tar.gzfor community edition,emqx-enterprise-<version>.tar.gzfor enterprise edition.
- This can be done by checking the
- In the
emqxscript, we parse the desired operation and target version and check if scripts calledinstall_upgrade.escript-<target version>andemqx-<target version>exist in thebindirectory.- If it does, it means that the target version was already unpacked
at some point, and we just execute
emqx-<target version>passing it the necessary info. - We also need to check inside the
emqxscript if it is theemqx-<target version>script itself, to avoid an infinite loop.
- If it does, it means that the target version was already unpacked
at some point, and we just execute
- If any such file does not exist, then, without executing the
currently installed
install_upgrade.escriptfile:- We check if the
<relname>-<target version>.tar.gzfile is at the expected location (releases) and it's readable, bailing out otherwise. - We extract only the
install_upgrade.escript-<target version>andemqx-<target version>files to thebindirectory. - Then we just call
emqx-<target version>with the same arguments:emqx-<target version> {install,unpack,upgrade} <target version>.
- We check if the
For downgrading, since a newer script might have bug fixes and also have laxer restrictions on the source and target versions (for example, an older script might forbid 5.0 <-> 5.1, but the newer one allows it), we have to use the newer script as well. Otherwise the user might risk getting stuck at the newer version without being able to downgrade.
No configuration changes needed.
Since EMQX 5.0, at the time of writing, has not been tracking appup changes for hot upgrades, so this change shouldn't pose backwards compatibility issues.
The documentation for 5.0 currently doesn't even have a section for hot upgrades, so it'll need to be ported from 4.x.
The final implementation must include unit test or common test code. If some more tests such as integration test or benchmarking test that need to be done manually, list them here.
No prior alternatives discussed.