440 lines
13 KiB
Bash
Executable File
440 lines
13 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# KAWA OS Installation Script
|
|
# Ce script est exécuté après le boot de l'ISO KAWA CELL en RAM
|
|
# Il configure automatiquement la connexion au mesh KAWA et installe le système
|
|
#
|
|
# Usage: curl -fsSL https://git.du-senegal.com/kawa_bot/kawa-context/raw/main/install-kawa.sh | bash
|
|
#
|
|
|
|
set -e
|
|
|
|
# Couleurs pour les messages
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Bannière KAWA
|
|
echo -e "${CYAN}"
|
|
cat << "EOF"
|
|
╔═══════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ ██╗ ██╗ █████╗ ██╗ ██╗ ██████╗ █████╗ ██████╗ ║
|
|
║ ██║ ██╔╝██╔══██╗██║ ██║ ██╔══██╗██╔══██╗██╔══██╗║
|
|
║ █████╔╝ ███████║██║ ██║ ██████╔╝███████║██████╔╝║
|
|
║ ██╔═██╗ ██╔══██║██║ ██║ ██╔══██╗██╔══██║██╔══██╗║
|
|
║ ██║ ██╗██║ ██║███████╗███████╗██████╔╝██║ ██║██║ ██║║
|
|
║ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝║
|
|
║ ║
|
|
║ KAWA OS - Installation Automatique ║
|
|
║ Version: 1.0.0 ║
|
|
╚═══════════════════════════════════════════════════════════╝
|
|
EOF
|
|
echo -e "${NC}"
|
|
|
|
# Configuration
|
|
HEADSCALE_URL="https://headscale.du-senegal.com"
|
|
HEADSCALE_FALLBACK="http://141.94.23.212"
|
|
HEADSCALE_AUTHKEY="f43f36ef159b3df799eb316b81bdac1b415c7cc2add174d0"
|
|
GIT_REPO="https://git.du-senegal.com/kawa_bot/kawa-context.git"
|
|
NAMESPACE="kawa"
|
|
|
|
# Fonctions utilitaires
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
|
|
|
|
# Détection du hostname
|
|
detect_hostname() {
|
|
log_step "Détection du nom d'hôte..."
|
|
|
|
# Générer un hostname basé sur le modèle de machine
|
|
if [ -f /sys/class/dmi/id/product_name ]; then
|
|
MODEL=$(cat /sys/class/dmi/id/product_name 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d ' ' | cut -c1-20)
|
|
else
|
|
MODEL="unknown"
|
|
fi
|
|
|
|
# Générer un suffixe aléatoire
|
|
SUFFIX=$(head -c 4 /dev/urandom | xxd -p)
|
|
|
|
# Hostname final
|
|
HOSTNAME="kawa-${MODEL}-${SUFFIX}"
|
|
|
|
log_info "Hostname détecté: $HOSTNAME"
|
|
echo "$HOSTNAME"
|
|
}
|
|
|
|
# Vérification des prérequis
|
|
check_prereqs() {
|
|
log_step "Vérification des prérequis..."
|
|
|
|
# Vérifier si on est root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
log_error "Ce script doit être exécuté en root"
|
|
exit 1
|
|
fi
|
|
|
|
# Vérifier si on est sur NixOS
|
|
if [ ! -f /etc/NIXOS ]; then
|
|
log_warn "Ce script est conçu pour NixOS"
|
|
fi
|
|
|
|
# Vérifier la connexion réseau
|
|
if ! ping -c 1 8.8.8.8 >/dev/null 2>&1; then
|
|
log_error "Pas de connexion réseau"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Prérequis OK"
|
|
}
|
|
|
|
# Installation de Tailscale
|
|
install_tailscale() {
|
|
log_step "Installation de Tailscale..."
|
|
|
|
# Sur NixOS, utiliser nix-env ou la config
|
|
if command -v nix-env &> /dev/null; then
|
|
nix-env -iA nixpkgs.tailscale || log_warn "Tailscale peut déjà être installé"
|
|
elif command -v apt-get &> /dev/null; then
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
else
|
|
log_error "Impossible d'installer Tailscale"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Tailscale installé"
|
|
}
|
|
|
|
# Connexion au mesh KAWA
|
|
connect_mesh() {
|
|
log_step "Connexion au mesh KAWA..."
|
|
|
|
local HOSTNAME="$1"
|
|
|
|
# Démarrer tailscaled
|
|
log_info "Démarrage de tailscaled..."
|
|
tailscaled 2>/dev/null &
|
|
sleep 3
|
|
|
|
# Essayer le serveur principal
|
|
log_info "Connexion à $HEADSCALE_URL..."
|
|
if tailscale up --login-server="$HEADSCALE_URL" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" 2>/dev/null; then
|
|
log_info "Connecté au mesh KAWA via $HEADSCALE_URL"
|
|
else
|
|
# Fallback
|
|
log_warn "Échec de connexion, essai du fallback $HEADSCALE_FALLBACK..."
|
|
if tailscale up --login-server="$HEADSCALE_FALLBACK" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" 2>/dev/null; then
|
|
log_info "Connecté au mesh KAWA via $HEADSCALE_FALLBACK"
|
|
else
|
|
log_error "Impossible de se connecter au mesh KAWA"
|
|
log_info "Vérifiez votre connexion réseau et réessayez"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Attendre la connexion
|
|
sleep 5
|
|
|
|
# Vérifier la connexion
|
|
tailscale status
|
|
|
|
log_info "Mesh KAWA connecté!"
|
|
}
|
|
|
|
# Téléchargement de la configuration
|
|
fetch_config() {
|
|
log_step "Téléchargement de la configuration KAWA..."
|
|
|
|
local TEMP_DIR=$(mktemp -d)
|
|
|
|
# Cloner le repo
|
|
log_info "Clonage de $GIT_REPO..."
|
|
git clone --depth 1 "$GIT_REPO" "$TEMP_DIR/kawa-config" || {
|
|
log_error "Impossible de cloner le repo"
|
|
exit 1
|
|
}
|
|
|
|
log_info "Configuration téléchargée dans $TEMP_DIR/kawa-config"
|
|
echo "$TEMP_DIR/kawa-config"
|
|
}
|
|
|
|
# Génération de la configuration NixOS
|
|
generate_nixos_config() {
|
|
log_step "Génération de la configuration NixOS..."
|
|
|
|
local HOSTNAME="$1"
|
|
local CONFIG_DIR="$2"
|
|
local DISK="${3:-/dev/sda}"
|
|
|
|
mkdir -p /etc/nixos
|
|
|
|
# Configuration de base KAWA
|
|
cat > /etc/nixos/configuration.nix << EOF
|
|
# KAWA OS Configuration
|
|
# Généré automatiquement par install-kawa.sh
|
|
# Hostname: $HOSTNAME
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
imports = [
|
|
./hardware-configuration.nix
|
|
./kawa-base.nix
|
|
];
|
|
|
|
# Configuration réseau
|
|
networking.hostName = "$HOSTNAME";
|
|
networking.networkmanager.enable = true;
|
|
|
|
# Timezone
|
|
time.timeZone = "Europe/Paris";
|
|
|
|
# Internationalisation
|
|
i18n.defaultLocale = "fr_FR.UTF-8";
|
|
|
|
# Utilisateurs
|
|
users.users.kawa = {
|
|
isNormalUser = true;
|
|
extraGroups = [ "wheel" "networkmanager" "docker" "audio" "video" ];
|
|
initialPassword = "kawa";
|
|
};
|
|
|
|
# Packages de base
|
|
environment.systemPackages = with pkgs; [
|
|
vim
|
|
git
|
|
curl
|
|
wget
|
|
tailscale
|
|
htop
|
|
neofetch
|
|
tmux
|
|
];
|
|
|
|
# Services
|
|
services.openssh.enable = true;
|
|
services.tailscale.enable = true;
|
|
|
|
# Firewall
|
|
networking.firewall.enable = true;
|
|
networking.firewall.allowedTCPPorts = [ 22 ];
|
|
|
|
# Version NixOS
|
|
system.stateVersion = "26.05";
|
|
}
|
|
EOF
|
|
|
|
# Configuration KAWA base
|
|
cat > /etc/nixos/kawa-base.nix << EOF
|
|
# KAWA Base Configuration
|
|
# Services communs à tous les nœuds KAWA
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
# Tailscale avec Headscale
|
|
services.tailscale = {
|
|
enable = true;
|
|
extraUpFlags = [
|
|
"--login-server=https://headscale.du-senegal.com"
|
|
"--authkey=f43f36ef159b3df799eb316b81bdac1b415c7cc2add174d0"
|
|
];
|
|
};
|
|
|
|
# NATS pour la communication inter-nœuds
|
|
services.nats = {
|
|
enable = true;
|
|
servername = "$HOSTNAME";
|
|
port = 4222;
|
|
httpPort = 8222;
|
|
};
|
|
|
|
# Docker
|
|
virtualisation.docker.enable = true;
|
|
|
|
# Ollama pour l'inférence locale
|
|
services.ollama = {
|
|
enable = true;
|
|
acceleration = "cuda";
|
|
};
|
|
|
|
# Git
|
|
programs.git.enable = true;
|
|
|
|
# Scripts KAWA
|
|
environment.etc."kawa/scripts" = {
|
|
source = /var/lib/kawa/scripts;
|
|
};
|
|
}
|
|
EOF
|
|
|
|
# Générer la configuration hardware
|
|
nixos-generate-config --root /mnt 2>/dev/null || {
|
|
log_warn "Configuration hardware générée manuellement"
|
|
cp /etc/nixos/hardware-configuration.nix /mnt/etc/nixos/ 2>/dev/null || true
|
|
}
|
|
|
|
log_info "Configuration NixOS générée"
|
|
}
|
|
|
|
# Installation sur le disque
|
|
install_to_disk() {
|
|
log_step "Installation sur le disque..."
|
|
|
|
local DISK="$1"
|
|
|
|
# Lister les disques disponibles
|
|
log_info "Disques disponibles:"
|
|
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep disk
|
|
|
|
# Demander confirmation
|
|
read -p "Installer KAWA OS sur $DISK ? (y/N): " confirm
|
|
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
|
log_warn "Installation annulée"
|
|
exit 0
|
|
fi
|
|
|
|
# Partitionnement
|
|
log_info "Partitionnement de $DISK..."
|
|
|
|
# Créer les partitions
|
|
parted "$DISK" --script mklabel gpt
|
|
parted "$DISK" --script mkpart ESP fat32 1MiB 512MiB
|
|
parted "$DISK" --script set 1 esp on
|
|
parted "$DISK" --script mkpart primary 512MiB 100%
|
|
|
|
# Formater
|
|
mkfs.vfat -n BOOT "${DISK}1"
|
|
mkfs.ext4 -L NIXOS "${DISK}2"
|
|
|
|
# Monter
|
|
mount "${DISK}2" /mnt
|
|
mkdir -p /mnt/boot
|
|
mount "${DISK}1" /mnt/boot
|
|
|
|
log_info "Disque préparé"
|
|
}
|
|
|
|
# Installation complète
|
|
install_system() {
|
|
log_step "Installation du système..."
|
|
|
|
# Installer NixOS
|
|
nixos-install --no-root-passwd || {
|
|
log_error "Erreur lors de l'installation"
|
|
exit 1
|
|
}
|
|
|
|
log_info "Système installé!"
|
|
}
|
|
|
|
# Post-installation
|
|
post_install() {
|
|
log_step "Post-installation..."
|
|
|
|
# Copier les configs KAWA
|
|
mkdir -p /mnt/var/lib/kawa/scripts
|
|
mkdir -p /mnt/var/lib/kawa/config
|
|
|
|
# Configurer le mesh
|
|
log_info "Configuration du mesh KAWA..."
|
|
|
|
# Message final
|
|
echo -e "${CYAN}"
|
|
cat << "EOF"
|
|
╔═══════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ ✅ KAWA OS Installation terminée! ║
|
|
║ ║
|
|
║ Prochaines étapes: ║
|
|
║ 1. Redémarrez la machine ║
|
|
║ 2. Connectez-vous avec: user: kawa, password: kawa ║
|
|
║ 3. Le nœud sera automatiquement connecté au mesh ║
|
|
║ ║
|
|
║ Commandes utiles: ║
|
|
║ - tailscale status : Voir le statut du mesh ║
|
|
║ - tailscale ip : Voir l'IP du nœud ║
|
|
║ - nats-server : Bus de messages KAWA ║
|
|
║ ║
|
|
╚═══════════════════════════════════════════════════════════╝
|
|
EOF
|
|
echo -e "${NC}"
|
|
}
|
|
|
|
# Mode live USB (sans installation)
|
|
live_mode() {
|
|
log_step "Mode Live USB (sans installation sur disque)..."
|
|
|
|
local HOSTNAME="$1"
|
|
local CONFIG_DIR="$2"
|
|
|
|
# Configurer le mesh
|
|
connect_mesh "$HOSTNAME"
|
|
|
|
# Copier les scripts KAWA
|
|
mkdir -p /var/lib/kawa/scripts
|
|
cp -r "$CONFIG_DIR/scripts"/* /var/lib/kawa/scripts/ 2>/dev/null || true
|
|
|
|
# Configurer le hostname
|
|
hostnamectl set-hostname "$HOSTNAME" 2>/dev/null || echo "$HOSTNAME" > /etc/hostname
|
|
|
|
log_info "Mode Live configuré!"
|
|
log_info "Ce nœud est connecté au mesh KAWA en tant que $HOSTNAME"
|
|
|
|
# Afficher l'IP
|
|
log_info "IP Mesh: $(tailscale ip 2>/dev/null || echo 'en attente...')"
|
|
}
|
|
|
|
# Main
|
|
main() {
|
|
log_info "Démarrage de l'installation KAWA OS..."
|
|
|
|
# Vérifier les prérequis
|
|
check_prereqs
|
|
|
|
# Détecter le hostname
|
|
HOSTNAME=$(detect_hostname)
|
|
|
|
# Demander le mode
|
|
echo ""
|
|
echo -e "${YELLOW}Mode d'installation:${NC}"
|
|
echo " 1) Mode Live USB (en RAM, sans installation sur disque)"
|
|
echo " 2) Installation sur disque"
|
|
echo ""
|
|
read -p "Choisir le mode (1/2): " mode
|
|
|
|
# Télécharger la config
|
|
CONFIG_DIR=$(fetch_config)
|
|
|
|
case "$mode" in
|
|
1)
|
|
live_mode "$HOSTNAME" "$CONFIG_DIR"
|
|
;;
|
|
2)
|
|
# Lister les disques
|
|
log_info "Disques disponibles:"
|
|
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep disk
|
|
|
|
read -p "Disque cible (ex: /dev/sda): " DISK
|
|
|
|
install_tailscale
|
|
install_to_disk "$DISK"
|
|
generate_nixos_config "$HOSTNAME" "$CONFIG_DIR" "$DISK"
|
|
connect_mesh "$HOSTNAME"
|
|
install_system
|
|
post_install
|
|
;;
|
|
*)
|
|
log_error "Mode invalide"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Exécution
|
|
main "$@" |