tfutils / tfenv

Terraform version manager
MIT License
4.52k stars 454 forks source link

Support both amd64 and arm64 binaries #337

Open FernandoMiguel opened 2 years ago

FernandoMiguel commented 2 years ago

mac M1 users that default their install to arm64 can be stuck on using old providers that dont have arm binaries. Users can TFENV_ARCH=amd64 tfenv install latest , or any other version, but if there is already an arm one it does not replace it.

it should be possible to have both binary versions installed, and the user could then pick the arch

$ TFENV_ARCH=amd64 TFENV_TERRAFORM_VERSION=latest:^1.2 terraform -v
Terraform v1.2.3
on darwin_amd64

$ TFENV_ARCH=arm64 TFENV_TERRAFORM_VERSION=latest:^1.3 terraform -v
Terraform v1.3.0-alpha20220608
on darwin_arm64

that way, users could temporarily pick the right arch, without having to uninstall the default arm64, just to run amd64 binaries.

Zordrak commented 2 years ago

After some thought I'm not sure of a way to reliably implement this without a total refactor of the versioning mechanism to incorporate architecture and version number into every decision. I welcome alternative suggestions to achieve this. As a workaround for the affected, I would recommend a dual-install. One tfenv per architecture which you can call for the architecture you need.

reegnz commented 1 year ago

One solution I've come up with that seems to work reliably: Whenever you need to use amd64 binaries, you set two env vars instead of one:

export TFENV_ARCH=amd64
export TFENV_CONFIG_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/tfenv/${TFENV_ARCH}

When you want to switch back to arm64, you unset or redefine the TFENV_CONFIG_DIR:

unset TFENV_ARCH
unset TFENV_CONFIG_DIR

You can easily wrap those two into a convenient shell function too:

tfenv_switch_arch() {
  if [-n "$TFENV_ARCH" ]; then
    echo "tfenv: switching to native" >&2
    unset TFENV_ARCH TFENV_CONFIG_DIR
    return
  fi
  echo "tfenv: switching to amd64" >&2
  export TFENV_ARCH=amd64
  export TFENV_CONFIG_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/tfenv/${TFENV_ARCH}
}

Drop it in your zshrc and use it as needed.

You don't even need a dual-install, just setting another env-var to a different location to cache the binaries. I could prepare a PR for tfenv to handle the switching between the TFENV_CONFIG_DIR based on whether the TFENV_ARCH variable is defined or not. That would be backward-compatible eg. define a new TFEV_CONFIG_DIR if TFENV_ARCH is declared: TFENV_CONFIG_DIR=${TFENV_CONFIG_DIR}/${TFENV_ARCH}.

FernandoMiguel commented 1 year ago

never thought of using TFENV_CONFIG_DIR that's nice!

FernandoMiguel commented 1 year ago

yeah, i would love for tfenv to detect this scenario and handle this natively by using a diff directory. a PR would be appreciated!