from typing import Optional from pyinfra import host from pyinfra.api import deploy from pyinfra.operations import apt, files, server, dnf from pyinfra.facts.server import LinuxName from pyinfra.facts import server as server_facts ELIXIR_DEFAULTS = { "elixir_version": "1.13.4", "erlang_version": "25", } def install_for_ubuntu(): elixir_is_updated = False erlang_is_updated = False wanted_elixir_version = host.data.elixir_version wanted_erlang_version = host.data.erlang_version elixir_command = host.get_fact(server_facts.Which, command="elixir") if elixir_command: elixir_version = host.get_fact(ElixirVersion) elixir_is_updated = elixir_version == wanted_elixir_version erlang_command = host.get_fact(server_facts.Which, command="erl") if erlang_command: erlang_version = host.get_fact(ErlangVersion) erlang_is_updated = erlang_version == wanted_erlang_version if elixir_is_updated and erlang_is_updated: return # elixir is non trivial to install because we can't # rely on the ubuntu package repo to be updated # # so we use the Erlang Solutions repository as recommended by elixir themselves. erlang_repo_deb_path = "/tmp/erlang-solutions.deb" files.download( name="download erlang solutions repo deb file", src="https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb", dest=erlang_repo_deb_path, ) apt.deb( name="install erlang solutions repo", src=erlang_repo_deb_path, ) # TODO: we don't need to update if we already installed the deb apt.update(cache_time=3600) # its in two separate steps as recommended by readme. who am i to judge apt.packages( name="install erlang", packages=[ f"erlang={otp_version}" if otp_version else f"erlang", f"erlang-manpages={otp_version}" if otp_version else f"erlang-manpages", ], ) apt.packages( name="install elixir", packages=[f"elixir={elixir_version}" if elixir_version else "elixir"], ) @deploy("Install Elixir", data_defaults=ELIXIR_DEFAULTS) def install(): linux_name = host.get_fact(LinuxName) if linux_name == "Fedora": dnf.packages(["erlang", "elixir"]) else: install_for_ubuntu() server.shell(name="test elixir exists", commands=["elixir -v"])