[FIX] script todo: démarrer le bureau, pas seulement l'activer
Une VM graphique restait sur une console texte jusqu'au premier redémarrage. GNOME installé, gdm3 installé, graphical.target par défaut, lien display-manager.service posé par le paquet — et rien à l'écran. Deux causes superposées, mesurées sur erplibre-ubuntu-2604-gnome : graphical.target était DÉJÀ atteinte quand le paquet est arrivé, et une cible active ne rattrape pas un service ajouté après coup. Et « systemctl enable gdm » rend 0 sans rien faire sur Debian et Ubuntu : l'unité n'a pas de « WantedBy », seulement l'alias que le paquet pose lui-même. Le bureau est donc démarré, avec repli sur le service de la saveur, et l'échec se dit au lieu de se taire. Vérifié : bureau arrêté puis fragment rejoué -> gnome-shell revient, écran de connexion GDM à l'image. --- EN --- A graphical VM stayed on a text console until its first reboot. GNOME installed, gdm3 installed, graphical.target the default, the display-manager.service alias in place by the package — and nothing on screen. Two causes stacked, measured on erplibre-ubuntu-2604-gnome: graphical.target had ALREADY been reached when the package arrived, and an active target does not pick up a service added afterwards. And "systemctl enable gdm" returns 0 doing nothing on Debian and Ubuntu: the unit has no "WantedBy", only the alias the package installs itself. The desktop is therefore started, with a fallback to the flavour's service, and a failure says so instead of staying quiet. Verified: desktop stopped then the fragment replayed -> gnome-shell back, GDM greeter on screen. Assisted-by: Claude Opus 5
This commit is contained in:
parent
0bd7c2fb1d
commit
49bc354d25
3 changed files with 120 additions and 0 deletions
|
|
@ -5333,6 +5333,25 @@ class TODO:
|
|||
# images cloud démarrent en multi-user.target.
|
||||
"sudo systemctl set-default graphical.target || true; "
|
||||
f"sudo systemctl enable {de['service']} >/dev/null 2>&1 || true; "
|
||||
# Et il faut le DÉMARRER, pas seulement l'activer. Deux raisons,
|
||||
# toutes deux mesurées sur erplibre-ubuntu-2604-gnome :
|
||||
#
|
||||
# - graphical.target était DÉJÀ atteinte quand le paquet est
|
||||
# arrivé, et une cible active ne rattrape pas un service ajouté
|
||||
# après coup : display-manager.service est resté inactif ;
|
||||
# - sur Debian et Ubuntu, « systemctl enable gdm » rend 0 sans
|
||||
# rien faire — l'unité n'a pas de « WantedBy », seulement
|
||||
# « Alias=display-manager.service » que le paquet a déjà posé.
|
||||
#
|
||||
# Résultat : GNOME installé, gdm3 installé, cible graphique par
|
||||
# défaut… et la console de la VM restait en mode texte jusqu'au
|
||||
# premier redémarrage. L'écran, c'est justement ce qu'on est venu
|
||||
# chercher sur une VM graphique.
|
||||
"if sudo systemctl start display-manager.service 2>/dev/null || "
|
||||
f"sudo systemctl start {de['service']} 2>/dev/null; then "
|
||||
f'echo " {t("graphical session started")}"; '
|
||||
f'else echo " ⚠ {t("graphical session not started; reboot the VM")}"; '
|
||||
"fi; "
|
||||
# xrdp là où il existe ; sur Arch c'est TigerVNC, qui se configure
|
||||
# par utilisateur et n'a pas de service à activer d'office.
|
||||
"if command -v xrdp >/dev/null 2>&1; then "
|
||||
|
|
|
|||
|
|
@ -2244,6 +2244,14 @@ TRANSLATIONS = {
|
|||
"fr": "À lancer sur VOTRE poste :",
|
||||
"en": "Run this on YOUR workstation:",
|
||||
},
|
||||
"graphical session started": {
|
||||
"fr": "session graphique démarrée",
|
||||
"en": "graphical session started",
|
||||
},
|
||||
"graphical session not started; reboot the VM": {
|
||||
"fr": "session graphique non démarrée ; redémarrer la VM",
|
||||
"en": "graphical session not started; reboot the VM",
|
||||
},
|
||||
"Hypervisor console (QEMU screen, no guest server)": {
|
||||
"fr": "Console de l'hyperviseur (écran QEMU, rien dans l'invitée)",
|
||||
"en": "Hypervisor console (QEMU screen, no guest server)",
|
||||
|
|
|
|||
|
|
@ -631,6 +631,99 @@ class TestPycharmCommunity(unittest.TestCase):
|
|||
self.assertIn("JetBrains", self.cmd)
|
||||
|
||||
|
||||
class TestTheDesktopActuallyStarts(unittest.TestCase):
|
||||
"""Installer un bureau ne suffit pas : il faut le DÉMARRER.
|
||||
|
||||
Vécu sur erplibre-ubuntu-2604-gnome, et le diagnostic ne sautait pas aux
|
||||
yeux : GNOME installé, gdm3 installé, graphical.target par défaut, lien
|
||||
display-manager.service en place — et la console de la VM restait en mode
|
||||
texte. Deux causes superposées :
|
||||
|
||||
- graphical.target était DÉJÀ atteinte quand le paquet est arrivé, et une
|
||||
cible active ne rattrape pas un service ajouté après coup ;
|
||||
- « systemctl enable gdm » rend 0 sans rien faire sur Debian et Ubuntu :
|
||||
l'unité n'a pas de « WantedBy », seulement un alias que le paquet pose.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.todo = TODO.__new__(TODO)
|
||||
self.cmd = self.todo._qemu_desktop_remote_cmd("gnome", "deb")
|
||||
|
||||
def _start_block(self, cmd=None):
|
||||
"""Le seul « if » qui démarre le bureau, extrait tel quel."""
|
||||
cmd = cmd or self.cmd
|
||||
start = cmd.index("if sudo systemctl start display-manager")
|
||||
return cmd[start : cmd.index("fi; ", start) + 4]
|
||||
|
||||
def test_it_starts_and_does_not_only_enable(self):
|
||||
self.assertIn("systemctl start display-manager.service", self.cmd)
|
||||
|
||||
def test_it_falls_back_to_the_desktop_service(self):
|
||||
"""« display-manager.service » est un alias que les paquets Debian
|
||||
posent ; ailleurs c'est « gdm » qui porte le WantedBy."""
|
||||
block = self._start_block()
|
||||
self.assertIn("systemctl start gdm", block)
|
||||
|
||||
def test_it_comes_after_the_default_target_and_before_xrdp(self):
|
||||
self.assertLess(
|
||||
self.cmd.index("set-default graphical.target"),
|
||||
self.cmd.index("start display-manager.service"),
|
||||
)
|
||||
self.assertLess(
|
||||
self.cmd.index("start display-manager.service"),
|
||||
self.cmd.index("command -v xrdp"),
|
||||
)
|
||||
|
||||
def _run(self, systemctl_body):
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
bin_dir = pathlib.Path(tmp) / "bin"
|
||||
bin_dir.mkdir()
|
||||
(bin_dir / "sudo").write_text('#!/bin/bash\nexec "$@"\n')
|
||||
(bin_dir / "systemctl").write_text(
|
||||
f"#!/bin/bash\n{systemctl_body}\n"
|
||||
)
|
||||
for n in ("sudo", "systemctl"):
|
||||
(bin_dir / n).chmod(0o755)
|
||||
res = subprocess.run(
|
||||
["bash", "-c", self._start_block()],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
env=dict(os.environ, PATH=f"{bin_dir}:/usr/bin:/bin"),
|
||||
timeout=30,
|
||||
)
|
||||
return res.stdout
|
||||
|
||||
def test_the_alias_path_reports_a_started_session(self):
|
||||
out = self._run("exit 0")
|
||||
self.assertIn("session", out.lower())
|
||||
self.assertNotIn("⚠", out)
|
||||
|
||||
def test_the_fallback_path_also_reports_started(self):
|
||||
"""display-manager absent, gdm présent : c'est le cas d'Arch."""
|
||||
out = self._run(
|
||||
'case "$*" in *display-manager*) exit 1;; *) exit 0;; esac'
|
||||
)
|
||||
self.assertNotIn("⚠", out)
|
||||
|
||||
def test_when_nothing_starts_it_says_to_reboot(self):
|
||||
"""Le pire serait de se taire : l'utilisateur cherche un écran."""
|
||||
out = self._run("exit 1")
|
||||
self.assertIn("⚠", out)
|
||||
self.assertIn("boot", out.lower() + "reboot")
|
||||
|
||||
def test_the_block_is_valid_shell(self):
|
||||
res = subprocess.run(
|
||||
["bash", "-n"],
|
||||
input=self._start_block(),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertEqual(0, res.returncode, res.stderr)
|
||||
|
||||
|
||||
class TestPycharmFirstOpen(unittest.TestCase):
|
||||
"""Ouverture sans écran, pour que le .idea existe avant l'installation.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue