Fenêtres de maintenance pour les installations¶
Les fenêtres de maintenance restreignent les moments où POST /install/jobs est autorisé à réellement pousser des paquets vers une machine — définies par tag d'inventaire ou en tant qu'override par machine. Une machine sans fenêtre applicable exécute les installations immédiatement, exactement comme avant l'existence de cette fonctionnalité ; ajouter une fenêtre est ce qui active la restriction.
1. Prérequis¶
- Le rôle
adminpour créer ou supprimer des fenêtres. Lister les fenêtres existantes ne nécessite que le rôleauditorou supérieur. - Connaître le nom de fuseau horaire IANA pour la fenêtre (ex.
Europe/Paris,America/New_York) — les fenêtres sont stockées en heure locale (horloge murale) plus un fuseau horaire nommé, et non un décalage UTC fixe, de sorte que le passage à l'heure d'été/hiver (DST) est géré automatiquement. - Décidez si vous ciblez un tag (toutes les machines qui le portent) ou une machine spécifique (un override qui remplace intégralement les fenêtres issues des tags de cette machine, sans jamais fusionner avec elles).
Ouvert par défaut
Une machine sans fenêtre de tag et sans override client exécute les jobs d'installation immédiatement, à tout moment — comportement inchangé pour les parcs qui ne configurent jamais cette fonctionnalité.
2. Vérifier les fenêtres existantes¶
curl -s http://repod.example.com:8000/api/v1/inventory/maintenance-windows \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .
Filtrer par principal :
curl -s "http://repod.example.com:8000/api/v1/inventory/maintenance-windows?principal_type=tag&principal_id=prod" \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .
3. Créer une fenêtre¶
curl -s -X POST http://repod.example.com:8000/api/v1/inventory/maintenance-windows \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"principal_type": "tag",
"principal_id": "prod",
"days": ["mon", "tue", "wed", "thu", "fri"],
"start_time": "02:00",
"end_time": "04:00",
"timezone": "Europe/Paris"
}' | jq .
| Champ | Valeurs | Signification |
|---|---|---|
principal_type |
tag | client |
Indique si cette fenêtre s'applique à toutes les machines portant un tag, ou remplace celle d'une machine spécifique |
principal_id |
chaîne | Le nom du tag (ex. prod), ou l'id du client, selon principal_type |
days |
liste de mon|tue|wed|thu|fri|sat|sun |
Les jours de la semaine où la fenêtre est ouverte |
start_time |
"HH:MM" |
Heure de début locale |
end_time |
"HH:MM" |
Heure de fin locale. Si antérieure à start_time, la fenêtre franchit minuit. |
timezone |
nom IANA | ex. Europe/Paris, UTC |
Réponse (201) :
{
"window": {
"id": "...",
"principal_type": "tag",
"principal_id": "prod",
"days": ["mon", "tue", "wed", "thu", "fri"],
"start_time": "02:00",
"end_time": "04:00",
"timezone": "Europe/Paris",
"created_by": "admin",
"created_at": "..."
}
}
Exemple complet — n'autoriser les installations sur les machines prod que du lundi au vendredi de 02h00 à 04h00, Europe/Paris :
Le POST ci-dessus fait exactement cela. À partir de ce moment :
POST /install/jobsciblant une machine taguéeprod(viatarget_idsoutarget_tags) est accepté immédiatement si l'heure actuelle àEurope/Parisse situe dans une fenêtre correspondante ; sinon le job est créé mais son thread d'arrière-plan bloque à l'étapewaiting_windowjusqu'à l'ouverture de la fenêtre (ou l'annulation du job).- La fenêtre effective d'un job, lorsque plusieurs machines ciblées sont impliquées, est l'intersection des fenêtres de toutes les machines ciblées — les machines sans aucune fenêtre ne contraignent pas l'intersection.
- Si l'intersection ne peut jamais être satisfaite — par exemple si deux machines ciblées ont des fenêtres sur des jours entièrement disjoints —
POST /install/jobsrenvoie immédiatement409plutôt que de mettre en file d'attente indéfiniment :
Une fenêtre client remplace les fenêtres de tag, elle ne fusionne jamais avec elles
Une fenêtre principal_type: "client" pour une machine spécifique remplace intégralement les fenêtres issues des tags de cette machine — les fenêtres de tag ne sont pas combinées avec elle. Cela reflète la même convention « override remplace, ne fusionne jamais » utilisée par machine_access (voir Restreindre l'accès aux distributions & aux machines). Pour donner à une machine prod un planning de maintenance différent du reste du parc, créez une fenêtre de type client référençant son id ; il n'est pas nécessaire de supprimer d'abord la fenêtre au niveau du tag.
4. Fenêtres franchissant minuit¶
Un end_time antérieur à start_time est interprété comme franchissant minuit :
curl -s -X POST http://repod.example.com:8000/api/v1/inventory/maintenance-windows \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"principal_type": "tag",
"principal_id": "batch-nodes",
"days": ["sat", "sun"],
"start_time": "23:00",
"end_time": "01:00",
"timezone": "UTC"
}' | jq .
Cette fenêtre est ouverte de 23h00 le samedi à 01h00 le dimanche, puis à nouveau de 23h00 le dimanche à 01h00 le lundi.
5. Supprimer une fenêtre¶
curl -s -X DELETE http://repod.example.com:8000/api/v1/inventory/maintenance-windows/<window_id> \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx"
Renvoie 204 en cas de succès, 404 si la fenêtre n'existe pas. Supprimer la dernière fenêtre d'un tag/d'une machine la rouvre aux installations à tout moment.
6. Vérifier que ça a fonctionné¶
En dehors de la fenêtre — créer un job ciblant uniquement des machines taguées prod doit soit attendre, soit, si aucune fenêtre commune n'existe du tout entre les cibles, échouer rapidement :
curl -s -X POST http://repod.example.com:8000/api/v1/install/jobs \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"package_name": "nginx",
"package_version": "1.24.0-1",
"target_tags": ["prod"]
}' | jq .
# Interroger le statut du job — attendu : step="waiting_window" en dehors de 02:00-04:00 Europe/Paris
curl -s http://repod.example.com:8000/api/v1/install/jobs/<job_id> \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq '.step'
À l'intérieur de la fenêtre — la même requête doit passer directement au flux dry-run/confirmation, sans jamais signaler waiting_window.
Fenêtres disjointes entre les cibles — cibler deux machines dont les fenêtres ne se chevauchent jamais doit échouer immédiatement avec 409, sans jamais rester bloqué :
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://repod.example.com:8000/api/v1/install/jobs \
-H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"package_name": "nginx",
"target_ids": ["<id-machine-A-avec-fenêtre-lundi>", "<id-machine-B-avec-fenêtre-mardi-uniquement>"]
}'
# → 409