diff --git a/script/qemu/deploy_qemu.py b/script/qemu/deploy_qemu.py index 491fc47..45e23aa 100755 --- a/script/qemu/deploy_qemu.py +++ b/script/qemu/deploy_qemu.py @@ -1660,6 +1660,26 @@ SERVICE_GUIDE: tuple[tuple[str, str, str], ...] = ( ) +# N'apparaît que sur une VM déployée AVEC un bureau. Vécu : GNOME installé, +# gdm3 installé, cible graphique par défaut… et la console restait en mode texte. +# graphical.target était déjà atteinte quand le paquet est arrivé, et une cible +# active ne rattrape pas un service ajouté après coup. « enable » seul n'y change +# rien sur Debian et Ubuntu — l'unité n'a pas de WantedBy, seulement un alias — +# d'où le « --now », qui démarre. +DESKTOP_GUIDE: tuple[tuple[str, str, str], ...] = ( + ( + "systemctl status display-manager", + "état du bureau graphique", + "graphical desktop state", + ), + ( + "sudo systemctl enable --now gdm", + "le démarrer (« --now » : enable seul ne suffit pas)", + 'start it ("--now": enable alone does nothing)', + ), +) + + def erplibre_guide( el_dir: str, el_make: str = "", editor: str = "" ) -> tuple[tuple[str, str, str], ...]: @@ -1770,11 +1790,14 @@ def build_motd( el_dir: str = "", el_make: str = "", editor: str = "", + desktop: bool = False, ) -> str: """Texte du /etc/motd de la VM. Fonction PURE : aucun I/O, donc testable. La section ERPLibre n'apparaît qu'avec `el_dir` : une VM déployée sans installation ne doit pas annoncer un dépôt et un service qui n'existent pas. + Le bloc « Bureau » suit la même règle avec `desktop` : sur un serveur, ces + deux commandes ne mèneraient à aucune unité. """ body: list[str] = [] mgr = DISTRO_PKG.get(distro, "") @@ -1795,6 +1818,14 @@ def build_motd( body.append("") el_rows = erplibre_guide(el_dir, el_make, editor) body += motd_block("ERPLibre", el_rows, lang, gloss_col(el_rows)) + if desktop: + body.append("") + body += motd_block( + _pick(("Bureau", "Desktop"), lang), + DESKTOP_GUIDE, + lang, + gloss_col(DESKTOP_GUIDE), + ) body.append("") body += motd_block( _pick(("Système", "System"), lang), sys_rows, lang, narrow @@ -2016,6 +2047,7 @@ def guide_files(args: argparse.Namespace) -> list[tuple[str, str, str, str]]: args.erplibre_dir, args.erplibre_make, editor, + bool(args.desktop), ), "", ) diff --git a/test/test_qemu_motd.py b/test/test_qemu_motd.py index 1fde3ff..8156cd9 100644 --- a/test/test_qemu_motd.py +++ b/test/test_qemu_motd.py @@ -352,5 +352,56 @@ class TestInstallerGuideNames(unittest.TestCase): ) +class TestDesktopBlock(unittest.TestCase): + """Le bloc « Bureau » : présent seulement là où un bureau existe. + + Vécu : une VM graphique restait sur une console texte, GNOME installé et + gdm3 installé — graphical.target était déjà atteinte quand le paquet est + arrivé. La commande qui répare tient sur une ligne, encore faut-il la lire + quelque part. Sur un serveur, elle ne mènerait à aucune unité : le bloc + n'y apparaît pas. + """ + + def _motd(self, desktop): + return dq.build_motd( + "ubuntu", + "26.04", + "amd64", + "fr", + "~/git/erplibre", + "install_odoo_18", + "vim", + desktop, + ) + + def test_a_server_gets_no_desktop_block(self): + self.assertNotIn("Bureau", self._motd(False)) + + def test_a_graphical_vm_gets_it(self): + self.assertIn("Bureau", self._motd(True)) + + def test_it_carries_the_command_that_repairs(self): + """« --now » et non « enable » seul : sur Debian et Ubuntu, l'unité n'a + pas de WantedBy, et « enable » rend 0 sans rien faire.""" + motd = self._motd(True) + self.assertIn("systemctl enable --now gdm", motd) + self.assertIn("systemctl status display-manager", motd) + + def test_it_says_why_now_matters(self): + self.assertIn("--now", self._motd(True)) + + def test_it_stays_inside_the_frame(self): + """Le guide est encadré : une ligne trop longue casse la boîte.""" + lines = self._motd(True).splitlines() + width = max(len(line) for line in lines) + border = [line for line in lines if line.startswith("╭")][0] + self.assertEqual(len(border), width) + + def test_the_default_is_no_block(self): + """Un appelant qui n'en sait rien n'annonce pas un bureau.""" + motd = dq.build_motd("ubuntu", "26.04", "amd64", "fr") + self.assertNotIn("Bureau", motd) + + if __name__ == "__main__": unittest.main()