#!/usr/bin/env bash # KLYRN bootstrap — served at https://get.klyrn.com # # curl -fsSL https://get.klyrn.com | bash # # This script deliberately does almost nothing: it checks the platform, # downloads the signed klyrn binary, verifies it, and hands over to # `klyrn install`, where every real step is a resumable, verifiable stage. # # Everything lives in one function that is called on the last line, so bash # has read the whole script before running any of it: a truncated download # does nothing, and no child process can swallow the rest of the script # from the pipe. set -euo pipefail KLYRN_TMP="" trap '[ -n "$KLYRN_TMP" ] && rm -rf "$KLYRN_TMP"' EXIT klyrn_bootstrap() { local DL CHANNEL VERSION PUBKEY OS_ID OS_VER OS_NAME ARCH TMP BIN_URL SHA DL="${KLYRN_DOWNLOAD_BASE:-https://dl.klyrn.com}" # "dev" until the first stable release is published; then "stable". CHANNEL="${KLYRN_CHANNEL:-dev}" VERSION="${KLYRN_VERSION:-latest}" # ed25519 public key (hex) used to sign release manifests. The served copy # at get.klyrn.com has the current key injected; the repository copy is # empty so a build never trusts a key by accident. With no key only the # sha256 in the manifest is checked (the manifest itself is unsigned then). PUBKEY="${KLYRN_PUBKEY:-fffd32e16d789fba3328293d188af15fa57d7d4acc4fc5636f6cecf1d15e4a61}" say() { printf '\033[1m%s\033[0m\n' "$*"; } fail() { printf '\n\033[31m%s\033[0m\n' "$*" >&2; exit 1; } [ "$(id -u)" = "0" ] || fail "Run as root: curl -fsSL https://get.klyrn.com | sudo bash" command -v curl >/dev/null || fail "curl is required (apt-get install -y curl)" # Read os-release in a subshell: sourcing it here would overwrite VERSION. OS_ID="$(. /etc/os-release 2>/dev/null && echo "${ID:-}")" OS_VER="$(. /etc/os-release 2>/dev/null && echo "${VERSION_ID:-}")" OS_NAME="$(. /etc/os-release 2>/dev/null && echo "${PRETTY_NAME:-unknown}")" [ -n "$OS_ID" ] || fail "Cannot read /etc/os-release" [ "$OS_ID" = "ubuntu" ] && [ "$OS_VER" = "24.04" ] || \ fail "KLYRN V1 supports Ubuntu 24.04 LTS. This is ${OS_NAME}." case "$(uname -m)" in x86_64|amd64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; *) fail "Unsupported architecture $(uname -m)" ;; esac TMP="$(mktemp -d /tmp/klyrn-get.XXXXXX)" KLYRN_TMP="$TMP" say "Downloading KLYRN (${CHANNEL}/${VERSION}, linux/${ARCH})" curl -fsSL "${DL}/${CHANNEL}/${VERSION}/manifest.json" -o "$TMP/manifest.json"