Aller au contenu principal
Paris / --:--:--

Hey , Je m'appelle Clément.

Stage ingénieur informatique · mai 2027 Recrutez-moi
Retour

Logiciel de sauvegarde open source

C# Avalonia .NET 10 XUnit GitHub Actions

EasySave est un gestionnaire de jobs de sauvegarde en C# qui supporte les stratégies complète et différentielle, exécute les jobs en parallèle, chiffre les fichiers à la volée, et envoie les logs vers un serveur TCP distant. Il embarque deux frontends : une GUI desktop cross-platform (Avalonia) et un TUI console navigable au clavier, partageant le même moteur métier sans duplication.

Architecture

Diagramme d'architecture EasySave

La solution est découpée en six projets découplés : EasySave.Core (logique métier partagée), EasySave.GUI, EasySave.CLI, EasyLog (logger modulaire), EasyLog.Server (agrégation TCP, Docker), et CryptoSoft (outil de chiffrement autonome).

Les deux frontends reposent sur MVVM. Les interactions utilisateur passent par des implémentations ICommand ([RelayCommand]), qui exécutent des opérations asynchrones sans bloquer le thread UI. Ajouter un nouveau frontend se résume à câbler une nouvelle vue, le core et les ViewModels restent intacts.

Avalonia a été choisi plutôt que WPF pour son support cross-platform : il utilise le moteur de rendu 2D Skia au lieu de DirectX, ce qui permet à la même base de code C# de tourner sur Windows, Linux et macOS sans branches spécifiques.

Design patterns utilisés : Strategy pour les types de sauvegarde et les formats de logs, Observer pour la propagation d’état en temps réel, Singleton pour les services partagés.

Exécution parallèle et ordonnancement des priorités

Chaque job de sauvegarde s’exécute dans une Task dédiée via Task.Run, avec async/await pour toutes les opérations d’E/S. Les CancellationToken servent de base aux commandes Play/Pause/Stop : chaque composant vérifie régulièrement son token et s’arrête proprement si nécessaire.

L’état partagé est protégé par un ReaderWriterLockSlim (nombreuses lectures concurrentes, peu d’écritures), tandis que lock est réservé aux sections critiques locales. Les SemaphoreSlim modélisent les ressources limitées, notamment le nombre maximum de transferts de gros fichiers autorisés simultanément.

L’ordonnancement des priorités fonctionne par extensions : l’utilisateur déclare quels types de fichiers sont critiques (ex. .docx, .pdf). Avant chaque job, SeparatePriorityFiles dans FileUtils.cs découpe l’ensemble de fichiers en deux groupes. TransferLimitService coordonne ensuite entre les jobs actifs : WaitForPriorityFile bloque un transfert non prioritaire tant qu’un fichier critique est en attente, et AddPendingPriorityFile enregistre sa présence dans la couche de coordination. Cela garantit que dès les premières minutes d’un job, les fichiers essentiels sont déjà sécurisés.

Le monitoring des logiciels métier tourne en arrière-plan : dès qu’un processus configuré est détecté, tous les jobs actifs se mettent en pause automatiquement et reprennent à sa fermeture.

Chiffrement des fichiers

Les fichiers sont chiffrés pendant la sauvegarde via CryptoSoft, appelé en subprocess. L’appel est sécurisé : EasySave signe un timestamp UTC Unix avec une clé RSA 4096 bits et transmet le timestamp et sa signature à CryptoSoft via des variables d’environnement. CryptoSoft vérifie la signature et rejette tout appel de plus de 2 secondes, bloquant les attaques par rejeu. La clé privée est stockée dans %AppData%\ProSoft\EasySave\keys\ avec des restrictions ACL au niveau OS.

CryptoSoft impose une instance unique par machine via un Mutex nommé (scopé machine et utilisateur), mettant en file d’attente les demandes concurrentes. EasySave maintient également un verrou logiciel avant chaque invocation, deux barrières combinées pour éliminer les race conditions en environnement concurrent.

Deux algorithmes sont disponibles : XOR pour l’obfuscation légère, et AES-256 pour le chiffrement fort. Pour AES, la passphrase est passée dans SHA-256 pour dériver une clé de 32 octets, garantissant une longueur correcte quelle que soit la saisie. Les fichiers chiffrés sont suffixés en .lock.

Journalisation

Des objets LogEntry sont produits pour chaque événement significatif (transfert, chiffrement, erreur) et routés vers une destination selon la configuration. En mode local, les entrées sont sérialisées dans des fichiers JSON ou XML par date. En mode distant, elles sont envoyées via socket TCP à EasyLog.Server, un service Docker qui les désérialise et les écrit sur un volume monté. Un mode hybride (local et distant) est aussi supporté. La bibliothèque de log est une DLL séparée, découplée des deux frontends et de EasySave.Core.

CI/CD

Pipeline GitHub Actions

Deux workflows tournent sur GitHub Actions. Le premier se déclenche sur chaque pull request : checkout, setup .NET 10, restore, build, et suite de tests complète. Une PR ne peut pas être fusionnée tant que toutes les étapes ne passent pas.

Le second se déclenche sur les tags de version correspondant à v*.* - GUI. Il exécute les mêmes étapes de validation, puis publie les binaires multi-plateformes (Windows, Linux, macOS, x64 et ARM), archive les artefacts, les uploade sur GitHub, et crée automatiquement une release. Chaque tag correspond à un ensemble de binaires reproductibles et testés.

Pourquoi ces choix

Avalonia plutôt que WPF. WPF lie l’application à DirectX et donc à Windows. Comme le support cross-platform était une contrainte dès le départ, le moteur Skia d’Avalonia s’imposait. Une seule base de code, trois plateformes, aucune branche spécifique.

Six projets plutôt qu’un seul. Le découpage est volontaire : CryptoSoft et EasyLog peuvent évoluer indépendamment ou être réutilisés dans d’autres outils sans embarquer tout le moteur de sauvegarde. Cela permet aussi aux clients sur d’anciennes versions d’EasySave de continuer à utiliser la même interface DLL de log, même si l’implémentation change.

Authentification RSA pour CryptoSoft. CryptoSoft est un outil CLI, ce qui signifie que n’importe quel processus sur la machine peut l’appeler. Sans authentification, une application malveillante pourrait l’utiliser pour chiffrer des fichiers arbitraires. Le mécanisme RSA + fenêtre de 2 secondes impose une frontière d’autorisation stricte sans rien changer pour les appelants légitimes.

Double barrière pour l’instance unique. Le Mutex OS seul laisse une petite fenêtre de race condition entre le moment où EasySave vérifie si CryptoSoft tourne et le moment où il lance réellement le processus. Le verrou logiciel côté EasySave ferme complètement cette fenêtre.

ReaderWriterLockSlim pour l’état global. L’état des jobs est lu en permanence (rafraîchissement UI, polling de statut) mais écrit rarement (démarrage/arrêt d’un job). Un lock classique sérialiserait toutes les lectures inutilement. ReaderWriterLockSlim correspond au profil d’accès réel.

Priorité par extension, pas par fichier. Demander aux utilisateurs de marquer des fichiers individuellement serait inutilisable en pratique. Les extensions sont le bon niveau d’abstraction : simple à configurer, compréhensible par un utilisateur non technique, et suffisamment précis pour que la logique d’ordonnancement puisse agir dessus.

Contact

Parlons-en.

Pas de formulaires, pas d’agenda, envoyez-moi un email avec ce que vous avez en tête. Je lis tout.

contact@clementomnes.dev