Hey everyone,

We already have multiple ways of installing Elixir 
(https://elixir-lang.org/install.html) but I believe we can still do 
better. Elixir is cross-platform but Erlang/OTP is not. We need to get OTP 
for **our OS/architecture**, ideally prebuilt or otherwise we need to 
compile it from source. I've listed some challenges with existing 
installation methods here: 
https://github.com/erlef/build-and-packaging-wg/issues/80.

Since a few releases ago, Elixir project maintains installer for Windows, 
e.g. 
<https://github.com/elixir-lang/elixir/releases/download/v1.17.2/elixir-otp-27.exe>,
 
but that still requires OTP. The installer tries to be helpful, finds 
whether OTP is already installed and the version matches and otherwise show 
a link to download it. This is a GUI installer that fortunately can be 
running headless, `.\elixir-otp-27.exe /S /D=C:\elixir`, but, again, we 
need to first install OTP.

I believe we can significantly improve Elixir getting started experience by 
having a "one click install" but for terminals, download a single script 
that installs Elixir and OTP for their system.

I've created a proof-of-concept called Elixir Install 
(https://elixir-install.org) and we can use it in bash  for 
macOS/Ubuntu/Windows:

    $ curl -fsS https://elixir-install.org/install.sh
    $ sh install.sh elixir@1.17.2 otp@27.0.1
    $ export PATH=$HOME/.elixir-install/installs/otp/27.0.1/bin:$PATH
    $ export 
PATH=$HOME/.elixir-install/installs/elixir/1.17.2-otp-27/bin:$PATH
    iex

and Powershell on Windows:

    > curl.exe -fsS https://elixir-install.org/install.bat
    > .\install.bat elixir@1.17.2 otp@27.0.1
    > $env:PATH = 
"$env:USERPROFILE\.elixir-install\installs\otp\27.0.1\bin;$env:PATH"
    > $env:PATH = 
"$env:USERPROFILE\.elixir-install\installs\elixir\1.17.2-otp-27\bin;$env:PATH"
    > iex.bat

(The actual script is .bat because I noticed that even though Windows ships 
with Powershell, by default running external scripts is prohibited.)

The script can also be executed without arguments, it will install the 
latest Elixir & OTP (hardcoded inside the script)

    $ curl -fsS https://elixir-install.org/install.sh | sh
    downloading 
https://github.com/erlef/otp_builds/releases/download/OTP-27.0.1/OTP-27.0.1-macos-arm64.tar.gz
    downloading 
https://github.com/elixir-lang/elixir/releases/download/v1.17.2/elixir-otp-27.zip
    (...)

The script is downloading OTP from these places:

  *  macOS: 
<https://github.com/erlef/otp_builds/releases/download/OTP-27.0.1/OTP-27.0.1-macos-arm64.tar.gz>,
 
see https://github.com/erlef/build-and-packaging-wg/issues/80
  *  Ubuntu: 
<https://builds.hex.pm/builds/otp/arm64/ubuntu-22.04/OTP-27.0.1.tar.gz>, 
see <https://github.com/hexpm/bob?tab=readme-ov-file#erlang-builds>. In the 
future I'd like to move it to <github.com/erlef/otp_builds> too.
  *  Windows: 
<https://github.com/erlang/otp/releases/download/OTP-27.0.1/otp_win64_27.0.1.zip>

I'd like to propose making this official under elixir-lang.org, that is:

  *  https://elixir-lang.org/install.sh
  *  https://elixir-lang.org/install.bat

## Security

In my proof of concept there are no additional security considerations 
besides using https. If this is not good enough, I think we could use the 
same security model as `mix local.hex`, that is, we'd download the build, 
the builds.txt (with all builds and their checksums), and the 
builds.txt.signed, and verify the signature against the public key the 
install would ship with. See https://blog.voltone.net/post/25 for more 
information.

To have an idea, this would be along the lines of:

    curl -fsSO https://builds.hex.pm/installs/hex-1.x.csv
    curl -fsSO https://builds.hex.pm/installs/hex-1.x.csv.signed
    # run `mix local.public_keys --detailed` and create public_key.pem
    openssl dgst -sha256 -verify public_key.pem -signature <(openssl base64 
-d -in hex-1.x.csv.signed) hex-1.x.csv

`openssl` is available on macOS, Windows, and Ubuntu Desktop.

## Non-Goals

  * No version management along the lines of asdf/mise/etc, this is better 
solved by these tools anyway.

## Caveats

In my proof of concept, the script requires sh and unzip on UNIX. (On 
Windows it's using curl too, which is built-in, but can be easily rewritten 
to using Powershell `Invoke-WebRequest`.) One caveat with this is while 
this works out of the box on Ubuntu Desktop,
the official Ubuntu Docker images does not have these and so they need to 
be installed:

    $ docker run --rm -it ubuntu bash
    docker$ apt update && apt install -y curl unzip
    docker$ curl -fsS https://elixir-install.org/install.sh | sh

This applies to `openssl` mentioned in the security section too. We could 
solve this by instead of a script have an executable (written in 
Go/Rust/Zig/etc) that would have everything it needs to download, unpack, 
and verify things. I think this would complicate things (executable would 
now or down the road have to be code signed, which fortunately we have some 
experience with already), users will be presented with a list to pick, and 
scripts would need a heuristic to figure out which installer to download.

## BEAMup

Tristan Sloughter is working on 
[BEAMup](https://erlangforums.com/t/beamup-a-new-way-to-install-erlang-gleam-and-more-to-come/3912),
 
similar tool but way more ambitious and with bigger scope. I'd like to 
think much smaller scope of elixir-lang.org/install.sh would make it easier 
to maintain. The most complicated underlying piece, having prebuilt OTP, is 
shared between the tools anyway.

## Elixir.app

Brian Cardarella shared a proof-of-concept of a GUI installer for macOS: 
https://x.com/bcardarella/status/1831040691801088308. Again, this would 
have bigger scope and the underlying foundation in prebuilt OTP is shared 
anyway.

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/6bbf2aa9-7d1b-42fe-a61e-abf72729519an%40googlegroups.com.

Reply via email to