#!/usr/bin/env bash # # EnterpriseChat Server — instalador para Linux. # # Uso: # curl -fsSL https://enterprisechat.es/install.sh | sudo bash # # Detecta la distribución (Debian/Ubuntu vs RHEL/AlmaLinux/RockyLinux), # descarga el paquete correspondiente desde GitHub Releases, verifica el # SHA-256 publicado, instala el paquete y arranca el servicio systemd. # # Más info: https://enterprisechat.es # set -euo pipefail REPO="angelcripto/enterprisechat" TMP="$(mktemp -d -t enterprisechat-XXXXXX)" trap 'rm -rf "$TMP"' EXIT c_red() { printf '\033[31m%s\033[0m\n' "$*"; } c_green() { printf '\033[32m%s\033[0m\n' "$*"; } c_yellow() { printf '\033[33m%s\033[0m\n' "$*"; } c_blue() { printf '\033[34m%s\033[0m\n' "$*"; } # ---- 1. Pre-requisitos -------------------------------------------------- if [[ $EUID -ne 0 ]]; then c_red "Este instalador necesita ejecutarse como root." c_yellow "Sugerencia: curl -fsSL https://enterprisechat.es/install.sh | sudo bash" exit 1 fi for cmd in curl uname; do if ! command -v "$cmd" >/dev/null 2>&1; then c_red "Falta '$cmd' en este sistema. Instálalo y reintenta." exit 1 fi done ARCH="$(uname -m)" case "$ARCH" in x86_64|amd64) ARCH="amd64" ;; aarch64|arm64) ARCH="arm64" ;; *) c_red "Arquitectura $ARCH no soportada todavía (solo x86_64 / aarch64)." exit 1 ;; esac # Detecta familia de distribución para elegir entre .deb y .rpm. PKG="" if [[ -f /etc/os-release ]]; then . /etc/os-release case "${ID_LIKE:-$ID}" in *debian*|*ubuntu*) PKG="deb" ;; *rhel*|*fedora*|*centos*|*almalinux*|*rocky*) PKG="rpm" ;; esac fi if [[ -z "$PKG" ]]; then c_yellow "No reconozco esta distribución automáticamente." c_yellow "Descarga manual desde: https://github.com/$REPO/releases/latest" exit 1 fi c_blue "==> Distribución detectada: ${PRETTY_NAME:-desconocida} ($PKG, $ARCH)" # ---- 2. Resolver release mas reciente (incluyendo pre-releases) --------- # La URL /releases/latest/download/... de GitHub solo resuelve releases # estables; con pre-releases (tag con suffix -alpha/-beta/-rc) devuelve # 404. Consultamos la API REST para coger la release mas reciente # (incluyendo pre-releases) y bajamos su asset por browser_download_url. ASSET="enterprisechat_${ARCH}.${PKG}" SHA="${ASSET}.sha256" c_blue "==> Buscando release mas reciente en GitHub" RELS_JSON="$TMP/releases.json" if ! curl -fsSL --retry 3 \ -H "User-Agent: EnterpriseChat-Installer" \ -o "$RELS_JSON" \ "https://api.github.com/repos/$REPO/releases?per_page=10"; then c_red "No se pudo consultar https://api.github.com/repos/$REPO/releases" c_yellow "Verifica conectividad a api.github.com y que haya releases publicadas." exit 1 fi if command -v jq >/dev/null 2>&1; then DEB_URL="$(jq -r --arg name "$ASSET" ' [.[] | select(.draft|not)] | first | .assets[] | select(.name == $name) | .browser_download_url ' "$RELS_JSON")" SHA_URL="$(jq -r --arg name "$SHA" ' [.[] | select(.draft|not)] | first | .assets[] | select(.name == $name) | .browser_download_url // empty ' "$RELS_JSON")" TAG_NAME="$(jq -r '[.[] | select(.draft|not)] | first | .tag_name' "$RELS_JSON")" else DEB_URL="$(python3 -c " import sys, json rels = [r for r in json.load(open('$RELS_JSON')) if not r.get('draft')] if not rels: sys.exit(1) print(next((a['browser_download_url'] for a in rels[0]['assets'] if a['name']=='$ASSET'), '')) ")" SHA_URL="$(python3 -c " import sys, json rels = [r for r in json.load(open('$RELS_JSON')) if not r.get('draft')] if not rels: sys.exit(1) print(next((a['browser_download_url'] for a in rels[0]['assets'] if a['name']=='$SHA'), '')) ")" TAG_NAME="$(python3 -c " import json rels = [r for r in json.load(open('$RELS_JSON')) if not r.get('draft')] print(rels[0]['tag_name'] if rels else '') ")" fi if [[ -z "$DEB_URL" ]]; then c_red "La ultima release ($TAG_NAME) no contiene el asset $ASSET." c_yellow "Comprueba https://github.com/$REPO/releases/tag/$TAG_NAME" exit 1 fi c_blue " Release: $TAG_NAME" c_blue "==> Descargando $ASSET" if ! curl -fsSL --retry 3 -o "$TMP/$ASSET" "$DEB_URL"; then c_red "No se pudo descargar $DEB_URL" exit 1 fi # Checksum opcional pero recomendado. if [[ -n "$SHA_URL" ]] && curl -fsSL --retry 2 -o "$TMP/$SHA" "$SHA_URL" 2>/dev/null; then c_blue "==> Verificando SHA-256" EXPECTED="$(awk '{print $1}' "$TMP/$SHA")" ACTUAL="$(sha256sum "$TMP/$ASSET" | awk '{print $1}')" if [[ "$EXPECTED" != "$ACTUAL" ]]; then c_red "SHA-256 NO COINCIDE. Esperado: $EXPECTED, obtenido: $ACTUAL" c_red "Aborto por seguridad: el paquete descargado no es el publicado." exit 1 fi c_green " SHA-256 OK" else c_yellow " (Sin checksum publicado todavía; omitido)" fi # ---- 3. Instalar -------------------------------------------------------- c_blue "==> Instalando paquete" if [[ "$PKG" == "deb" ]]; then export DEBIAN_FRONTEND=noninteractive apt-get install -y "$TMP/$ASSET" || { dpkg -i "$TMP/$ASSET"; apt-get install -fy; } else if command -v dnf >/dev/null 2>&1; then dnf install -y "$TMP/$ASSET" else yum install -y "$TMP/$ASSET" || rpm -i "$TMP/$ASSET" fi fi # ---- 4. Arrancar servicio ----------------------------------------------- c_blue "==> Habilitando y arrancando el servicio" systemctl daemon-reload systemctl enable --now enterprisechat.service sleep 2 systemctl --no-pager status enterprisechat.service | head -10 || true # ---- 5. Mostrar contraseña inicial -------------------------------------- PWFILE=/opt/enterprisechat/.first-admin-password echo c_green "=================================================================" c_green " EnterpriseChat instalado correctamente." c_green "=================================================================" echo echo " URL admin: http://$(hostname -I | awk '{print $1}'):5080/" echo " Usuario: admin" if [[ -s "$PWFILE" ]]; then echo " Contraseña: $(cat "$PWFILE")" rm -f "$PWFILE" echo c_yellow " Esta contraseña SOLO se muestra esta vez. Anótala." else echo " Contraseña: (ya consumida o todavía no generada — revisa journalctl -u enterprisechat)" fi echo echo " Logs: journalctl -u enterprisechat -f" echo " Servicio: systemctl {status|restart|stop} enterprisechat" echo " Datos: /opt/enterprisechat/" echo