Files
FWS-ISO/pkgbuilds/anaconda/PKGBUILD
T
nocode 7d6bba42b2 feat(anaconda): add hostname field to user spoke and fix keyboard layout by territory
Replace keyboard correction logic in kickstart with anaconda package patches:

- Add "Nom de machine" (hostname) field to the User spoke in anaconda GUI
- user.py writes the hostname value to /tmp/fws-hostname for the kickstart %post
- Simplify kickstart to read from /tmp/fws-hostname instead of live hostname
- Fix keyboard layout selection to use full locale (e.g. fr_CH) instead of just language (fr)
  to correctly derive territory-specific keymaps (ch(fr) for Switzerland, not fr for France)
- Remove outdated fix_keyboard() function from kickstart

Also add --network=host flag to podman run in setup-aur.sh to ensure DNS and internet
connectivity through the host stack instead of the bridge (fixes timeout issues on
certain networks with firewalld/NAT).

Bump anaconda pkgrel from 2 to 4.
2026-06-23 10:48:32 +02:00

213 lines
11 KiB
Bash

# Maintainer: FWS
# ============================================================================
# anaconda — l'installateur Fedora (rhinstaller) PORTÉ sur Arch pour FWS.
# Build autotools : ./autogen.sh && ./configure && make && make install
# (le source compile aussi widgets/ via AC_CONFIG_SUBDIRS → on retire ces
# fichiers en package(), ils sont fournis par le paquet anaconda-widgets).
#
# ⚠️ SCAFFOLD À ITÉRER : ce PKGBUILD est un point de départ fidèle au spec
# amont, mais Anaconda est profondément couplé à Fedora. Il faudra très
# probablement itérer sur Arch RÉEL (via ./setup-aur.sh) pour :
# - des BuildRequires manquants au configure,
# - des chemins/macros Fedora (systemd-rpm-macros, find_lang…),
# - la compat Python 3.14 d'Arch (Anaconda vise le Python de Fedora).
#
# DÉVIATIONS FWS vs Requires du spec (justifiées) :
# - RETIRÉS car payload liveimg (jamais le payload DNF) : python3-libdnf5,
# python3-rpm. → cf. verdict « drop DNF » (libdnf5 importé seulement dans
# dnf_manager.py, chemin non pris avec liveimg).
# - RETIRÉ libselinux : Arch n'est pas SELinux (blivet/anaconda gèrent son
# absence). - RETIRÉS Fedora-only / N/A archiso : subscription-manager,
# s390utils-*, crypto-policies(-scripts), glibc-langpack-*, dracut-network,
# teamd/NetworkManager-team, flatpak(-libs). - grub2-common → grub (Arch).
# - RISQUE connu : python3-crypt-r (module `crypt` retiré de Python ≥ 3.13)
# n'a peut-être pas d'équivalent Arch → à packager si l'import casse.
# ============================================================================
pkgname=anaconda
pkgver=45.8
pkgrel=4
pkgdesc="The Anaconda installer (porté sur Arch pour FWS, payload liveimg)"
arch=('x86_64')
url="https://github.com/rhinstaller/anaconda"
license=('GPL-2.0-or-later')
depends=(
# — interface & widgets —
'anaconda-widgets' 'gtk3' 'python-gobject' 'gsettings-desktop-schemas'
'adwaita-icon-theme' 'librsvg' 'nm-connection-editor'
# — cœur Python Anaconda —
'python' 'python-meh' 'python-simpleline' 'pykickstart' 'python-dasbus'
'python-productmd' 'python-pid' 'python-langtable' 'python-iso639'
'python-requests' 'python-requests-file' 'python-requests-ftp'
# — stockage —
'python-blivet' 'libblockdev' 'python-pyparted' 'parted' 'util-linux'
'lvm2' 'cryptsetup' 'mdadm' 'dosfstools' 'e2fsprogs' 'xfsprogs' 'btrfs-progs'
# — rapport de crash (python-meh importe `report` en dur) —
'libreport'
# — système / réseau / boot —
'networkmanager' 'kbd' 'chrony' 'systemd' 'dbus' 'openssh' 'grub'
'libpwquality' 'python-systemd' 'python-xkbregistry' 'cracklib'
)
# NB : pas de 'glade' — module Glade désactivé au build (cf. build()).
makedepends=(
'autoconf' 'automake' 'libtool' 'gettext' 'intltool' 'gtk-doc'
'gobject-introspection' 'python' 'gdk-pixbuf2' 'libxml2'
'desktop-file-utils' 'glib2-devel' 'libarchive' 'rpm-tools'
)
source=("anaconda-$pkgver.tar.gz::https://github.com/rhinstaller/anaconda/archive/refs/tags/anaconda-$pkgver.tar.gz")
sha256sums=('5ef1464bff7f28a4a09a821cbb0121f09ef504ec169288d742373f86807ec4ed')
_srcdir="anaconda-anaconda-$pkgver"
prepare() {
cd "$srcdir/$_srcdir"
# ── FWS : clavier par défaut selon le TERRITOIRE de la locale ──────────────
# set_layouts() amont fait « locale = get_language_id(self.language) » →
# get_language_id JETTE le territoire (fr_CH.UTF-8 → 'fr') → list_keyboards('fr')
# = 'fr(oss)' (France) au lieu de 'ch(fr)' (Suisse). On passe la LOCALE COMPLÈTE
# (self.language) : langtable.list_keyboards('fr_CH.UTF-8') = 'ch(fr)'. La
# validation l'accepte (is_valid_langcode → parse_locale().language non vide).
# → le clavier du GUI ET du système installé suivent enfin la locale choisie.
sed -i \
's/^\(\s*\)locale = get_language_id(self\.language)/\1locale = self.language # FWS: garder le territoire (fr_CH -> ch(fr))/' \
pyanaconda/modules/localization/localization.py
# Garde-fou : casse le build si le motif amont a changé (le patch silencieux).
grep -q 'locale = self.language # FWS' \
pyanaconda/modules/localization/localization.py
# ── FWS : champ « Nom de machine » dans le spoke Utilisateur ───────────────
# Anaconda ne propage PAS le hostname (le champ du spoke Réseau est perdu chez
# nous → /etc/hostname vide). On ajoute donc un champ Hostname à l'onglet de
# création de compte (ligne 2 de la grille, libre) ; user.py écrit la valeur
# dans /tmp/fws-hostname, que le %post du kickstart applique à /etc/hostname.
python3 - <<'PYEOF'
import glob
# 1) user.glade : insérer label + entry "Host name" APRÈS le bloc username_entry.
glades = [p for p in glob.glob("pyanaconda/**/user.glade", recursive=True)
if 'username_entry' in open(p, encoding='utf-8').read()]
assert glades, "FWS: user.glade introuvable"
g = glades[0]
s = open(g, encoding='utf-8').read()
assert 'id="hostname_entry"' not in s, "FWS: glade déjà patché"
i = s.index('id="username_entry"')
k = s.index('</packing>', i) # fin du packing de username_entry
j = s.index('</child>', k) + len('</child>') # fin du <child> EXTERNE (pas l'accessible)
block = '''
<child>
<object class="GtkLabel" id="hostname_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="xpad">10</property>
<property name="label" translatable="yes" context="GUI|User">_Host name</property>
<property name="use-underline">True</property>
<property name="mnemonic-widget">hostname_entry</property>
<property name="xalign">1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="hostname_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="width-chars">50</property>
<child internal-child="accessible">
<object class="AtkObject" id="hostname_entry-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Host Name</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>'''
open(g, 'w', encoding='utf-8').write(s[:j] + block + s[j:])
# 2) user.py (GUI) : récupérer le widget + écrire /tmp/fws-hostname dans apply().
pys = glob.glob("pyanaconda/ui/gui/spokes/user.py")
assert pys, "FWS: user.py introuvable"
p = pys[0]
s = open(p, encoding='utf-8').read()
anchor = 'self._username_entry = self.builder.get_object("username_entry")'
assert anchor in s, "FWS: ancre username_entry absente"
s = s.replace(anchor,
anchor + '\n self._hostname_entry = self.builder.get_object("hostname_entry")',
1)
ap = 'set_user_list(self._users_module, self._user_list, remove_unset=True)'
assert ap in s, "FWS: ancre apply() absente"
s = s.replace(ap, ap + '''
# FWS : mémorise le nom de machine saisi (cible pas encore montée) pour
# le %post du kickstart, qui l'écrira dans /etc/hostname.
try:
_hn = self._hostname_entry.get_text().strip()
except Exception:
_hn = ""
try:
with open("/tmp/fws-hostname", "w") as _f:
_f.write(_hn)
except OSError:
pass''', 1)
open(p, 'w', encoding='utf-8').write(s)
print("FWS: champ Hostname ajouté au spoke Utilisateur (glade + user.py)")
PYEOF
}
build() {
cd "$srcdir/$_srcdir"
# Glade désactivé (catalogue designer, inutile au runtime) → pas de dép glade.
# La variable d'env doit être posée AVANT autogen.sh (lue par m4 à l'autoreconf)
# EN PLUS du flag --disable-glade au configure.
export ANACONDA_DISABLE_GLADE=yes
# autogen.sh : autoreconf -vfi racine + (cd widgets && ./autogen.sh).
./autogen.sh
# ANACONDA_RELEASE=1 : release réelle, pas la date de création du tarball.
./configure \
--prefix=/usr --libdir=/usr/lib --sysconfdir=/etc \
--disable-glade --disable-gtk-doc ANACONDA_RELEASE=1
make
}
package() {
cd "$srcdir/$_srcdir"
make DESTDIR="$pkgdir" install
find "$pkgdir" -name '*.la' -delete
# Répertoires attendus par Anaconda (créés vides par le spec).
install -d "$pkgdir/usr/share/anaconda/addons" \
"$pkgdir/usr/share/anaconda/post-scripts"
# Fichiers widgets : fournis par le paquet anaconda-widgets → on les retire
# ici (le build principal recompile widgets/ via AC_CONFIG_SUBDIRS) pour
# éviter le conflit de fichiers à l'install. On enlève TOUT l'empreinte
# widgets : lib, typelib, pkgconfig, headers, .gir, doc, override gi.
rm -f "$pkgdir"/usr/lib/libAnacondaWidgets.so*
rm -f "$pkgdir"/usr/lib/girepository-*/AnacondaWidgets*.typelib
rm -f "$pkgdir"/usr/lib/pkgconfig/AnacondaWidgets.pc
rm -rf "$pkgdir"/usr/include/AnacondaWidgets
rm -f "$pkgdir"/usr/share/gir-1.0/AnacondaWidgets*.gir
rm -rf "$pkgdir"/usr/share/gtk-doc/html/AnacondaWidgets
rm -f "$pkgdir"/usr/lib/python*/site-packages/gi/overrides/AnacondaWidgets*
# interactive-defaults.ks : FWS le fournit via l'overlay airootfs
# (configs/*/airootfs/usr/share/anaconda/) avec le payload liveimg. mkarchiso
# copie l'overlay AVANT pacstrap → si le paquet livrait aussi ce fichier, pacman
# planterait (« exists in filesystem »). On retire donc la version amont : le
# fichier de l'overlay reste la seule à ce chemin, et anaconda le lit au runtime.
rm -f "$pkgdir"/usr/share/anaconda/interactive-defaults.ks
# usr-merge Arch : /usr/sbin est un LIEN → /usr/bin. Anaconda installe dans
# /usr/sbin (vrai dossier sur Fedora) → conflit avec le paquet 'filesystem'.
# On rapatrie le contenu dans /usr/bin et on supprime le dossier sbin.
if [ -d "$pkgdir/usr/sbin" ] && [ ! -L "$pkgdir/usr/sbin" ]; then
install -d "$pkgdir/usr/bin"
cp -aT "$pkgdir/usr/sbin" "$pkgdir/usr/bin"
rm -rf "$pkgdir/usr/sbin"
fi
}