Alternativen

Alternativen ermöglichen die parallele Installation von Paketen, die dieselbe Funktionalität bieten, indem sie Sätze von symbolischen Links (einen pro Paket) verwalten, die auf alternative Dateien verweisen, etwa so: /Pfad/Originaldatei -> /etc/alternatives/Paketname-Originaldatei -> /Pfad/Originaldatei.Suffix. Weitere Informationen finden Sie in der Handbuchseite zu update-alternatives(8).

Verwendung in Fedora

Alternativen KÖNNEN verwendet werden, um die parallele Installation von Software zu ermöglichen, wenn:

  • die Software als direkter Ersatz verwendet werden kann und so ähnlich funktioniert, dass Benutzer und andere Programme im Rahmen des Zumutbaren nicht wissen müssen, welche Variante aktuell installiert ist

UND

  • die Auswahl der Software systemweit ausschließlich durch den Systemadministrator erfolgt; Endbenutzer müssen nicht zwischen den Varianten wechseln.

Umgekehrt dürfen Alternativen NICHT verwendet werden, wenn:

  • die Software kein direkter Ersatz ist. Wenn sich beispielsweise gängige Befehlszeilenargumente zwischen den beiden Varianten unterscheiden, DÜRFEN Alternativen NICHT verwendet werden.

OR

  • Endbenutzer werden Wert darauf legen, welche Variante sie verwenden. Wenn ein Benutzer ohne Root-Rechte durch den Wechsel zwischen den Varianten einen Vorteil hätte, DÜRFEN Alternativen NICHT verwendet werden.

Ein gutes Beispiel für die Verwendung von Alternativen sind die verschiedenen MTAs, die alle /usr/bin/sendmail mit ähnlichen Befehlszeilenargumenten bereitstellen.

Schlechte Beispiele für die Verwendung von Alternativen sind:

  • die verschiedenen MPI-Umgebungen, bei denen es den Benutzern sowohl wichtig ist, gegen welche MPI-Umgebung sie kompilieren, als auch, gegen welche sie das Programm ausführen

  • die Wahl des Editors beim Aufruf von „vi“, die vom Funktionsumfang, der Kompatibilität mit Plugins usw. abhängt

In Fällen, in denen eine parallele Installation wünschenswertist, Alternativen jedoch ungeeignet sind, können Szenarien auftreten, in denen Umgebungsmodule angebracht sind. MPI und python-sphinx (bis Fedora 31) sind Beispiele für Pakete, die environment-modules zu diesem Zweck verwenden.

Verwendung von Alternativen

Wenn ein Paket Alternativen verwendet, MÜSSEN die Dateien, die andernfalls in Konflikt geraten würden, mit einem entsprechenden Suffix installiert werden (z.B. %{_bindir}/sendmail.postfix statt %{_bindir}/sendmail), die ursprünglichen Speicherorte MÜSSEN aktualisiert werden (z. B. touch %{_bindir}/sendmail), die von den Alternativen erstellten Links MÜSSEN in der Dateiliste als %ghost aufgeführt werden und die entsprechenden „Requires:“ MÜSSEN hinzugefügt werden, wie in den folgenden Beispielen.

Durch das Hinzufügen der „alternativisierten“ Dateien zur Dateiliste wird sichergestellt, dass sie den jeweiligen Paketen zugeordnet sind, was bedeutet, dass Befehle wie die folgenden funktionieren:

  • rpm -qf /usr/bin/foo

  • dnf install /usr/bin/foo

  • repoquery --whatprovides /usr/bin/foo

Alles funktioniert einwandfrei. Die Verwendung von %ghost zu diesem Zweck ermöglicht die Verwendung von Glob-Mustern und generierten Dateilisten.

Beispiele

Beispiel aus antlr.spec:

Requires(post): %{_bindir}/update-alternatives
Requires(postun): %{_bindir}/update-alternatives
...
%install
...
touch %{buildroot}%{_bindir}/antlr

%post
update-alternatives --install %{_bindir}/antlr \
  %{name} %{_bindir}/antlr-java 10

%postun
if [ $1 -eq 0 ] ; then
  update-alternatives --remove %{name} %{_bindir}/antlr-java
fi
...
%files
...
%ghost %{_bindir}/antlr
%{_bindir}/antlr-java

Und ein etwas komplexeres Beispiel für den Alternativen-Aufruf aus sendmail.spec, leicht bearbeitet:

Requires(post): %{_bindir}/update-alternatives
Requires(postun): %{_bindir}/update-alternatives
Requires(preun): %{_bindir}/update-alternatives
...
%install
...
# rename files for alternative usage
mv %{buildroot}%{_bindir}/sendmail %{buildroot}%{_bindir}/sendmail.sendmail
touch %{buildroot}%{_bindir}/sendmail
for i in mailq newaliases rmail; do
    mv %{buildroot}%{_bindir}/$i %{buildroot}%{_bindir}/$i.sendmail
    touch %{buildroot}%{_bindir}/$i
done
mv %{buildroot}%{_mandir}/man1/mailq.1 %{buildroot}%{_mandir}/man1/mailq.sendmail.1
touch %{buildroot}%{_mandir}/man1/mailq.1
mv %{buildroot}%{_mandir}/man1/newaliases.1 %{buildroot}%{_mandir}/man1/newaliases.sendmail.1
touch %{buildroot}%{_mandir}/man1/newaliases.1
mv %{buildroot}%{_mandir}/man5/aliases.5 %{buildroot}%{_mandir}/man5/aliases.sendmail.5
touch %{buildroot}%{_mandir}/man5/aliases.5
mv %{buildroot}%{_mandir}/man8/sendmail.8 %{buildroot}%{_mandir}/man8/sendmail.sendmail.8
touch %{buildroot}%{_mandir}/man8/sendmail.8

%postun
if [ "$1" -ge "1" ]; then
    if [ "`readlink %{_sysconfdir}/alternatives/mta`" == "%{_bindir}/sendmail.sendmail" ]; then
        %{_bindir}/alternatives --set mta %{_bindir}/sendmail.sendmail
    fi
fi

%post
# Set up the alternatives files for MTAs.
update-alternatives --install %{_bindir}/sendmail mta %{_bindir}/sendmail.sendmail 90 \
    --slave %{_bindir}/mailq mta-mailq %{_bindir}/mailq.sendmail \
    --slave %{_bindir}/newaliases mta-newaliases %{_bindir}/newaliases.sendmail \
    --slave %{_bindir}/rmail mta-rmail %{_bindir}/rmail.sendmail \
    --slave /usr/lib/sendmail mta-sendmail /usr/lib/sendmail.sendmail \
    --slave %{_sysconfdir}/pam.d/smtp mta-pam %{_sysconfdir}/pam.d/smtp.sendmail \
    --slave %{_mandir}/man8/sendmail.8.gz mta-sendmailman %{_mandir}/man8/sendmail.sendmail.8.gz \
    --slave %{_mandir}/man1/mailq.1.gz mta-mailqman %{_mandir}/man1/mailq.sendmail.1.gz \
    --slave %{_mandir}/man1/newaliases.1.gz mta-newaliasesman %{_mandir}/man1/newaliases.sendmail.1.gz \
    --slave %{_mandir}/man5/aliases.5.gz mta-aliasesman %{_mandir}/man5/aliases.sendmail.5.gz \
    --initscript sendmail
...

%preun
if [ $1 = 0 ]; then
    update-alternatives --remove mta %{_bindir}/sendmail.sendmail
fi
...

%files
...
%ghost %{_bindir}/sendmail
%ghost %{_bindir}/mailq
%ghost %{_bindir}/newaliases
%ghost %{_bindir}/rmail
%ghost /usr/lib/sendmail
%ghost %{_sysconfdir}/pam.d/smtp
%ghost %{_mandir}/man8/sendmail.8.gz
%ghost %{_mandir}/man1/mailq.1.gz
%ghost %{_mandir}/man1/newaliases.1.gz
%ghost %{_mandir}/man5/aliases.5.gz

%{_bindir}/sendmail.sendmail
%{_bindir}/mailq.sendmail
%{_bindir}/newaliases.sendmail
%{_bindir}/rmail.sendmail
/usr/lib/sendmail.sendmail
%config(noreplace) %{_sysconfdir}/pam.d/smtp.sendmail
%{_mandir}/man8/sendmail.sendmail.8.gz
%{_mandir}/man1/mailq.sendmail.1.gz
%{_mandir}/man1/newaliases.sendmail.1.gz
%{_mandir}/man5/aliases.sendmail.5.gz

%attr(0755,root,root) %{_initrddir}/sendmail