diff --git a/script/todo/qemu_deploy_form.py b/script/todo/qemu_deploy_form.py index e982af9..1f1f83e 100644 --- a/script/todo/qemu_deploy_form.py +++ b/script/todo/qemu_deploy_form.py @@ -166,6 +166,9 @@ def apply_profile( # spec entière depuis qu'il se choisit machine par machine ; # `desktop` n'est plus que le défaut commun. "desktop": desktop, + # Branche ERPLibre. Même raison : « » signifie « celle du + # formulaire », et une surcharge la remplace pour cette VM. + "branch": "", } ) return out @@ -861,6 +864,11 @@ def run_deploy_form(ctx, run_app: bool = True): def _mise_usable(self): return any(vm["arch"] in mise_arches for vm in self.vms) + def _branch(self): + """Branche du formulaire : le défaut de chaque VM.""" + value = self.query_one("#f_branch", Select).value + return value if isinstance(value, str) else branches[0] + def _default_desktop(self): """« » pour un serveur, sinon la clé de la saveur choisie.""" """Type de VM par défaut. Chaque rangée peut s'en écarter.""" @@ -983,11 +991,17 @@ def run_deploy_form(ctx, run_app: bool = True): Select( [(b, b) for b in branches], classes="vmbranch", + # Repli sur la branche du FORMULAIRE, jamais sur + # branches[0] : les rangées sont remontées dès que le + # jeu de VM change (une entrée cochée, une copie + # ajoutée, un renommage), et elles retombaient alors + # toutes sur « develop » quel que soit le choix commun. value=( - item.get("branch") - or self.rows[i]["vm"].get("branch") - or branches[0] - ), + self.rows[i]["vm"].get("branch") + if i < len(self.rows) + else "" + ) + or self._branch(), allow_blank=False, id=f"v{i}_branch", ), @@ -1322,6 +1336,19 @@ def run_deploy_form(ctx, run_app: bool = True): # suivra donc le profil s'il change — ce qui est aussi le plus # attendu quand on n'a rien changé de visible. vm_now = self.rows[index]["vm"] + if field == "branch": + # « la branche du formulaire » n'est pas une surcharge : + # la VM doit suivre si on la change en haut. + current = vm_now.get("branch") or self._branch() + if event.value == current: + return + self._set_override( + index, + "branch", + "" if event.value == self._branch() else event.value, + ) + self._recompute() + return if field == "type": new_desk = "" if event.value == SERVER else event.value if new_desk == (vm_now.get("desktop") or ""): diff --git a/script/todo/todo.py b/script/todo/todo.py index db3253e..c706508 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -4898,8 +4898,12 @@ class TODO: # commande distante en dépend, donc elle se construit par VM ; celle-ci # reste le défaut pour les noms absents du dict. desk_map = desktop if isinstance(desktop, dict) else {} + # Même contrat que `desktop` : une chaîne pour tout le parc, ou + # une carte {nom: branche} quand elles diffèrent d'une VM à l'autre. + branch_map = branch if isinstance(branch, dict) else {} + branch_def = "" if branch_map else branch remote = self._qemu_erplibre_remote_cmd( - branch, + branch_def, final_cmd, prod, "" if desk_map else desktop, @@ -4928,9 +4932,9 @@ class TODO: "version": v, "arch": a, } - if desk_map: + if desk_map or branch_map: entry["remote_cmd"] = self._qemu_erplibre_remote_cmd( - branch, + branch_map.get(name, branch_def), final_cmd, prod, desk_map.get(name, ""), @@ -4943,7 +4947,9 @@ class TODO: if not vms: print(t("No VM to install.")) return - manifest = launch_installs(vms, branch, remote) + manifest = launch_installs( + vms, branch_def or next(iter(branch_map.values()), ""), remote + ) print(f"\n🖥 {t('Opening the interactive monitor...')}") # Affiche tous les chemins de log (pour les consulter/partager même si # on quitte le dashboard avant la fin). @@ -6291,6 +6297,14 @@ class TODO: desktop = next((d for d in desktop_map.values() if d), "") python_provider = spec.get("python_provider") or "" app_store = spec.get("app_store") or "deb" + # Branche par VM : « » sur une VM veut dire « celle du formulaire ». + branch_map = { + vm["name"]: (vm.get("branch") or install_branch or "") + for vm in pending + } + for _n in deployed: + branch_map.setdefault(_n, install_branch or "") + branch_multi = len(set(branch_map.values())) > 1 ssh_key = spec.get("ssh_key") add_ssh_config = spec["add_ssh_config"] parallelism = spec["parallelism"] @@ -6360,7 +6374,7 @@ class TODO: # Installs détachées en parallèle + dashboard Textual. self._qemu_install_erplibre_monitored( deployed, - install_branch, + branch_map if branch_multi else install_branch, ip_map, install["cmd"] if install else None, install["prod"] if install else False,