OTP 24 overlay: resolving code:which/1 non‑determinism in repeatable development environments
0 reputation · 09 Aug 2022, 02:32 UTC
0 reputation · 09 Aug 2022, 02:32 UTC
Build a Docker‑based CI pipeline that can run an Erlang release on multiple OTP releases (23 and 24) while keeping module resolution deterministic.
OTP 24 introduced the overlay mechanism, allowing partial patching without a full system restart. However, the code:which/1 resolution order changed between OTP 23 and 24 when external code directories are present. This can lead to different modules being loaded in the same container image, breaking repeatability. There is no documented flag to revert to the old resolution order, and release_handler scripts must be written manually to downgrade an overlay, which is error‑prone.
1. What configuration options (e.g., code_path or environment variables) can enforce the OTP 23 module resolution order in OTP 24?
2. Does OTP 24 provide a mechanism or flag to disable overlay loading for a specific release, and if so, how can it be applied in a CI pipeline?
3. What best‑practice release_handler scripts exist for safely rolling back an overlay upgrade when a build container is reused across major OTP versions?
32775 reputation · 09 Aug 2022, 12:43 UTC
1. Enforce OTP 23 resolution order in OTP 24: Set the external code directories before the overlay directory in the VM’s code path. Use the ERL_LIBS environment variable or the -pa flag when invoking erl.
export ERL_LIBS=$EXTERNAL_DIR:$OVERLAY_DIR (external first).erl -pa $EXTERNAL_DIR -pa $OVERLAY_DIR …2. Disable overlay loading for a specific release: OTP 24 does not provide a dedicated flag, but the overlay is only active when a non‑empty overlay directory exists. To disable it, either:
ERL_CODE_PATH_OVERLAY="" to clear the path passed to the runtime.3. Best‑practice release_handler rollback script for reused containers:
%% 1. Unpack the previous release
release_handler:unpack_release(PrevRelease).
%% 2. Install the previous release
release_handler:install_release(PrevRelease).
%% 3. Roll back the current release
release_handler:rollback_release().
%% 4. Remove any overlay files that were added by the newer release
filelib:delete_dir(OverlayDir),
%% 5. Purge stale modules that might still be loaded
[code:purge(Module) || Module <- code:all_loaded()].
This sequence guarantees that the VM ends up with the code from the previous release, with no overlay artifacts lingering.
code:get_path() and confirm the external directory appears before the overlay directory.code:which(MyModule) on a module that exists in both locations to verify the file path comes from the external directory.filelib:is_dir(OverlayDir) should return false or the directory should be empty if you want overlays disabled.release_handler:which_releases() and code:which(MyModule) again to ensure the original module is loaded.To fine‑tune the recommendation, could you confirm whether the release you are testing contains an overlay directory and whether it is non‑empty when the VM starts?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.