#!/usr/bin/env bash set -euo pipefail API_URL="https://api.mvo.network" DOWNLOAD_BASE_URL="https://mvo.network/downloads/" TOKEN="" INSTALL_DIR="/usr/local/bin" BIN_NAME="tunnel" usage() { cat <<'EOF' Uso: curl -fsSL https://get.mvo.network | sudo bash Opcional (já fazer login): curl -fsSL https://get.mvo.network | sudo bash -s -- --token SUA_API_KEY Flags: --token API Key (X-API-Key) para executar "tunnel login" após instalar --api-url API base (default: https://api.mvo.network) --download-base Base alternativa de download (default: https://mvo.network/downloads/) --install-dir Diretório de instalação (default: /usr/local/bin) --bin Nome do binário instalado (default: tunnel) EOF } while [[ $# -gt 0 ]]; do case "$1" in --token) TOKEN="${2:-}"; shift 2 ;; --api-url) API_URL="${2:-}"; shift 2 ;; --download-base) DOWNLOAD_BASE_URL="${2:-}"; shift 2 ;; --install-dir) INSTALL_DIR="${2:-}"; shift 2 ;; --bin) BIN_NAME="${2:-}"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "Argumento inválido: $1" >&2; usage; exit 2 ;; esac done API_URL="$(printf "%s" "${API_URL}" | tr -d '\r' | sed 's/[[:space:]]//g')" API_URL="${API_URL%/}" if [[ "${API_URL}" == "" ]]; then API_URL="https://api.mvo.network" fi DOWNLOAD_BASE_URL="$(printf "%s" "${DOWNLOAD_BASE_URL}" | tr -d '\r' | sed 's/[[:space:]]//g')" DOWNLOAD_BASE_URL="${DOWNLOAD_BASE_URL%/}/" if [[ "${DOWNLOAD_BASE_URL}" == "/" ]]; then DOWNLOAD_BASE_URL="https://mvo.network/downloads/" fi uname_s="$(uname -s | tr '[:upper:]' '[:lower:]')" uname_m="$(uname -m | tr '[:upper:]' '[:lower:]')" os="" arch="" case "${uname_s}" in linux) os="linux" ;; darwin) os="darwin" ;; msys*|mingw*|cygwin*) os="windows" ;; *) echo "SO não suportado: ${uname_s}" >&2; exit 1 ;; esac case "${uname_m}" in x86_64|amd64) arch="amd64" ;; aarch64|arm64) arch="arm64" ;; *) echo "Arquitetura não suportada: ${uname_m}" >&2; exit 1 ;; esac file_name="" case "${os}-${arch}" in linux-amd64) file_name="tunnel-linux-amd64" ;; linux-arm64) file_name="tunnel-linux-arm64" ;; darwin-amd64) file_name="tunnel-darwin-amd64" ;; darwin-arm64) file_name="tunnel-darwin-arm64" ;; windows-amd64) file_name="tunnel-windows-amd64.exe" ;; windows-arm64) file_name="tunnel-windows-arm64.exe" ;; *) echo "SO/arch não suportado: ${os}/${arch}" >&2; exit 1 ;; esac need() { command -v "$1" >/dev/null 2>&1; } if ! need curl; then echo "curl não encontrado. Instale curl e tente novamente." >&2 exit 1 fi tmp_dir="$(mktemp -d)" cleanup() { rm -rf "${tmp_dir}" >/dev/null 2>&1 || true; } trap cleanup EXIT url="" sha="" ver="" rel_json="" if rel_json="$(curl -fsSL "${API_URL}/v1/client/release?os=${os}&arch=${arch}" 2>/dev/null || true)"; then url="$(printf "%s" "${rel_json}" | sed -n 's/.*"url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" sha="$(printf "%s" "${rel_json}" | sed -n 's/.*"sha256"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" ver="$(printf "%s" "${rel_json}" | sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" fi if [[ "${url}" == "" ]]; then url="${DOWNLOAD_BASE_URL}${file_name}" fi dst_tmp="${tmp_dir}/${BIN_NAME}" curl -fL --retry 5 --retry-delay 2 -o "${dst_tmp}" "${url}" if [[ "${sha}" != "" ]]; then if need sha256sum; then printf "%s %s\n" "${sha}" "${dst_tmp}" | sha256sum -c - >/dev/null elif need shasum; then got="$(shasum -a 256 "${dst_tmp}" | awk '{print $1}')" if [[ "${got}" != "${sha}" ]]; then echo "SHA256 inválido (esperado ${sha}, obtido ${got})" >&2 exit 1 fi else echo "Aviso: não encontrei sha256sum/shasum para validar integridade." >&2 fi fi mkdir -p "${INSTALL_DIR}" install -m 0755 "${dst_tmp}" "${INSTALL_DIR}/${BIN_NAME}" echo "OK: instalado ${INSTALL_DIR}/${BIN_NAME}${ver:+ (v${ver})}" if [[ "${TOKEN}" != "" ]]; then "${INSTALL_DIR}/${BIN_NAME}" login --api-url "${API_URL}" --token "${TOKEN}" --verbose fi