#!/usr/bin/env bash set -euo pipefail ############################################ # Required env (installer contract) ############################################ : "${RUNTIME:?RUNTIME required}" : "${RUNTIME_VERSION:?RUNTIME_VERSION required}" : "${ARCHIVE_EXT:?ARCHIVE_EXT required}" ############################################ # Optional env ############################################ ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://10.60.0.251:8080}" ZLH_RUNTIME_ROOT="${ZLH_RUNTIME_ROOT:-/opt/zlh/runtimes}" ARCHIVE_PREFIX="${ARCHIVE_PREFIX:-${RUNTIME}}" ############################################ # Derived paths ############################################ RUNTIME_ROOT="${ZLH_RUNTIME_ROOT}/${RUNTIME}" DEST_DIR="${RUNTIME_ROOT}/${RUNTIME_VERSION}" CURRENT_LINK="${RUNTIME_ROOT}/current" ############################################ # Logging helpers ############################################ log() { echo "[zlh-installer:${RUNTIME}] $*" } fail() { echo "[zlh-installer:${RUNTIME}] ERROR: $*" >&2 exit 1 } ############################################ # Artifact helpers ############################################ artifact_name() { echo "${ARCHIVE_PREFIX}-${RUNTIME_VERSION}.${ARCHIVE_EXT}" } artifact_url() { echo "${ZLH_ARTIFACT_BASE_URL%/}/devcontainer/${RUNTIME}/${RUNTIME_VERSION}/$(artifact_name)" } ############################################ # Download / extract ############################################ download_artifact() { local url out url="$(artifact_url)" out="/tmp/$(artifact_name)" log "Downloading ${url}" if command -v curl >/dev/null 2>&1; then curl -fL "${url}" -o "${out}" elif command -v wget >/dev/null 2>&1; then wget -O "${out}" "${url}" else fail "curl or wget is required" fi } extract_artifact() { local out out="/tmp/$(artifact_name)" log "Extracting to ${DEST_DIR}" mkdir -p "${DEST_DIR}" case "${ARCHIVE_EXT}" in tar.xz|tar.gz) tar -xf "${out}" -C "${DEST_DIR}" --strip-components=1 ;; *) fail "Unsupported archive type: ${ARCHIVE_EXT}" ;; esac } ############################################ # Runtime wiring ############################################ update_symlinks() { ln -sfn "${DEST_DIR}" "${CURRENT_LINK}" ln -sfn "${CURRENT_LINK}/bin" "${RUNTIME_ROOT}/bin" } write_profile() { cat >/etc/profile.d/zlh-${RUNTIME}.sh </dev/null 2>&1; then log "ssh-keygen not present, skipping SSH host key setup" return 0 fi if ls /etc/ssh/ssh_host_*_key >/dev/null 2>&1; then log "SSH host keys already exist" return 0 fi log "Generating SSH host keys" ssh-keygen -A # Best-effort service restart (container init systems vary) systemctl enable ssh >/dev/null 2>&1 || true systemctl restart ssh >/dev/null 2>&1 || \ systemctl restart sshd >/dev/null 2>&1 || true } ############################################ # Entry point ############################################ install_runtime() { log "Installing ${RUNTIME} ${RUNTIME_VERSION}" mkdir -p "${RUNTIME_ROOT}" if [[ -d "${DEST_DIR}" ]]; then log "Version already installed at ${DEST_DIR}" else download_artifact extract_artifact fi update_symlinks write_profile chmod -R 755 "${DEST_DIR}" ensure_ssh_host_keys log "Install complete" }