Skip to content

Go Edition: Install command #497

@Zordrak

Description

@Zordrak

Summary

Implement the tfenv install command for the Go edition with full parity to the Bash edition, including all version specifiers and concurrent install locking.

Parent Epic

Part of #488 — Go Edition: Full Feature Parity Implementation

Motivation

tfenv install is the primary command users interact with. It must resolve version specifiers, download and verify binaries, and install them to the versions directory. It must handle concurrent installs safely (e.g., multiple Terragrunt workers calling tfenv install simultaneously).

Clean-Room Constraint

This is a clean-room implementation. Contributors MUST NOT read, reference, copy, or adapt source code from tofuutils/tenv, hashicorp/hc-install, or any other third-party tfenv-like tool. The sole reference is tfenv's own Bash source code, documentation, and test suite.

Proposed Design

Command Interface

tfenv install [<version>]
tfenv install latest
tfenv install latest:<regex>
tfenv install latest-allowed
tfenv install min-required

When called without arguments, reads .terraform-version or default version file.

Install Flow

  1. Validate argument count (0 or 1 args only — [ "${#}" -gt 1 ] is an error)
  2. Resolve version specifier → version:regex pair (using resolve-version logic)
  3. Pre-release filtering: If TFENV_SKIP_REMOTE_CHECK is not set, fetch remote versions. For latest with numeric-only regex, exclude pre-release versions (containing -). For regex containing letters (e.g., rc, alpha), include pre-releases.
  4. Check if version already installed (${TFENV_CONFIG_DIR}/versions/${version}/terraform exists) — this check happens BEFORE any network calls for exact versions
  5. If already installed, print Terraform v${version} is already installed and exit 0
  6. Acquire per-version install lock
  7. Re-check if installed (another process may have completed while we waited for lock)
  8. Determine platform: OS detection + architecture with ARM64 fallback logic (delegated to platform package from Go Edition: Configuration, state directory & platform detection #492)
  9. Download, verify (PGP + SHA256), and extract (delegated to Go Edition: Download, PGP verification, SHA256 verification & extraction #496)
  10. Release lock
  11. Print success: Installation of terraform v${version} successful. To make this your default version, run 'tfenv use ${version}'

Concurrent Install Locking

When multiple processes try to install the same version simultaneously (common with Terragrunt run-all):

Bash edition mechanism (reference: libexec/tfenv-install lines 100-125):

  • Uses mkdir as an atomic lock: mkdir "${TFENV_CONFIG_DIR}/.install-lock-${version}"
  • If lock exists, wait 1 second and retry (up to 60 retries)
  • On first wait, print info: Another process is installing Terraform v${version}. Waiting...
  • After timeout (60s), warn about stale lock, remove it, and retry once
  • Check if version appeared while waiting (another process finished)
  • Lock removed on normal exit, error, INT, and TERM signals via trap

Go edition should use the same mkdir approach for cross-platform atomic locking (works on Linux, macOS, and Windows/MSYS). flock/fcntl is not portable to Windows.

  • Lock directory: ${TFENV_CONFIG_DIR}/.install-lock-${version}
  • defer for cleanup ensures lock is released on all exit paths
  • Stale lock detection: if lock is older than N minutes (e.g., 10), consider it stale

Auto-Install

TFENV_AUTO_INSTALL=true (default) triggers install when the terraform shim is invoked and the resolved version is not installed. This is handled by the exec/shim layer but the install command must support being called programmatically (not just via CLI).

Acceptance Criteria

  • tfenv install 1.5.0 installs Terraform 1.5.0
  • tfenv install latest installs the latest stable version
  • tfenv install latest:^1.5 installs the latest 1.5.x version
  • tfenv install latest-allowed installs based on HCL constraints
  • tfenv install min-required installs the minimum satisfying version
  • tfenv install (no args) reads .terraform-version or default version file
  • Already-installed versions print a message and exit 0 (no re-download)
  • Concurrent installs of the same version are serialized via locking
  • Concurrent installs of different versions proceed in parallel
  • Lock is released on success, failure, and process termination
  • Stale locks (from crashed processes) are detected and cleaned up
  • Exit code 0 on success, non-zero on failure
  • Clear error messages for: version not found, network failure, verification failure, disk full
  • Acceptance tests cover all version specifiers (using mock server)
  • Acceptance test covers concurrent install scenario
  • Issue tfenv install fails on a clean machine: lock mkdir ENOENT misreported as "Another process is installing" #487 scenario (lock mkdir ENOENT) is handled correctly

Dependencies

Implementation Notes

Labels

type:feature, priority:high, complexity:medium, category:install

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions