diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9f87fda --- /dev/null +++ b/flake.nix @@ -0,0 +1,30 @@ +{ + description = "KAWA OS - NixOS Configuration"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = { self, nixpkgs, ... }@inputs: { + nixosModules = { + default = import ./nixos; + kawa = import ./nixos/kawa.nix; + }; + + nixosConfigurations = { + # Exemple de configuration + kawa-node = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./nixos + { + services.kawa = { + enable = true; + hostname = "kawa-node-01"; + }; + } + ]; + }; + }; + }; +} diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..1027eaa --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,18 @@ +# KAWA OS - Configuration par défaut +# Usage: import dans configuration.nix + +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./kawa.nix + ]; + + services.kawa = { + enable = true; + autoConnect = true; + enableNats = true; + enableSyncthing = true; + enableOllama = false; # Activer si GPU disponible + }; +} diff --git a/nixos/kawa.nix b/nixos/kawa.nix new file mode 100644 index 0000000..8b6ac22 --- /dev/null +++ b/nixos/kawa.nix @@ -0,0 +1,148 @@ +# KAWA OS - Module NixOS +# Configuration automatique pour rejoindre le mesh KAWA + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.kawa; +in +{ + options.services.kawa = { + enable = mkEnableOption "KAWA mesh network"; + + hostname = mkOption { + type = types.str; + default = ""; + description = "Hostname personnalisé pour le nœud KAWA"; + }; + + headscaleUrl = mkOption { + type = types.str; + default = "https://headscale.du-senegal.com"; + description = "URL du serveur Headscale"; + }; + + headscaleFallback = mkOption { + type = types.str; + default = "http://141.94.23.212"; + description = "URL de fallback du serveur Headscale"; + }; + + authKey = mkOption { + type = types.str; + default = "f43f36ef159b3df799eb316b81bdac1b415c7cc2add174d0"; + description = "Clé d'authentification Headscale"; + }; + + autoConnect = mkOption { + type = types.bool; + default = true; + description = "Connexion automatique au mesh au démarrage"; + }; + + # Services KAWA + enableNats = mkOption { + type = types.bool; + default = true; + description = "Activer le client NATS"; + }; + + enableSyncthing = mkOption { + type = types.bool; + default = true; + description = "Activer Syncthing pour la synchronisation"; + }; + + enableOllama = mkOption { + type = types.bool; + default = false; + description = "Activer Ollama pour l'inférence locale"; + }; + }; + + config = mkIf cfg.enable { + # Tailscale configuration + services.tailscale = { + enable = true; + extraUpFlags = [ + "--login-server=${cfg.headscaleUrl}" + "--authkey=${cfg.authKey}" + "--hostname=${if cfg.hostname != "" then cfg.hostname else "kawa-${config.networking.hostName}"}" + ]; + }; + + # NATS client + services.nats = mkIf cfg.enableNats { + enable = true; + server = "100.64.0.1:4222"; + }; + + # Syncthing + services.syncthing = mkIf cfg.enableSyncthing { + enable = true; + user = "kawa"; + group = "kawa"; + config = { + folders = { + "kawa-memory" = { + path = "/home/kawa/.local/share/kawa/memory"; + devices = [ "vps-7ed4abb0" ]; + }; + "kawa-workspace" = { + path = "/home/kawa/.local/share/kawa/workspace"; + devices = [ "vps-7ed4abb0" ]; + }; + "kawa-forge" = { + path = "/home/kawa/.local/share/kawa/forge"; + devices = [ "vps-7ed4abb0" ]; + }; + }; + }; + }; + + # Ollama (optionnel) + services.ollama = mkIf cfg.enableOllama { + enable = true; + acceleration = false; # À activer si GPU disponible + }; + + # Utilisateur KAWA + users.users.kawa = { + isNormalUser = true; + description = "KAWA Node User"; + extraGroups = [ "wheel" "networkmanager" "tailscale" ]; + }; + + # Firewall + networking.firewall = { + allowedTCPPorts = [ 22 4222 22000 ]; + allowedUDPPorts = [ 41641 22000 ]; + trustedInterfaces = [ "tailscale0" ]; + }; + + # Environment packages + environment.systemPackages = with pkgs; [ + tailscale + natscli + syncthing + git + curl + wget + ]; + + # Systemd service pour la connexion automatique + systemd.services.kawa-connect = mkIf cfg.autoConnect { + description = "KAWA Mesh Auto-Connect"; + after = [ "network-online.target" "tailscale.service" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.tailscale}/bin/tailscale up --login-server=${cfg.headscaleUrl} --authkey=${cfg.authKey} --force-reauth"; + RemainAfterExit = true; + }; + }; + }; +} diff --git a/setup b/setup index 4ac9325..c106e95 100755 --- a/setup +++ b/setup @@ -8,50 +8,231 @@ HEADSCALE_URL="https://headscale.du-senegal.com" HEADSCALE_FALLBACK="http://141.94.23.212" HEADSCALE_AUTHKEY="f43f36ef159b3df799eb316b81bdac1b415c7cc2add174d0" +# Paramètres NATS +NATS_SERVER="100.64.0.1:4222" +NATS_CLUSTER="KAWA" +NATS_USER="kawa" +NATS_PASS="kawa123" + +# Paramètres Syncthing +SYNCTHING_DEVICE_ID="" # Sera généré +SYNCTHING_FOLDERS="kawa-memory,kawa-workspace,kawa-forge" +SYNCTHING_VPS_ID="AHF53QZ-ZYCQ2K7-556QBZ2-2UAYZL4-QNEQOGZ-PHZQIAG-4ZRXI3P-QLLJNA6" + echo "🜄 KAWA OS - Installation" echo "" # Détection du type de système detect_system() { + # NixOS + if [ -f /etc/NIXOS ]; then + echo "nixos" + return + fi + + # Debian/Ubuntu + if [ -f /etc/debian_version ]; then + echo "debian" + return + fi + + # Fedora/RHEL + if [ -f /etc/redhat-release ]; then + echo "redhat" + return + fi + + # Arch Linux + if [ -f /etc/arch-release ]; then + echo "arch" + return + fi + + # Docker/Container if [ -f /.dockerenv ]; then echo "docker" - elif grep -q "docker\|lxc\|container" /proc/1/cgroup 2>/dev/null; then - echo "container" - elif [ -f /sys/class/dmi/id/product_name ]; then - echo "physical" - else - echo "unknown" + return fi + + # Container générique + if grep -q "docker\|lxc\|container" /proc/1/cgroup 2>/dev/null; then + echo "container" + return + fi + + # Machine physique + if [ -f /sys/class/dmi/id/product_name ]; then + echo "physical" + return + fi + + echo "unknown" } -# Génération du hostname -generate_hostname() { - local SYSTEM_TYPE=$(detect_system) - local MODEL - local SUFFIX +# Installation spécifique NixOS +install_nixos() { + echo "📦 Installation NixOS détectée" + echo "" - case "$SYSTEM_TYPE" in - docker|container) - # Pour les conteneurs, utiliser le hostname du host ou générer - if [ -f /etc/hostname ]; then - MODEL=$(cat /etc/hostname | tr '[:upper:]' '[:lower:]' | tr -d ' ' | cut -c1-15) - else - MODEL="container" - fi - SUFFIX=$(head -c 4 /dev/urandom | xxd -p 2>/dev/null || echo "$(date +%s | tail -c 4)") - echo "kawa-${MODEL}-${SUFFIX}" - ;; - physical) - # Pour les machines physiques - MODEL=$(cat /sys/class/dmi/id/product_name 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d ' ' | cut -c1-15 || echo "node") - SUFFIX=$(head -c 4 /dev/urandom | xxd -p 2>/dev/null || echo "$(date +%s | tail -c 4)") - echo "kawa-${MODEL}-${SUFFIX}" - ;; - *) - SUFFIX=$(head -c 4 /dev/urandom | xxd -p 2>/dev/null || echo "$(date +%s | tail -c 4)") - echo "kawa-node-${SUFFIX}" - ;; - esac + # Demander le hostname + read -p "Hostname pour ce nœud (ex: kawa-node-01): " HOSTNAME_INPUT + HOSTNAME="${HOSTNAME_INPUT:-kawa-node-$(head -c 4 /dev/urandom | xxd -p 2>/dev/null || echo "$(date +%s | tail -c 4)")}" + + # Créer la configuration NixOS + echo "Création de la configuration NixOS..." + + NIXOS_CONFIG="/etc/nixos/kawa-configuration.nix" + + cat > "$NIXOS_CONFIG" << NIXOS_EOF +# KAWA Node - Configuration NixOS +# Généré automatiquement par kawa-setup + +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./hardware-configuration.nix + ./kawa.nix + ]; + + # Configuration réseau + networking.hostName = "$HOSTNAME"; + networking.firewall = { + allowedTCPPorts = [ 22 4222 22000 ]; + allowedUDPPorts = [ 41641 22000 ]; + trustedInterfaces = [ "tailscale0" ]; + }; + + # Tailscale/Headscale + services.tailscale = { + enable = true; + extraUpFlags = [ + "--login-server=$HEADSCALE_URL" + "--authkey=$HEADSCALE_AUTHKEY" + "--hostname=$HOSTNAME" + "--force-reauth" + ]; + }; + + # NATS Client + services.nats = { + enable = true; + server = "$NATS_SERVER"; + }; + + # Syncthing + services.syncthing = { + enable = true; + user = "kawa"; + group = "kawa"; + config = { + devices = { + "vps-7ed4abb0" = { id = "$SYNCTHING_VPS_ID"; }; + }; + folders = { + "kawa-memory" = { + path = "/home/kawa/.local/share/kawa/memory"; + devices = [ "vps-7ed4abb0" ]; + }; + "kawa-workspace" = { + path = "/home/kawa/.local/share/kawa/workspace"; + devices = [ "vps-7ed4abb0" ]; + }; + "kawa-forge" = { + path = "/home/kawa/.local/share/kawa/forge"; + devices = [ "vps-7ed4abb0" ]; + }; + }; + }; + }; + + # Utilisateur KAWA + users.users.kawa = { + isNormalUser = true; + extraGroups = [ "wheel" "networkmanager" "tailscale" "syncthing" ]; + }; + + # Packages système + environment.systemPackages = with pkgs; [ + tailscale + natscli + syncthing + git + curl + wget + htop + ]; +} +NIXOS_EOF + + # Copier le module kawa.nix + cp ./nixos/kawa.nix /etc/nixos/ 2>/dev/null || true + + echo "" + echo "✓ Configuration NixOS créée: $NIXOS_CONFIG" + echo "" + echo "Pour appliquer:" + echo " sudo nixos-rebuild switch" + echo "" + echo "Ou ajouter à votre configuration existante:" + echo " imports = [ ./kawa.nix ];" + echo " services.kawa.enable = true;" + + return 0 +} + +# Installation standard (Debian/Ubuntu/Fedora/etc.) +install_standard() { + echo "📦 Installation standard ($1)" + + HOSTNAME="${2:-kawa-$SYSTEM_TYPE-$(head -c 4 /dev/urandom | xxd -p 2>/dev/null || echo "$(date +%s | tail -c 4)")}" + echo "Hostname: $HOSTNAME" + echo "" + + # Vérifier connexion existante + check_existing + + # Installer Tailscale si nécessaire + if ! command -v tailscale &> /dev/null; then + echo "Installation de Tailscale..." + curl -fsSL https://tailscale.com/install.sh | sh + fi + + # Démarrer tailscaled + echo "Démarrage de tailscaled..." + tailscaled 2>/dev/null & + sleep 3 + + # Connexion au mesh + echo "Connexion au mesh KAWA..." + + tailscale down 2>/dev/null || true + sleep 1 + + if tailscale up --login-server="$HEADSCALE_URL" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" --force-reauth 2>/dev/null; then + echo "✓ Connecté via $HEADSCALE_URL" + elif tailscale up --login-server="$HEADSCALE_FALLBACK" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" --force-reauth 2>/dev/null; then + echo "✓ Connecté via $HEADSCALE_FALLBACK" + else + echo "✗ Échec de connexion" + exit 1 + fi + + sleep 2 + + # Afficher les infos + echo "" + echo "🜄 Nœud KAWA configuré!" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "Hostname: $HOSTNAME" + echo "IP Mesh: $(tailscale ip 2>/dev/null || echo 'en attente...')" + echo "NATS: $NATS_SERVER" + echo "" + echo "Commandes utiles:" + echo " tailscale status # Voir le mesh" + echo " tailscale ip # Voir l'IP" + echo " tailscale ping NODE # Ping un nœud" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" } # Vérifier si déjà connecté @@ -76,59 +257,21 @@ check_existing() { echo "Détection du système..." SYSTEM_TYPE=$(detect_system) echo "Type détecté: $SYSTEM_TYPE" - -HOSTNAME=$(generate_hostname) -echo "Hostname: $HOSTNAME" echo "" -# Vérifier connexion existante -check_existing - -# Installer Tailscale si nécessaire -if ! command -v tailscale &> /dev/null; then - echo "Installation de Tailscale..." - curl -fsSL https://tailscale.com/install.sh | sh -fi - -# Démarrer tailscaled -echo "Démarrage de tailscaled..." -tailscaled 2>/dev/null & -sleep 3 - -# Connexion au mesh -echo "Connexion au mesh KAWA..." - -# Déconnexion préalable si existante -tailscale down 2>/dev/null || true -sleep 1 - -# Tentative de connexion -if tailscale up --login-server="$HEADSCALE_URL" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" --force-reauth 2>/dev/null; then - echo "✓ Connecté via $HEADSCALE_URL" -elif tailscale up --login-server="$HEADSCALE_FALLBACK" --authkey="$HEADSCALE_AUTHKEY" --hostname="$HOSTNAME" --force-reauth 2>/dev/null; then - echo "✓ Connecté via $HEADSCALE_FALLBACK" -else - echo "✗ Échec de connexion" - echo "" - echo "Vérifiez:" - echo " - La connexion réseau" - echo " - Le serveur Headscale est accessible" - echo " - L'authkey est valide" - exit 1 -fi - -sleep 2 - -# Afficher les infos -echo "" -echo "🜄 Nœud KAWA configuré!" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "Hostname: $HOSTNAME" -echo "IP Mesh: $(tailscale ip 2>/dev/null || echo 'en attente...')" -echo "IPv6: $(tailscale ip -6 2>/dev/null || echo 'en attente...')" -echo "" -echo "Commandes utiles:" -echo " tailscale status # Voir le mesh" -echo " tailscale ip # Voir l'IP" -echo " tailscale ping NODE # Ping un nœud" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" \ No newline at end of file +case "$SYSTEM_TYPE" in + nixos) + install_nixos + ;; + debian|redhat|arch|physical) + install_standard "$SYSTEM_TYPE" + ;; + docker|container) + install_standard "container" + ;; + *) + echo "Type de système non reconnu: $SYSTEM_TYPE" + echo "Tentative d'installation standard..." + install_standard "unknown" + ;; +esac