[ADD] arch: Canadian pacman mirrors first

Measured from Montréal on extra.db: mirror.quantum5.ca 2.0 s,
mirror.xenyth.net 7.1 s, against 8.0 s for geo.mirror.pkgbuild.com. The
official "geographic" mirror is therefore not the best one here, and
reflector, which sorts by throughput from inside the VM, had not picked
them.

Both are PREPENDED, never substituted: whatever reflector chose stays
below, as fallback. The write therefore comes after it, since "--save"
overwrites the file. Guarded on x86_64, these mirrors serving that
architecture only. Host side, the addition is idempotent.

The desktop install went through neither step: it ran without the near
mirrors and without the full update a rolling release demands, so it
pulled from Europe and broke on partial upgrades.

--- FR ---

Mesuré depuis Montréal sur extra.db : mirror.quantum5.ca 2,0 s,
mirror.xenyth.net 7,1 s, contre 8,0 s pour geo.mirror.pkgbuild.com. Le
miroir « géographique » officiel n'est donc pas le meilleur ici, et
reflector, qui trie par débit depuis la VM, ne les avait pas retenus.

Les deux sont mis EN TÊTE, jamais substitués : ce que reflector a choisi
reste dessous, en repli. L'écriture vient donc après lui, puisque
« --save » écrase le fichier. Gardé sur x86_64, ces miroirs ne servant que
cette architecture. Côté hôte, l'ajout est idempotent.

L'installation du bureau ne passait par aucune des deux étapes : elle
s'exécutait sans les miroirs proches et sans la mise à jour complète
qu'exige une rolling release, tirant donc d'Europe et cassant sur des
mises à jour partielles.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-11 22:29:33 -04:00
parent 7f6c18037d
commit e4aea8b8a6
2 changed files with 84 additions and 14 deletions

View file

@ -16,6 +16,21 @@ EL_USER=${USER}
# pacman résilient : --needed saute ce qui est déjà là, --noconfirm en non
# interactif.
PAC="sudo pacman -S --needed --noconfirm"
# Miroirs canadiens EN TÊTE de la mirrorlist. Mesuré depuis Montreal sur
# extra.db : quantum5 2,0 s, xenyth 7,1 s, contre 8,0 s pour
# geo.mirror.pkgbuild.com — le miroir « geographique » officiel n'est donc pas
# le meilleur ici. Les deux ne servent que x86_64 (Arch Linux ARM a ses propres
# miroirs), d'où la garde. On les AJOUTE en tete sans effacer l'existant : les
# miroirs deja configures restent en repli.
if [ "$(uname -m)" = "x86_64" ] \
&& ! grep -q "mirror.quantum5.ca" /etc/pacman.d/mirrorlist 2> /dev/null; then
echo -e "\n---- Miroirs pacman canadiens ----"
printf 'Server = https://mirror.quantum5.ca/archlinux/$repo/os/$arch\nServer = https://mirror.xenyth.net/archlinux/$repo/os/$arch\n' \
| sudo tee /etc/pacman.d/mirrorlist.el > /dev/null
sudo sh -c 'cat /etc/pacman.d/mirrorlist >> /etc/pacman.d/mirrorlist.el \
&& mv /etc/pacman.d/mirrorlist.el /etc/pacman.d/mirrorlist'
fi
# Mise à jour COMPLÈTE obligatoire : Arch est en rolling release et NE SUPPORTE
# PAS les mises à jour partielles. Sur une image cloud dont la glibc est
# ancienne, un « pacman -S <paquet récent> » lie le binaire à une glibc plus

View file

@ -4442,6 +4442,71 @@ class TODO:
"https://mirror.us.leaseweb.net/opensuse",
)
# Miroirs Arch canadiens, du plus rapide au suivant. Mesuré depuis
# Montréal sur extra.db : quantum5 2,0 s, xenyth 7,1 s, contre 8,0 s pour
# geo.mirror.pkgbuild.com — le miroir « géographique » officiel n'est donc
# pas le meilleur ici. Arch n'est proposé qu'en amd64 dans le catalogue,
# et ces deux-là ne servent que x86_64 (Arch Linux ARM a ses propres
# miroirs) : la garde d'architecture le dit quand même.
_QEMU_PACMAN_MIRRORS = (
"https://mirror.quantum5.ca/archlinux/$repo/os/$arch",
"https://mirror.xenyth.net/archlinux/$repo/os/$arch",
)
def _qemu_pacman_mirror_cmd(self):
"""Place les miroirs canadiens EN TÊTE de la mirrorlist.
reflector écrase le fichier avec « --save » : il faut donc écrire
après lui, pas avant. Ses miroirs restent dessous, comme repli."""
# « \\n » et non un vrai saut de ligne : la commande distante est UNE
# chaîne, passée à bash -c après shlex.quote. Un retour littéral y
# survivrait, mais rendrait la chaîne illisible et fragile à relire.
# « $repo » et « $arch » restent littéraux : c'est pacman qui les
# substitue, d'où les guillemets SIMPLES autour du format.
lines = "".join(f"Server = {m}\\n" for m in self._QEMU_PACMAN_MIRRORS)
first = self._QEMU_PACMAN_MIRRORS[0].split("/")[2]
return (
'[ "$(uname -m)" = x86_64 ] && { '
# Idempotent : la préparation Arch passe deux fois quand une VM
# est graphique (bureau puis ERPLibre), et empiler les mêmes
# miroirs à chaque passage allongerait la liste sans rien gagner.
f'grep -q "{first}" /etc/pacman.d/mirrorlist 2>/dev/null || {{ '
f"printf '{lines}' | sudo tee /etc/pacman.d/mirrorlist.el "
"> /dev/null; "
"sudo sh -c 'cat /etc/pacman.d/mirrorlist "
">> /etc/pacman.d/mirrorlist.el "
"&& mv /etc/pacman.d/mirrorlist.el /etc/pacman.d/mirrorlist'; "
"}; }; "
)
def _qemu_pacman_prepare_cmd(self):
"""Préparation Arch : verrou, miroirs proches, mise à jour COMPLÈTE.
Les trois sont indissociables, et il faut les faire AVANT la moindre
installation. Une image cloud Arch est un instantané dont la base de
paquets pointe des versions déjà retirées des miroirs : « pacman -S »
s'y arrête sur « failed retrieving file … 404 » — vécu sur llvm-libs
et perl. Arch ne supporte pas la mise à jour partielle.
Ce bloc ne vivait QUE dans le chemin ERPLibre. Or le bureau s'installe
AVANT lui : une VM graphique échouait donc toujours, sans jamais
atteindre le code qui l'aurait sauvée."""
return (
"if command -v pacman >/dev/null 2>&1; then "
# Verrou périmé (cloud-init interrompu) : le retirer SEULEMENT si
# aucun pacman ne tourne, sinon on attend qu'il se libère.
"pgrep -x pacman >/dev/null 2>&1 "
"|| sudo rm -f /var/lib/pacman/db.lck; "
# reflector d'abord, nos miroirs ensuite : « --save » écrase le
# fichier, écrire avant lui ne servirait à rien.
"sudo pacman -Sy --needed --noconfirm reflector || true; "
"sudo reflector --latest 20 --protocol https --sort rate "
"--save /etc/pacman.d/mirrorlist || true; "
+ self._qemu_pacman_mirror_cmd()
+ "sudo pacman -Syu --noconfirm || true; "
"fi; "
)
def _qemu_zypper_mirror_cmd(self):
"""Réécrit l'hôte des dépôts zypper vers un miroir plus proche."""
mirrors = " ".join(self._QEMU_ZYPPER_MIRRORS)
@ -4487,7 +4552,8 @@ class TODO:
"elif command -v pacman >/dev/null 2>&1; then "
"pgrep -x pacman >/dev/null 2>&1 "
"|| sudo rm -f /var/lib/pacman/db.lck; "
f"sudo pacman -S --needed --noconfirm {de['pacman']} "
+ self._qemu_pacman_prepare_cmd()
+ f"sudo pacman -S --needed --noconfirm {de['pacman']} "
f"{rem['pacman']['packages']}; "
"elif command -v zypper >/dev/null 2>&1; then "
"sudo zypper --non-interactive refresh || true; "
@ -4639,19 +4705,8 @@ class TODO:
"sudo dnf install -y --refresh $PKGS || "
"{ sudo dnf clean all; sudo dnf install -y --refresh $PKGS; }; "
"elif command -v pacman >/dev/null 2>&1; then "
# Verrou pacman périmé (cloud-init interrompu) : le retirer SEULEMENT
# si aucun pacman ne tourne, sinon on attend qu'il se libère.
"pgrep -x pacman >/dev/null 2>&1 "
"|| sudo rm -f /var/lib/pacman/db.lck; "
# Arch : reflector sélectionne les miroirs HTTPS les plus rapides,
# puis MISE À JOUR COMPLÈTE (-Syu) : Arch (rolling) ne supporte pas
# les màj partielles ; sur une image cloud à la glibc ancienne, un
# « pacman -S <paquet récent> » casse avec « GLIBC_x.yy not found ».
"sudo pacman -Sy --needed --noconfirm reflector || true; "
"sudo reflector --latest 20 --protocol https --sort rate "
"--save /etc/pacman.d/mirrorlist || true; "
"sudo pacman -Syu --noconfirm || true; "
"sudo pacman -S --needed --noconfirm $PKGS; "
+ self._qemu_pacman_prepare_cmd()
+ "sudo pacman -S --needed --noconfirm $PKGS; "
"elif command -v zypper >/dev/null 2>&1; then "
# openSUSE : « --non-interactive » vaut le -y des autres, et
# « --auto-agree-with-licenses », qui va APRÈS « install »,