Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERL-1323: Make Erlang/OTP work from any installation directory by removing the need for an absolute path #4461

Closed
OTP-Maintainer opened this issue Aug 1, 2020 · 4 comments
Labels

Comments

@OTP-Maintainer
Copy link

Original reporter: jeromedebretagne
Affected version: Not Specified
Component: Not Specified
Migrated from: https://bugs.erlang.org/browse/ERL-1323


The current Erlang/OTP installation process (using _make release_ for instance) creates a few executable scripts (_bin/erl_, _bin/start_, _bin/start_erl_, _erts-X.Y.Z/bin/erl_, etc.) which define one or more absolute paths (_BINDIR_, _ROOTDIR_) that are freezing the installation into a specific directory.

This approach has the following consequences:
 # it is not possible to freely move the installation directory later on, as the above scripts then point to incorrect paths
 # it is needed to know upfront in which absolute path the Erlang runtime will be installed, or an extra step is required to update the scripts (using the ./Install script) to fix the paths and freeze the installation once the exact location is finally known

Looking at all the scripts, including the _./Install_ one, what seems to really matter is the directory structure relative to $ERL_ROOT in fact. I don't know the history/background for this choice to require an absolute path, it certainly brings some benefits (simplicity? robustness and wide-compatibility?) but it also adds an extra layer of complexity which creates some friction in a world of VMs / containers.

There are some ways to find the absolute path of a script from within itself, including following symlinks, such as this one:
{code:java}
prog="$0"
while [ -h "${prog}" ]; do
    newProg=`ls -ld "${prog}"`
    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
    if expr "x${newProg}" : 'x/' >/dev/null; then
        prog="${newProg}"
    else
        progdir=`dirname "${prog}"`
        prog="${progdir}/${newProg}"
    fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
cd "${progdir}"
progdir=`pwd`
prog="${progdir}"/`basename "${prog}"`
echo "${prog}"
cd "${oldwd}"{code}
from [dalvik/dx/etc/dx|https://android.googlesource.com/platform/dalvik/+/master/dx/etc/dx] as discussed and referenced here on [Stack Overflow|https://stackoverflow.com/questions/4774054/reliable-way-for-a-bash-script-to-get-the-full-path-to-itself]

Would a PR going in this direction be acceptable if removing the hardcoded absolute paths?

What would be other requirements to take into consideration (OS compatibility)? Other documented expectations that should be looked at carefully?

A smooth transition could be to keep full backwards compatibility with the current _./Install_ script approach by simply providing a default behavior when %FINAL_ROOTDIR% has not been set.

Thanks, Jérôme
@OTP-Maintainer
Copy link
Author

jeromedebretagne said:

For completeness, there is already one system at least for which point 2. above is already a deal breaker, which is Android 10, cf. [this issue #2 in erlanglauncher|https://github.com/JeromeDeBretagne/erlanglauncher/issues/2] .

Indeed, when targeting Android 10 and above, native executables (binaries or scripts) can have the needed execute permission only when preset in the APK and extracted within a specific directory (the app's native '_lib_' directory), following this change [Removed execute permission for app home directory|https://developer.android.com/about/versions/10/behavior-changes-10#execute-permission].

However, the absolute path of this '_lib_' directory is unknown until app installation time as it contains random characters (for instance '_/data/app/~~XQXxwg2AgjdCIm7mBvYUIg==/com.my.package-oThErRAnDOmChar==/lib_') and its content can't be updated once extracted as the app data is set as read-only for the [W^X security reasons|https://en.wikipedia.org/wiki/W%5EX]! To work around this recent restriction, the Erlang runtime will have to be modified to become fully independent of its installation path to keep working on Android going forward.

I know that Android is not a supported system, that's why I'm willing to investigate an approach that would fix this Android-specific issue while also providing similar benefits to the wider Erlang ecosystem.

Let me know your thoughts!

Jérôme

@OTP-Maintainer
Copy link
Author

richardc said:

+1. This has been on my wishlist since forever, but I've never dug deeply enough to find a good universal solution. Maybe such script trickery is enough.

@OTP-Maintainer
Copy link
Author

jeromedebretagne said:

Hi Richard,

I've created two pull requests, https://github.com/erlang/otp/pull/2863 and https://github.com/erlang/otp/pull/2879 to implement the changes discussed in this issue. The first one adds configurability to cover the Android specificities (through an environment variable) and the second one implements the proposed "script trickery". I've taken a smooth approach by keeping a full backwards compatibility with the existing installation scripts.

I don't seem to have the right permission on GitHub to add you as a reviewer, but I'd be glad to get your feedback.

Thanks, Jérôme

@garazdawi
Copy link
Contributor

#5427 is now merged which solves this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants