Installer source
Read exactly what the installer runs.
These are the same scripts served by the raw install URLs. They verify the downloaded native CLI checksum, install it for your user, and start the guided server setup.
macOS and Linux
Raw script#!/bin/sh
set -eu
say() {
printf '%s\n' "$*"
}
fail() {
say "OpenTeam installer: $*" >&2
exit 1
}
command_exists() {
command -v "$1" >/dev/null 2>&1
}
cyan=""; green=""; bold=""; reset=""
if [ -t 1 ] && [ "$(printenv TERM 2>/dev/null || printf dumb)" != "dumb" ] && ! printenv NO_COLOR >/dev/null 2>&1; then
cyan=$(printf '\033[36m'); green=$(printf '\033[32m')
bold=$(printf '\033[1m'); reset=$(printf '\033[0m')
fi
step() {
printf ' %b%s%b %s\n' "$3" "$1" "$reset" "$2"
}
# ASCII source keeps raw-template bundlers from turning glyphs into literal Unicode escapes.
diamond=$(printf '\342\227\207'); checkmark=$(printf '\342\234\223')
ellipsis=$(printf '\342\200\246'); middot=$(printf '\302\267')
os_name=$(uname -s 2>/dev/null || printf unknown)
arch_name=$(uname -m 2>/dev/null || printf unknown)
case "$os_name" in
Darwin) platform="macOS"; binary_os="darwin" ;;
Linux) platform="Linux"; binary_os="linux" ;;
*) fail "unsupported system: $os_name. Use https://openteam.so/download for other options." ;;
esac
case "$arch_name" in
x86_64|amd64) architecture="x64" ;;
arm64|aarch64) architecture="arm64" ;;
*) fail "unsupported architecture: $arch_name. OpenTeam supports x64 and arm64 hosts." ;;
esac
printf '\n %bOPENTEAM%b / install\n' "$bold$cyan" "$reset"
say " $platform $middot $architecture"
say ""
command_exists curl || fail "curl is required to download the OpenTeam CLI."
repository=$(printenv OPENTEAM_REPOSITORY 2>/dev/null || printf raghavpillai/openteam)
cli_version=$(printenv OPENTEAM_VERSION 2>/dev/null || printf latest)
if [ "$cli_version" = "latest" ]; then
release_json=$(curl -fsSL "https://api.github.com/repos/$repository/releases/latest") ||
fail "no public OpenTeam release is available yet."
release_tag=$(printf '%s' "$release_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)
[ -n "$release_tag" ] || fail "the latest GitHub release did not include a tag."
else
case "$cli_version" in
v*) release_tag="$cli_version" ;;
*) release_tag="v$cli_version" ;;
esac
fi
asset_name="openteam-$binary_os-$architecture"
release_base="https://github.com/$repository/releases/download/$release_tag"
temporary_directory=$(mktemp -d 2>/dev/null || mktemp -d -t openteam)
binary_path="$temporary_directory/$asset_name"
checksums_path="$temporary_directory/SHA256SUMS"
cleanup() {
rm -rf "$temporary_directory"
}
trap cleanup EXIT HUP INT TERM
step "$diamond" "Downloading CLI $release_tag$ellipsis" "$cyan"
# Prefer the gzip copy (about a third of the size); fall back to the raw binary for releases
# that predate it. The checksum below is always verified against the decompressed binary.
if command_exists gunzip && curl -fsL --retry 3 --connect-timeout 15 "$release_base/$asset_name.gz" -o "$binary_path.gz" 2>/dev/null; then
gunzip -f "$binary_path.gz" || fail "could not decompress $asset_name.gz."
else
rm -f "$binary_path.gz"
curl -fsSL --retry 3 --connect-timeout 15 "$release_base/$asset_name" -o "$binary_path" ||
fail "could not download $asset_name from $release_tag."
fi
curl -fsSL --retry 3 --connect-timeout 15 "$release_base/SHA256SUMS" -o "$checksums_path" ||
fail "could not download checksums for $release_tag."
expected_checksum=$(awk -v name="$asset_name" '$2 == name || $2 ~ ("/" name "$") { print $1; exit }' "$checksums_path")
[ -n "$expected_checksum" ] || fail "SHA256SUMS does not contain $asset_name."
if command_exists sha256sum; then
actual_checksum=$(sha256sum "$binary_path" | awk '{print $1}')
elif command_exists shasum; then
actual_checksum=$(shasum -a 256 "$binary_path" | awk '{print $1}')
else
fail "sha256sum or shasum is required to verify the download."
fi
[ "$actual_checksum" = "$expected_checksum" ] || fail "the OpenTeam CLI checksum did not match."
step "$checkmark" "Download verified" "$green"
chmod +x "$binary_path"
user_home=$(printenv HOME 2>/dev/null || true)
[ -n "$user_home" ] || fail "HOME is not set. Set OPENTEAM_BIN_DIR to choose where to install the CLI."
bin_directory=$(printenv OPENTEAM_BIN_DIR 2>/dev/null || printf '%s/.local/bin' "$user_home")
mkdir -p "$bin_directory"
installed_binary="$bin_directory/openteam"
if command_exists install; then
install -m 0755 "$binary_path" "$installed_binary"
else
cp "$binary_path" "$installed_binary"
chmod +x "$installed_binary"
fi
step "$checkmark" "CLI installed" "$green"
say " $installed_binary"
case ":$PATH:" in
*":$bin_directory:"*) ;;
*) say " Add $bin_directory to PATH to run openteam later." ;;
esac
printf '\n %bSERVER SETUP%b\n\n' "$bold$cyan" "$reset"
# Opening /dev/tty can fail even when it is readable (for example, in CI).
if ( : </dev/tty ) 2>/dev/null; then
"$installed_binary" install "$@" </dev/tty
exit $?
fi
# The CLI checks prerequisites before asking for a terminal. Keep it installed
# when setup is blocked, so the user can fix Docker and resume with openteam setup.
"$installed_binary" install "$@" </dev/null
Windows PowerShell
Raw script$ErrorActionPreference = "Stop"
function Fail([string]$Message) {
Write-Error "OpenTeam installer: $Message"
exit 1
}
$installerColor = -not [Console]::IsOutputRedirected -and -not (Test-Path Env:NO_COLOR) -and $env:TERM -ne "dumb"
function Write-Step([string]$Mark, [string]$Message, [string]$Color = "Cyan") {
if ($installerColor) { Write-Host " $Mark $Message" -ForegroundColor $Color }
else { Write-Host " $Mark $Message" }
}
Write-Host ""
Write-Step "OPENTEAM" "/ install"
Write-Host " Windows"
Write-Host ""
$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant()
switch ($architecture) {
"x64" { $assetName = "openteam-windows-x64.exe" }
"arm64" { $assetName = "openteam-windows-x64.exe" }
default { Fail "unsupported Windows architecture: $architecture" }
}
$repository = if ($env:OPENTEAM_REPOSITORY) { $env:OPENTEAM_REPOSITORY } else { "raghavpillai/openteam" }
$requestedVersion = if ($env:OPENTEAM_VERSION) { $env:OPENTEAM_VERSION } else { "latest" }
if ($requestedVersion -eq "latest") {
try { $releaseTag = (Invoke-RestMethod "https://api.github.com/repos/$repository/releases/latest").tag_name }
catch { Fail "no public OpenTeam release is available yet." }
} else {
$releaseTag = if ($requestedVersion.StartsWith("v")) { $requestedVersion } else { "v$requestedVersion" }
}
$releaseBase = "https://github.com/$repository/releases/download/$releaseTag"
$temporaryDirectory = Join-Path ([System.IO.Path]::GetTempPath()) ("openteam-" + [guid]::NewGuid())
New-Item -ItemType Directory -Path $temporaryDirectory | Out-Null
$binaryPath = Join-Path $temporaryDirectory $assetName
$checksumsPath = Join-Path $temporaryDirectory "SHA256SUMS"
$binDirectory = if ($env:OPENTEAM_BIN_DIR) { $env:OPENTEAM_BIN_DIR } else { Join-Path $env:LOCALAPPDATA "OpenTeam\bin" }
$installedBinary = Join-Path $binDirectory "openteam.exe"
$installerProgressPreference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
try {
Write-Step ([char]0x25C7) "Downloading CLI $releaseTag$([char]0x2026)"
# Prefer the gzip copy; fall back to the raw binary for releases that predate it.
# Basic parsing avoids browser/HTML prompts in Windows PowerShell 5.1.
$compressedPath = "$binaryPath.gz"
try {
Invoke-WebRequest "$releaseBase/$assetName.gz" -UseBasicParsing -OutFile $compressedPath
$compressedStream = [System.IO.File]::OpenRead($compressedPath)
$binaryStream = [System.IO.File]::Create($binaryPath)
$gzipStream = New-Object System.IO.Compression.GZipStream($compressedStream, [System.IO.Compression.CompressionMode]::Decompress)
$gzipStream.CopyTo($binaryStream)
$gzipStream.Dispose(); $binaryStream.Dispose(); $compressedStream.Dispose()
} catch {
Invoke-WebRequest "$releaseBase/$assetName" -UseBasicParsing -OutFile $binaryPath
}
Invoke-WebRequest "$releaseBase/SHA256SUMS" -UseBasicParsing -OutFile $checksumsPath
$checksumLine = Get-Content $checksumsPath | Where-Object {
$fields = $_.Trim() -split "\s+", 2
$fields.Count -eq 2 -and (($fields[1].Trim() -replace "^\*", "") -replace "^.*/", "") -ceq $assetName
} | Select-Object -First 1
if (-not $checksumLine) { Fail "SHA256SUMS does not contain $assetName." }
$expectedChecksum = ($checksumLine.Trim() -split "\s+")[0].ToLowerInvariant()
$actualChecksum = (Get-FileHash -Algorithm SHA256 $binaryPath).Hash.ToLowerInvariant()
if ($actualChecksum -ne $expectedChecksum) { Fail "the OpenTeam CLI checksum did not match." }
Write-Step ([char]0x2713) "Download verified" "Green"
New-Item -ItemType Directory -Force -Path $binDirectory | Out-Null
Copy-Item -Force $binaryPath $installedBinary
Write-Step ([char]0x2713) "CLI installed" "Green"
Write-Host " $installedBinary"
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (-not $userPath) { $userPath = "" }
if (-not (($userPath -split ";") -contains $binDirectory)) {
$newPath = if ($userPath) { "$($userPath.TrimEnd(";"));$binDirectory" } else { $binDirectory }
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
Write-Host "Added $binDirectory to your user PATH."
}
Write-Host ""
Write-Step "SERVER" "SETUP"
Write-Host ""
& $installedBinary install @args
exit $LASTEXITCODE
} finally {
$ProgressPreference = $installerProgressPreference
Remove-Item -Recurse -Force $temporaryDirectory -ErrorAction SilentlyContinue
}