first
This commit is contained in:
147
AGENTS.md
Normal file
147
AGENTS.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## But du depot
|
||||||
|
|
||||||
|
Ce projet construit un framework de post-installation pour Debian 13, lance via :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://gitea.maison43.duckdns.org/gilles/postinstall-debian/raw/branch/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
L'objectif est de proposer une base modulaire, testable et evolutive pour installer et configurer un systeme Debian apres installation.
|
||||||
|
|
||||||
|
## Regles de travail
|
||||||
|
- ecrire les commentaires et les explication en francais
|
||||||
|
- Toujours privilegier une architecture modulaire.
|
||||||
|
- Chaque outil doit vivre dans son propre module.
|
||||||
|
- Ne pas melanger logique framework, logique UI et logique d'installation d'un outil.
|
||||||
|
- Eviter les actions destructives ou silencieuses sur le systeme.
|
||||||
|
- Garder le code compatible avec Debian 13 et un shell Bash standard.
|
||||||
|
- Favoriser du code lisible, structure et compose de fonctions courtes.
|
||||||
|
|
||||||
|
## Structure cible
|
||||||
|
|
||||||
|
Le depot doit converger vers cette structure :
|
||||||
|
|
||||||
|
```text
|
||||||
|
install.sh
|
||||||
|
README.md
|
||||||
|
consigne.md
|
||||||
|
tools.md
|
||||||
|
CHANGELOG.md
|
||||||
|
AGENTS.md
|
||||||
|
|
||||||
|
assets/
|
||||||
|
config/
|
||||||
|
core/
|
||||||
|
docs/
|
||||||
|
hardware/
|
||||||
|
lib/
|
||||||
|
menus/
|
||||||
|
modules/
|
||||||
|
profiles/
|
||||||
|
tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Responsabilites par zone
|
||||||
|
|
||||||
|
- `install.sh` : point d'entree compatible `curl | bash`.
|
||||||
|
- `core/` : bootstrap, runtime, registre des modules, dispatch.
|
||||||
|
- `lib/` : fonctions reutilisables UI, logs, validations, paquets, systeme, reseau.
|
||||||
|
- `menus/` : menus interactifs.
|
||||||
|
- `modules/` : outils installables, un dossier par outil.
|
||||||
|
- `profiles/` : groupes de modules predefinis.
|
||||||
|
- `hardware/` : selections liees au materiel.
|
||||||
|
- `assets/` : themes, polices, wallpapers, icones et ressources visuelles.
|
||||||
|
- `tests/` : tests framework et tests de modules.
|
||||||
|
- `docs/` : documentation de conception et d'usage.
|
||||||
|
|
||||||
|
## Contrat d'un module
|
||||||
|
|
||||||
|
Chaque module doit idealement contenir :
|
||||||
|
|
||||||
|
```text
|
||||||
|
modules/<categorie>/<outil>/
|
||||||
|
module.sh
|
||||||
|
config.sh
|
||||||
|
metadata.conf
|
||||||
|
tests.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Fonctions attendues quand elles sont pertinentes :
|
||||||
|
|
||||||
|
- `module_<outil>_metadata`
|
||||||
|
- `module_<outil>_check`
|
||||||
|
- `module_<outil>_install`
|
||||||
|
- `module_<outil>_configure`
|
||||||
|
- `module_<outil>_test`
|
||||||
|
|
||||||
|
## Standards Bash
|
||||||
|
|
||||||
|
- Utiliser `set -u` et une gestion d'erreurs explicite lorsque l'architecture sera en place.
|
||||||
|
- Citer correctement les variables.
|
||||||
|
- Preferer `command -v` pour verifier les dependances.
|
||||||
|
- Centraliser les logs, messages UI et validations dans `lib/`.
|
||||||
|
- Garder les effets de bord dans des fonctions nommees clairement.
|
||||||
|
- Prevoir ShellCheck des que les scripts existent.
|
||||||
|
|
||||||
|
## Experience utilisateur
|
||||||
|
|
||||||
|
Le framework doit fournir :
|
||||||
|
|
||||||
|
- une interface console claire
|
||||||
|
- des messages colores et coherents
|
||||||
|
- des etapes visibles
|
||||||
|
- des confirmations quand une action est sensible
|
||||||
|
- un resume final des operations
|
||||||
|
|
||||||
|
Fonctions UI a prevoir :
|
||||||
|
|
||||||
|
- `ui_header`
|
||||||
|
- `ui_section`
|
||||||
|
- `ui_info`
|
||||||
|
- `ui_success`
|
||||||
|
- `ui_warn`
|
||||||
|
- `ui_error`
|
||||||
|
- `ui_menu`
|
||||||
|
- `ui_confirm`
|
||||||
|
- `ui_pause`
|
||||||
|
|
||||||
|
## Securite
|
||||||
|
|
||||||
|
- Verifier la distribution et les privileges avant toute installation.
|
||||||
|
- Verifier le reseau si une action distante est necessaire.
|
||||||
|
- Ne pas modifier silencieusement des fichiers critiques.
|
||||||
|
- Preferer des changements explicites, journalises et reversibles quand possible.
|
||||||
|
|
||||||
|
## Methode pour ajouter un outil
|
||||||
|
|
||||||
|
Avant implementation, passer par :
|
||||||
|
|
||||||
|
1. Brainstorming de l'outil.
|
||||||
|
2. Decision d'architecture.
|
||||||
|
3. Implementation du module.
|
||||||
|
4. Integration menu, profil ou materiel si necessaire.
|
||||||
|
5. Tests.
|
||||||
|
6. Documentation.
|
||||||
|
|
||||||
|
Les informations minimales d'un outil dans `tools.md` sont :
|
||||||
|
|
||||||
|
- nom
|
||||||
|
- description
|
||||||
|
- categorie
|
||||||
|
- questions
|
||||||
|
- methode d'installation
|
||||||
|
- tests
|
||||||
|
- statut
|
||||||
|
|
||||||
|
## Priorite immediate
|
||||||
|
|
||||||
|
Avant d'ajouter des outils, construire l'ossature du framework :
|
||||||
|
|
||||||
|
- point d'entree `install.sh`
|
||||||
|
- dossiers standards
|
||||||
|
- bibliotheques de base
|
||||||
|
- mecanisme de chargement
|
||||||
|
- premiers menus
|
||||||
|
- documentation de demarrage
|
||||||
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- Creation de l'architecture initiale du depot
|
||||||
|
- Ajout du bootstrap Bash minimal
|
||||||
|
- Ajout des bibliotheques de base et du menu principal
|
||||||
|
- Ajout du premier module `system/user-sudo`
|
||||||
113
README.md
113
README.md
@@ -0,0 +1,113 @@
|
|||||||
|
# postinstall-debian
|
||||||
|
|
||||||
|
Framework Bash modulaire de post-installation pour Debian 13, pense pour etre lance via `curl | bash`.
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Fournir une base propre pour :
|
||||||
|
|
||||||
|
- installer des outils
|
||||||
|
- appliquer des configurations
|
||||||
|
- regrouper des modules par profil ou materiel
|
||||||
|
- proposer une interface console simple
|
||||||
|
- tester les modules isolemment
|
||||||
|
|
||||||
|
## Etat actuel
|
||||||
|
|
||||||
|
Le depot contient maintenant une architecture initiale :
|
||||||
|
|
||||||
|
- un point d'entree `install.sh`
|
||||||
|
- un noyau `core/`
|
||||||
|
- des bibliotheques reutilisables `lib/`
|
||||||
|
- des menus interactifs par categorie
|
||||||
|
- des modules systeme, reseau, hardware, boot et conteneurs
|
||||||
|
- l'arborescence cible du framework
|
||||||
|
|
||||||
|
## Demarrage local
|
||||||
|
|
||||||
|
Execution recommandee pour tester le bootstrap :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo bash install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Le script ouvre ensuite un menu interactif. Pour le premier module disponible :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo bash install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis :
|
||||||
|
|
||||||
|
```text
|
||||||
|
4. Configuration systeme
|
||||||
|
1. system/user-groups
|
||||||
|
2. system/user-sudo
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple pour `system/user-groups` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
4
|
||||||
|
1
|
||||||
|
gilles
|
||||||
|
audio,video,plugdev,dialout,netdev,lpadmin,scanner
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple pour `network/ssh-server` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
1
|
||||||
|
1
|
||||||
|
7
|
||||||
|
22
|
||||||
|
y
|
||||||
|
n
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple pour `network/mdns-avahi` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
1
|
||||||
|
1
|
||||||
|
3
|
||||||
|
y
|
||||||
|
y
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple pour `network/identity` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
monpc
|
||||||
|
local
|
||||||
|
```
|
||||||
|
|
||||||
|
Exemple pour `network/ip-config` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
enp0s31f6
|
||||||
|
static
|
||||||
|
10.0.0.25
|
||||||
|
22
|
||||||
|
10.0.0.1
|
||||||
|
10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prochaines etapes
|
||||||
|
|
||||||
|
- remplir `tools.md`
|
||||||
|
- ajouter les modules suivants
|
||||||
|
- implementer les menus interactifs
|
||||||
|
- ajouter des tests shell et ShellCheck
|
||||||
|
|
||||||
|
## Validation reseau
|
||||||
|
|
||||||
|
Une checklist de validation LAN est disponible ici :
|
||||||
|
|
||||||
|
- [docs/lan-validation.md](/home/gilles/Documents/vscode/postinstall-debian/docs/lan-validation.md)
|
||||||
|
|||||||
3
config/default.conf
Normal file
3
config/default.conf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Configuration par defaut du framework
|
||||||
|
FRAMEWORK_NAME="postinstall-debian"
|
||||||
|
FRAMEWORK_TARGET="debian-13"
|
||||||
3
config/mdns-avahi.yaml
Normal file
3
config/mdns-avahi.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mdns:
|
||||||
|
enable: yes
|
||||||
|
publish_workstation: yes
|
||||||
19
config/nfs-client.shares.yaml
Normal file
19
config/nfs-client.shares.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
shares:
|
||||||
|
- id: media
|
||||||
|
name: Media
|
||||||
|
description: Partage multimedia principal
|
||||||
|
server: 10.0.0.20
|
||||||
|
remote_path: /srv/nfs/media
|
||||||
|
mount_path: /mnt/nfs/media
|
||||||
|
access: rw
|
||||||
|
mount_options: defaults,_netdev,x-systemd.automount,noatime
|
||||||
|
enabled_by_default: false
|
||||||
|
- id: backup
|
||||||
|
name: Backup
|
||||||
|
description: Partage de sauvegarde
|
||||||
|
server: 10.0.0.30
|
||||||
|
remote_path: /srv/nfs/backup
|
||||||
|
mount_path: /mnt/nfs/backup
|
||||||
|
access: ro
|
||||||
|
mount_options: defaults,_netdev,x-systemd.automount,noatime
|
||||||
|
enabled_by_default: false
|
||||||
6
config/nfs-server.exports.yaml
Normal file
6
config/nfs-server.exports.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
exports:
|
||||||
|
- id: public_data
|
||||||
|
path: /srv/nfs/public
|
||||||
|
clients: 10.0.0.0/22
|
||||||
|
options: rw,sync,no_subtree_check
|
||||||
|
description: Export principal reseau local
|
||||||
10
config/samba-shares.yaml
Normal file
10
config/samba-shares.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
workgroup: home
|
||||||
|
wsdd2: yes
|
||||||
|
shares:
|
||||||
|
- id: public_home
|
||||||
|
name: public
|
||||||
|
path: /home/gilles
|
||||||
|
user: gilles
|
||||||
|
read_only: yes
|
||||||
|
public: yes
|
||||||
|
description: Partage public du dossier personnel
|
||||||
4
config/ssh-server.yaml
Normal file
4
config/ssh-server.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
ssh:
|
||||||
|
port: 22
|
||||||
|
password_authentication: yes
|
||||||
|
permit_root_login: no
|
||||||
524
consigne.md
Normal file
524
consigne.md
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
# CONSIGNE.md
|
||||||
|
|
||||||
|
## Objectif du projet
|
||||||
|
|
||||||
|
Créer un dépôt Git hébergé sur Gitea :
|
||||||
|
|
||||||
|
https://gitea.maison43.duckdns.org/gilles/postinstall-debian
|
||||||
|
|
||||||
|
Ce dépôt doit permettre l'exécution d'un script **post‑installation Debian 13** via une commande simple :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://gitea.maison43.duckdns.org/gilles/postinstall-debian/raw/branch/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Le script doit permettre :
|
||||||
|
|
||||||
|
- d'installer automatiquement des outils
|
||||||
|
- de configurer le système
|
||||||
|
- de proposer des menus interactifs
|
||||||
|
- d'être évolutif et modulaire
|
||||||
|
- d'intégrer facilement de nouveaux outils
|
||||||
|
- d'offrir une interface console claire et agréable
|
||||||
|
|
||||||
|
Le projet doit être pensé comme un **framework de post‑installation Debian 13**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Principes généraux
|
||||||
|
|
||||||
|
## Modularité
|
||||||
|
|
||||||
|
Chaque outil doit être installé via un **module indépendant**.
|
||||||
|
|
||||||
|
Un module correspond à :
|
||||||
|
|
||||||
|
- un script d'installation
|
||||||
|
- un script de configuration
|
||||||
|
- des métadonnées
|
||||||
|
- des tests éventuels
|
||||||
|
|
||||||
|
Chaque module doit pouvoir être :
|
||||||
|
|
||||||
|
- installé indépendamment
|
||||||
|
- intégré dans un menu
|
||||||
|
- utilisé dans un profil
|
||||||
|
- testé isolément
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Structure du dépôt
|
||||||
|
|
||||||
|
Structure recommandée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
postinstall-debian/
|
||||||
|
|
||||||
|
install.sh
|
||||||
|
README.md
|
||||||
|
CONSIGNE.md
|
||||||
|
tools.md
|
||||||
|
CHANGELOG.md
|
||||||
|
|
||||||
|
assets/
|
||||||
|
config/
|
||||||
|
core/
|
||||||
|
lib/
|
||||||
|
menus/
|
||||||
|
modules/
|
||||||
|
profiles/
|
||||||
|
hardware/
|
||||||
|
tests/
|
||||||
|
docs/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Organisation détaillée
|
||||||
|
|
||||||
|
## install.sh
|
||||||
|
|
||||||
|
Script principal.
|
||||||
|
|
||||||
|
Fonctions :
|
||||||
|
|
||||||
|
- vérification environnement
|
||||||
|
- vérification Debian
|
||||||
|
- gestion sudo/root
|
||||||
|
- chargement librairies
|
||||||
|
- chargement thème console
|
||||||
|
- affichage menu principal
|
||||||
|
|
||||||
|
Doit fonctionner via **curl | bash**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dossier core/
|
||||||
|
|
||||||
|
Scripts internes du framework.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
- bootstrap.sh
|
||||||
|
- runtime.sh
|
||||||
|
- registry.sh
|
||||||
|
- dispatcher.sh
|
||||||
|
|
||||||
|
Rôle :
|
||||||
|
|
||||||
|
- gestion des modules
|
||||||
|
- gestion de l'environnement
|
||||||
|
- découverte des outils
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dossier lib/
|
||||||
|
|
||||||
|
Fonctions réutilisables.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
ui.sh
|
||||||
|
log.sh
|
||||||
|
package.sh
|
||||||
|
system.sh
|
||||||
|
network.sh
|
||||||
|
prompts.sh
|
||||||
|
validation.sh
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dossier menus/
|
||||||
|
|
||||||
|
Gestion des menus interactifs.
|
||||||
|
|
||||||
|
Menus possibles :
|
||||||
|
|
||||||
|
Menu principal
|
||||||
|
Installation par catégorie
|
||||||
|
Installation par profil
|
||||||
|
Installation par matériel
|
||||||
|
Configuration système
|
||||||
|
Tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dossier modules/
|
||||||
|
|
||||||
|
Chaque outil possède un dossier dédié.
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
|
||||||
|
```
|
||||||
|
modules/dev/git/
|
||||||
|
|
||||||
|
module.sh
|
||||||
|
config.sh
|
||||||
|
metadata.conf
|
||||||
|
tests.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Fonctions attendues :
|
||||||
|
|
||||||
|
module_git_metadata
|
||||||
|
module_git_check
|
||||||
|
module_git_install
|
||||||
|
module_git_configure
|
||||||
|
module_git_test
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Catégories d'outils
|
||||||
|
|
||||||
|
Les outils doivent être classés.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
system
|
||||||
|
network
|
||||||
|
dev
|
||||||
|
gnome
|
||||||
|
desktop
|
||||||
|
multimedia
|
||||||
|
containers
|
||||||
|
virtualization
|
||||||
|
security
|
||||||
|
monitoring
|
||||||
|
backup
|
||||||
|
shell
|
||||||
|
productivity
|
||||||
|
communication
|
||||||
|
selfhosted
|
||||||
|
hardware
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Profils
|
||||||
|
|
||||||
|
Les profils installent plusieurs outils.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
Desktop minimal
|
||||||
|
Développeur
|
||||||
|
Homelab
|
||||||
|
Laptop
|
||||||
|
VM de test
|
||||||
|
|
||||||
|
Un profil contient une **liste de modules**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Installation par matériel
|
||||||
|
|
||||||
|
Possibilité d'installer un ensemble d'outils selon le matériel.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
Laptop ASUS
|
||||||
|
HP EliteDesk
|
||||||
|
VM Debian
|
||||||
|
Poste GNOME
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Interface utilisateur
|
||||||
|
|
||||||
|
Le script doit être user friendly.
|
||||||
|
|
||||||
|
Prévoir :
|
||||||
|
|
||||||
|
couleurs
|
||||||
|
messages clairs
|
||||||
|
étapes visibles
|
||||||
|
résumé final
|
||||||
|
|
||||||
|
Fonctions UI :
|
||||||
|
|
||||||
|
ui_header
|
||||||
|
ui_section
|
||||||
|
ui_info
|
||||||
|
ui_success
|
||||||
|
ui_warn
|
||||||
|
ui_error
|
||||||
|
ui_menu
|
||||||
|
ui_confirm
|
||||||
|
ui_pause
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Journalisation
|
||||||
|
|
||||||
|
Créer un système de logs.
|
||||||
|
|
||||||
|
Objectifs :
|
||||||
|
|
||||||
|
- log installation
|
||||||
|
- log erreurs
|
||||||
|
- log tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sécurité curl | bash
|
||||||
|
|
||||||
|
Le script doit :
|
||||||
|
|
||||||
|
- vérifier Debian
|
||||||
|
- vérifier réseau
|
||||||
|
- vérifier droits
|
||||||
|
|
||||||
|
Éviter :
|
||||||
|
|
||||||
|
- suppression brutale
|
||||||
|
- modification silencieuse fichiers critiques
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gestion des erreurs
|
||||||
|
|
||||||
|
Prévoir :
|
||||||
|
|
||||||
|
- arrêt propre
|
||||||
|
- messages clairs
|
||||||
|
- gestion codes retour
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Qualité Bash
|
||||||
|
|
||||||
|
Le code doit :
|
||||||
|
|
||||||
|
- être lisible
|
||||||
|
- être structuré
|
||||||
|
- utiliser des fonctions
|
||||||
|
|
||||||
|
Utiliser si possible :
|
||||||
|
|
||||||
|
shellcheck
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# tools.md
|
||||||
|
|
||||||
|
Ce fichier liste les outils demandés.
|
||||||
|
|
||||||
|
Pour chaque outil :
|
||||||
|
|
||||||
|
nom
|
||||||
|
description
|
||||||
|
catégorie
|
||||||
|
questions
|
||||||
|
méthode installation
|
||||||
|
tests
|
||||||
|
statut
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Brainstorming avant ajout d'un outil
|
||||||
|
|
||||||
|
Questions obligatoires :
|
||||||
|
|
||||||
|
Quel est l'outil
|
||||||
|
|
||||||
|
Quel usage
|
||||||
|
|
||||||
|
Installation via apt ?
|
||||||
|
|
||||||
|
Dépendances
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
|
||||||
|
Service systemd
|
||||||
|
|
||||||
|
Interface graphique
|
||||||
|
|
||||||
|
Compatibilité Debian 13
|
||||||
|
|
||||||
|
Tests possibles
|
||||||
|
|
||||||
|
Menu cible
|
||||||
|
|
||||||
|
Profil cible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
|
||||||
|
Types de tests possibles :
|
||||||
|
|
||||||
|
- présence binaire
|
||||||
|
- version
|
||||||
|
- service actif
|
||||||
|
- port ouvert
|
||||||
|
|
||||||
|
Tests VM Debian 13 recommandés.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Intégration d'un outil
|
||||||
|
|
||||||
|
Cycle :
|
||||||
|
|
||||||
|
1 Brainstorming
|
||||||
|
|
||||||
|
2 Décision architecture
|
||||||
|
|
||||||
|
3 Implémentation module
|
||||||
|
|
||||||
|
4 Intégration menu
|
||||||
|
|
||||||
|
5 Tests
|
||||||
|
|
||||||
|
6 Documentation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gestion des thèmes et ressources visuelles
|
||||||
|
|
||||||
|
Le projet doit permettre d'intégrer des **ressources graphiques et thèmes**.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
|
||||||
|
- thèmes GRUB
|
||||||
|
- thèmes GNOME
|
||||||
|
- thèmes GTK
|
||||||
|
- packs d'icônes
|
||||||
|
- curseurs
|
||||||
|
- wallpapers
|
||||||
|
- polices
|
||||||
|
- thèmes terminal
|
||||||
|
|
||||||
|
Ces ressources doivent être stockées dans **assets/**.
|
||||||
|
|
||||||
|
Structure possible :
|
||||||
|
|
||||||
|
```text
|
||||||
|
assets/
|
||||||
|
|
||||||
|
assets/grub/
|
||||||
|
assets/gnome/
|
||||||
|
assets/icons/
|
||||||
|
assets/cursors/
|
||||||
|
assets/fonts/
|
||||||
|
assets/wallpapers/
|
||||||
|
assets/terminal/
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque thème doit idéalement posséder :
|
||||||
|
|
||||||
|
metadata.conf
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
|
||||||
|
THEME_ID
|
||||||
|
THEME_NAME
|
||||||
|
THEME_TYPE
|
||||||
|
THEME_TARGET
|
||||||
|
THEME_DESCRIPTION
|
||||||
|
THEME_DEPENDENCIES
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Menus de personnalisation
|
||||||
|
|
||||||
|
Ajouter un menu :
|
||||||
|
|
||||||
|
Personnalisation
|
||||||
|
|
||||||
|
Sous menus :
|
||||||
|
|
||||||
|
Thèmes GRUB
|
||||||
|
Thèmes GNOME
|
||||||
|
Icônes
|
||||||
|
Curseurs
|
||||||
|
Wallpapers
|
||||||
|
Fonts
|
||||||
|
Terminal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bonnes pratiques pour GRUB
|
||||||
|
|
||||||
|
Toujours :
|
||||||
|
|
||||||
|
sauvegarder config
|
||||||
|
régénérer grub
|
||||||
|
avertir utilisateur
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# GNOME
|
||||||
|
|
||||||
|
Distinguer :
|
||||||
|
|
||||||
|
GTK
|
||||||
|
Shell
|
||||||
|
Icônes
|
||||||
|
Curseurs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Métadonnées modules
|
||||||
|
|
||||||
|
Chaque module peut définir :
|
||||||
|
|
||||||
|
TOOL_NAME
|
||||||
|
TOOL_ID
|
||||||
|
TOOL_CATEGORY
|
||||||
|
TOOL_DESCRIPTION
|
||||||
|
TOOL_DEPENDENCIES
|
||||||
|
TOOL_SUPPORTED_ON
|
||||||
|
TOOL_TEST_AVAILABLE
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
|
||||||
|
Créer documentation :
|
||||||
|
|
||||||
|
architecture.md
|
||||||
|
add_tool_workflow.md
|
||||||
|
menu_strategy.md
|
||||||
|
testing_strategy.md
|
||||||
|
security_notes.md
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# README
|
||||||
|
|
||||||
|
Le README doit contenir :
|
||||||
|
|
||||||
|
objectif
|
||||||
|
installation
|
||||||
|
structure dépôt
|
||||||
|
ajout outils
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Priorités du projet
|
||||||
|
|
||||||
|
1 Clarté
|
||||||
|
|
||||||
|
2 Stabilité
|
||||||
|
|
||||||
|
3 Modularité
|
||||||
|
|
||||||
|
4 Testabilité
|
||||||
|
|
||||||
|
5 Évolutivité
|
||||||
|
|
||||||
|
6 UX terminal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Conclusion
|
||||||
|
|
||||||
|
Ce dépôt doit devenir une **plateforme de post‑installation Debian 13 modulaire** permettant :
|
||||||
|
|
||||||
|
- installation d'outils
|
||||||
|
- configuration système
|
||||||
|
- personnalisation
|
||||||
|
- évolution continue
|
||||||
|
|
||||||
|
Le projet doit rester lisible, modulaire et maintenable sur le long terme.
|
||||||
|
|
||||||
98
core/bootstrap.sh
Normal file
98
core/bootstrap.sh
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BOOTSTRAP_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=lib/network.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/network.sh"
|
||||||
|
# shellcheck source=lib/prompts.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/prompts.sh"
|
||||||
|
# shellcheck source=lib/validation.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/lib/validation.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=core/registry.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/core/registry.sh"
|
||||||
|
# shellcheck source=core/dispatcher.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/core/dispatcher.sh"
|
||||||
|
# shellcheck source=menus/main.sh
|
||||||
|
source "$BOOTSTRAP_ROOT/menus/main.sh"
|
||||||
|
|
||||||
|
bootstrap_parse_args() {
|
||||||
|
BOOTSTRAP_MODE="menu"
|
||||||
|
BOOTSTRAP_MODULE_ID=""
|
||||||
|
BOOTSTRAP_TARGET_USER=""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--module)
|
||||||
|
BOOTSTRAP_MODE="module"
|
||||||
|
BOOTSTRAP_MODULE_ID="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--user)
|
||||||
|
BOOTSTRAP_TARGET_USER="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
BOOTSTRAP_MODE="help"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
ui_error "Argument non reconnu : $1"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$BOOTSTRAP_MODE" == "module" && -z "$BOOTSTRAP_MODULE_ID" ]]; then
|
||||||
|
ui_error "Option --module incomplete"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap_print_help() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
bash install.sh
|
||||||
|
bash install.sh --module <module-id> [--user <username>]
|
||||||
|
|
||||||
|
Exemples:
|
||||||
|
bash install.sh --module system/user-sudo
|
||||||
|
bash install.sh --module system/user-sudo --user gilles
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap_run() {
|
||||||
|
bootstrap_parse_args "$@" || exit 1
|
||||||
|
|
||||||
|
runtime_init "$BOOTSTRAP_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
ui_header "Postinstall Debian"
|
||||||
|
ui_info "Initialisation du framework"
|
||||||
|
|
||||||
|
system_require_bash
|
||||||
|
system_require_debian
|
||||||
|
system_require_root
|
||||||
|
network_warn_if_offline
|
||||||
|
|
||||||
|
registry_init
|
||||||
|
|
||||||
|
case "$BOOTSTRAP_MODE" in
|
||||||
|
help)
|
||||||
|
bootstrap_print_help
|
||||||
|
;;
|
||||||
|
module)
|
||||||
|
dispatcher_run_module "$BOOTSTRAP_MODULE_ID" "$BOOTSTRAP_TARGET_USER"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
menu_main
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
190
core/dispatcher.sh
Normal file
190
core/dispatcher.sh
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
dispatcher_prompt_and_run_module() {
|
||||||
|
local module_id="$1"
|
||||||
|
local target_user=""
|
||||||
|
local selected_groups=""
|
||||||
|
local ssh_port=""
|
||||||
|
local ssh_password_auth=""
|
||||||
|
local ssh_root_login=""
|
||||||
|
local avahi_enable=""
|
||||||
|
local avahi_publish_workstation=""
|
||||||
|
local host_name=""
|
||||||
|
local domain_name=""
|
||||||
|
local iface=""
|
||||||
|
local ip_mode=""
|
||||||
|
local ip_address=""
|
||||||
|
local ip_prefix=""
|
||||||
|
local ip_gateway=""
|
||||||
|
local ip_dns=""
|
||||||
|
local selected_nfs_shares=""
|
||||||
|
local share_name=""
|
||||||
|
local share_path=""
|
||||||
|
local share_user=""
|
||||||
|
local share_read_only=""
|
||||||
|
local share_public=""
|
||||||
|
local archive_name=""
|
||||||
|
local docker_data_dir=""
|
||||||
|
local default_nfs_ids=""
|
||||||
|
local nfs_entry=""
|
||||||
|
local nfs_item_id=""
|
||||||
|
local nfs_item_name=""
|
||||||
|
local nfs_mount_path=""
|
||||||
|
local nfs_access=""
|
||||||
|
local nfs_enabled=""
|
||||||
|
local nfs_item_labels=()
|
||||||
|
local nfs_item_ids=()
|
||||||
|
local nfs_labels_blob=""
|
||||||
|
local default_nfs_indices=""
|
||||||
|
local nfs_action=""
|
||||||
|
local nfs_mount_now=""
|
||||||
|
local nfs_server_mode=""
|
||||||
|
local samba_mode=""
|
||||||
|
|
||||||
|
case "$module_id" in
|
||||||
|
system/user-sudo)
|
||||||
|
target_user="$(prompt_read_default "Nom de l'utilisateur a configurer" "${POSTINSTALL_DEFAULT_USER:-gilles}")"
|
||||||
|
dispatcher_run_module "$module_id" "$target_user"
|
||||||
|
;;
|
||||||
|
system/user-groups)
|
||||||
|
target_user="$(prompt_read_default "Nom de l'utilisateur a configurer" "${POSTINSTALL_DEFAULT_USER:-gilles}")"
|
||||||
|
selected_groups="$(prompt_read_csv_default "Groupes a ajouter, separes par des virgules" "${POSTINSTALL_USER_GROUPS_DEFAULT_GROUPS:-audio,video,plugdev,dialout,netdev,lpadmin,scanner}")"
|
||||||
|
dispatcher_run_module "$module_id" "$target_user" "$selected_groups"
|
||||||
|
;;
|
||||||
|
network/ssh-server)
|
||||||
|
ssh_port="$(prompt_read_default "Port SSH" "${POSTINSTALL_SSH_PORT:-22}")"
|
||||||
|
ssh_password_auth="$(prompt_confirm_default "Autoriser l'authentification par mot de passe" "${POSTINSTALL_SSH_PASSWORD_AUTH:-yes}")"
|
||||||
|
ssh_root_login="$(prompt_confirm_default "Autoriser la connexion root SSH" "${POSTINSTALL_SSH_ROOT_LOGIN:-no}")"
|
||||||
|
dispatcher_run_module "$module_id" "$ssh_port" "$ssh_password_auth" "$ssh_root_login"
|
||||||
|
;;
|
||||||
|
network/mdns-avahi)
|
||||||
|
avahi_enable="$(prompt_confirm_default "Activer la publication mDNS de la machine" "${POSTINSTALL_MDNS_AVAHI_ENABLE:-yes}")"
|
||||||
|
avahi_publish_workstation="$(prompt_confirm_default "Publier la machine comme poste de travail" "${POSTINSTALL_MDNS_AVAHI_PUBLISH_WORKSTATION:-yes}")"
|
||||||
|
dispatcher_run_module "$module_id" "$avahi_enable" "$avahi_publish_workstation"
|
||||||
|
;;
|
||||||
|
network/identity)
|
||||||
|
host_name="$(prompt_read_default "Hostname" "${POSTINSTALL_NETWORK_IDENTITY_DEFAULT_HOSTNAME:-debian}")"
|
||||||
|
domain_name="$(prompt_read_default "Domaine local" "${POSTINSTALL_NETWORK_IDENTITY_DEFAULT_DOMAIN:-local}")"
|
||||||
|
dispatcher_run_module "$module_id" "$host_name" "$domain_name"
|
||||||
|
;;
|
||||||
|
network/ip-config)
|
||||||
|
iface="$(prompt_read_default "Interface reseau" "${POSTINSTALL_NETWORK_IP_DEFAULT_INTERFACE:-$(system_primary_interface)}")"
|
||||||
|
ip_mode="$(prompt_read_default "Mode reseau (dhcp ou static)" "${POSTINSTALL_NETWORK_IP_DEFAULT_MODE:-dhcp}")"
|
||||||
|
if [[ "$ip_mode" == "static" ]]; then
|
||||||
|
ip_address="$(prompt_read_default "Adresse IP" "${POSTINSTALL_NETWORK_IP_DEFAULT_ADDRESS:-10.0.0.10}")"
|
||||||
|
ip_prefix="$(prompt_read_default "Prefixe CIDR" "${POSTINSTALL_NETWORK_IP_DEFAULT_PREFIX:-22}")"
|
||||||
|
ip_gateway="$(prompt_read_default "Passerelle" "${POSTINSTALL_NETWORK_IP_DEFAULT_GATEWAY:-10.0.0.1}")"
|
||||||
|
ip_dns="$(prompt_read_default "DNS" "${POSTINSTALL_NETWORK_IP_DEFAULT_DNS:-10.0.0.1}")"
|
||||||
|
else
|
||||||
|
ip_address=""
|
||||||
|
ip_prefix=""
|
||||||
|
ip_gateway=""
|
||||||
|
ip_dns=""
|
||||||
|
fi
|
||||||
|
dispatcher_run_module "$module_id" "$iface" "$ip_mode" "$ip_address" "$ip_prefix" "$ip_gateway" "$ip_dns"
|
||||||
|
;;
|
||||||
|
network/nfs-client)
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$RUNTIME_PROJECT_ROOT/modules/network/nfs-client/module.sh"
|
||||||
|
nfs_action="$(prompt_select_from_list "Action NFS client" "activer des partages" "desactiver des partages")"
|
||||||
|
nfs_item_labels=()
|
||||||
|
nfs_item_ids=()
|
||||||
|
if [[ "$nfs_action" == "desactiver des partages" ]]; then
|
||||||
|
ui_section "Partages NFS actifs dans fstab"
|
||||||
|
while IFS= read -r nfs_entry; do
|
||||||
|
[[ -n "$nfs_entry" ]] || continue
|
||||||
|
IFS='|' read -r nfs_item_id nfs_item_name nfs_mount_path nfs_remote nfs_access <<< "$nfs_entry"
|
||||||
|
nfs_item_ids+=("$nfs_item_id")
|
||||||
|
nfs_item_labels+=("$nfs_item_id : $nfs_item_name -> $nfs_mount_path ($nfs_access)")
|
||||||
|
done < <(module_nfs_client_active_entries)
|
||||||
|
if [[ "${#nfs_item_ids[@]}" -eq 0 ]]; then
|
||||||
|
ui_info "Aucun partage NFS actif a desactiver"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
nfs_labels_blob="$(printf '%s\n' "${nfs_item_labels[@]}")"
|
||||||
|
selected_nfs_shares="$(prompt_select_multiple_from_list "Selectionner les partages a retirer de fstab, indexes separes par des virgules" "" "$nfs_labels_blob" "${nfs_item_ids[@]}")"
|
||||||
|
dispatcher_run_module "$module_id" "disable" "$selected_nfs_shares"
|
||||||
|
else
|
||||||
|
ui_section "Partages NFS client disponibles"
|
||||||
|
while IFS= read -r nfs_entry; do
|
||||||
|
[[ -n "$nfs_entry" ]] || continue
|
||||||
|
IFS='|' read -r nfs_item_id nfs_item_name _ _ _ nfs_mount_path nfs_access _ nfs_enabled <<< "$nfs_entry"
|
||||||
|
nfs_item_ids+=("$nfs_item_id")
|
||||||
|
nfs_item_labels+=("$nfs_item_id : $nfs_item_name -> $nfs_mount_path ($nfs_access)")
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
default_nfs_indices="$(module_nfs_client_default_indices)"
|
||||||
|
nfs_labels_blob="$(printf '%s\n' "${nfs_item_labels[@]}")"
|
||||||
|
selected_nfs_shares="$(prompt_select_multiple_from_list "Selectionner les partages a activer dans fstab, indexes separes par des virgules" "$default_nfs_indices" "$nfs_labels_blob" "${nfs_item_ids[@]}")"
|
||||||
|
nfs_mount_now="$(prompt_confirm_default "Monter immediatement les partages selectionnes" "yes")"
|
||||||
|
dispatcher_run_module "$module_id" "enable" "$selected_nfs_shares" "$nfs_mount_now"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
network/nfs-server)
|
||||||
|
nfs_server_mode="$(prompt_select_from_list "Mode de synchronisation NFS serveur" "add-only" "strict")"
|
||||||
|
ui_info "Synchronisation des exports NFS depuis le fichier YAML du repo"
|
||||||
|
dispatcher_run_module "$module_id" "$nfs_server_mode"
|
||||||
|
;;
|
||||||
|
network/samba-share)
|
||||||
|
samba_mode="$(prompt_select_from_list "Mode de synchronisation Samba" "add-only" "strict")"
|
||||||
|
ui_info "Synchronisation des partages Samba depuis le fichier YAML du repo"
|
||||||
|
dispatcher_run_module "$module_id" "$samba_mode"
|
||||||
|
;;
|
||||||
|
hardware/detect)
|
||||||
|
dispatcher_run_module "$module_id"
|
||||||
|
;;
|
||||||
|
boot/grub-theme)
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$RUNTIME_PROJECT_ROOT/modules/boot/grub-theme/module.sh"
|
||||||
|
mapfile -t grub_archives < <(module_grub_theme_list_archives)
|
||||||
|
if [[ "${#grub_archives[@]}" -eq 0 ]]; then
|
||||||
|
ui_warn "Aucune archive de theme GRUB disponible"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
archive_name="$(prompt_select_from_list "Selectionner une archive de theme" "${grub_archives[@]}")"
|
||||||
|
dispatcher_run_module "$module_id" "$archive_name"
|
||||||
|
;;
|
||||||
|
containers/docker-engine)
|
||||||
|
target_user="$(prompt_read_default "Utilisateur a ajouter au groupe docker" "${POSTINSTALL_DOCKER_TARGET_USER:-gilles}")"
|
||||||
|
docker_data_dir="$(prompt_read_default "Dossier Docker" "/home/${target_user}/docker")"
|
||||||
|
dispatcher_run_module "$module_id" "$target_user" "$docker_data_dir"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
dispatcher_run_module "$module_id"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatcher_run_module() {
|
||||||
|
local module_id="$1"
|
||||||
|
local module_path=""
|
||||||
|
local module_slug=""
|
||||||
|
local install_function=""
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
if ! registry_has_module "$module_id"; then
|
||||||
|
ui_error "Module introuvable : $module_id"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
module_path="$(registry_module_path "$module_id")"
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$module_path"
|
||||||
|
|
||||||
|
module_slug="${module_id##*/}"
|
||||||
|
module_slug="${module_slug//-/_}"
|
||||||
|
install_function="module_${module_slug}_install"
|
||||||
|
|
||||||
|
if ! declare -F "$install_function" >/dev/null 2>&1; then
|
||||||
|
ui_error "Fonction d'installation absente pour le module : $module_id"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_section "Execution du module $module_id"
|
||||||
|
"$install_function" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatcher_not_implemented() {
|
||||||
|
local feature="$1"
|
||||||
|
ui_warn "Fonction non implementee : $feature"
|
||||||
|
}
|
||||||
42
core/registry.sh
Normal file
42
core/registry.sh
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
REGISTRY_MODULE_COUNT=0
|
||||||
|
declare -a REGISTRY_MODULES=()
|
||||||
|
declare -A REGISTRY_MODULE_PATHS=()
|
||||||
|
|
||||||
|
registry_init() {
|
||||||
|
local module_file=""
|
||||||
|
local module_id=""
|
||||||
|
REGISTRY_MODULE_COUNT=0
|
||||||
|
REGISTRY_MODULES=()
|
||||||
|
REGISTRY_MODULE_PATHS=()
|
||||||
|
|
||||||
|
while IFS= read -r module_file; do
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$module_file"
|
||||||
|
module_id="${module_file#"$RUNTIME_PROJECT_ROOT/modules/"}"
|
||||||
|
module_id="${module_id%/module.sh}"
|
||||||
|
REGISTRY_MODULES+=("$module_id")
|
||||||
|
REGISTRY_MODULE_PATHS["$module_id"]="$module_file"
|
||||||
|
done < <(find "$RUNTIME_PROJECT_ROOT/modules" -mindepth 3 -maxdepth 3 -type f -name 'module.sh' | sort)
|
||||||
|
|
||||||
|
REGISTRY_MODULE_COUNT="${#REGISTRY_MODULES[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
registry_summary() {
|
||||||
|
printf '%s' "$REGISTRY_MODULE_COUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
registry_list() {
|
||||||
|
printf '%s\n' "${REGISTRY_MODULES[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
registry_has_module() {
|
||||||
|
local module_id="$1"
|
||||||
|
[[ -n "${REGISTRY_MODULE_PATHS[$module_id]:-}" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
registry_module_path() {
|
||||||
|
local module_id="$1"
|
||||||
|
printf '%s\n' "${REGISTRY_MODULE_PATHS[$module_id]:-}"
|
||||||
|
}
|
||||||
12
core/runtime.sh
Normal file
12
core/runtime.sh
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
RUNTIME_PROJECT_ROOT=""
|
||||||
|
RUNTIME_LOG_DIR=""
|
||||||
|
RUNTIME_LOG_FILE=""
|
||||||
|
|
||||||
|
runtime_init() {
|
||||||
|
RUNTIME_PROJECT_ROOT="$1"
|
||||||
|
RUNTIME_LOG_DIR="${TMPDIR:-/tmp}/postinstall-debian"
|
||||||
|
RUNTIME_LOG_FILE="$RUNTIME_LOG_DIR/install.log"
|
||||||
|
mkdir -p "$RUNTIME_LOG_DIR"
|
||||||
|
}
|
||||||
26
docs/architecture.md
Normal file
26
docs/architecture.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Architecture
|
||||||
|
|
||||||
|
## Vue d'ensemble
|
||||||
|
|
||||||
|
Le framework est organise en couches :
|
||||||
|
|
||||||
|
- `install.sh` demarre le bootstrap.
|
||||||
|
- `core/` orchestre l'execution.
|
||||||
|
- `lib/` expose les fonctions reutilisables.
|
||||||
|
- `menus/` porte l'interface interactive.
|
||||||
|
- `modules/` contient les outils installables.
|
||||||
|
|
||||||
|
## Flux de demarrage
|
||||||
|
|
||||||
|
1. `install.sh` charge `core/bootstrap.sh`.
|
||||||
|
2. `bootstrap_run` initialise le runtime et le log.
|
||||||
|
3. Les verifications systeme sont executees.
|
||||||
|
4. Le registre scanne les modules disponibles.
|
||||||
|
5. Le menu principal est affiche.
|
||||||
|
|
||||||
|
## Decisions initiales
|
||||||
|
|
||||||
|
- Bash est conserve comme socle unique.
|
||||||
|
- Les effets de bord systeme sont isoles dans `lib/`.
|
||||||
|
- Le registre decouvre les modules par arborescence.
|
||||||
|
- Les modules metier restent independants du framework.
|
||||||
117
docs/lan-validation.md
Normal file
117
docs/lan-validation.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Validation LAN
|
||||||
|
|
||||||
|
Ce document sert a verifier le comportement reel du poste Debian sur le reseau local apres application des modules reseau.
|
||||||
|
|
||||||
|
## Preparation
|
||||||
|
|
||||||
|
- appliquer les modules reseau utiles depuis `bash install.sh`
|
||||||
|
- verifier l'adresse IP finale de la machine
|
||||||
|
- verifier que le poste Windows 11 est sur le meme reseau local
|
||||||
|
|
||||||
|
## Verification Debian
|
||||||
|
|
||||||
|
### Identite reseau
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hostnamectl
|
||||||
|
cat /etc/hostname
|
||||||
|
getent hosts "$(hostname)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connectivite IP
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip addr
|
||||||
|
ip route
|
||||||
|
ping -c 3 10.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
### mDNS et Avahi
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status avahi-daemon
|
||||||
|
grep -E 'disable-publishing|publish-workstation' /etc/avahi/avahi-daemon.conf
|
||||||
|
avahi-browse -a
|
||||||
|
ping -c 3 "$(hostname)".local
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status ssh
|
||||||
|
ss -ltnp | grep ':22'
|
||||||
|
cat /etc/ssh/sshd_config.d/postinstall-debian.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Samba
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status smbd
|
||||||
|
testparm -s
|
||||||
|
cat /etc/samba/smb.conf.d/postinstall-home.conf
|
||||||
|
systemctl status wsdd2
|
||||||
|
```
|
||||||
|
|
||||||
|
### NFS client
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep nfs /etc/fstab
|
||||||
|
mount | grep nfs
|
||||||
|
```
|
||||||
|
|
||||||
|
### NFS serveur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /etc/exports.d/postinstall.exports
|
||||||
|
exportfs -v
|
||||||
|
systemctl status nfs-kernel-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification Windows 11
|
||||||
|
|
||||||
|
### Ping et resolution
|
||||||
|
|
||||||
|
Depuis PowerShell :
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
ping <ip_debian>
|
||||||
|
ping <hostname>.local
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSH
|
||||||
|
|
||||||
|
Si OpenSSH Client est present sur Windows :
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
ssh gilles@<ip_debian>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Samba
|
||||||
|
|
||||||
|
Dans l'explorateur Windows :
|
||||||
|
|
||||||
|
- tester `\\<ip_debian>\public`
|
||||||
|
- tester `\\<hostname>\public`
|
||||||
|
|
||||||
|
Dans les parametres reseau Windows :
|
||||||
|
|
||||||
|
- verifier que la decouverte reseau est activee
|
||||||
|
- verifier que le partage de fichiers SMB est autorise
|
||||||
|
|
||||||
|
### Visibilite reseau
|
||||||
|
|
||||||
|
Verifier si la machine Debian apparait dans :
|
||||||
|
|
||||||
|
- `Reseau`
|
||||||
|
- le workgroup `home`
|
||||||
|
|
||||||
|
Si le poste n'apparait pas mais que `\\ip\public` fonctionne, verifier `wsdd2` sur Debian.
|
||||||
|
|
||||||
|
## Resultat attendu
|
||||||
|
|
||||||
|
- le poste Debian repond au ping sur son IP
|
||||||
|
- le nom `.local` fonctionne
|
||||||
|
- SSH accepte les connexions selon la politique definie dans `config/ssh-server.yaml`
|
||||||
|
- le partage Samba `public` est accessible depuis Linux et Windows 11
|
||||||
|
- le poste apparait idealement dans l'explorateur reseau Windows via Samba et `wsdd2`
|
||||||
|
- les exports NFS et montages NFS sont conformes aux fichiers YAML du repo
|
||||||
3
hardware/README.md
Normal file
3
hardware/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Hardware
|
||||||
|
|
||||||
|
Ce dossier contiendra des selections de modules associees a un materiel ou a un type de machine.
|
||||||
14
install.sh
Executable file
14
install.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=core/bootstrap.sh
|
||||||
|
source "$PROJECT_ROOT/core/bootstrap.sh"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
bootstrap_run "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
19
lib/log.sh
Normal file
19
lib/log.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
log_init() {
|
||||||
|
: > "$RUNTIME_LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_write() {
|
||||||
|
local level="$1"
|
||||||
|
local message="$2"
|
||||||
|
printf '%s [%s] %s\n' "$(date '+%F %T')" "$level" "$message" >> "$RUNTIME_LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
log_write "INFO" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
log_write "ERROR" "$1"
|
||||||
|
}
|
||||||
9
lib/network.sh
Normal file
9
lib/network.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
network_warn_if_offline() {
|
||||||
|
if command -v ping >/dev/null 2>&1 && ping -c 1 -W 1 1.1.1.1 >/dev/null 2>&1; then
|
||||||
|
ui_success "Connectivite reseau disponible"
|
||||||
|
else
|
||||||
|
ui_warn "Reseau non verifie ou indisponible"
|
||||||
|
fi
|
||||||
|
}
|
||||||
17
lib/package.sh
Normal file
17
lib/package.sh
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
package_is_installed() {
|
||||||
|
dpkg -s "$1" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
package_refresh_indexes() {
|
||||||
|
apt-get update
|
||||||
|
}
|
||||||
|
|
||||||
|
package_install() {
|
||||||
|
apt-get install -y "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
package_remove() {
|
||||||
|
apt-get remove -y "$@"
|
||||||
|
}
|
||||||
125
lib/prompts.sh
Normal file
125
lib/prompts.sh
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
prompt_read_default() {
|
||||||
|
local label="$1"
|
||||||
|
local default_value="${2:-}"
|
||||||
|
local answer=""
|
||||||
|
|
||||||
|
if [[ -n "$default_value" ]]; then
|
||||||
|
read -r -p "$label [$default_value] : " answer
|
||||||
|
printf '%s\n' "${answer:-$default_value}"
|
||||||
|
else
|
||||||
|
read -r -p "$label : " answer
|
||||||
|
printf '%s\n' "$answer"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_select_number() {
|
||||||
|
local label="$1"
|
||||||
|
local min_value="$2"
|
||||||
|
local max_value="$3"
|
||||||
|
local answer=""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r -p "$label [$min_value-$max_value] : " answer
|
||||||
|
if [[ "$answer" =~ ^[0-9]+$ ]] && (( answer >= min_value && answer <= max_value )); then
|
||||||
|
printf '%s\n' "$answer"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
ui_warn "Choix invalide"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_read_csv_default() {
|
||||||
|
local label="$1"
|
||||||
|
local default_value="$2"
|
||||||
|
local answer=""
|
||||||
|
|
||||||
|
read -r -p "$label [$default_value] : " answer
|
||||||
|
printf '%s\n' "${answer:-$default_value}"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_confirm_default() {
|
||||||
|
local label="$1"
|
||||||
|
local default_answer="${2:-n}"
|
||||||
|
local answer=""
|
||||||
|
local prompt_suffix="[y/N]"
|
||||||
|
|
||||||
|
if [[ "$default_answer" =~ ^[Yy]$ ]]; then
|
||||||
|
prompt_suffix="[Y/n]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r -p "$label $prompt_suffix : " answer
|
||||||
|
answer="${answer:-$default_answer}"
|
||||||
|
|
||||||
|
case "$answer" in
|
||||||
|
y|Y|yes|YES)
|
||||||
|
printf 'yes\n'
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
n|N|no|NO)
|
||||||
|
printf 'no\n'
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ui_warn "Repondre par y ou n"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_select_from_list() {
|
||||||
|
local label="$1"
|
||||||
|
shift
|
||||||
|
local options=("$@")
|
||||||
|
local index=1
|
||||||
|
local selection=""
|
||||||
|
|
||||||
|
for selection in "${options[@]}"; do
|
||||||
|
printf ' %d. %s\n' "$index" "$selection"
|
||||||
|
index=$((index + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
selection="$(prompt_select_number "$label" 1 "${#options[@]}")"
|
||||||
|
printf '%s\n' "${options[$((selection - 1))]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_select_multiple_from_list() {
|
||||||
|
local label="$1"
|
||||||
|
local default_indices="${2:-}"
|
||||||
|
local labels_csv="$3"
|
||||||
|
shift 3
|
||||||
|
local values=("$@")
|
||||||
|
local labels=()
|
||||||
|
local answer=""
|
||||||
|
local raw_index=""
|
||||||
|
local selected_values=""
|
||||||
|
local index=1
|
||||||
|
|
||||||
|
IFS=$'\n' read -r -d '' -a labels < <(printf '%s\0' "$labels_csv")
|
||||||
|
|
||||||
|
for raw_index in "${labels[@]}"; do
|
||||||
|
printf ' %d. %s\n' "$index" "$raw_index"
|
||||||
|
index=$((index + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
read -r -p "$label [${default_indices:-aucun}] : " answer
|
||||||
|
answer="${answer:-$default_indices}"
|
||||||
|
|
||||||
|
if [[ -z "$answer" ]]; then
|
||||||
|
printf '\n'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r raw_index; do
|
||||||
|
[[ -n "$raw_index" ]] || continue
|
||||||
|
raw_index="$(printf '%s' "$raw_index" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||||
|
if [[ ! "$raw_index" =~ ^[0-9]+$ ]] || (( raw_index < 1 || raw_index > ${#values[@]} )); then
|
||||||
|
ui_warn "Index ignore : $raw_index"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
selected_values="${selected_values:+$selected_values,}${values[$((raw_index - 1))]}"
|
||||||
|
done < <(printf '%s\n' "$answer" | tr ',' '\n')
|
||||||
|
|
||||||
|
printf '%s\n' "$selected_values"
|
||||||
|
}
|
||||||
59
lib/system.sh
Normal file
59
lib/system.sh
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
system_require_bash() {
|
||||||
|
if [[ -z "${BASH_VERSION:-}" ]]; then
|
||||||
|
printf 'Bash est requis.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
system_require_debian() {
|
||||||
|
if [[ ! -r /etc/os-release ]]; then
|
||||||
|
ui_error "Impossible de detecter le systeme"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -Eq '^ID=debian$|^ID_LIKE=.*debian' /etc/os-release; then
|
||||||
|
ui_error "Ce script cible Debian"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_success "Systeme Debian detecte"
|
||||||
|
}
|
||||||
|
|
||||||
|
system_require_root() {
|
||||||
|
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||||
|
ui_error "Relancer ce script avec sudo ou en root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_success "Privileges root valides"
|
||||||
|
}
|
||||||
|
|
||||||
|
system_user_exists() {
|
||||||
|
local user_name="$1"
|
||||||
|
id "$user_name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
system_group_exists() {
|
||||||
|
local group_name="$1"
|
||||||
|
getent group "$group_name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
system_user_in_group() {
|
||||||
|
local user_name="$1"
|
||||||
|
local group_name="$2"
|
||||||
|
id -nG "$user_name" 2>/dev/null | tr ' ' '\n' | grep -Fx "$group_name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
system_primary_interface() {
|
||||||
|
ip route get 1.1.1.1 2>/dev/null | awk '
|
||||||
|
/dev/ {
|
||||||
|
for (i = 1; i <= NF; i++) {
|
||||||
|
if ($i == "dev") {
|
||||||
|
print $(i + 1)
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
}
|
||||||
61
lib/ui.sh
Normal file
61
lib/ui.sh
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
UI_RESET=$'\033[0m'
|
||||||
|
UI_BOLD=$'\033[1m'
|
||||||
|
UI_BLUE=$'\033[34m'
|
||||||
|
UI_GREEN=$'\033[32m'
|
||||||
|
UI_YELLOW=$'\033[33m'
|
||||||
|
UI_RED=$'\033[31m'
|
||||||
|
|
||||||
|
ui_header() {
|
||||||
|
local message="$1"
|
||||||
|
printf '\n%s%s== %s ==%s\n\n' "$UI_BOLD" "$UI_BLUE" "$message" "$UI_RESET"
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_section() {
|
||||||
|
local message="$1"
|
||||||
|
printf '%s[%s]%s\n' "$UI_BLUE" "$message" "$UI_RESET"
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_info() {
|
||||||
|
local message="$1"
|
||||||
|
printf '%s[INFO]%s %s\n' "$UI_BLUE" "$UI_RESET" "$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_success() {
|
||||||
|
local message="$1"
|
||||||
|
printf '%s[OK]%s %s\n' "$UI_GREEN" "$UI_RESET" "$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_warn() {
|
||||||
|
local message="$1"
|
||||||
|
printf '%s[WARN]%s %s\n' "$UI_YELLOW" "$UI_RESET" "$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_error() {
|
||||||
|
local message="$1"
|
||||||
|
printf '%s[ERR]%s %s\n' "$UI_RED" "$UI_RESET" "$message" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_menu() {
|
||||||
|
local title="$1"
|
||||||
|
shift
|
||||||
|
local option
|
||||||
|
|
||||||
|
ui_section "$title"
|
||||||
|
for option in "$@"; do
|
||||||
|
printf ' - %s\n' "$option"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_confirm() {
|
||||||
|
local prompt="$1"
|
||||||
|
local answer=""
|
||||||
|
|
||||||
|
read -r -p "$prompt [y/N] " answer
|
||||||
|
[[ "$answer" =~ ^[Yy]$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_pause() {
|
||||||
|
read -r -p "Appuyer sur Entree pour continuer... " _
|
||||||
|
}
|
||||||
10
lib/validation.sh
Normal file
10
lib/validation.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
validation_require_file() {
|
||||||
|
local file_path="$1"
|
||||||
|
|
||||||
|
if [[ ! -f "$file_path" ]]; then
|
||||||
|
ui_error "Fichier requis manquant : $file_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
101
menus/main.sh
Normal file
101
menus/main.sh
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
menu_modules_by_prefix() {
|
||||||
|
local prefix="$1"
|
||||||
|
local title="$2"
|
||||||
|
local matching_modules=()
|
||||||
|
local module_id=""
|
||||||
|
local selection=""
|
||||||
|
local index=1
|
||||||
|
|
||||||
|
while IFS= read -r module_id; do
|
||||||
|
[[ "$module_id" == "$prefix"/* ]] || continue
|
||||||
|
matching_modules+=("$module_id")
|
||||||
|
done < <(registry_list)
|
||||||
|
|
||||||
|
if [[ "${#matching_modules[@]}" -eq 0 ]]; then
|
||||||
|
ui_warn "Aucun module disponible pour $title"
|
||||||
|
ui_pause
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_section "$title"
|
||||||
|
for module_id in "${matching_modules[@]}"; do
|
||||||
|
printf ' %d. %s\n' "$index" "$module_id"
|
||||||
|
index=$((index + 1))
|
||||||
|
done
|
||||||
|
printf ' 0. Retour\n'
|
||||||
|
|
||||||
|
selection="$(prompt_select_number "Selectionner un module" 0 "${#matching_modules[@]}")"
|
||||||
|
if [[ "$selection" == "0" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
dispatcher_prompt_and_run_module "${matching_modules[$((selection - 1))]}"
|
||||||
|
ui_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_category_selection() {
|
||||||
|
local categories=("network" "containers" "boot" "hardware")
|
||||||
|
local selection=""
|
||||||
|
|
||||||
|
ui_section "Installation par categorie"
|
||||||
|
printf ' 1. network\n'
|
||||||
|
printf ' 2. containers\n'
|
||||||
|
printf ' 3. boot\n'
|
||||||
|
printf ' 4. hardware\n'
|
||||||
|
printf ' 0. Retour\n'
|
||||||
|
|
||||||
|
selection="$(prompt_select_number "Selectionner une categorie" 0 4)"
|
||||||
|
case "$selection" in
|
||||||
|
0) return 0 ;;
|
||||||
|
1) menu_modules_by_prefix "network" "Configuration reseau" ;;
|
||||||
|
2) menu_modules_by_prefix "containers" "Conteneurs" ;;
|
||||||
|
3) menu_modules_by_prefix "boot" "Configuration du boot" ;;
|
||||||
|
4) menu_modules_by_prefix "hardware" "Materiel" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_system_configuration() {
|
||||||
|
menu_modules_by_prefix "system" "Configuration systeme"
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_main() {
|
||||||
|
local selection=""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
ui_menu \
|
||||||
|
"Menu principal" \
|
||||||
|
"1. Installation par categorie" \
|
||||||
|
"2. Installation par profil" \
|
||||||
|
"3. Installation par materiel" \
|
||||||
|
"4. Configuration systeme" \
|
||||||
|
"5. Tests" \
|
||||||
|
"0. Quitter"
|
||||||
|
|
||||||
|
ui_info "Modules detectes : $(registry_summary)"
|
||||||
|
ui_info "Log : $RUNTIME_LOG_FILE"
|
||||||
|
|
||||||
|
selection="$(prompt_select_number "Choisir une action" 0 5)"
|
||||||
|
|
||||||
|
case "$selection" in
|
||||||
|
0)
|
||||||
|
ui_info "Sortie du programme"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
menu_category_selection
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
menu_modules_by_prefix "hardware" "Materiel"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
menu_system_configuration
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
dispatcher_not_implemented "menu $selection"
|
||||||
|
ui_pause
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
4
modules/boot/grub-theme/config.sh
Normal file
4
modules/boot/grub-theme/config.sh
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
POSTINSTALL_GRUB_THEME_ARCHIVE_DIR_PRIMARY="assets/grub"
|
||||||
|
POSTINSTALL_GRUB_THEME_ARCHIVE_DIR_FALLBACK="themes/grub"
|
||||||
|
POSTINSTALL_GRUB_THEME_INSTALL_DIR="/boot/grub/themes/postinstall-debian"
|
||||||
|
POSTINSTALL_GRUB_THEME_CONFIG_FILE="/etc/default/grub.d/postinstall-debian.cfg"
|
||||||
4
modules/boot/grub-theme/metadata.conf
Normal file
4
modules/boot/grub-theme/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="boot/grub-theme"
|
||||||
|
MODULE_NAME="Theme GRUB"
|
||||||
|
MODULE_CATEGORY="boot"
|
||||||
|
MODULE_DESCRIPTION="Installe un theme GRUB depuis les archives locales du depot"
|
||||||
85
modules/boot/grub-theme/module.sh
Normal file
85
modules/boot/grub-theme/module.sh
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_GRUB_THEME_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_GRUB_THEME_PROJECT_ROOT="$(cd "$MODULE_GRUB_THEME_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_GRUB_THEME_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/boot/grub-theme/config.sh
|
||||||
|
source "$MODULE_GRUB_THEME_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/boot/grub-theme/metadata.conf
|
||||||
|
source "$MODULE_GRUB_THEME_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_grub_theme_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_grub_theme_archive_dir() {
|
||||||
|
if [[ -d "$MODULE_GRUB_THEME_PROJECT_ROOT/$POSTINSTALL_GRUB_THEME_ARCHIVE_DIR_PRIMARY" ]]; then
|
||||||
|
printf '%s\n' "$MODULE_GRUB_THEME_PROJECT_ROOT/$POSTINSTALL_GRUB_THEME_ARCHIVE_DIR_PRIMARY"
|
||||||
|
else
|
||||||
|
printf '%s\n' "$MODULE_GRUB_THEME_PROJECT_ROOT/$POSTINSTALL_GRUB_THEME_ARCHIVE_DIR_FALLBACK"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_grub_theme_list_archives() {
|
||||||
|
local archive_dir=""
|
||||||
|
archive_dir="$(module_grub_theme_archive_dir)"
|
||||||
|
find "$archive_dir" -maxdepth 1 -type f \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) -printf '%f\n' | sort
|
||||||
|
}
|
||||||
|
|
||||||
|
module_grub_theme_extract() {
|
||||||
|
local archive_name="$1"
|
||||||
|
local archive_dir=""
|
||||||
|
local archive_path=""
|
||||||
|
local target_dir=""
|
||||||
|
|
||||||
|
archive_dir="$(module_grub_theme_archive_dir)"
|
||||||
|
archive_path="$archive_dir/$archive_name"
|
||||||
|
target_dir="$POSTINSTALL_GRUB_THEME_INSTALL_DIR/${archive_name%.*}"
|
||||||
|
|
||||||
|
mkdir -p "$target_dir"
|
||||||
|
|
||||||
|
case "$archive_name" in
|
||||||
|
*.zip)
|
||||||
|
if ! package_is_installed unzip; then
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install unzip
|
||||||
|
fi
|
||||||
|
unzip -o "$archive_path" -d "$target_dir" >/dev/null
|
||||||
|
;;
|
||||||
|
*.tar.gz|*.tgz)
|
||||||
|
tar -xzf "$archive_path" -C "$target_dir"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
ui_error "Archive de theme non supportee : $archive_name"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
find "$target_dir" -type f -name 'theme.txt' | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module_grub_theme_install() {
|
||||||
|
local archive_name="$1"
|
||||||
|
local theme_path=""
|
||||||
|
|
||||||
|
if [[ -z "$archive_name" ]]; then
|
||||||
|
ui_error "Aucune archive de theme specifiee"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /etc/default/grub.d
|
||||||
|
theme_path="$(module_grub_theme_extract "$archive_name")" || return 1
|
||||||
|
|
||||||
|
printf 'GRUB_THEME="%s"\n' "$theme_path" > "$POSTINSTALL_GRUB_THEME_CONFIG_FILE"
|
||||||
|
update-grub
|
||||||
|
|
||||||
|
log_info "Theme GRUB configure : $archive_name"
|
||||||
|
ui_success "Theme GRUB configure : $archive_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_grub_theme_test() {
|
||||||
|
test -f "$POSTINSTALL_GRUB_THEME_CONFIG_FILE" || return 1
|
||||||
|
grep -q '^GRUB_THEME=' "$POSTINSTALL_GRUB_THEME_CONFIG_FILE" || return 1
|
||||||
|
}
|
||||||
28
modules/boot/grub-theme/tests.sh
Normal file
28
modules/boot/grub-theme/tests.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_GRUB_THEME_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_GRUB_THEME_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/boot/grub-theme/module.sh
|
||||||
|
source "$MODULE_GRUB_THEME_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! test -f /etc/default/grub.d/postinstall-debian.cfg; then
|
||||||
|
printf 'grub-theme test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_grub_theme_test; then
|
||||||
|
printf 'grub-theme test OK\n'
|
||||||
|
else
|
||||||
|
printf 'grub-theme test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
5
modules/containers/docker-engine/config.sh
Normal file
5
modules/containers/docker-engine/config.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
POSTINSTALL_DOCKER_TARGET_USER="${POSTINSTALL_DEFAULT_USER:-gilles}"
|
||||||
|
POSTINSTALL_DOCKER_DATA_DIR="/home/${POSTINSTALL_DEFAULT_USER:-gilles}/docker"
|
||||||
|
POSTINSTALL_DOCKER_KEYRING_DIR="/etc/apt/keyrings"
|
||||||
|
POSTINSTALL_DOCKER_KEYRING_FILE="/etc/apt/keyrings/docker.asc"
|
||||||
|
POSTINSTALL_DOCKER_SOURCES_FILE="/etc/apt/sources.list.d/docker.list"
|
||||||
4
modules/containers/docker-engine/metadata.conf
Normal file
4
modules/containers/docker-engine/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="containers/docker-engine"
|
||||||
|
MODULE_NAME="Installation de Docker Engine"
|
||||||
|
MODULE_CATEGORY="containers"
|
||||||
|
MODULE_DESCRIPTION="Installe Docker Engine via le depot officiel Docker pour Debian"
|
||||||
74
modules/containers/docker-engine/module.sh
Normal file
74
modules/containers/docker-engine/module.sh
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_DOCKER_ENGINE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_DOCKER_ENGINE_PROJECT_ROOT="$(cd "$MODULE_DOCKER_ENGINE_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_DOCKER_ENGINE_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$MODULE_DOCKER_ENGINE_PROJECT_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=modules/containers/docker-engine/config.sh
|
||||||
|
source "$MODULE_DOCKER_ENGINE_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/containers/docker-engine/metadata.conf
|
||||||
|
source "$MODULE_DOCKER_ENGINE_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_docker_engine_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_docker_engine_remove_conflicts() {
|
||||||
|
local packages=(docker.io docker-doc docker-compose podman-docker containerd runc)
|
||||||
|
local pkg=""
|
||||||
|
|
||||||
|
for pkg in "${packages[@]}"; do
|
||||||
|
if package_is_installed "$pkg"; then
|
||||||
|
package_remove "$pkg"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
module_docker_engine_install() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_DOCKER_TARGET_USER}"
|
||||||
|
local data_dir="${2:-/home/$target_user/docker}"
|
||||||
|
local version_codename=""
|
||||||
|
local arch=""
|
||||||
|
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install ca-certificates curl
|
||||||
|
install -m 0755 -d "$POSTINSTALL_DOCKER_KEYRING_DIR"
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg -o "$POSTINSTALL_DOCKER_KEYRING_FILE"
|
||||||
|
chmod a+r "$POSTINSTALL_DOCKER_KEYRING_FILE"
|
||||||
|
|
||||||
|
version_codename="$(. /etc/os-release && printf '%s' "$VERSION_CODENAME")"
|
||||||
|
arch="$(dpkg --print-architecture)"
|
||||||
|
printf 'deb [arch=%s signed-by=%s] https://download.docker.com/linux/debian %s stable\n' "$arch" "$POSTINSTALL_DOCKER_KEYRING_FILE" "$version_codename" > "$POSTINSTALL_DOCKER_SOURCES_FILE"
|
||||||
|
|
||||||
|
module_docker_engine_remove_conflicts
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
|
||||||
|
if ! system_group_exists docker; then
|
||||||
|
groupadd docker
|
||||||
|
fi
|
||||||
|
|
||||||
|
if system_user_exists "$target_user" && ! system_user_in_group "$target_user" docker; then
|
||||||
|
usermod -aG docker "$target_user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$data_dir"
|
||||||
|
if system_user_exists "$target_user"; then
|
||||||
|
chown "$target_user:$target_user" "$data_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl enable --now docker
|
||||||
|
systemctl restart docker
|
||||||
|
|
||||||
|
log_info "Docker Engine installe pour $target_user"
|
||||||
|
ui_success "Docker Engine installe"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_docker_engine_test() {
|
||||||
|
command -v docker >/dev/null 2>&1 || return 1
|
||||||
|
docker --version >/dev/null 2>&1 || return 1
|
||||||
|
docker compose version >/dev/null 2>&1 || return 1
|
||||||
|
}
|
||||||
28
modules/containers/docker-engine/tests.sh
Normal file
28
modules/containers/docker-engine/tests.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_DOCKER_ENGINE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_DOCKER_ENGINE_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/containers/docker-engine/module.sh
|
||||||
|
source "$MODULE_DOCKER_ENGINE_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
printf 'docker-engine test SKIPPED: docker not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_docker_engine_test; then
|
||||||
|
printf 'docker-engine test OK\n'
|
||||||
|
else
|
||||||
|
printf 'docker-engine test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
1
modules/hardware/detect/config.sh
Normal file
1
modules/hardware/detect/config.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
POSTINSTALL_HARDWARE_DETECT_REPORT_FILE="/var/log/postinstall-debian/hardware-report.txt"
|
||||||
4
modules/hardware/detect/metadata.conf
Normal file
4
modules/hardware/detect/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="hardware/detect"
|
||||||
|
MODULE_NAME="Detection hardware"
|
||||||
|
MODULE_CATEGORY="hardware"
|
||||||
|
MODULE_DESCRIPTION="Installe les outils de detection et genere un rapport materiel"
|
||||||
43
modules/hardware/detect/module.sh
Normal file
43
modules/hardware/detect/module.sh
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_HARDWARE_DETECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_HARDWARE_DETECT_PROJECT_ROOT="$(cd "$MODULE_HARDWARE_DETECT_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_HARDWARE_DETECT_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/hardware/detect/config.sh
|
||||||
|
source "$MODULE_HARDWARE_DETECT_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/hardware/detect/metadata.conf
|
||||||
|
source "$MODULE_HARDWARE_DETECT_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_detect_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_detect_install() {
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install lshw pciutils usbutils dmidecode
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$POSTINSTALL_HARDWARE_DETECT_REPORT_FILE")"
|
||||||
|
{
|
||||||
|
printf '== lshw -short ==\n'
|
||||||
|
lshw -short 2>/dev/null || true
|
||||||
|
printf '\n== lspci ==\n'
|
||||||
|
lspci 2>/dev/null || true
|
||||||
|
printf '\n== lsusb ==\n'
|
||||||
|
lsusb 2>/dev/null || true
|
||||||
|
printf '\n== dmidecode -t system ==\n'
|
||||||
|
dmidecode -t system 2>/dev/null || true
|
||||||
|
} > "$POSTINSTALL_HARDWARE_DETECT_REPORT_FILE"
|
||||||
|
|
||||||
|
log_info "Rapport hardware genere : $POSTINSTALL_HARDWARE_DETECT_REPORT_FILE"
|
||||||
|
ui_success "Rapport hardware genere"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_detect_test() {
|
||||||
|
package_is_installed lshw || return 1
|
||||||
|
package_is_installed pciutils || return 1
|
||||||
|
package_is_installed usbutils || return 1
|
||||||
|
package_is_installed dmidecode || return 1
|
||||||
|
test -s "$POSTINSTALL_HARDWARE_DETECT_REPORT_FILE"
|
||||||
|
}
|
||||||
35
modules/hardware/detect/tests.sh
Normal file
35
modules/hardware/detect/tests.sh
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_HARDWARE_DETECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_HARDWARE_DETECT_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/hardware/detect/module.sh
|
||||||
|
source "$MODULE_HARDWARE_DETECT_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed lshw; then
|
||||||
|
printf 'hardware-detect test SKIPPED: lshw not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f /var/log/postinstall-debian/hardware-report.txt; then
|
||||||
|
printf 'hardware-detect test SKIPPED: report not generated\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_detect_test; then
|
||||||
|
printf 'hardware-detect test OK\n'
|
||||||
|
else
|
||||||
|
printf 'hardware-detect test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
3
modules/network/identity/config.sh
Normal file
3
modules/network/identity/config.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
POSTINSTALL_NETWORK_IDENTITY_DEFAULT_HOSTNAME="${HOSTNAME:-debian}"
|
||||||
|
POSTINSTALL_NETWORK_IDENTITY_DEFAULT_DOMAIN="local"
|
||||||
|
POSTINSTALL_NETWORK_IDENTITY_STATE_FILE="/etc/postinstall-debian/network-identity.conf"
|
||||||
4
modules/network/identity/metadata.conf
Normal file
4
modules/network/identity/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/identity"
|
||||||
|
MODULE_NAME="Identite reseau"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Configure le hostname et l'identite locale de la machine"
|
||||||
68
modules/network/identity/module.sh
Normal file
68
modules/network/identity/module.sh
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NETWORK_IDENTITY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_NETWORK_IDENTITY_PROJECT_ROOT="$(cd "$MODULE_NETWORK_IDENTITY_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=modules/network/identity/config.sh
|
||||||
|
source "$MODULE_NETWORK_IDENTITY_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/identity/metadata.conf
|
||||||
|
source "$MODULE_NETWORK_IDENTITY_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_identity_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_identity_validate_hostname() {
|
||||||
|
local host_name="$1"
|
||||||
|
[[ "$host_name" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
module_identity_update_hosts() {
|
||||||
|
local host_name="$1"
|
||||||
|
local domain_name="${2:-}"
|
||||||
|
local fqdn="$host_name"
|
||||||
|
local temp_file=""
|
||||||
|
|
||||||
|
if [[ -n "$domain_name" ]]; then
|
||||||
|
fqdn="$host_name.$domain_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
temp_file="$(mktemp)"
|
||||||
|
awk '!/^127\.0\.1\.1[[:space:]]/' /etc/hosts > "$temp_file"
|
||||||
|
printf '127.0.1.1 %s %s\n' "$fqdn" "$host_name" >> "$temp_file"
|
||||||
|
cat "$temp_file" > /etc/hosts
|
||||||
|
rm -f "$temp_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_identity_install() {
|
||||||
|
local host_name="${1:-$POSTINSTALL_NETWORK_IDENTITY_DEFAULT_HOSTNAME}"
|
||||||
|
local domain_name="${2:-$POSTINSTALL_NETWORK_IDENTITY_DEFAULT_DOMAIN}"
|
||||||
|
|
||||||
|
if ! module_identity_validate_hostname "$host_name"; then
|
||||||
|
ui_error "Hostname invalide : $host_name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v hostnamectl >/dev/null 2>&1; then
|
||||||
|
hostnamectl set-hostname "$host_name"
|
||||||
|
else
|
||||||
|
hostname "$host_name"
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$host_name" > /etc/hostname
|
||||||
|
module_identity_update_hosts "$host_name" "$domain_name"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$POSTINSTALL_NETWORK_IDENTITY_STATE_FILE")"
|
||||||
|
{
|
||||||
|
printf 'HOSTNAME=%s\n' "$host_name"
|
||||||
|
printf 'DOMAIN=%s\n' "$domain_name"
|
||||||
|
} > "$POSTINSTALL_NETWORK_IDENTITY_STATE_FILE"
|
||||||
|
|
||||||
|
log_info "Hostname configure : $host_name"
|
||||||
|
ui_success "Hostname configure : $host_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_identity_test() {
|
||||||
|
test -f "$POSTINSTALL_NETWORK_IDENTITY_STATE_FILE" || return 1
|
||||||
|
test -s /etc/hostname || return 1
|
||||||
|
hostnamectl >/dev/null 2>&1 || return 1
|
||||||
|
}
|
||||||
28
modules/network/identity/tests.sh
Normal file
28
modules/network/identity/tests.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NETWORK_IDENTITY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_NETWORK_IDENTITY_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/identity/module.sh
|
||||||
|
source "$MODULE_NETWORK_IDENTITY_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! test -f /etc/postinstall-debian/network-identity.conf; then
|
||||||
|
printf 'network-identity test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_identity_test; then
|
||||||
|
printf 'network-identity test OK\n'
|
||||||
|
else
|
||||||
|
printf 'network-identity test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
7
modules/network/ip-config/config.sh
Normal file
7
modules/network/ip-config/config.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_INTERFACE=""
|
||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_MODE="dhcp"
|
||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_ADDRESS="10.0.0.10"
|
||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_PREFIX="22"
|
||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_GATEWAY="10.0.0.1"
|
||||||
|
POSTINSTALL_NETWORK_IP_DEFAULT_DNS="10.0.0.1"
|
||||||
|
POSTINSTALL_NETWORK_IP_STATE_FILE="/etc/postinstall-debian/network-ip-config.conf"
|
||||||
4
modules/network/ip-config/metadata.conf
Normal file
4
modules/network/ip-config/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/ip-config"
|
||||||
|
MODULE_NAME="Configuration IP initiale"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Configure une interface reseau en DHCP ou en IP statique"
|
||||||
157
modules/network/ip-config/module.sh
Normal file
157
modules/network/ip-config/module.sh
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NETWORK_IP_CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_NETWORK_IP_CONFIG_PROJECT_ROOT="$(cd "$MODULE_NETWORK_IP_CONFIG_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$MODULE_NETWORK_IP_CONFIG_PROJECT_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=modules/network/ip-config/config.sh
|
||||||
|
source "$MODULE_NETWORK_IP_CONFIG_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/ip-config/metadata.conf
|
||||||
|
source "$MODULE_NETWORK_IP_CONFIG_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_ip_config_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_detect_backend() {
|
||||||
|
if command -v nmcli >/dev/null 2>&1 && systemctl is-active --quiet NetworkManager; then
|
||||||
|
printf 'networkmanager\n'
|
||||||
|
elif [[ -d /etc/systemd/network ]]; then
|
||||||
|
printf 'networkd\n'
|
||||||
|
else
|
||||||
|
printf 'ifupdown\n'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_validate_mode() {
|
||||||
|
[[ "$1" == "dhcp" || "$1" == "static" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_nmcli_connection_for_device() {
|
||||||
|
local iface="$1"
|
||||||
|
nmcli -t -f NAME,DEVICE connection show | awk -F: -v iface="$iface" '$2 == iface { print $1; exit }'
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_write_networkd() {
|
||||||
|
local iface="$1"
|
||||||
|
local mode="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local dns="$6"
|
||||||
|
local file_path="/etc/systemd/network/10-postinstall-${iface}.network"
|
||||||
|
|
||||||
|
mkdir -p /etc/systemd/network
|
||||||
|
{
|
||||||
|
printf '[Match]\nName=%s\n\n' "$iface"
|
||||||
|
printf '[Network]\n'
|
||||||
|
if [[ "$mode" == "dhcp" ]]; then
|
||||||
|
printf 'DHCP=yes\n'
|
||||||
|
else
|
||||||
|
printf 'Address=%s/%s\n' "$address" "$prefix"
|
||||||
|
printf 'Gateway=%s\n' "$gateway"
|
||||||
|
printf 'DNS=%s\n' "$dns"
|
||||||
|
fi
|
||||||
|
} > "$file_path"
|
||||||
|
|
||||||
|
if systemctl is-active --quiet systemd-networkd; then
|
||||||
|
systemctl restart systemd-networkd
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_write_ifupdown() {
|
||||||
|
local iface="$1"
|
||||||
|
local mode="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local dns="$6"
|
||||||
|
local netmask="255.255.252.0"
|
||||||
|
local file_path="/etc/network/interfaces.d/postinstall-${iface}"
|
||||||
|
|
||||||
|
mkdir -p /etc/network/interfaces.d
|
||||||
|
{
|
||||||
|
printf 'auto %s\n' "$iface"
|
||||||
|
if [[ "$mode" == "dhcp" ]]; then
|
||||||
|
printf 'iface %s inet dhcp\n' "$iface"
|
||||||
|
else
|
||||||
|
printf 'iface %s inet static\n' "$iface"
|
||||||
|
printf ' address %s/%s\n' "$address" "$prefix"
|
||||||
|
printf ' gateway %s\n' "$gateway"
|
||||||
|
printf ' dns-nameservers %s\n' "$dns"
|
||||||
|
printf ' netmask %s\n' "$netmask"
|
||||||
|
fi
|
||||||
|
} > "$file_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_write_networkmanager() {
|
||||||
|
local iface="$1"
|
||||||
|
local mode="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local dns="$6"
|
||||||
|
local connection_name=""
|
||||||
|
|
||||||
|
connection_name="$(module_ip_config_nmcli_connection_for_device "$iface")"
|
||||||
|
if [[ -z "$connection_name" ]]; then
|
||||||
|
connection_name="postinstall-${iface}"
|
||||||
|
nmcli connection add type ethernet ifname "$iface" con-name "$connection_name" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$mode" == "dhcp" ]]; then
|
||||||
|
nmcli connection modify "$connection_name" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""
|
||||||
|
else
|
||||||
|
nmcli connection modify "$connection_name" ipv4.method manual ipv4.addresses "$address/$prefix" ipv4.gateway "$gateway" ipv4.dns "$dns"
|
||||||
|
fi
|
||||||
|
nmcli connection up "$connection_name" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_install() {
|
||||||
|
local iface="${1:-$POSTINSTALL_NETWORK_IP_DEFAULT_INTERFACE}"
|
||||||
|
local mode="${2:-$POSTINSTALL_NETWORK_IP_DEFAULT_MODE}"
|
||||||
|
local address="${3:-$POSTINSTALL_NETWORK_IP_DEFAULT_ADDRESS}"
|
||||||
|
local prefix="${4:-$POSTINSTALL_NETWORK_IP_DEFAULT_PREFIX}"
|
||||||
|
local gateway="${5:-$POSTINSTALL_NETWORK_IP_DEFAULT_GATEWAY}"
|
||||||
|
local dns="${6:-$POSTINSTALL_NETWORK_IP_DEFAULT_DNS}"
|
||||||
|
local backend=""
|
||||||
|
|
||||||
|
iface="${iface:-$(system_primary_interface)}"
|
||||||
|
|
||||||
|
if [[ -z "$iface" ]]; then
|
||||||
|
ui_error "Impossible de detecter l'interface reseau"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! module_ip_config_validate_mode "$mode"; then
|
||||||
|
ui_error "Mode reseau invalide : $mode"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
backend="$(module_ip_config_detect_backend)"
|
||||||
|
case "$backend" in
|
||||||
|
networkmanager) module_ip_config_write_networkmanager "$iface" "$mode" "$address" "$prefix" "$gateway" "$dns" ;;
|
||||||
|
networkd) module_ip_config_write_networkd "$iface" "$mode" "$address" "$prefix" "$gateway" "$dns" ;;
|
||||||
|
*) module_ip_config_write_ifupdown "$iface" "$mode" "$address" "$prefix" "$gateway" "$dns" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$POSTINSTALL_NETWORK_IP_STATE_FILE")"
|
||||||
|
{
|
||||||
|
printf 'INTERFACE=%s\n' "$iface"
|
||||||
|
printf 'MODE=%s\n' "$mode"
|
||||||
|
printf 'BACKEND=%s\n' "$backend"
|
||||||
|
printf 'ADDRESS=%s\n' "$address"
|
||||||
|
printf 'PREFIX=%s\n' "$prefix"
|
||||||
|
printf 'GATEWAY=%s\n' "$gateway"
|
||||||
|
printf 'DNS=%s\n' "$dns"
|
||||||
|
} > "$POSTINSTALL_NETWORK_IP_STATE_FILE"
|
||||||
|
|
||||||
|
log_info "Configuration IP appliquee sur $iface via $backend"
|
||||||
|
ui_success "Configuration IP appliquee sur $iface via $backend"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ip_config_test() {
|
||||||
|
test -f "$POSTINSTALL_NETWORK_IP_STATE_FILE" || return 1
|
||||||
|
ip addr >/dev/null 2>&1 || return 1
|
||||||
|
}
|
||||||
28
modules/network/ip-config/tests.sh
Normal file
28
modules/network/ip-config/tests.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NETWORK_IP_CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_NETWORK_IP_CONFIG_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/ip-config/module.sh
|
||||||
|
source "$MODULE_NETWORK_IP_CONFIG_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! test -f /etc/postinstall-debian/network-ip-config.conf; then
|
||||||
|
printf 'network-ip-config test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_ip_config_test; then
|
||||||
|
printf 'network-ip-config test OK\n'
|
||||||
|
else
|
||||||
|
printf 'network-ip-config test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
4
modules/network/mdns-avahi/config.sh
Normal file
4
modules/network/mdns-avahi/config.sh
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
POSTINSTALL_MDNS_AVAHI_ENABLE="yes"
|
||||||
|
POSTINSTALL_MDNS_AVAHI_PUBLISH_WORKSTATION="yes"
|
||||||
|
POSTINSTALL_MDNS_AVAHI_CONFIG_FILE="/etc/avahi/avahi-daemon.conf"
|
||||||
|
POSTINSTALL_MDNS_AVAHI_SETTINGS_FILE="config/mdns-avahi.yaml"
|
||||||
4
modules/network/mdns-avahi/metadata.conf
Normal file
4
modules/network/mdns-avahi/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/mdns-avahi"
|
||||||
|
MODULE_NAME="Publication mDNS Avahi"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Installe et configure Avahi pour publier la machine sur le reseau local"
|
||||||
104
modules/network/mdns-avahi/module.sh
Normal file
104
modules/network/mdns-avahi/module.sh
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_MDNS_AVAHI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_MDNS_AVAHI_PROJECT_ROOT="$(cd "$MODULE_MDNS_AVAHI_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_MDNS_AVAHI_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/network/mdns-avahi/config.sh
|
||||||
|
source "$MODULE_MDNS_AVAHI_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/mdns-avahi/metadata.conf
|
||||||
|
source "$MODULE_MDNS_AVAHI_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_mdns_avahi_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_config_path() {
|
||||||
|
printf '%s/%s\n' "$MODULE_MDNS_AVAHI_PROJECT_ROOT" "$POSTINSTALL_MDNS_AVAHI_SETTINGS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_settings() {
|
||||||
|
local config_path=""
|
||||||
|
local enable_value="$POSTINSTALL_MDNS_AVAHI_ENABLE"
|
||||||
|
local publish_workstation="$POSTINSTALL_MDNS_AVAHI_PUBLISH_WORKSTATION"
|
||||||
|
|
||||||
|
config_path="$(module_mdns_avahi_config_path)"
|
||||||
|
if [[ -f "$config_path" ]]; then
|
||||||
|
while IFS='=' read -r key value; do
|
||||||
|
case "$key" in
|
||||||
|
enable) enable_value="$value" ;;
|
||||||
|
publish_workstation) publish_workstation="$value" ;;
|
||||||
|
esac
|
||||||
|
done < <(
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*enable:/ { print "enable=" $2 }
|
||||||
|
/^[[:space:]]*publish_workstation:/ { print "publish_workstation=" $2 }
|
||||||
|
' "$config_path"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s|%s\n' "$enable_value" "$publish_workstation"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_require_package() {
|
||||||
|
if package_is_installed "avahi-daemon"; then
|
||||||
|
ui_info "Paquet avahi-daemon deja installe"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_warn "Paquet avahi-daemon absent, installation en cours"
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install avahi-daemon avahi-utils libnss-mdns
|
||||||
|
log_info "Paquets Avahi installes"
|
||||||
|
ui_success "Paquets Avahi installes"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_write_config() {
|
||||||
|
local enable_value="${1:-$POSTINSTALL_MDNS_AVAHI_ENABLE}"
|
||||||
|
local publish_workstation="${2:-$POSTINSTALL_MDNS_AVAHI_PUBLISH_WORKSTATION}"
|
||||||
|
local disable_value="yes"
|
||||||
|
|
||||||
|
if [[ "$enable_value" == "yes" ]]; then
|
||||||
|
disable_value="no"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$POSTINSTALL_MDNS_AVAHI_CONFIG_FILE" "${POSTINSTALL_MDNS_AVAHI_CONFIG_FILE}.bak.postinstall" 2>/dev/null || true
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
-e "s/^#*disable-publishing=.*/disable-publishing=$disable_value/" \
|
||||||
|
-e "s/^#*publish-workstation=.*/publish-workstation=$publish_workstation/" \
|
||||||
|
"$POSTINSTALL_MDNS_AVAHI_CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_check() {
|
||||||
|
package_is_installed "avahi-daemon" || return 1
|
||||||
|
systemctl is-active --quiet avahi-daemon || return 1
|
||||||
|
grep -Eq '^disable-publishing=no$' "$POSTINSTALL_MDNS_AVAHI_CONFIG_FILE" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_install() {
|
||||||
|
local settings=""
|
||||||
|
local enable_value=""
|
||||||
|
local publish_workstation=""
|
||||||
|
|
||||||
|
settings="$(module_mdns_avahi_settings)"
|
||||||
|
IFS='|' read -r enable_value publish_workstation <<< "$settings"
|
||||||
|
|
||||||
|
module_mdns_avahi_require_package || return 1
|
||||||
|
module_mdns_avahi_write_config "$enable_value" "$publish_workstation"
|
||||||
|
|
||||||
|
systemctl enable --now avahi-daemon
|
||||||
|
systemctl restart avahi-daemon
|
||||||
|
|
||||||
|
log_info "Avahi configure, publication=$enable_value workstation=$publish_workstation"
|
||||||
|
ui_success "Avahi configure"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_mdns_avahi_test() {
|
||||||
|
package_is_installed "avahi-daemon" || return 1
|
||||||
|
test -f "$POSTINSTALL_MDNS_AVAHI_CONFIG_FILE" || return 1
|
||||||
|
test -f "$(module_mdns_avahi_config_path)" || return 1
|
||||||
|
systemctl is-active --quiet avahi-daemon || return 1
|
||||||
|
grep -Eq '^disable-publishing=(no|yes)$' "$POSTINSTALL_MDNS_AVAHI_CONFIG_FILE" || return 1
|
||||||
|
}
|
||||||
40
modules/network/mdns-avahi/tests.sh
Executable file
40
modules/network/mdns-avahi/tests.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_MDNS_AVAHI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_MDNS_AVAHI_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/mdns-avahi/module.sh
|
||||||
|
source "$MODULE_MDNS_AVAHI_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed avahi-daemon; then
|
||||||
|
printf 'mdns-avahi test SKIPPED: avahi-daemon not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f "$PROJECT_ROOT/config/mdns-avahi.yaml"; then
|
||||||
|
printf 'mdns-avahi test FAILED: missing repository config\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! systemctl status avahi-daemon >/dev/null 2>&1; then
|
||||||
|
printf 'mdns-avahi test SKIPPED: systemd status unavailable in this environment\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_mdns_avahi_test; then
|
||||||
|
printf 'mdns-avahi test OK\n'
|
||||||
|
else
|
||||||
|
printf 'mdns-avahi test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
2
modules/network/nfs-client/config.sh
Normal file
2
modules/network/nfs-client/config.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
POSTINSTALL_NFS_CLIENT_STATE_FILE="/etc/postinstall-debian/nfs-client.conf"
|
||||||
|
POSTINSTALL_NFS_CLIENT_SHARES_FILE="config/nfs-client.shares.yaml"
|
||||||
4
modules/network/nfs-client/metadata.conf
Normal file
4
modules/network/nfs-client/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/nfs-client"
|
||||||
|
MODULE_NAME="Client NFS"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Installe les utilitaires client NFS"
|
||||||
219
modules/network/nfs-client/module.sh
Normal file
219
modules/network/nfs-client/module.sh
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NFS_CLIENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_NFS_CLIENT_PROJECT_ROOT="$(cd "$MODULE_NFS_CLIENT_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_NFS_CLIENT_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-client/config.sh
|
||||||
|
source "$MODULE_NFS_CLIENT_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-client/metadata.conf
|
||||||
|
source "$MODULE_NFS_CLIENT_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_nfs_client_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_config_path() {
|
||||||
|
printf '%s/%s\n' "$MODULE_NFS_CLIENT_PROJECT_ROOT" "$POSTINSTALL_NFS_CLIENT_SHARES_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_entries() {
|
||||||
|
local config_path=""
|
||||||
|
config_path="$(module_nfs_client_config_path)"
|
||||||
|
|
||||||
|
awk '
|
||||||
|
function flush() {
|
||||||
|
if (id != "") {
|
||||||
|
print id "|" name "|" description "|" server "|" remote_path "|" mount_path "|" access "|" mount_options "|" enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^[[:space:]]*-[[:space:]]id:/ {
|
||||||
|
flush()
|
||||||
|
id=$0; sub(/.*id:[[:space:]]*/, "", id)
|
||||||
|
name=description=server=remote_path=mount_path=access=mount_options=enabled=""
|
||||||
|
next
|
||||||
|
}
|
||||||
|
/^[[:space:]]*name:/ { name=$0; sub(/.*name:[[:space:]]*/, "", name); next }
|
||||||
|
/^[[:space:]]*description:/ { description=$0; sub(/.*description:[[:space:]]*/, "", description); next }
|
||||||
|
/^[[:space:]]*server:/ { server=$0; sub(/.*server:[[:space:]]*/, "", server); next }
|
||||||
|
/^[[:space:]]*remote_path:/ { remote_path=$0; sub(/.*remote_path:[[:space:]]*/, "", remote_path); next }
|
||||||
|
/^[[:space:]]*mount_path:/ { mount_path=$0; sub(/.*mount_path:[[:space:]]*/, "", mount_path); next }
|
||||||
|
/^[[:space:]]*access:/ { access=$0; sub(/.*access:[[:space:]]*/, "", access); next }
|
||||||
|
/^[[:space:]]*mount_options:/ { mount_options=$0; sub(/.*mount_options:[[:space:]]*/, "", mount_options); next }
|
||||||
|
/^[[:space:]]*enabled_by_default:/ { enabled=$0; sub(/.*enabled_by_default:[[:space:]]*/, "", enabled); next }
|
||||||
|
END { flush() }
|
||||||
|
' "$config_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_default_ids() {
|
||||||
|
local entry=""
|
||||||
|
local ids=""
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r share_id _ _ _ _ _ _ _ enabled <<< "$entry"
|
||||||
|
if [[ "$enabled" == "true" ]]; then
|
||||||
|
ids="${ids:+$ids,}$share_id"
|
||||||
|
fi
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
|
||||||
|
printf '%s\n' "$ids"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_default_indices() {
|
||||||
|
local entry=""
|
||||||
|
local indices=""
|
||||||
|
local index=1
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r share_id _ _ _ _ _ _ _ enabled <<< "$entry"
|
||||||
|
if [[ "$enabled" == "true" ]]; then
|
||||||
|
indices="${indices:+$indices,}$index"
|
||||||
|
fi
|
||||||
|
index=$((index + 1))
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
|
||||||
|
printf '%s\n' "$indices"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_fstab_line() {
|
||||||
|
local server="$1"
|
||||||
|
local remote_path="$2"
|
||||||
|
local mount_path="$3"
|
||||||
|
local access="$4"
|
||||||
|
local mount_options="$5"
|
||||||
|
local options="$mount_options"
|
||||||
|
|
||||||
|
if [[ "$access" == "ro" && "$options" != *ro* ]]; then
|
||||||
|
options="${options},ro"
|
||||||
|
elif [[ "$access" == "rw" && "$options" != *rw* ]]; then
|
||||||
|
options="${options},rw"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s:%s %s nfs %s 0 0' "$server" "$remote_path" "$mount_path" "$options"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_enable_share() {
|
||||||
|
local share_id="$1"
|
||||||
|
local mount_now="${2:-no}"
|
||||||
|
local entry=""
|
||||||
|
local line=""
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
|
||||||
|
[[ "$current_id" == "$share_id" ]] || continue
|
||||||
|
|
||||||
|
mkdir -p "$mount_path"
|
||||||
|
line="$(module_nfs_client_fstab_line "$server" "$remote_path" "$mount_path" "$access" "$mount_options")"
|
||||||
|
if ! grep -Fq "$server:$remote_path $mount_path nfs" /etc/fstab; then
|
||||||
|
printf '%s\n' "$line" >> /etc/fstab
|
||||||
|
log_info "Partage NFS client ajoute a fstab : $share_id"
|
||||||
|
ui_success "Partage NFS active : $share_id"
|
||||||
|
else
|
||||||
|
ui_info "Partage NFS deja present dans fstab : $share_id"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$mount_now" == "yes" ]]; then
|
||||||
|
if command -v mountpoint >/dev/null 2>&1 && mountpoint -q "$mount_path"; then
|
||||||
|
ui_info "Partage deja monte : $mount_path"
|
||||||
|
elif mount "$mount_path"; then
|
||||||
|
log_info "Partage NFS monte : $share_id"
|
||||||
|
ui_success "Partage NFS monte : $share_id"
|
||||||
|
else
|
||||||
|
log_info "Echec du montage NFS : $share_id"
|
||||||
|
ui_warn "Impossible de monter immediatement $mount_path"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
|
||||||
|
ui_warn "Partage NFS introuvable dans la configuration : $share_id"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_active_entries() {
|
||||||
|
local entry=""
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
|
||||||
|
if grep -Fq "$server:$remote_path $mount_path nfs" /etc/fstab; then
|
||||||
|
printf '%s|%s|%s|%s|%s\n' "$current_id" "$name" "$mount_path" "$server:$remote_path" "$access"
|
||||||
|
fi
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_disable_share() {
|
||||||
|
local share_id="$1"
|
||||||
|
local entry=""
|
||||||
|
local temp_file=""
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
|
||||||
|
[[ "$current_id" == "$share_id" ]] || continue
|
||||||
|
|
||||||
|
if command -v mountpoint >/dev/null 2>&1 && mountpoint -q "$mount_path"; then
|
||||||
|
if umount "$mount_path"; then
|
||||||
|
log_info "Partage NFS demonte : $share_id"
|
||||||
|
ui_success "Partage NFS demonte : $share_id"
|
||||||
|
else
|
||||||
|
log_info "Echec du demontage NFS : $share_id"
|
||||||
|
ui_warn "Impossible de demonter $mount_path, suppression de l'entree fstab quand meme"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
temp_file="$(mktemp)"
|
||||||
|
grep -Fv "$server:$remote_path $mount_path nfs" /etc/fstab > "$temp_file"
|
||||||
|
cat "$temp_file" > /etc/fstab
|
||||||
|
rm -f "$temp_file"
|
||||||
|
|
||||||
|
log_info "Partage NFS retire de fstab : $share_id"
|
||||||
|
ui_success "Partage NFS desactive : $share_id"
|
||||||
|
return 0
|
||||||
|
done < <(module_nfs_client_entries)
|
||||||
|
|
||||||
|
ui_warn "Partage NFS introuvable dans la configuration : $share_id"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_install() {
|
||||||
|
local action="${1:-enable}"
|
||||||
|
local selected_ids="${2:-}"
|
||||||
|
local mount_now="${3:-no}"
|
||||||
|
local share_id=""
|
||||||
|
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install nfs-common
|
||||||
|
|
||||||
|
if [[ -n "$selected_ids" ]]; then
|
||||||
|
while IFS= read -r share_id; do
|
||||||
|
[[ -n "$share_id" ]] || continue
|
||||||
|
if [[ "$action" == "disable" ]]; then
|
||||||
|
module_nfs_client_disable_share "$share_id"
|
||||||
|
else
|
||||||
|
module_nfs_client_enable_share "$share_id" "$mount_now"
|
||||||
|
fi
|
||||||
|
done < <(printf '%s\n' "$selected_ids" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed '/^$/d')
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$POSTINSTALL_NFS_CLIENT_STATE_FILE")"
|
||||||
|
{
|
||||||
|
printf 'ENABLED=yes\n'
|
||||||
|
printf 'ACTION=%s\n' "$action"
|
||||||
|
printf 'SHARES=%s\n' "$selected_ids"
|
||||||
|
printf 'MOUNT_NOW=%s\n' "$mount_now"
|
||||||
|
} > "$POSTINSTALL_NFS_CLIENT_STATE_FILE"
|
||||||
|
log_info "Client NFS installe"
|
||||||
|
ui_success "Client NFS installe"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_client_test() {
|
||||||
|
package_is_installed nfs-common || return 1
|
||||||
|
command -v mount.nfs >/dev/null 2>&1 || return 1
|
||||||
|
test -f "$(module_nfs_client_config_path)" || return 1
|
||||||
|
}
|
||||||
35
modules/network/nfs-client/tests.sh
Normal file
35
modules/network/nfs-client/tests.sh
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NFS_CLIENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_NFS_CLIENT_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-client/module.sh
|
||||||
|
source "$MODULE_NFS_CLIENT_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed nfs-common; then
|
||||||
|
printf 'nfs-client test SKIPPED: nfs-common not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f "$PROJECT_ROOT/config/nfs-client.shares.yaml"; then
|
||||||
|
printf 'nfs-client test FAILED: missing repository config\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_nfs_client_test; then
|
||||||
|
printf 'nfs-client test OK\n'
|
||||||
|
else
|
||||||
|
printf 'nfs-client test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
5
modules/network/nfs-server/config.sh
Normal file
5
modules/network/nfs-server/config.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
POSTINSTALL_NFS_SERVER_EXPORT_PATH="/srv/nfs/share"
|
||||||
|
POSTINSTALL_NFS_SERVER_CLIENTS="10.0.0.0/22"
|
||||||
|
POSTINSTALL_NFS_SERVER_EXPORT_MODE="rw"
|
||||||
|
POSTINSTALL_NFS_SERVER_EXPORT_FILE="/etc/exports.d/postinstall.exports"
|
||||||
|
POSTINSTALL_NFS_SERVER_EXPORTS_FILE="config/nfs-server.exports.yaml"
|
||||||
4
modules/network/nfs-server/metadata.conf
Normal file
4
modules/network/nfs-server/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/nfs-server"
|
||||||
|
MODULE_NAME="Serveur NFS"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Installe et configure un export NFS"
|
||||||
144
modules/network/nfs-server/module.sh
Normal file
144
modules/network/nfs-server/module.sh
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NFS_SERVER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_NFS_SERVER_PROJECT_ROOT="$(cd "$MODULE_NFS_SERVER_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_NFS_SERVER_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-server/config.sh
|
||||||
|
source "$MODULE_NFS_SERVER_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-server/metadata.conf
|
||||||
|
source "$MODULE_NFS_SERVER_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_nfs_server_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_config_path() {
|
||||||
|
printf '%s/%s\n' "$MODULE_NFS_SERVER_PROJECT_ROOT" "$POSTINSTALL_NFS_SERVER_EXPORTS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_entries() {
|
||||||
|
local config_path=""
|
||||||
|
config_path="$(module_nfs_server_config_path)"
|
||||||
|
|
||||||
|
awk '
|
||||||
|
function flush() {
|
||||||
|
if (id != "") {
|
||||||
|
print id "|" path "|" clients "|" options "|" description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^[[:space:]]*-[[:space:]]id:/ {
|
||||||
|
flush()
|
||||||
|
id=$0; sub(/.*id:[[:space:]]*/, "", id)
|
||||||
|
path=clients=options=description=""
|
||||||
|
next
|
||||||
|
}
|
||||||
|
/^[[:space:]]*path:/ { path=$0; sub(/.*path:[[:space:]]*/, "", path); next }
|
||||||
|
/^[[:space:]]*clients:/ { clients=$0; sub(/.*clients:[[:space:]]*/, "", clients); next }
|
||||||
|
/^[[:space:]]*options:/ { options=$0; sub(/.*options:[[:space:]]*/, "", options); next }
|
||||||
|
/^[[:space:]]*description:/ { description=$0; sub(/.*description:[[:space:]]*/, "", description); next }
|
||||||
|
END { flush() }
|
||||||
|
' "$config_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_repo_lines() {
|
||||||
|
local entry=""
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r export_id export_path clients options description <<< "$entry"
|
||||||
|
printf '%s %s(%s)\n' "$export_path" "$clients" "$options"
|
||||||
|
done < <(module_nfs_server_entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_write_managed_file() {
|
||||||
|
local temp_file="$1"
|
||||||
|
|
||||||
|
{
|
||||||
|
printf '# BEGIN postinstall-debian managed exports\n'
|
||||||
|
cat "$temp_file"
|
||||||
|
printf '# END postinstall-debian managed exports\n'
|
||||||
|
} > "$POSTINSTALL_NFS_SERVER_EXPORT_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_sync_add_only() {
|
||||||
|
local line=""
|
||||||
|
local current_content=""
|
||||||
|
local temp_file=""
|
||||||
|
|
||||||
|
mkdir -p /etc/exports.d
|
||||||
|
temp_file="$(mktemp)"
|
||||||
|
|
||||||
|
if [[ -f "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" ]]; then
|
||||||
|
awk '
|
||||||
|
/^# BEGIN postinstall-debian managed exports$/ { skip=1; next }
|
||||||
|
/^# END postinstall-debian managed exports$/ { skip=0; next }
|
||||||
|
!skip { print }
|
||||||
|
' "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" > "$temp_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ -n "$line" ]] || continue
|
||||||
|
mkdir -p "${line%% *}"
|
||||||
|
if ! grep -Fq "$line" "$temp_file"; then
|
||||||
|
printf '%s\n' "$line" >> "$temp_file"
|
||||||
|
log_info "Export NFS ajoute depuis le repo : $line"
|
||||||
|
ui_success "Export NFS ajoute"
|
||||||
|
else
|
||||||
|
ui_info "Export NFS deja present : $line"
|
||||||
|
fi
|
||||||
|
done < <(module_nfs_server_repo_lines)
|
||||||
|
|
||||||
|
module_nfs_server_write_managed_file "$temp_file"
|
||||||
|
rm -f "$temp_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_sync_strict() {
|
||||||
|
local temp_file=""
|
||||||
|
local line=""
|
||||||
|
|
||||||
|
mkdir -p /etc/exports.d
|
||||||
|
temp_file="$(mktemp)"
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ -n "$line" ]] || continue
|
||||||
|
mkdir -p "${line%% *}"
|
||||||
|
printf '%s\n' "$line" >> "$temp_file"
|
||||||
|
done < <(module_nfs_server_repo_lines)
|
||||||
|
|
||||||
|
module_nfs_server_write_managed_file "$temp_file"
|
||||||
|
rm -f "$temp_file"
|
||||||
|
|
||||||
|
log_info "Exports NFS synchronises en mode strict"
|
||||||
|
ui_success "Exports NFS synchronises en mode strict"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_install() {
|
||||||
|
local sync_mode="${1:-add-only}"
|
||||||
|
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install nfs-kernel-server
|
||||||
|
|
||||||
|
if [[ "$sync_mode" == "strict" ]]; then
|
||||||
|
module_nfs_server_sync_strict
|
||||||
|
elif [[ "$sync_mode" == "add-only" || "$sync_mode" == "repo" ]]; then
|
||||||
|
module_nfs_server_sync_add_only
|
||||||
|
else
|
||||||
|
mkdir -p "$POSTINSTALL_NFS_SERVER_EXPORT_PATH"
|
||||||
|
printf '%s %s(%s,sync,no_subtree_check)\n' "$POSTINSTALL_NFS_SERVER_EXPORT_PATH" "$POSTINSTALL_NFS_SERVER_CLIENTS" "$POSTINSTALL_NFS_SERVER_EXPORT_MODE" > "$POSTINSTALL_NFS_SERVER_EXPORT_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exportfs -ra
|
||||||
|
systemctl enable --now nfs-kernel-server
|
||||||
|
systemctl restart nfs-kernel-server
|
||||||
|
|
||||||
|
log_info "Serveur NFS synchronise depuis le repo"
|
||||||
|
ui_success "Serveur NFS configure"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_nfs_server_test() {
|
||||||
|
package_is_installed nfs-kernel-server || return 1
|
||||||
|
test -f "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" || return 1
|
||||||
|
test -f "$(module_nfs_server_config_path)" || return 1
|
||||||
|
}
|
||||||
40
modules/network/nfs-server/tests.sh
Normal file
40
modules/network/nfs-server/tests.sh
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_NFS_SERVER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_NFS_SERVER_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/nfs-server/module.sh
|
||||||
|
source "$MODULE_NFS_SERVER_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed nfs-kernel-server; then
|
||||||
|
printf 'nfs-server test SKIPPED: nfs-kernel-server not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f "$PROJECT_ROOT/config/nfs-server.exports.yaml"; then
|
||||||
|
printf 'nfs-server test FAILED: missing repository config\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f /etc/exports.d/postinstall.exports; then
|
||||||
|
printf 'nfs-server test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_nfs_server_test; then
|
||||||
|
printf 'nfs-server test OK\n'
|
||||||
|
else
|
||||||
|
printf 'nfs-server test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
8
modules/network/samba-share/config.sh
Normal file
8
modules/network/samba-share/config.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
POSTINSTALL_SAMBA_SHARE_NAME="public"
|
||||||
|
POSTINSTALL_SAMBA_SHARE_PATH="/home/gilles"
|
||||||
|
POSTINSTALL_SAMBA_SHARE_USER="gilles"
|
||||||
|
POSTINSTALL_SAMBA_SHARE_READ_ONLY="yes"
|
||||||
|
POSTINSTALL_SAMBA_SHARE_PUBLIC="yes"
|
||||||
|
POSTINSTALL_SAMBA_CONFIG_DIR="/etc/samba"
|
||||||
|
POSTINSTALL_SAMBA_INCLUDE_FILE="/etc/samba/smb.conf.d/postinstall-home.conf"
|
||||||
|
POSTINSTALL_SAMBA_SHARES_FILE="config/samba-shares.yaml"
|
||||||
4
modules/network/samba-share/metadata.conf
Normal file
4
modules/network/samba-share/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/samba-share"
|
||||||
|
MODULE_NAME="Partage Samba public"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Installe Samba et partage un dossier sur le reseau local"
|
||||||
186
modules/network/samba-share/module.sh
Normal file
186
modules/network/samba-share/module.sh
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_SAMBA_SHARE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_SAMBA_SHARE_PROJECT_ROOT="$(cd "$MODULE_SAMBA_SHARE_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_SAMBA_SHARE_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$MODULE_SAMBA_SHARE_PROJECT_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=modules/network/samba-share/config.sh
|
||||||
|
source "$MODULE_SAMBA_SHARE_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/samba-share/metadata.conf
|
||||||
|
source "$MODULE_SAMBA_SHARE_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_samba_share_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_config_path() {
|
||||||
|
printf '%s/%s\n' "$MODULE_SAMBA_SHARE_PROJECT_ROOT" "$POSTINSTALL_SAMBA_SHARES_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_global_settings() {
|
||||||
|
local config_path=""
|
||||||
|
local workgroup="WORKGROUP"
|
||||||
|
local wsdd2_enabled="yes"
|
||||||
|
|
||||||
|
config_path="$(module_samba_share_config_path)"
|
||||||
|
if [[ -f "$config_path" ]]; then
|
||||||
|
while IFS='=' read -r key value; do
|
||||||
|
case "$key" in
|
||||||
|
workgroup) workgroup="$value" ;;
|
||||||
|
wsdd2) wsdd2_enabled="$value" ;;
|
||||||
|
esac
|
||||||
|
done < <(
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*workgroup:/ { print "workgroup=" $2 }
|
||||||
|
/^[[:space:]]*wsdd2:/ { print "wsdd2=" $2 }
|
||||||
|
' "$config_path"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s|%s\n' "$workgroup" "$wsdd2_enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_entries() {
|
||||||
|
local config_path=""
|
||||||
|
config_path="$(module_samba_share_config_path)"
|
||||||
|
|
||||||
|
awk '
|
||||||
|
function flush() {
|
||||||
|
if (id != "") {
|
||||||
|
print id "|" name "|" path "|" user "|" read_only "|" public "|" description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^[[:space:]]*-[[:space:]]id:/ {
|
||||||
|
flush()
|
||||||
|
id=$0; sub(/.*id:[[:space:]]*/, "", id)
|
||||||
|
name=path=user=read_only=public=description=""
|
||||||
|
next
|
||||||
|
}
|
||||||
|
/^[[:space:]]*name:/ { name=$0; sub(/.*name:[[:space:]]*/, "", name); next }
|
||||||
|
/^[[:space:]]*path:/ { path=$0; sub(/.*path:[[:space:]]*/, "", path); next }
|
||||||
|
/^[[:space:]]*user:/ { user=$0; sub(/.*user:[[:space:]]*/, "", user); next }
|
||||||
|
/^[[:space:]]*read_only:/ { read_only=$0; sub(/.*read_only:[[:space:]]*/, "", read_only); next }
|
||||||
|
/^[[:space:]]*public:/ { public=$0; sub(/.*public:[[:space:]]*/, "", public); next }
|
||||||
|
/^[[:space:]]*description:/ { description=$0; sub(/.*description:[[:space:]]*/, "", description); next }
|
||||||
|
END { flush() }
|
||||||
|
' "$config_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_ensure_include() {
|
||||||
|
mkdir -p /etc/samba/smb.conf.d
|
||||||
|
if ! grep -Fq 'include = /etc/samba/smb.conf.d/postinstall-home.conf' /etc/samba/smb.conf; then
|
||||||
|
printf '\ninclude = /etc/samba/smb.conf.d/postinstall-home.conf\n' >> /etc/samba/smb.conf
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_manage_wsdd2() {
|
||||||
|
local wsdd2_enabled="$1"
|
||||||
|
|
||||||
|
if [[ "$wsdd2_enabled" == "yes" ]]; then
|
||||||
|
if package_install wsdd2; then
|
||||||
|
systemctl enable --now wsdd2 || ui_warn "Impossible d'activer wsdd2"
|
||||||
|
else
|
||||||
|
ui_warn "Paquet wsdd2 indisponible ou installation echouee"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_render_block() {
|
||||||
|
local share_name="$1"
|
||||||
|
local share_path="$2"
|
||||||
|
local share_user="$3"
|
||||||
|
local read_only="$4"
|
||||||
|
local is_public="$5"
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
[$share_name]
|
||||||
|
path = $share_path
|
||||||
|
browseable = yes
|
||||||
|
read only = $read_only
|
||||||
|
guest ok = $is_public
|
||||||
|
public = $is_public
|
||||||
|
force user = $share_user
|
||||||
|
create mask = 0644
|
||||||
|
directory mask = 0755
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_sync_file() {
|
||||||
|
local sync_mode="${1:-add-only}"
|
||||||
|
local settings=""
|
||||||
|
local workgroup=""
|
||||||
|
local wsdd2_enabled=""
|
||||||
|
local entry=""
|
||||||
|
local temp_file=""
|
||||||
|
local rendered_file=""
|
||||||
|
|
||||||
|
settings="$(module_samba_share_global_settings)"
|
||||||
|
IFS='|' read -r workgroup wsdd2_enabled <<< "$settings"
|
||||||
|
|
||||||
|
mkdir -p /etc/samba/smb.conf.d
|
||||||
|
temp_file="$(mktemp)"
|
||||||
|
rendered_file="$(mktemp)"
|
||||||
|
|
||||||
|
if [[ "$sync_mode" == "add-only" && -f "$POSTINSTALL_SAMBA_INCLUDE_FILE" ]]; then
|
||||||
|
awk '
|
||||||
|
/^# BEGIN postinstall-debian managed samba$/ { skip=1; next }
|
||||||
|
/^# END postinstall-debian managed samba$/ { skip=0; next }
|
||||||
|
!skip { print }
|
||||||
|
' "$POSTINSTALL_SAMBA_INCLUDE_FILE" > "$temp_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r entry; do
|
||||||
|
[[ -n "$entry" ]] || continue
|
||||||
|
IFS='|' read -r share_id share_name share_path share_user read_only is_public description <<< "$entry"
|
||||||
|
|
||||||
|
if ! system_user_exists "$share_user"; then
|
||||||
|
ui_warn "Utilisateur Samba introuvable, partage ignore : $share_user"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$share_path"
|
||||||
|
chown "$share_user:$share_user" "$share_path"
|
||||||
|
module_samba_share_render_block "$share_name" "$share_path" "$share_user" "$read_only" "$is_public" >> "$rendered_file"
|
||||||
|
printf '\n' >> "$rendered_file"
|
||||||
|
done < <(module_samba_share_entries)
|
||||||
|
|
||||||
|
{
|
||||||
|
cat "$temp_file"
|
||||||
|
printf '# BEGIN postinstall-debian managed samba\n'
|
||||||
|
printf '[global]\n'
|
||||||
|
printf ' workgroup = %s\n' "$workgroup"
|
||||||
|
printf ' map to guest = Bad User\n'
|
||||||
|
printf ' server min protocol = SMB2\n\n'
|
||||||
|
cat "$rendered_file"
|
||||||
|
printf '# END postinstall-debian managed samba\n'
|
||||||
|
} > "$POSTINSTALL_SAMBA_INCLUDE_FILE"
|
||||||
|
|
||||||
|
module_samba_share_manage_wsdd2 "$wsdd2_enabled"
|
||||||
|
rm -f "$temp_file" "$rendered_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_install() {
|
||||||
|
local sync_mode="${1:-add-only}"
|
||||||
|
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install samba
|
||||||
|
module_samba_share_ensure_include
|
||||||
|
module_samba_share_sync_file "$sync_mode"
|
||||||
|
|
||||||
|
testparm -s >/dev/null || return 1
|
||||||
|
systemctl enable --now smbd
|
||||||
|
systemctl restart smbd
|
||||||
|
|
||||||
|
log_info "Partages Samba synchronises depuis le repo"
|
||||||
|
ui_success "Partages Samba configures"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_samba_share_test() {
|
||||||
|
package_is_installed samba || return 1
|
||||||
|
test -f "$POSTINSTALL_SAMBA_INCLUDE_FILE" || return 1
|
||||||
|
test -f "$(module_samba_share_config_path)" || return 1
|
||||||
|
testparm -s >/dev/null 2>&1 || return 1
|
||||||
|
}
|
||||||
40
modules/network/samba-share/tests.sh
Normal file
40
modules/network/samba-share/tests.sh
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_SAMBA_SHARE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_SAMBA_SHARE_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/samba-share/module.sh
|
||||||
|
source "$MODULE_SAMBA_SHARE_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed samba; then
|
||||||
|
printf 'samba-share test SKIPPED: samba not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f "$PROJECT_ROOT/config/samba-shares.yaml"; then
|
||||||
|
printf 'samba-share test FAILED: missing repository config\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f /etc/samba/smb.conf.d/postinstall-home.conf; then
|
||||||
|
printf 'samba-share test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_samba_share_test; then
|
||||||
|
printf 'samba-share test OK\n'
|
||||||
|
else
|
||||||
|
printf 'samba-share test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
6
modules/network/ssh-server/config.sh
Normal file
6
modules/network/ssh-server/config.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
POSTINSTALL_SSH_PORT="22"
|
||||||
|
POSTINSTALL_SSH_PASSWORD_AUTH="yes"
|
||||||
|
POSTINSTALL_SSH_ROOT_LOGIN="no"
|
||||||
|
POSTINSTALL_SSH_CONFIG_DIR="/etc/ssh/sshd_config.d"
|
||||||
|
POSTINSTALL_SSH_CONFIG_FILE="/etc/ssh/sshd_config.d/postinstall-debian.conf"
|
||||||
|
POSTINSTALL_SSH_SETTINGS_FILE="config/ssh-server.yaml"
|
||||||
4
modules/network/ssh-server/metadata.conf
Normal file
4
modules/network/ssh-server/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="network/ssh-server"
|
||||||
|
MODULE_NAME="Serveur SSH"
|
||||||
|
MODULE_CATEGORY="network"
|
||||||
|
MODULE_DESCRIPTION="Installe et configure openssh-server pour l'administration distante"
|
||||||
132
modules/network/ssh-server/module.sh
Normal file
132
modules/network/ssh-server/module.sh
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_SSH_SERVER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_SSH_SERVER_PROJECT_ROOT="$(cd "$MODULE_SSH_SERVER_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_SSH_SERVER_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/network/ssh-server/config.sh
|
||||||
|
source "$MODULE_SSH_SERVER_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/network/ssh-server/metadata.conf
|
||||||
|
source "$MODULE_SSH_SERVER_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_ssh_server_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_config_path() {
|
||||||
|
printf '%s/%s\n' "$MODULE_SSH_SERVER_PROJECT_ROOT" "$POSTINSTALL_SSH_SETTINGS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_settings() {
|
||||||
|
local config_path=""
|
||||||
|
local port="$POSTINSTALL_SSH_PORT"
|
||||||
|
local password_auth="$POSTINSTALL_SSH_PASSWORD_AUTH"
|
||||||
|
local root_login="$POSTINSTALL_SSH_ROOT_LOGIN"
|
||||||
|
|
||||||
|
config_path="$(module_ssh_server_config_path)"
|
||||||
|
if [[ -f "$config_path" ]]; then
|
||||||
|
while IFS='=' read -r key value; do
|
||||||
|
case "$key" in
|
||||||
|
port) port="$value" ;;
|
||||||
|
password_authentication) password_auth="$value" ;;
|
||||||
|
permit_root_login) root_login="$value" ;;
|
||||||
|
esac
|
||||||
|
done < <(
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*port:/ { print "port=" $2 }
|
||||||
|
/^[[:space:]]*password_authentication:/ { print "password_authentication=" $2 }
|
||||||
|
/^[[:space:]]*permit_root_login:/ { print "permit_root_login=" $2 }
|
||||||
|
' "$config_path"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s|%s|%s\n' "$port" "$password_auth" "$root_login"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_validate_port() {
|
||||||
|
local port="$1"
|
||||||
|
|
||||||
|
[[ "$port" =~ ^[0-9]+$ ]] || return 1
|
||||||
|
(( port >= 1 && port <= 65535 ))
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_require_package() {
|
||||||
|
if package_is_installed "openssh-server"; then
|
||||||
|
ui_info "Paquet openssh-server deja installe"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_warn "Paquet openssh-server absent, installation en cours"
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install openssh-server
|
||||||
|
log_info "Paquet openssh-server installe"
|
||||||
|
ui_success "Paquet openssh-server installe"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_write_config() {
|
||||||
|
local ssh_port="${1:-$POSTINSTALL_SSH_PORT}"
|
||||||
|
local password_auth="${2:-$POSTINSTALL_SSH_PASSWORD_AUTH}"
|
||||||
|
local root_login="${3:-$POSTINSTALL_SSH_ROOT_LOGIN}"
|
||||||
|
|
||||||
|
mkdir -p "$POSTINSTALL_SSH_CONFIG_DIR"
|
||||||
|
cat > "$POSTINSTALL_SSH_CONFIG_FILE" <<EOF
|
||||||
|
# Fichier gere par postinstall-debian
|
||||||
|
Port $ssh_port
|
||||||
|
PasswordAuthentication $password_auth
|
||||||
|
PermitRootLogin $root_login
|
||||||
|
UsePAM yes
|
||||||
|
X11Forwarding no
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_check() {
|
||||||
|
local ssh_port="${1:-$POSTINSTALL_SSH_PORT}"
|
||||||
|
|
||||||
|
package_is_installed "openssh-server" || return 1
|
||||||
|
systemctl is-active --quiet ssh || return 1
|
||||||
|
ss -ltn 2>/dev/null | awk '{print $4}' | grep -Eq "(^|:)$ssh_port$"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_install() {
|
||||||
|
local settings=""
|
||||||
|
local ssh_port=""
|
||||||
|
local password_auth=""
|
||||||
|
local root_login=""
|
||||||
|
|
||||||
|
settings="$(module_ssh_server_settings)"
|
||||||
|
IFS='|' read -r ssh_port password_auth root_login <<< "$settings"
|
||||||
|
|
||||||
|
if ! module_ssh_server_validate_port "$ssh_port"; then
|
||||||
|
ui_error "Port SSH invalide : $ssh_port"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
module_ssh_server_require_package || return 1
|
||||||
|
module_ssh_server_write_config "$ssh_port" "$password_auth" "$root_login"
|
||||||
|
|
||||||
|
if command -v sshd >/dev/null 2>&1; then
|
||||||
|
sshd -t || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl enable --now ssh
|
||||||
|
systemctl restart ssh
|
||||||
|
|
||||||
|
log_info "Serveur SSH configure sur le port $ssh_port"
|
||||||
|
ui_success "Serveur SSH configure sur le port $ssh_port"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ssh_server_test() {
|
||||||
|
local settings=""
|
||||||
|
local ssh_port=""
|
||||||
|
|
||||||
|
settings="$(module_ssh_server_settings)"
|
||||||
|
IFS='|' read -r ssh_port _ _ <<< "$settings"
|
||||||
|
|
||||||
|
package_is_installed "openssh-server" || return 1
|
||||||
|
command -v ssh >/dev/null 2>&1 || return 1
|
||||||
|
test -f "$POSTINSTALL_SSH_CONFIG_FILE" || return 1
|
||||||
|
test -f "$(module_ssh_server_config_path)" || return 1
|
||||||
|
systemctl is-active --quiet ssh || return 1
|
||||||
|
ss -ltn 2>/dev/null | awk '{print $4}' | grep -Eq "(^|:)$ssh_port$"
|
||||||
|
}
|
||||||
45
modules/network/ssh-server/tests.sh
Executable file
45
modules/network/ssh-server/tests.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_SSH_SERVER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_SSH_SERVER_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/network/ssh-server/module.sh
|
||||||
|
source "$MODULE_SSH_SERVER_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed openssh-server; then
|
||||||
|
printf 'ssh-server test SKIPPED: openssh-server not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f "$PROJECT_ROOT/config/ssh-server.yaml"; then
|
||||||
|
printf 'ssh-server test FAILED: missing repository config\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! systemctl status ssh >/dev/null 2>&1; then
|
||||||
|
printf 'ssh-server test SKIPPED: systemd status unavailable in this environment\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! test -f /etc/ssh/sshd_config.d/postinstall-debian.conf; then
|
||||||
|
printf 'ssh-server test SKIPPED: module configuration not applied\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_ssh_server_test "${1:-22}"; then
|
||||||
|
printf 'ssh-server test OK\n'
|
||||||
|
else
|
||||||
|
printf 'ssh-server test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
2
modules/system/user-groups/config.sh
Normal file
2
modules/system/user-groups/config.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
POSTINSTALL_USER_GROUPS_TARGET_USER="${POSTINSTALL_DEFAULT_USER:-gilles}"
|
||||||
|
POSTINSTALL_USER_GROUPS_DEFAULT_GROUPS="audio,video,plugdev,dialout,netdev,lpadmin,scanner"
|
||||||
4
modules/system/user-groups/metadata.conf
Normal file
4
modules/system/user-groups/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="system/user-groups"
|
||||||
|
MODULE_NAME="Configuration groupes utilisateur"
|
||||||
|
MODULE_CATEGORY="system"
|
||||||
|
MODULE_DESCRIPTION="Ajoute un utilisateur cible a une liste de groupes systeme utiles"
|
||||||
93
modules/system/user-groups/module.sh
Normal file
93
modules/system/user-groups/module.sh
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_USER_GROUPS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_USER_GROUPS_PROJECT_ROOT="$(cd "$MODULE_USER_GROUPS_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=modules/system/user-groups/config.sh
|
||||||
|
source "$MODULE_USER_GROUPS_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/system/user-groups/metadata.conf
|
||||||
|
source "$MODULE_USER_GROUPS_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_user_groups_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_groups_normalize_csv() {
|
||||||
|
local raw_groups="$1"
|
||||||
|
|
||||||
|
printf '%s\n' "$raw_groups" \
|
||||||
|
| tr ',' '\n' \
|
||||||
|
| sed 's/^[[:space:]]*//;s/[[:space:]]*$//' \
|
||||||
|
| sed '/^$/d'
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_groups_check() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_GROUPS_TARGET_USER}"
|
||||||
|
local requested_groups="${2:-$POSTINSTALL_USER_GROUPS_DEFAULT_GROUPS}"
|
||||||
|
local group_name=""
|
||||||
|
|
||||||
|
if ! system_user_exists "$target_user"; then
|
||||||
|
ui_error "Utilisateur introuvable : $target_user"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r group_name; do
|
||||||
|
if ! system_group_exists "$group_name"; then
|
||||||
|
ui_warn "Groupe introuvable : $group_name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! system_user_in_group "$target_user" "$group_name"; then
|
||||||
|
ui_warn "Utilisateur $target_user non membre du groupe $group_name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done < <(module_user_groups_normalize_csv "$requested_groups")
|
||||||
|
|
||||||
|
ui_success "Tous les groupes demandes sont deja appliques a $target_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_groups_install() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_GROUPS_TARGET_USER}"
|
||||||
|
local requested_groups="${2:-$POSTINSTALL_USER_GROUPS_DEFAULT_GROUPS}"
|
||||||
|
local group_name=""
|
||||||
|
local changed=0
|
||||||
|
|
||||||
|
if ! system_user_exists "$target_user"; then
|
||||||
|
ui_error "Impossible de configurer les groupes : utilisateur absent ($target_user)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r group_name; do
|
||||||
|
if ! system_group_exists "$group_name"; then
|
||||||
|
ui_warn "Groupe ignore car absent : $group_name"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if system_user_in_group "$target_user" "$group_name"; then
|
||||||
|
ui_info "Aucun changement : $target_user est deja dans $group_name"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
usermod -aG "$group_name" "$target_user"
|
||||||
|
log_info "Utilisateur $target_user ajoute au groupe $group_name"
|
||||||
|
ui_success "Utilisateur $target_user ajoute au groupe $group_name"
|
||||||
|
changed=1
|
||||||
|
done < <(module_user_groups_normalize_csv "$requested_groups")
|
||||||
|
|
||||||
|
if [[ "$changed" -eq 0 ]]; then
|
||||||
|
ui_info "Aucun changement de groupes necessaire"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_groups_test() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_GROUPS_TARGET_USER}"
|
||||||
|
local requested_groups="${2:-$POSTINSTALL_USER_GROUPS_DEFAULT_GROUPS}"
|
||||||
|
local group_name=""
|
||||||
|
|
||||||
|
system_user_exists "$target_user" || return 1
|
||||||
|
|
||||||
|
while IFS= read -r group_name; do
|
||||||
|
system_group_exists "$group_name" || return 1
|
||||||
|
system_user_in_group "$target_user" "$group_name" || return 1
|
||||||
|
done < <(module_user_groups_normalize_csv "$requested_groups")
|
||||||
|
}
|
||||||
25
modules/system/user-groups/tests.sh
Executable file
25
modules/system/user-groups/tests.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_USER_GROUPS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_USER_GROUPS_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$PROJECT_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/system/user-groups/module.sh
|
||||||
|
source "$MODULE_USER_GROUPS_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if module_user_groups_test "${1:-gilles}" "${2:-audio,video}"; then
|
||||||
|
printf 'user-groups test OK\n'
|
||||||
|
else
|
||||||
|
printf 'user-groups test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
2
modules/system/user-sudo/config.sh
Normal file
2
modules/system/user-sudo/config.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
POSTINSTALL_USER_SUDO_TARGET_USER="${POSTINSTALL_DEFAULT_USER:-gilles}"
|
||||||
|
POSTINSTALL_USER_SUDO_TARGET_GROUP="sudo"
|
||||||
4
modules/system/user-sudo/metadata.conf
Normal file
4
modules/system/user-sudo/metadata.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
MODULE_ID="system/user-sudo"
|
||||||
|
MODULE_NAME="Configuration sudo utilisateur"
|
||||||
|
MODULE_CATEGORY="system"
|
||||||
|
MODULE_DESCRIPTION="Ajoute un utilisateur cible au groupe sudo et valide la configuration sudo"
|
||||||
103
modules/system/user-sudo/module.sh
Normal file
103
modules/system/user-sudo/module.sh
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_USER_SUDO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MODULE_USER_SUDO_PROJECT_ROOT="$(cd "$MODULE_USER_SUDO_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$MODULE_USER_SUDO_PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=modules/system/user-sudo/config.sh
|
||||||
|
source "$MODULE_USER_SUDO_DIR/config.sh"
|
||||||
|
# shellcheck source=modules/system/user-sudo/metadata.conf
|
||||||
|
source "$MODULE_USER_SUDO_DIR/metadata.conf"
|
||||||
|
|
||||||
|
module_user_sudo_require_package() {
|
||||||
|
if package_is_installed "sudo"; then
|
||||||
|
ui_info "Paquet sudo deja installe"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_warn "Paquet sudo absent, installation en cours"
|
||||||
|
package_refresh_indexes
|
||||||
|
package_install sudo
|
||||||
|
log_info "Paquet sudo installe"
|
||||||
|
ui_success "Paquet sudo installe"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_sudo_metadata() {
|
||||||
|
printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_sudo_check() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_SUDO_TARGET_USER}"
|
||||||
|
|
||||||
|
if ! package_is_installed "sudo"; then
|
||||||
|
ui_warn "Paquet sudo non installe"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! system_user_exists "$target_user"; then
|
||||||
|
ui_error "Utilisateur introuvable : $target_user"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! system_group_exists "$POSTINSTALL_USER_SUDO_TARGET_GROUP"; then
|
||||||
|
ui_error "Groupe requis introuvable : $POSTINSTALL_USER_SUDO_TARGET_GROUP"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if system_user_in_group "$target_user" "$POSTINSTALL_USER_SUDO_TARGET_GROUP"; then
|
||||||
|
ui_success "Utilisateur $target_user deja membre du groupe sudo"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_warn "Utilisateur $target_user non membre du groupe sudo"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_sudo_install() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_SUDO_TARGET_USER}"
|
||||||
|
|
||||||
|
module_user_sudo_require_package || return 1
|
||||||
|
|
||||||
|
if ! system_user_exists "$target_user"; then
|
||||||
|
ui_error "Impossible de configurer sudo : utilisateur absent ($target_user)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! system_group_exists "$POSTINSTALL_USER_SUDO_TARGET_GROUP"; then
|
||||||
|
ui_error "Impossible de configurer sudo : groupe absent ($POSTINSTALL_USER_SUDO_TARGET_GROUP)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if system_user_in_group "$target_user" "$POSTINSTALL_USER_SUDO_TARGET_GROUP"; then
|
||||||
|
log_info "Aucun changement sudo requis pour $target_user"
|
||||||
|
ui_info "Aucun changement : $target_user est deja dans sudo"
|
||||||
|
else
|
||||||
|
usermod -aG "$POSTINSTALL_USER_SUDO_TARGET_GROUP" "$target_user"
|
||||||
|
log_info "Utilisateur $target_user ajoute au groupe sudo"
|
||||||
|
ui_success "Utilisateur $target_user ajoute au groupe sudo"
|
||||||
|
fi
|
||||||
|
|
||||||
|
module_user_sudo_configure "$target_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_sudo_configure() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_SUDO_TARGET_USER}"
|
||||||
|
|
||||||
|
if command -v visudo >/dev/null 2>&1; then
|
||||||
|
visudo -cf /etc/sudoers >/dev/null
|
||||||
|
log_info "Validation visudo reussie pour $target_user"
|
||||||
|
ui_success "Configuration sudo validee avec visudo"
|
||||||
|
else
|
||||||
|
ui_warn "visudo indisponible, validation sudo non effectuee"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_user_sudo_test() {
|
||||||
|
local target_user="${1:-$POSTINSTALL_USER_SUDO_TARGET_USER}"
|
||||||
|
|
||||||
|
package_is_installed "sudo" || return 1
|
||||||
|
system_user_exists "$target_user" || return 1
|
||||||
|
system_group_exists "$POSTINSTALL_USER_SUDO_TARGET_GROUP" || return 1
|
||||||
|
system_user_in_group "$target_user" "$POSTINSTALL_USER_SUDO_TARGET_GROUP"
|
||||||
|
}
|
||||||
32
modules/system/user-sudo/tests.sh
Executable file
32
modules/system/user-sudo/tests.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MODULE_USER_SUDO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$MODULE_USER_SUDO_DIR/../../.." && pwd)"
|
||||||
|
|
||||||
|
# shellcheck source=lib/ui.sh
|
||||||
|
source "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
# shellcheck source=lib/log.sh
|
||||||
|
source "$PROJECT_ROOT/lib/log.sh"
|
||||||
|
# shellcheck source=lib/package.sh
|
||||||
|
source "$PROJECT_ROOT/lib/package.sh"
|
||||||
|
# shellcheck source=lib/system.sh
|
||||||
|
source "$PROJECT_ROOT/lib/system.sh"
|
||||||
|
# shellcheck source=core/runtime.sh
|
||||||
|
source "$PROJECT_ROOT/core/runtime.sh"
|
||||||
|
# shellcheck source=modules/system/user-sudo/module.sh
|
||||||
|
source "$MODULE_USER_SUDO_DIR/module.sh"
|
||||||
|
|
||||||
|
runtime_init "$PROJECT_ROOT"
|
||||||
|
log_init
|
||||||
|
|
||||||
|
if ! package_is_installed sudo; then
|
||||||
|
printf 'user-sudo test SKIPPED: sudo package not installed\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if module_user_sudo_test "${1:-gilles}"; then
|
||||||
|
printf 'user-sudo test OK\n'
|
||||||
|
else
|
||||||
|
printf 'user-sudo test FAILED\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
3
profiles/README.md
Normal file
3
profiles/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Profiles
|
||||||
|
|
||||||
|
Ce dossier contiendra des profils de modules predefinis comme `desktop-minimal`, `developer` ou `homelab`.
|
||||||
12
tests/smoke.sh
Executable file
12
tests/smoke.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
|
test -f "$PROJECT_ROOT/install.sh"
|
||||||
|
test -f "$PROJECT_ROOT/core/bootstrap.sh"
|
||||||
|
test -f "$PROJECT_ROOT/lib/ui.sh"
|
||||||
|
test -f "$PROJECT_ROOT/menus/main.sh"
|
||||||
|
|
||||||
|
printf 'Smoke test OK\n'
|
||||||
BIN
themes/grub/debian-1080p.zip
Normal file
BIN
themes/grub/debian-1080p.zip
Normal file
Binary file not shown.
BIN
themes/grub/debian-2K.zip
Normal file
BIN
themes/grub/debian-2K.zip
Normal file
Binary file not shown.
BIN
themes/grub/linux-1080p.zip
Normal file
BIN
themes/grub/linux-1080p.zip
Normal file
Binary file not shown.
BIN
themes/grub/linux-2K.zip
Normal file
BIN
themes/grub/linux-2K.zip
Normal file
Binary file not shown.
203
tools.md
Normal file
203
tools.md
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
# tools.md
|
||||||
|
|
||||||
|
Ce fichier reference les outils a integrer au framework.
|
||||||
|
|
||||||
|
## Modele
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom :
|
||||||
|
Description :
|
||||||
|
Categorie :
|
||||||
|
Questions :
|
||||||
|
Methode installation :
|
||||||
|
Tests :
|
||||||
|
Difficulte :
|
||||||
|
Statut :
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backlog priorise
|
||||||
|
|
||||||
|
### 1. system/user-sudo
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Configuration sudo utilisateur
|
||||||
|
Description : installe sudo si absent puis configure l'utilisateur gilles selon les bonnes pratiques Debian
|
||||||
|
Categorie : system
|
||||||
|
Questions : faut-il verifier si l'utilisateur existe, creer une regle dediee dans /etc/sudoers.d, et imposer une validation via visudo ?
|
||||||
|
Methode installation : verifier la presence du paquet sudo, l'installer si necessaire, verifier la presence de l'utilisateur, l'ajouter au groupe sudo si necessaire, appliquer une validation de la configuration sudo
|
||||||
|
Tests : id gilles ; getent group sudo ; sudo -l -U gilles ; visudo -cf /etc/sudoers
|
||||||
|
Difficulte : faible
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. system/user-groups
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Configuration groupes utilisateur
|
||||||
|
Description : ajoute l'utilisateur gilles aux groupes systeme utiles selon les bonnes pratiques
|
||||||
|
Categorie : system
|
||||||
|
Questions : quels groupes doivent etre proposes par defaut : dialout, plugdev, video, audio, netdev, lpadmin, scanner ?
|
||||||
|
Methode installation : verifier les groupes existants, proposer une selection de groupes, ajouter l'utilisateur uniquement aux groupes retenus
|
||||||
|
Tests : id gilles ; getent group <nom_groupe>
|
||||||
|
Difficulte : faible
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. network/identity
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Identite reseau de la machine
|
||||||
|
Description : configure le nom de la machine, le nom reseau et les elements de base de resolution locale
|
||||||
|
Categorie : network
|
||||||
|
Questions : quel hostname definir, faut-il gerer un domaine local, faut-il mettre a jour /etc/hosts ?
|
||||||
|
Methode installation : demander hostname, nom du reseau local si necessaire, mettre a jour hostnamectl et les fichiers systeme associes
|
||||||
|
Tests : hostnamectl ; cat /etc/hostname ; getent hosts $(hostname)
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. network/ip-config
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Configuration IP initiale
|
||||||
|
Description : configure la machine en DHCP ou en IP statique sur le reseau local
|
||||||
|
Categorie : network
|
||||||
|
Questions : interface cible, mode DHCP ou statique, gateway 10.0.0.1, DNS 10.0.0.1, masque /22, IP complete ou dernier octet uniquement ?
|
||||||
|
Methode installation : detecter l'interface principale, proposer DHCP ou statique, ecrire la configuration reseau adaptee, appliquer proprement les changements
|
||||||
|
Tests : ip addr ; ip route ; resolvectl status ou cat /etc/resolv.conf ; ping gateway
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. network/mdns-avahi
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Publication mDNS Avahi
|
||||||
|
Description : installe et configure avahi pour ameliorer la detection de la machine sur le reseau local
|
||||||
|
Categorie : network
|
||||||
|
Questions : faut-il publier le nom de la machine en .local et activer la decouverte des services ?
|
||||||
|
Methode installation : installer avahi-daemon, activer le service, verifier la publication locale
|
||||||
|
Tests : systemctl is-active avahi-daemon ; avahi-browse -a ; ping <hostname>.local
|
||||||
|
Difficulte : faible
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. network/ssh-server
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Serveur SSH
|
||||||
|
Description : installe et active openssh-server pour l'administration distante
|
||||||
|
Categorie : network
|
||||||
|
Questions : faut-il autoriser l'authentification par mot de passe, desactiver root login, changer le port ou rester sur le port standard ?
|
||||||
|
Methode installation : installer openssh-server, activer le service, appliquer des reglages de securite minimum
|
||||||
|
Tests : systemctl is-active ssh ; ss -ltnp | grep ':22' ; ssh -V
|
||||||
|
Difficulte : faible
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. network/samba-share
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Partage Samba public
|
||||||
|
Description : installe samba et partage /home/gilles sur le reseau local en acces public si valide
|
||||||
|
Categorie : network
|
||||||
|
Questions : partage public reellement souhaite, acces lecture seule ou lecture/ecriture, workgroup, impact securite acceptable ?
|
||||||
|
Methode installation : installer samba, creer une definition de partage dediee, ajuster les permissions du dossier cible, redemarrer les services
|
||||||
|
Tests : testparm -s ; systemctl is-active smbd ; smbclient -L localhost -N
|
||||||
|
Difficulte : moyenne a elevee
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8. network/nfs-client
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Client NFS
|
||||||
|
Description : installe les paquets permettant de monter des partages NFS distants
|
||||||
|
Categorie : network
|
||||||
|
Questions : faut-il proposer un montage permanent ou seulement preparer les outils client ?
|
||||||
|
Methode installation : installer les utilitaires NFS client et preparer une base de configuration si necessaire
|
||||||
|
Tests : command -v mount.nfs ; showmount -e <serveur>
|
||||||
|
Difficulte : faible
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9. network/nfs-server
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Serveur NFS
|
||||||
|
Description : installe et configure un export NFS pour le reseau local
|
||||||
|
Categorie : network
|
||||||
|
Questions : quel dossier exporter, quels hotes autoriser, acces lecture seule ou lecture/ecriture ?
|
||||||
|
Methode installation : installer nfs-kernel-server, definir un export explicite, recharger la configuration
|
||||||
|
Tests : systemctl is-active nfs-server ou nfs-kernel-server ; exportfs -v ; showmount -e localhost
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10. network/ftp-server
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Serveur FTP
|
||||||
|
Description : installe un serveur FTP si le besoin est confirme
|
||||||
|
Categorie : network
|
||||||
|
Questions : le besoin existe-t-il vraiment alors que SSH permet deja SFTP plus proprement ?
|
||||||
|
Methode installation : a definir uniquement si le besoin est maintenu apres validation
|
||||||
|
Tests : a definir
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : en attente de validation
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11. boot/grub-theme
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Theme GRUB
|
||||||
|
Description : configure GRUB pour utiliser un theme present dans assets/grub
|
||||||
|
Categorie : boot
|
||||||
|
Questions : quel theme choisir, faut-il memoriser la derniere entree selectionnee, faut-il modifier le timeout ou la resolution ?
|
||||||
|
Methode installation : lister les themes disponibles, copier ou referencer le theme choisi, mettre a jour la configuration GRUB puis regenerer la configuration
|
||||||
|
Tests : grep GRUB_THEME /etc/default/grub ; update-grub ; verification visuelle au reboot
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12. hardware/detect
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Detection hardware
|
||||||
|
Description : detecte le materiel et prepare des recommandations de paquets ou de configuration
|
||||||
|
Categorie : hardware
|
||||||
|
Questions : quels outils retenir pour un premier niveau fiable : lshw, lspci, lsusb, dmidecode, inxi ?
|
||||||
|
Methode installation : installer les outils de detection retenus, produire un resume lisible, preparer une table de recommandations
|
||||||
|
Tests : lshw -short ; lspci ; lsusb ; dmidecode -t system
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
### 13. containers/docker-engine
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nom : Installation de Docker Engine
|
||||||
|
Description : installe Docker Engine sur Debian via la methode officielle Docker
|
||||||
|
Categorie : containers
|
||||||
|
Questions : faut-il suivre strictement le depot officiel Docker, supprimer les paquets en conflit, activer le service au boot, ajouter gilles au groupe docker, creer /home/gilles/docker ?
|
||||||
|
Methode installation : suivre la documentation officielle Debian, ajouter le depot Docker, installer docker-ce et plugins, ajouter gilles au groupe docker, creer /home/gilles/docker
|
||||||
|
Tests : docker --version ; docker compose version ; systemctl is-active docker ; docker run hello-world
|
||||||
|
Difficulte : moyenne
|
||||||
|
Statut : implemente
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ordre de dev recommande
|
||||||
|
|
||||||
|
1. system/user-sudo
|
||||||
|
2. system/user-groups
|
||||||
|
3. network/ssh-server
|
||||||
|
4. network/mdns-avahi
|
||||||
|
5. network/identity
|
||||||
|
6. network/ip-config
|
||||||
|
7. containers/docker-engine
|
||||||
|
8. boot/grub-theme
|
||||||
|
9. hardware/detect
|
||||||
|
10. network/samba-share
|
||||||
|
11. network/nfs-client
|
||||||
|
12. network/nfs-server
|
||||||
|
13. network/ftp-server
|
||||||
Reference in New Issue
Block a user