diff --git a/script/todo/qemu_deploy_form.py b/script/todo/qemu_deploy_form.py index 04a787d..61c5397 100644 --- a/script/todo/qemu_deploy_form.py +++ b/script/todo/qemu_deploy_form.py @@ -370,6 +370,8 @@ def run_deploy_form(ctx, run_app: bool = True): # livrent snapd — la question n'a de sens que pour celles-là, graphiques. app_stores = list(ctx.get("app_stores") or []) snap_distros = set(ctx.get("snap_distros") or ()) + # Fuseaux proposés, celui de l'hôte en tête (voir todo.py). + timezones = list(ctx.get("timezones") or []) defaults = ctx.get("defaults") or {} result = {"spec": None} @@ -683,10 +685,23 @@ def run_deploy_form(ctx, run_app: bool = True): id="f_monitor", ) yield Static(t("Timezone"), classes="grouptitle") + # Une liste plutôt qu'une saisie : un nom IANA mal + # orthographié n'est pas refusé par cloud-init, il est + # IGNORÉ — la VM reste en UTC et on ne s'en aperçoit + # qu'aux horodatages. « libre… » garde la porte ouverte + # aux six cents autres fuseaux de la base. + yield Select( + [(z, z) for z in timezones] + + [(t("free value…"), FREE)], + value=(timezones[0] if timezones else SELECT_NULL), + allow_blank=False, + id="f_tz_sel", + ) yield Input( value=ctx.get("timezone") or "", placeholder=t("Timezone for the VMs"), id="f_tz", + classes="freeval", ) yield Static("SSH", classes="grouptitle") yield Input( @@ -1452,6 +1467,19 @@ def run_deploy_form(ctx, run_app: bool = True): # ci-dessous sans rien recalculer, et les rangées restaient sur # l'ancienne version. Elles n'en gardent pas de copie — « » y # veut dire « celle du formulaire » — il suffit de redessiner. + if event.select.id == "f_tz_sel": + # « libre… » révèle la saisie ; un fuseau choisi la referme et + # y recopie le nom, seule valeur que lisent _form_values et la + # spec — un seul endroit porte la réponse. + free = event.value is FREE + field = self.query_one("#f_tz", Input) + field.display = free + field.disabled = not free + if free: + field.focus() + elif isinstance(event.value, str): + field.value = event.value + return if event.select.id in ("f_branch", "f_profile_install"): self._clear_overrides( ("branch",) diff --git a/script/todo/todo.py b/script/todo/todo.py index 7e6528a..949ab41 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -4413,6 +4413,52 @@ class TODO: ) QEMU_SNAP_DISTROS = ("ubuntu",) + # Fuseaux proposés au déploiement. Des NOMS IANA, pas des décalages : + # cloud-init écrit /etc/timezone et refuse « UTC-5 », qui ne dit d'ailleurs + # rien de l'heure d'été. Un nom porte ses propres règles de bascule. + # + # Liste courte et ordonnée par usage réel plutôt qu'exhaustive : la base + # IANA en compte près de six cents, illisibles dans une liste déroulante. + # Le Québec d'abord, le reste du Canada ensuite, puis les places qu'on + # rencontre en pratique. La saisie libre reste offerte pour le reste. + QEMU_TIMEZONES = ( + "America/Montreal", + "America/Toronto", + "America/Halifax", + "America/Winnipeg", + "America/Edmonton", + "America/Vancouver", + "America/St_Johns", + "UTC", + "America/New_York", + "America/Chicago", + "America/Denver", + "America/Los_Angeles", + "America/Sao_Paulo", + "Europe/London", + "Europe/Paris", + "Europe/Brussels", + "Europe/Zurich", + "Europe/Madrid", + "Europe/Berlin", + "Africa/Casablanca", + "Asia/Dubai", + "Asia/Kolkata", + "Asia/Shanghai", + "Asia/Tokyo", + "Australia/Sydney", + ) + + @classmethod + def _qemu_timezone_choices(cls, current=""): + """Liste à proposer : le fuseau de l'hôte en tête, sans doublon. + + Le mettre en premier plutôt que de le supposer présent : une machine + hors de cette liste doit quand même voir le sien en un coup d'œil.""" + out = [current] if current else [] + out += [z for z in cls.QEMU_TIMEZONES if z != current] + return out + @classmethod def _qemu_desktop_suffixes(cls): """{clé de saveur: suffixe de nom}. La TUI le reçoit par son contexte @@ -5762,6 +5808,9 @@ class TODO: "desktop_disk_gb": self.QEMU_DESKTOP_EXTRA_DISK_GB, "mise_arches": self.QEMU_MISE_ARCHES, "app_stores": [(k, t(lbl)) for k, lbl in self.QEMU_APP_STORES], + "timezones": self._qemu_timezone_choices( + self._qemu_host_timezone() + ), "snap_distros": self.QEMU_SNAP_DISTROS, "desktop_suffixes": self._qemu_desktop_suffixes(), "desktops": [