Dimensionner les ressources VM depuis les logiciels hébergés
Les cœurs/RAM/disque d'une VM sont estimés depuis l'empreinte des rôles hébergés (roles/<rôle>/meta/empreinte.yml) sommée au socle SE, au lieu d'hériter des specs du golden template. Le générateur écrit proxmox_coeurs/memoire/disque_taille ; le clonage les passe à Proxmox (omit si absent → aucune régression). Override par hôte dans le plan. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c77ec20e4a
commit
5d30a3a608
20 changed files with 293 additions and 0 deletions
4
Makefile
4
Makefile
|
|
@ -325,6 +325,8 @@ cloner-vm: ansible-runtime
|
|||
[[ -n "$(FORMAT_DISQUE)" ]] && extra_vars+=( -e proxmox_clone_format="$(FORMAT_DISQUE)" ); \
|
||||
[[ -n "$(CLONE_COMPLET)" ]] && extra_vars+=( -e proxmox_clone_complet="$(CLONE_COMPLET)" ); \
|
||||
[[ -n "$(TAILLE_DISQUE)" ]] && extra_vars+=( -e proxmox_clone_taille_disque="$(TAILLE_DISQUE)" ); \
|
||||
[[ -n "$(COEURS)" ]] && extra_vars+=( -e proxmox_clone_coeurs="$(COEURS)" ); \
|
||||
[[ -n "$(MEMOIRE)" ]] && extra_vars+=( -e proxmox_clone_memoire="$(MEMOIRE)" ); \
|
||||
[[ -n "$(DISQUE_PROXMOX)" ]] && extra_vars+=( -e proxmox_clone_disque="$(DISQUE_PROXMOX)" ); \
|
||||
[[ -n "$(DNS)" ]] && extra_vars+=( -e proxmox_clone_dns="$(DNS)" ); \
|
||||
[[ -n "$(CIUSER)" ]] && extra_vars+=( -e proxmox_clone_ciuser="$(CIUSER)" ); \
|
||||
|
|
@ -363,6 +365,8 @@ creer-vm: _instance-requise
|
|||
VLAN="$$SETOPS_VLAN" \
|
||||
STOCKAGE_PROXMOX="$${SETOPS_STOCKAGE:-$(STOCKAGE_PROXMOX)}" \
|
||||
TAILLE_DISQUE="$${SETOPS_DISQUE:-$(TAILLE_DISQUE)}" \
|
||||
COEURS="$${SETOPS_COEURS:-$(COEURS)}" \
|
||||
MEMOIRE="$${SETOPS_MEMOIRE:-$(MEMOIRE)}" \
|
||||
NOEUD_PROXMOX="$${SETOPS_NOEUD:-$(NOEUD_PROXMOX)}" \
|
||||
VMID_MODELE="$(VMID_MODELE)" \
|
||||
FORMAT_DISQUE="$(FORMAT_DISQUE)" \
|
||||
|
|
|
|||
102
docs/dimensionnement-ressources.md
Normal file
102
docs/dimensionnement-ressources.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Dimensionnement dérivé des ressources VM
|
||||
|
||||
Ce document décrit comment Set-OPS **estime les ressources d'une VM** (cœurs, RAM,
|
||||
disque) à partir des **propriétés des logiciels** qu'elle héberge et du **socle SE**,
|
||||
plutôt que de laisser chaque clone hériter aveuglément des specs du golden template.
|
||||
|
||||
> Décision actée le 2026-06-25 : extension assumée de la *modélisation* du plan de
|
||||
> contrôle (cf. `positionnement.md`). C'est le prolongement naturel de la dérivation
|
||||
> réseau (`nomenclature.yml`) — du dimensionnement, pas une fonction de type NetBox.
|
||||
|
||||
## Principe
|
||||
|
||||
```
|
||||
ressources(VM) = socle_SE + Σ empreinte(logiciel hébergé) → marge → arrondi
|
||||
```
|
||||
|
||||
Précédence (du plus fort au plus faible) :
|
||||
1. **Valeur explicite par hôte** dans `serveurs.yml` (`coeurs` / `memoire` / `disque`) — gagne toujours.
|
||||
2. **Valeur dérivée** (socle + empreintes + marge + arrondi) sinon.
|
||||
|
||||
Comme Ansible/Proxmox sont idempotents, ajuster une empreinte puis régénérer ne fait
|
||||
que recalculer la cible ; aucune dérive silencieuse.
|
||||
|
||||
## Où vit chaque donnée
|
||||
|
||||
| Donnée | Emplacement | Remarque |
|
||||
| --- | --- | --- |
|
||||
| Empreinte d'un logiciel | `roles/<groupe>/meta/empreinte.yml` | Propriété du logiciel, voyage avec le rôle. Fichier *pur données* (parsable sans Jinja). |
|
||||
| Groupes sans rôle dédié | `EMPREINTES_SANS_ROLE` dans `scripts/inventory_rules.py` | p. ex. `serveur_web_frontal`, `serveur_web_dorsal`. |
|
||||
| Repli ultime | `EMPREINTE_DEFAUT` | groupe inconnu : empreinte minimale. |
|
||||
| Socle SE | `SOCLE_SE` dans `inventory_rules.py` | coût de base Debian durci. |
|
||||
| Override par hôte | `serveurs.yml` (`coeurs`/`memoire`/`disque`) | déjà supporté par le générateur (`PLACEMENT`). |
|
||||
| Politique (marges, paliers, plafonds) | constantes en tête de `inventory_rules.py` | |
|
||||
|
||||
Format d'une empreinte (`roles/<rôle>/meta/empreinte.yml`) :
|
||||
```yaml
|
||||
setops_empreinte: { coeurs: 2, memoire_mo: 2048, disque_go: 20 }
|
||||
```
|
||||
|
||||
## Règles d'agrégation (valeurs en vigueur)
|
||||
|
||||
- **Socle SE** : 1 cœur / 512 Mo / 8 Go.
|
||||
- **RAM** : `(socle + Σ rôles) × 1.20`, arrondie au palier **512 Mo**, **min 1024 Mo**.
|
||||
- **Disque** : `(socle + Σ rôles) × 1.25`, arrondi au palier **5 Go**, **min 12 Go**,
|
||||
émis sous la forme `"<n>G"`.
|
||||
- **Cœurs** : `max(socle, Σ rôles)`, entier, **min 1**, **plafond 8** (CPU *burstable* :
|
||||
ni additif strict, ni marge).
|
||||
|
||||
Seuls les **groupes de service** de l'hôte (issus de `applications.yml`) entrent dans
|
||||
la somme. Le socle (`serveur_debian`/`serveur_durci`) et les groupes d'état sont exclus.
|
||||
|
||||
## Chaîne technique
|
||||
|
||||
1. `scripts/inventory_rules.py` — `deriver_ressources(groupes_service, racine_roles)`
|
||||
lit les empreintes et calcule.
|
||||
2. `scripts/instancier.py` — pour chaque hôte, écrit `proxmox_coeurs`,
|
||||
`proxmox_memoire`, `proxmox_disque_taille` dans l'inventaire généré
|
||||
(via `setdefault` : un override `serveurs.yml` prime).
|
||||
3. `scripts/inventory_host.py` — `parametres-proxmox` émet `SETOPS_COEURS` /
|
||||
`SETOPS_MEMOIRE` / `SETOPS_DISQUE` lus par `make creer-vm`.
|
||||
4. `Makefile` (`creer-vm` → `cloner-vm`) relaie vers `proxmox_clone_coeurs` /
|
||||
`proxmox_clone_memoire`.
|
||||
5. `playbooks/proxmox/cloner_vm_debian.yml` — passe `cores`/`memory` à `proxmox_kvm`
|
||||
(avec `omit` si absent : aucune régression, on garde alors les specs du template).
|
||||
|
||||
## Empreintes actuelles
|
||||
|
||||
| Rôle | cœurs | RAM (Mo) | disque (Go) |
|
||||
| --- | --- | --- | --- |
|
||||
| serveur_step_ca | 1 | 256 | 2 |
|
||||
| serveur_powerdns | 1 | 512 | 2 |
|
||||
| serveur_sendmail | 1 | 512 | 5 |
|
||||
| serveur_nginx | 1 | 512 | 3 |
|
||||
| serveur_openldap | 1 | 512 | 3 |
|
||||
| serveur_keycloak | 2 | 1536 | 5 |
|
||||
| serveur_postgresql | 2 | 2048 | 20 |
|
||||
| serveur_redis | 1 | 512 | 2 |
|
||||
| serveur_forgejo | 1 | 1024 | 20 |
|
||||
| serveur_prometheus | 1 | 1024 | 20 |
|
||||
| serveur_loki | 1 | 1024 | 20 |
|
||||
| serveur_grafana | 1 | 512 | 2 |
|
||||
| serveur_icinga | 2 | 1024 | 10 |
|
||||
| serveur_web_frontal (repli) | 1 | 512 | 5 |
|
||||
| serveur_web_dorsal (repli) | 1 | 1024 | 10 |
|
||||
|
||||
## Ajuster
|
||||
|
||||
- **Une empreinte de logiciel** : éditer `roles/<rôle>/meta/empreinte.yml`.
|
||||
- **Un hôte précis** : poser `coeurs`/`memoire`/`disque` sur le serveur dans
|
||||
`serveurs.yml` (l'override prime sur la dérivation).
|
||||
- **La politique** (marges, paliers, socle, plafond) : constantes en tête de
|
||||
`inventory_rules.py`.
|
||||
|
||||
Puis : `make instancier` (voir le diff), `make instancier-appliquer` (FORCE=1 si
|
||||
changement intentionnel).
|
||||
|
||||
## Limite connue
|
||||
|
||||
Les ressources s'appliquent **à la création de la VM** (clonage). Modifier une
|
||||
empreinte n'**ajuste pas** automatiquement une VM déjà existante : il faut un
|
||||
re-clonage ou un redimensionnement Proxmox manuel. Le **plan**, lui, reste la source
|
||||
de vérité et se régénère à volonté.
|
||||
|
|
@ -121,6 +121,8 @@
|
|||
vmid: "{{ proxmox_clone_vmid_modele | int }}"
|
||||
newid: "{{ proxmox_clone_vmid | int }}"
|
||||
name: "{{ proxmox_clone_nom }}"
|
||||
cores: "{{ proxmox_clone_coeurs | int if proxmox_clone_coeurs is defined and proxmox_clone_coeurs | string | length > 0 else omit }}"
|
||||
memory: "{{ proxmox_clone_memoire | int if proxmox_clone_memoire is defined and proxmox_clone_memoire | string | length > 0 else omit }}"
|
||||
storage: "{{ proxmox_clone_stockage | default(omit, true) }}"
|
||||
format: "{{ proxmox_clone_format | default(omit, true) }}"
|
||||
full: "{{ proxmox_clone_complet | default(true) | bool }}"
|
||||
|
|
|
|||
8
roles/serveur_forgejo/meta/empreinte.yml
Normal file
8
roles/serveur_forgejo/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 1024
|
||||
disque_go: 20
|
||||
8
roles/serveur_grafana/meta/empreinte.yml
Normal file
8
roles/serveur_grafana/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 2
|
||||
8
roles/serveur_icinga/meta/empreinte.yml
Normal file
8
roles/serveur_icinga/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 2
|
||||
memoire_mo: 1024
|
||||
disque_go: 10
|
||||
8
roles/serveur_keycloak/meta/empreinte.yml
Normal file
8
roles/serveur_keycloak/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 2
|
||||
memoire_mo: 1536
|
||||
disque_go: 5
|
||||
8
roles/serveur_loki/meta/empreinte.yml
Normal file
8
roles/serveur_loki/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 1024
|
||||
disque_go: 20
|
||||
8
roles/serveur_nginx/meta/empreinte.yml
Normal file
8
roles/serveur_nginx/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 3
|
||||
8
roles/serveur_openldap/meta/empreinte.yml
Normal file
8
roles/serveur_openldap/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 3
|
||||
8
roles/serveur_postgresql/meta/empreinte.yml
Normal file
8
roles/serveur_postgresql/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 2
|
||||
memoire_mo: 2048
|
||||
disque_go: 20
|
||||
8
roles/serveur_powerdns/meta/empreinte.yml
Normal file
8
roles/serveur_powerdns/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 2
|
||||
8
roles/serveur_prometheus/meta/empreinte.yml
Normal file
8
roles/serveur_prometheus/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 1024
|
||||
disque_go: 20
|
||||
8
roles/serveur_redis/meta/empreinte.yml
Normal file
8
roles/serveur_redis/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 2
|
||||
8
roles/serveur_sendmail/meta/empreinte.yml
Normal file
8
roles/serveur_sendmail/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 512
|
||||
disque_go: 5
|
||||
8
roles/serveur_step_ca/meta/empreinte.yml
Normal file
8
roles/serveur_step_ca/meta/empreinte.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py).
|
||||
# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote.
|
||||
# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque).
|
||||
setops_empreinte:
|
||||
coeurs: 1
|
||||
memoire_mo: 256
|
||||
disque_go: 2
|
||||
|
|
@ -30,10 +30,12 @@ from inventory_rules import (
|
|||
charger_nomenclature,
|
||||
charger_serveurs,
|
||||
deriver_nomenclature,
|
||||
deriver_ressources,
|
||||
fonction_seq,
|
||||
)
|
||||
|
||||
RACINE = Path(__file__).resolve().parents[1]
|
||||
ROLES = RACINE / "roles"
|
||||
INSTANCE = Path(os.environ.get("SETOPS_INSTANCE") or (RACINE / "instance"))
|
||||
INVENTAIRE = INSTANCE / "inventories/production/hosts.yml"
|
||||
GENERE = INSTANCE / "inventories/production/hosts.genere.yml"
|
||||
|
|
@ -75,6 +77,12 @@ def generer() -> dict:
|
|||
for cle_srv, cle_var in PLACEMENT:
|
||||
if str(srv.get(cle_srv, "")).strip():
|
||||
hostvars[cle_var] = srv[cle_srv]
|
||||
# Ressources derivees des logiciels (groupes de service) + socle SE.
|
||||
# setdefault : une valeur explicite du plan (PLACEMENT ci-dessus) gagne.
|
||||
ressources = deriver_ressources(sorted(services_par_hote.get(nom, set())), ROLES)
|
||||
hostvars.setdefault("proxmox_coeurs", ressources["coeurs"])
|
||||
hostvars.setdefault("proxmox_memoire", ressources["memoire"])
|
||||
hostvars.setdefault("proxmox_disque_taille", ressources["disque"])
|
||||
etat = "hotes_actifs" if srv.get("etat") == "actif" else "hotes_planifies"
|
||||
children[etat]["hosts"][nom] = hostvars
|
||||
groupes = set(GROUPES_SOCLE) | services_par_hote.get(nom, set()) | set(srv.get("integrations") or [])
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ CHAMPS_PROXMOX: tuple[tuple[str, str, bool], ...] = (
|
|||
("SETOPS_STOCKAGE", "proxmox_stockage", False),
|
||||
("SETOPS_DISQUE", "proxmox_disque_taille", False),
|
||||
("SETOPS_NOEUD", "proxmox_noeud", False),
|
||||
("SETOPS_COEURS", "proxmox_coeurs", False),
|
||||
("SETOPS_MEMOIRE", "proxmox_memoire", False),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -385,6 +385,75 @@ def reconcilier_serveur(nom: str, srv: dict, hote_inventaire: dict | None, nomen
|
|||
"absent_inventaire": hote_inventaire is None}
|
||||
|
||||
|
||||
# --- Dimensionnement derive des ressources VM -------------------------------
|
||||
# ressources(VM) = socle_SE + somme(empreinte des logiciels) -> marge -> arrondi.
|
||||
# Les empreintes vivent dans roles/<groupe>/meta/empreinte.yml (propriete du
|
||||
# logiciel). Les groupes sans role dedie ont un repli ci-dessous. Le plan peut
|
||||
# tout surcharger par hote (serveurs.yml: coeurs/memoire/disque).
|
||||
|
||||
SOCLE_SE = {"coeurs": 1, "memoire_mo": 512, "disque_go": 8}
|
||||
EMPREINTE_DEFAUT = {"coeurs": 1, "memoire_mo": 512, "disque_go": 5}
|
||||
EMPREINTES_SANS_ROLE = {
|
||||
"serveur_web_frontal": {"coeurs": 1, "memoire_mo": 512, "disque_go": 5},
|
||||
"serveur_web_dorsal": {"coeurs": 1, "memoire_mo": 1024, "disque_go": 10},
|
||||
}
|
||||
MARGE_MEMOIRE = 1.20
|
||||
MARGE_DISQUE = 1.25
|
||||
PALIER_MEMOIRE_MO = 512
|
||||
MIN_MEMOIRE_MO = 1024
|
||||
PALIER_DISQUE_GO = 5
|
||||
MIN_DISQUE_GO = 12
|
||||
MIN_COEURS = 1
|
||||
MAX_COEURS = 8
|
||||
CHAMPS_EMPREINTE = ("coeurs", "memoire_mo", "disque_go")
|
||||
|
||||
|
||||
def charger_empreinte_role(racine_roles: Path, groupe: str) -> dict | None:
|
||||
"""Lit roles/<groupe>/meta/empreinte.yml -> empreinte normalisee, ou None."""
|
||||
fichier = racine_roles / groupe / "meta" / "empreinte.yml"
|
||||
if not fichier.exists():
|
||||
return None
|
||||
with fichier.open("r", encoding="utf-8") as fh:
|
||||
data = yaml.safe_load(fh) or {}
|
||||
emp = (data or {}).get("setops_empreinte") or {}
|
||||
if not isinstance(emp, dict):
|
||||
raise ValueError(f"{fichier}: 'setops_empreinte' doit etre une table.")
|
||||
return {cle: int(emp.get(cle, 0)) for cle in CHAMPS_EMPREINTE}
|
||||
|
||||
|
||||
def empreinte_groupe(racine_roles: Path, groupe: str) -> dict:
|
||||
"""Empreinte d'un groupe de service : role > repli connu > defaut."""
|
||||
return (charger_empreinte_role(racine_roles, groupe)
|
||||
or EMPREINTES_SANS_ROLE.get(groupe)
|
||||
or EMPREINTE_DEFAUT)
|
||||
|
||||
|
||||
def _arrondi_superieur(valeur: float, palier: int) -> int:
|
||||
import math
|
||||
return int(math.ceil(valeur / palier) * palier)
|
||||
|
||||
|
||||
def deriver_ressources(groupes_service, racine_roles: Path, socle: dict | None = None) -> dict:
|
||||
"""Estime coeurs/memoire(Mo)/disque(Go) d'une VM depuis ses logiciels + le SE.
|
||||
|
||||
`groupes_service` : groupes applicatifs portes par l'hote (hors socle/etat).
|
||||
RAM et disque additifs (contraintes dures) ; coeurs en max (burstable).
|
||||
"""
|
||||
socle = socle or SOCLE_SE
|
||||
coeurs_somme = 0
|
||||
memoire = socle["memoire_mo"]
|
||||
disque = socle["disque_go"]
|
||||
for groupe in groupes_service:
|
||||
emp = empreinte_groupe(racine_roles, groupe)
|
||||
coeurs_somme += emp["coeurs"]
|
||||
memoire += emp["memoire_mo"]
|
||||
disque += emp["disque_go"]
|
||||
coeurs = max(MIN_COEURS, min(MAX_COEURS, max(socle["coeurs"], coeurs_somme)))
|
||||
memoire = max(MIN_MEMOIRE_MO, _arrondi_superieur(memoire * MARGE_MEMOIRE, PALIER_MEMOIRE_MO))
|
||||
disque = max(MIN_DISQUE_GO, _arrondi_superieur(disque * MARGE_DISQUE, PALIER_DISQUE_GO))
|
||||
return {"coeurs": coeurs, "memoire": memoire, "disque": f"{disque}G"}
|
||||
|
||||
|
||||
def charger_dependances(path: Path | None) -> dict:
|
||||
if not path:
|
||||
return {}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ def test_hote_complet_avec_noeud() -> None:
|
|||
"SETOPS_STOCKAGE='stockage-a'",
|
||||
"SETOPS_DISQUE='160G'",
|
||||
"SETOPS_NOEUD='noeud-a'",
|
||||
"SETOPS_COEURS='4'",
|
||||
"SETOPS_MEMOIRE='2048'",
|
||||
}
|
||||
assert set(lignes) == attendu, lignes
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue