[FIX] qemu deploy : l'unité de l'agent invité ne finit plus en échec
Dans le script du service qui pose qemu-guest-agent, « && » et « || » se lisent à égalité de gauche à droite : une pose apt réussie enchaînait sur « dnf install », puis sur le « command -v » d'un gestionnaire absent, qui rend 127 sous dash. Le service finissait en échec après avoir posé l'agent. Chaque branche est désormais entre accolades. Vérifié : le script extrait de la vraie configuration cloud-init rend 0 avec apt-get, dnf ou pacman factice. --- EN --- In the script of the service installing qemu-guest-agent, "&&" and "||" have equal precedence, left to right: a successful apt install went on to "dnf install", then to the "command -v" of a missing manager, which returns 127 under dash. The service ended in failure after installing the agent. Each branch is now braced. Checked: the script extracted from the real cloud-init configuration returns 0 with a fake apt-get, dnf or pacman. Assisted-by: Claude Opus 5
This commit is contained in:
parent
f6cc0bfc53
commit
ddde76f0cf
2 changed files with 76 additions and 9 deletions
|
|
@ -2537,10 +2537,9 @@ def build_cloud_config(
|
|||
" 2>/dev/null && break; done || true",
|
||||
# qemu-guest-agent : installé APRÈS sshd, et surtout HORS de cloud-init.
|
||||
#
|
||||
# Mesuré sur Ubuntu 26.04 s390x : « apt-get install qemu-guest-agent »
|
||||
# tire liburing2, ubuntu-helper-virt-hwe et ubuntu-virt depuis
|
||||
# ports.ubuntu.com, et cloud-final tourne 9 min 47. Or le suivi
|
||||
# d'installation attend « cloud-init status: done » : dix minutes
|
||||
# Son installation tire plusieurs paquets de virtualisation, et sur une
|
||||
# architecture émulée elle tient cloud-final une dizaine de minutes. Or
|
||||
# le suivi d'installation attend « cloud-init status: done » : autant
|
||||
# d'attente pour un paquet accessoire, avant même de commencer le
|
||||
# travail utile.
|
||||
#
|
||||
|
|
@ -2548,13 +2547,20 @@ def build_cloud_config(
|
|||
# en quelques secondes et l'agent apparaît quand il apparaît. On saute
|
||||
# aussi l'installation quand qemu-ga est déjà là, ce qui est le cas de
|
||||
# beaucoup d'images. Repli en ligne si systemd-run manque.
|
||||
#
|
||||
# Chaque branche de gestionnaire est entre accolades. Sans elles, « && »
|
||||
# et « || » se lisent à égalité de gauche à droite : une pose apt
|
||||
# réussie enchaîne sur « dnf install », puis sur le « command -v »
|
||||
# d'un gestionnaire absent, qui rend 127 sous dash — et le service
|
||||
# finit en échec après avoir posé l'agent. Le nom du service est celui
|
||||
# qu'attend _qemu_cloud_init_wait, côté hôte.
|
||||
" - command -v qemu-ga >/dev/null 2>&1 ||"
|
||||
" systemd-run --no-block --unit=erplibre-qga --collect"
|
||||
" /bin/sh -c 'command -v apt-get >/dev/null && { apt-get update -qq"
|
||||
" || true; apt-get install -y qemu-guest-agent; }"
|
||||
" || command -v dnf >/dev/null && dnf install -y qemu-guest-agent"
|
||||
" || command -v pacman >/dev/null && pacman -Sy --noconfirm"
|
||||
" qemu-guest-agent' 2>/dev/null"
|
||||
" /bin/sh -c '{ command -v apt-get >/dev/null && { apt-get update -qq"
|
||||
" || true; apt-get install -y qemu-guest-agent; }; }"
|
||||
" || { command -v dnf >/dev/null && dnf install -y qemu-guest-agent; }"
|
||||
" || { command -v pacman >/dev/null && pacman -Sy --noconfirm"
|
||||
" qemu-guest-agent; }' 2>/dev/null"
|
||||
" || (command -v apt-get >/dev/null && (timeout 120 apt-get update -qq"
|
||||
" || true; timeout 300 apt-get install -y qemu-guest-agent)) ||"
|
||||
" (command -v dnf >/dev/null && timeout 300 dnf install -y"
|
||||
|
|
|
|||
|
|
@ -1330,6 +1330,67 @@ class TestGnomeSiteExtensions(unittest.TestCase):
|
|||
self.assertIn("dbus-run-session", self.block)
|
||||
|
||||
|
||||
class TestLeServiceDeLAgentInvite(unittest.TestCase):
|
||||
"""Le service détaché qui pose qemu-guest-agent, lancé par cloud-init.
|
||||
|
||||
Son script essaie un gestionnaire de paquets après l'autre. Sans
|
||||
accolades autour de chaque branche, une pose réussie enchaîne sur le
|
||||
gestionnaire suivant, absent, et le service finit en échec — 127 sous
|
||||
dash — alors que l'agent est posé. Le script est extrait de la vraie
|
||||
configuration cloud-init, lue en YAML, et tourne dans un PATH où seul le
|
||||
gestionnaire choisi existe, faux : aucun paquet n'est posé, aucun
|
||||
service lancé.
|
||||
"""
|
||||
|
||||
def _script(self):
|
||||
import shlex
|
||||
|
||||
import yaml
|
||||
|
||||
from script.qemu import deploy_qemu
|
||||
|
||||
args = deploy_qemu.build_parser().parse_args(
|
||||
["--distro", "ubuntu", "--hostname", "vm"]
|
||||
)
|
||||
doc = yaml.safe_load(deploy_qemu.build_cloud_config(args, None, []))
|
||||
ligne = next(
|
||||
c
|
||||
for c in doc["runcmd"]
|
||||
if isinstance(c, str) and "--unit=erplibre-qga" in c
|
||||
)
|
||||
mots = shlex.split(ligne)
|
||||
# « systemd-run … /bin/sh -c '<script>' » : le script suit « -c ».
|
||||
return mots[mots.index("/bin/sh") + 2]
|
||||
|
||||
def test_a_successful_install_exits_zero(self):
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
script = self._script()
|
||||
for gestionnaire in ("apt-get", "dnf", "pacman"):
|
||||
with self.subTest(gestionnaire=gestionnaire):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
faux = pathlib.Path(tmp)
|
||||
os.symlink(shutil.which("sh"), faux / "sh")
|
||||
trace = faux / "trace"
|
||||
chemin = faux / gestionnaire
|
||||
chemin.write_text(
|
||||
f'#!/bin/sh\necho "$0 $*" >> "{trace}"\nexit 0\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
chemin.chmod(0o755)
|
||||
fini = subprocess.run(
|
||||
[str(faux / "sh"), "-c", script],
|
||||
env={"PATH": str(faux)},
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
self.assertEqual(0, fini.returncode, fini.stderr)
|
||||
self.assertIn("qemu-guest-agent", trace.read_text())
|
||||
|
||||
|
||||
class TestLeVerrouAptNeCoutePasDesMinutes(unittest.TestCase):
|
||||
"""« Impossible d'obtenir le verrou /var/lib/apt/lists/lock. Il est
|
||||
occupé par le processus N (apt-get) », répété pendant des minutes au
|
||||
|
|
|
|||
Loading…
Reference in a new issue