Replace manual upsert logic with SQLite native upsert in Docker CRUD repositories, enhance Ansible backup playbook with better error handling and file permissions, add favicon endpoint, and improve playbook editor UI with syntax highlighting, lint integration, quality badges, and enhanced code editing features
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled

This commit is contained in:
2025-12-17 15:36:49 -05:00
parent 785db4b302
commit 05087aa380
77 changed files with 15286 additions and 304 deletions
+1
View File
@@ -20,6 +20,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
openssh-client \
sshpass \
ansible \
ansible-lint \
git \
curl \
libjpeg62-turbo \
+29 -48
View File
@@ -1,67 +1,48 @@
---
services:
homelab-dashboard:
build:
context: ..
dockerfile: docker/Dockerfile
container_name: homelab-automation-dashboard
image: docker-registry.dev.home:5000/homelab-automation-api:latest
container_name: homelab-dashboard
restart: unless-stopped
ports:
- "8008:8000"
- "${PORT:-7070}:8008"
environment:
# zone horaire
- TZ=${TZ:-America/Montreal}
# Clé API pour l'authentification
# general variables
- TZ=${TZ:-America/Montreal}
# application variables
- API_KEY=${API_KEY:-dev-key-12345}
# Utilisateur SSH pour Ansible
- SSH_USER=${SSH_USER:-automation}
# Chemin de la clé SSH dans le container
- SSH_KEY_PATH=/app/ssh_keys/id_rsa
# Désactiver la vérification des clés SSH (pour les tests)
- ANSIBLE_HOST_KEY_CHECKING=False
# Timeout SSH
- ANSIBLE_TIMEOUT=30
# Homelab Data folder (monté sur /app/data)
- HOMELAB_DATA_DIR=${HOMELAB_DATA_DIR:-./data}
# SQLite DB path et URL (doivent correspondre à app/models/database.py)
- SSH_KEY_PATH=${SSH_KEY_PATH:-/app/ssh_keys/id_automation_ansible}
- HOMELAB_DATA_DIR=/app/data
- DB_PATH=/app/data/homelab.db
- DATABASE_URL=sqlite+aiosqlite:////app/data/homelab.db
# Répertoire des logs de tâches (format YYYY/MM/JJ)
- DIR_LOGS_TASKS=/app/tasks_logs
# Ansible inventory
- ANSIBLE_INVENTORY=./ansible/inventory
# Ansible playbooks
- ANSIBLE_PLAYBOOKS=./ansible/playbooks
# Ansible group_vars
- ANSIBLE_GROUP_VARS=./ansible/inventory/group_vars
# Notifications ntfy (peuvent aussi être définies dans .env)
- NTFY_BASE_URL=${NTFY_BASE_URL:-http://localhost:8150}
- DATABASE_URL=${DATABASE_URL:-sqlite+aiosqlite:////app/data/homelab.db}
- JWT_SECRET_KEY=${JWT_SECRET_KEY:-dev-key-12345}
- JWT_EXPIRE_MINUTES=${JWT_EXPIRE_MINUTES:-1440}
# ntfy notification variables
- NTFY_BASE_URL=${NTFY_BASE_URL:-https://ntfy.dracodev.net}
- NTFY_DEFAULT_TOPIC=${NTFY_DEFAULT_TOPIC:-homelab-events}
- NTFY_ENABLED=${NTFY_ENABLED:-true}
- NTFY_TIMEOUT=${NTFY_TIMEOUT:-5}
- NTFY_USERNAME=${NTFY_USERNAME:-}
- NTFY_PASSWORD=${NTFY_PASSWORD:-}
- NTFY_TOKEN=${NTFY_TOKEN:-}
- NTFY_MSG_TYPE=${NTFY_MSG_TYPE:-ALL}
- NTFY_MSG_TYPE=${NTFY_MSG_TYPE:-ERR}
- NTFY_TIMEOUT=${NTFY_TIMEOUT:-5}
# ansible variables
- ANSIBLE_HOST_KEY_CHECKING=False
- ANSIBLE_TIMEOUT=30
- ANSIBLE_INVENTORY=/app/ansible/inventory
- ANSIBLE_PLAYBOOKS=/app/ansible/playbooks
- ANSIBLE_GROUP_VARS=/app/ansible/inventory/group_vars
- DIR_LOGS_TASKS=/app/tasks_logs
volumes:
# Volume Docker natif pour la base de données SQLite (évite les problèmes I/O sur Windows)
- homelab_data:/app/data
# Monter l'inventaire Ansible (permet de modifier sans rebuild)
- ${ANSIBLE_INVENTORY:-../ansible/inventory}:/ansible/inventory
# Monter les playbooks (permet de modifier sans rebuild)
- ${ANSIBLE_PLAYBOOKS:-../ansible/playbooks}:/ansible/playbooks
# Monter les variables de groupe
- ${ANSIBLE_GROUP_VARS:-../ansible/inventory/group_vars}:/ansible/inventory/group_vars
# Monter les clés SSH depuis le host
- ${SSH_KEY_DIR:-~/.ssh}:/app/ssh_keys:ro
# Volume pour les logs (optionnel)
- homelab_logs:/app/logs
# Monter le répertoire des logs de tâches depuis le host
- ${DIR_LOGS_TASKS:-../tasks_logs}:/app/tasks_logs
- ${HOMELAB_DATA_DIR:-./data}:/app/data
- ${ANSIBLE_INVENTORY:-./ansible/inventory}:/app/ansible/inventory
- ${ANSIBLE_PLAYBOOKS:-./ansible/playbooks}:/app/ansible/playbooks
- ${ANSIBLE_GROUP_VARS:-./ansible/inventory/group_vars}:/app/ansible/inventory/group_vars
- ${HOMELAB_LOG_DIR:-./logs}:/app/logs
- ${DIR_LOGS_TASKS:-./tasks_logs}:/app/tasks_logs
networks:
- homelab-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
test: ["CMD", "curl", "-f", "http://homelab-dashboard:7070/api/health"]
interval: 30s
timeout: 10s
retries: 3
+139 -43
View File
@@ -1,51 +1,147 @@
#!/bin/bash
# init.sh - Script d'initialisation de l'environnement pour Homelab Automation
# Ce script prépare le fichier .env et les répertoires nécessaires.
set -e
# Se placer dans le dossier du script
cd "$(dirname "$0")"
echo "=== Initialisation de l'environnement Docker ==="
# 1. Configuration du fichier .env
if [ ! -f .env ]; then
echo "Creation du fichier .env a partir de .env.example..."
cp .env.example .env
# Génération d'une clé API aléatoire
API_KEY=$(openssl rand -hex 16 2>/dev/null || echo "change-me-please-123")
# Remplacement de la clé API par défaut (si sed disponible)
if command -v sed >/dev/null 2>&1; then
# Compatible Linux/Mac
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s/API_KEY=dev-key-12345/API_KEY=${API_KEY}/" .env
else
sed -i "s/API_KEY=dev-key-12345/API_KEY=${API_KEY}/" .env
fi
echo "Clé API générée aléatoirement."
fi
echo "--> Fichier .env créé. Pensez à l'éditer pour configurer vos accès SSH et notifications."
echo "Initializing environment variables..."
# general variables for all containers
HOSTNAME=$(hostname)
PORT="7070"
ENV="production"
TZ="America/Montreal"
DEFAULT_INTERFACE=$(ip route show default | awk '{print $5}'|head -n 1)
if [ -f /etc/alpine-release ]; then
# Alpine Linux
SERVER_IP=$(ip -o -4 addr show $DEFAULT_INTERFACE | awk '{print $4}' | cut -d/ -f1)
else
echo "--> Le fichier .env existe déjà."
# Debian-based systems
SERVER_IP=$(hostname -I | tr ' ' '\n' | grep -E "^$(ip -o -4 addr show $DEFAULT_INTERFACE | awk '{print $4}' | cut -d/ -f1)")
fi
# current user name
CURRENT_USER=$(whoami)
# Docker registry variables
REGISTRY_HOST="docker-registry.dev.home"
REGISTRY_PORT="5000"
IMAGE_NAME="homelab-automation-api"
DOCKER_CONFIG_DIR="/DOCKER_CONFIG"
APP_NAME="homelab-dashboard"
# Application specific variables
API_KEY=dev-key-12345
SSH_USER=automation
SSH_KEY_DIR=/home/$CURRENT_USER/.ssh
SSH_KEY_PATH=/app/ssh_keys/id_automation_ansible
HOMELAB_DATA_DIR=${DOCKER_CONFIG_DIR}/${APP_NAME}/data
HOMELAB_LOG_DIR=${DOCKER_CONFIG_DIR}/${APP_NAME}/logs
DB_PATH=${DOCKER_CONFIG_DIR}/${APP_NAME}/data/homelab.db
DATABASE_URL=sqlite+aiosqlite:////app/data/homelab.db
JWT_SECRET_KEY=dev-key-12345
JWT_EXPIRE_MINUTES=1440
# Ntfy notification variables
NTFY_BASE_URL=https://ntfy.dracodev.net
NTFY_DEFAULT_TOPIC=homelab-events
NTFY_ENABLED=true
NTFY_MSG_TYPE=ERR
NTFY_TIMEOUT=5
# Ansible variables
ANSIBLE_HOST_KEY_CHECKING=False
ANSIBLE_TIMEOUT=30
ANSIBLE_DIR=/NFS/OBSIDIAN_DOC/SessionsManager/60-📝TACHES📝/ANSIBLE
ANSIBLE_INVENTORY=/NFS/OBSIDIAN_DOC/SessionsManager/60-📝TACHES📝/ANSIBLE/inventory
ANSIBLE_PLAYBOOKS=/NFS/OBSIDIAN_DOC/SessionsManager/60-📝TACHES📝/ANSIBLE/playbooks
ANSIBLE_GROUP_VARS=/NFS/OBSIDIAN_DOC/SessionsManager/60-📝TACHES📝/ANSIBLE/inventory/group_vars
DIR_LOGS_TASKS=/NFS/OBSIDIAN_DOC/SessionsManager/60-📝TACHES📝/LOGS
# Write environment variables to .env file
echo "creating .env file..."
# Docker registry variables
echo "REGISTRY_HOST=$REGISTRY_HOST" >> .env
echo "REGISTRY_PORT=$REGISTRY_PORT" >> .env
echo "IMAGE_NAME=$IMAGE_NAME" >> .env
# general variables
echo "NGINX_HOSTNAME=$HOSTNAME" > .env
echo "PORT=$PORT" >> .env
echo "ENV=$ENV" >> .env
echo "TZ=$TZ" >> .env
echo "NGINX_SERVER_IP=$SERVER_IP" >> .env
# application specific variables
echo "API_KEY=$API_KEY" >> .env
echo "SSH_USER=$SSH_USER" >> .env
echo "SSH_KEY_DIR=$SSH_KEY_DIR" >> .env
echo "SSH_KEY_PATH=$SSH_KEY_PATH" >> .env
echo "HOMELAB_DATA_DIR=$HOMELAB_DATA_DIR" >> .env
echo "HOMELAB_LOG_DIR=$HOMELAB_LOG_DIR" >> .env
echo "DB_PATH=$DB_PATH" >> .env
echo "DATABASE_URL=$DATABASE_URL" >> .env
echo "JWT_SECRET_KEY=$JWT_SECRET_KEY" >> .env
echo "JWT_EXPIRE_MINUTES=$JWT_EXPIRE_MINUTES" >> .env
# ntfy notification variables
echo "NTFY_BASE_URL=$NTFY_BASE_URL" >> .env
echo "NTFY_DEFAULT_TOPIC=$NTFY_DEFAULT_TOPIC" >> .env
echo "NTFY_ENABLED=$NTFY_ENABLED" >> .env
echo "NTFY_MSG_TYPE=$NTFY_MSG_TYPE" >> .env
echo "NTFY_TIMEOUT=$NTFY_TIMEOUT" >> .env
# ansible variables
echo "ANSIBLE_HOST_KEY_CHECKING=$ANSIBLE_HOST_KEY_CHECKING" >> .env
echo "ANSIBLE_TIMEOUT=$ANSIBLE_TIMEOUT" >> .env
echo "ANSIBLE_INVENTORY=$ANSIBLE_INVENTORY" >> .env
echo "ANSIBLE_PLAYBOOKS=$ANSIBLE_PLAYBOOKS" >> .env
echo "ANSIBLE_GROUP_VARS=$ANSIBLE_GROUP_VARS" >> .env
echo "DIR_LOGS_TASKS=$DIR_LOGS_TASKS" >> .env
# Create directories
echo "Creating necessary directories..."
# valider si directory /DOCKER_CONFIG/ exists
if [ ! -d ${DOCKER_CONFIG_DIR} ]; then
mkdir ${DOCKER_CONFIG_DIR}
fi
if [ ! -d ${DOCKER_CONFIG_DIR}/${APP_NAME} ]; then
mkdir -p ${DOCKER_CONFIG_DIR}/${APP_NAME}
fi
if [ ! -d ${DOCKER_CONFIG_DIR}/${APP_NAME}/ssh_keys ]; then
mkdir -p ${DOCKER_CONFIG_DIR}/${APP_NAME}/ssh_keys
fi
if [ ! -d ${HOMELAB_DATA_DIR} ]; then
mkdir -p ${HOMELAB_DATA_DIR}
fi
if [ ! -d ${HOMELAB_LOG_DIR} ]; then
mkdir -p ${HOMELAB_LOG_DIR}
fi
if [ ! -d ${ANSIBLE_DIR} ]; then
mkdir ${ANSIBLE_DIR}
fi
if [ ! -d ${ANSIBLE_INVENTORY} ]; then
mkdir ${ANSIBLE_INVENTORY}
fi
if [ ! -d ${ANSIBLE_PLAYBOOKS} ]; then
mkdir ${ANSIBLE_PLAYBOOKS}
fi
if [ ! -d ${ANSIBLE_GROUP_VARS} ]; then
mkdir ${ANSIBLE_GROUP_VARS}
fi
if [ ! -d ${DIR_LOGS_TASKS} ]; then
mkdir ${DIR_LOGS_TASKS}
fi
# 2. Création des répertoires de données
echo "Vérification des répertoires de données..."
mkdir -p ../data
mkdir -p ../tasks_logs
# 3. Vérification des permissions
echo "Ajustement des permissions..."
chmod +x deploy-img.sh maj.sh init.sh 2>/dev/null || true
# Copier les fichiers et répertoires Ansible ../DOCKER_CONFIG/homelab-dashboard/ vers /DOCKER_CONFIG/homelab-dashboard/ansible/ et les écraser s'ils existent
echo "Copying Ansible configuration files..."
cp -r ../DOCKER_CONFIG/homelab-dashboard/ansible.cfg ${ANSIBLE_DIR}/
cp -r ../DOCKER_CONFIG/homelab-dashboard/inventory/* ${ANSIBLE_INVENTORY}/
cp -r ../DOCKER_CONFIG/homelab-dashboard/playbooks/* ${ANSIBLE_PLAYBOOKS}/
cp -r ../DOCKER_CONFIG/homelab-dashboard/inventory/group_vars/* ${ANSIBLE_GROUP_VARS}/
echo "=== Initialisation terminée ==="
echo "Pour démarrer l'application :"
echo " docker compose up -d --build"
echo ""
echo "Pour construire l'image :"
echo " ./build-img.ps1 (Windows/WSL)"
echo " docker build -f Dockerfile -t homelab-automation-api:latest .. (Linux)"
# copy ssh keys to the ssh_keys directory
echo "Copying SSH keys..."
cp -r ../DOCKER_CONFIG/homelab-dashboard/ssh_keys/known_hosts ${SSH_KEY_DIR}/
cp -r ../DOCKER_CONFIG/homelab-dashboard/ssh_keys/id_automation_ansible.pub ${SSH_KEY_DIR}/
cp -r ../DOCKER_CONFIG/homelab-dashboard/ssh_keys/id_automation_ansible ${SSH_KEY_DIR}/
# apply correct permissions to ssh keys
echo "Setting permissions for SSH keys..."
chmod 600 ${SSH_KEY_DIR}/id_automation_ansible
chmod 644 ${SSH_KEY_DIR}/id_automation_ansible.pub
chmod 644 ${SSH_KEY_DIR}/known_hosts
echo "Initialization complete. You can now execute bash ./maj.sh to update the Homelab Dashboard."
+3 -3
View File
@@ -10,10 +10,10 @@ if [[ -f ".env" ]]; then
source .env
fi
# Docker registry variables with default values
REGISTRY_HOST="${REGISTRY_HOST:-docker-registry.dev.home}"
REGISTRY_PORT="${REGISTRY_PORT:-5000}"
IMAGE_NAME="${IMAGE_NAME:-homelab-automation-api}"
REGISTRY="${REGISTRY_HOST}:${REGISTRY_PORT}"
IMAGE="${IMAGE_NAME}:latest"
@@ -22,6 +22,6 @@ docker image pull "${REGISTRY}/${IMAGE}"
# Restart stack with the current compose file
docker compose down
docker compose up -d
docker compose up -d --force-recreate
echo "Homelab Automation API updated and running."
echo "Homelab Dashboard updated and running."