From Fedora Project Wiki
(→‎Using Provides:: one more pro)
m (→‎Using alternatives: self-consistency)
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:PackagingDrafts]]
{{Draft}}
 
== Existing guideline ==
None.
 
== Proposal ==
Following change to Packaging Guidelines is proposed: Add a section '''Use of alternatives''' which would read:  


{{Draft}}
== Use of alternatives ==


== Motivation ==
=== What are alternatives ===
Current usage of alternatives is inconsistent, and rpm -qf /some/file will often say the file is unowned, even if it's been created by some package, which is especially misleading and annoying in case of binaries.
Alternatives provide means for parallel installation of packages which provide the same functionality by maintaining sets of symlinks (one per package) pointing to alternativized files like this:
<code>/path/original-file -> /etc/alternatives/packagename-original-file -> /path/original-file.suffix</code>
For more information, see <code>update-alternatives(8)</code> manpage.


== Solutions ==
=== Recommended usage ===
Alternatives can be used to allow parallel installation of software that can be used as a drop-in replacement and functions with sufficient similarity that users and other programs would, within reason, not need to know which variant is currently installed (for example: the various MTAs which all provide <code>/usr/sbin/sendmail</code>). Selection of which of the parallel-installed packages to use for a given alternativized file can only be done system-wide by a root-level user.
Alternatives are not recommended to facilitate parallel installation of software whose selection should be done by users (for example: the various MPI environments).


All of the options below are currently used in Fedora packages.
=== How to use alternatives ===
If a package is using alternatives, the files which would otherwise conflict must be installed with an appropriate suffix (for example: <code>%{_sbindir}/sendmail.postfix</code> instead of <code>%{_sbindir}/sendmail</code>), the original locations must be touched (for example: <code>touch %{_sbindir}/sendmail</code>), the links set up by alternatives must be listed as %ghost in the file list and proper Requires: must be added, like in the examples below.


=== Ignoring alternativized files ===
Putting the alternativized files in the file list ensures that they are owned by respective packages, which means that commands like:
Pros:
* rpm -qf /usr/bin/foo
* less work for packager(?)
* yum install /usr/bin/foo
* repoquery --whatprovides /usr/bin/foo
all work properly. Using %ghost for this purpose allows using globs and generated file lists.


Cons:
=== Examples ===
* alternativized files are unowned, which means:
** rpm -qf /usr/bin/foo doesn't work
** yum install /usr/bin/foo doesn't work
** repoquery --whatprovides /usr/bin/foo doesn't work


=== Using %ghost ===
Example from antlr.spec:
<pre>
<pre>
Requires(post): %{_sbindir}/update-alternatives
Requires(postun): %{_sbindir}/update-alternatives
...
%install
...
touch %{buildroot}%{_bindir}/antlr
%post
%{_sbindir}/update-alternatives --install %{_bindir}/antlr \
  %{name} %{_bindir}/antlr-java 10
%postun
if [ $1 -eq 0 ] ; then
  %{_sbindir}/update-alternatives --remove %{name} %{_bindir}/antlr-java
fi
...
%files
%files
...
...
%ghost %{_bindir}/foo
%ghost %{_bindir}/antlr
%{_bindir}/antlr-java
</pre>
</pre>


Pros:
And a more complex example of alternatives invocation from sendmail.spec, slightly edited:
* allows globs and generated file lists
<pre>
* alternativized files are owned, which means:
Requires(post): %{_sbindir}/update-alternatives
** rpm -qf /usr/bin/foo works
Requires(postun): %{_sbindir}/update-alternatives
** yum install /usr/bin/foo works
Requires(preun): %{_sbindir}/update-alternatives
** repoquery --whatprovides /usr/bin/foo works
...
%install
...
# rename files for alternative usage
mv %{buildroot}%{_sbindir}/sendmail %{buildroot}%{_sbindir}/sendmail.sendmail
touch %{buildroot}%{_sbindir}/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`" == "%{_sbindir}/sendmail.sendmail" ]; then
%{_sbindir}/alternatives --set mta %{_sbindir}/sendmail.sendmail
fi
fi
 
%post
# Set up the alternatives files for MTAs.
%{_sbindir}/update-alternatives --install %{_sbindir}/sendmail mta %{_sbindir}/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
%{_sbindir}/update-alternatives --remove mta %{_sbindir}/sendmail.sendmail
fi
...
 
%files
...
%ghost %{_sbindir}/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


Cons:
%{_sbindir}/sendmail.sendmail
* files owned by multiple packages are forbidden by [[Packaging:Guidelines#File_and_Directory_Ownership|FPG]].
%{_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


=== Using Provides: ===
%attr(0755,root,root) %{_initrddir}/sendmail
<pre>
Provides: %{_bindir}/foo
</pre>
</pre>


Pros:
== Motivation ==
* alternativized files are provided, which means:
Current usage of alternatives is inconsistent, and rpm -qf /some/file will often say the file is unowned, even if it's been created by some package, which is especially misleading and annoying in case of binaries.
** rpm -qf /usr/bin/foo works
 
** yum install /usr/bin/foo works
== Existing practice ==
** repoquery --whatprovides /usr/bin/foo works
 
** can be processed by yum without downloading additional filelists even if the file lies outside common directories
Packages using this solution:
* antlr
* cdrkit
* classpathx-jaf
* classpathx-mail
* ettercap
* jakarta-commons-dbcp
* java-1.5.0-gcj
* OpenEXR_Viewers
* pinentry
* saxon
* xalan-j2
* xemacs
* xerces-j2
 
Packages that need fixing:
* cups
* emacs
* esmtp
* exim
* fedora-usermgmt
* gcin
* gridengine
* ibus
* imsettings
* java-1.6.0-openjdk
* kinput2
* libextractor
* mx4j
* nabi
* openmpi
* postfix
* scim
* sendmail
* ssmtp
* tomcat5
* uim
* unison213
* unison227
* ushare


Cons:
[[Category:Packaging guidelines drafts]]
* unwieldy with lots of alternativized files

Latest revision as of 17:55, 14 April 2009

Warning.png
This page is a draft only
It is still under construction and content may change. Do not rely on the information on this page.

Existing guideline

None.

Proposal

Following change to Packaging Guidelines is proposed: Add a section Use of alternatives which would read:

Use of alternatives

What are alternatives

Alternatives provide means for parallel installation of packages which provide the same functionality by maintaining sets of symlinks (one per package) pointing to alternativized files like this: /path/original-file -> /etc/alternatives/packagename-original-file -> /path/original-file.suffix For more information, see update-alternatives(8) manpage.

Recommended usage

Alternatives can be used to allow parallel installation of software that can be used as a drop-in replacement and functions with sufficient similarity that users and other programs would, within reason, not need to know which variant is currently installed (for example: the various MTAs which all provide /usr/sbin/sendmail). Selection of which of the parallel-installed packages to use for a given alternativized file can only be done system-wide by a root-level user. Alternatives are not recommended to facilitate parallel installation of software whose selection should be done by users (for example: the various MPI environments).

How to use alternatives

If a package is using alternatives, the files which would otherwise conflict must be installed with an appropriate suffix (for example: %{_sbindir}/sendmail.postfix instead of %{_sbindir}/sendmail), the original locations must be touched (for example: touch %{_sbindir}/sendmail), the links set up by alternatives must be listed as %ghost in the file list and proper Requires: must be added, like in the examples below.

Putting the alternativized files in the file list ensures that they are owned by respective packages, which means that commands like:

  • rpm -qf /usr/bin/foo
  • yum install /usr/bin/foo
  • repoquery --whatprovides /usr/bin/foo

all work properly. Using %ghost for this purpose allows using globs and generated file lists.

Examples

Example from antlr.spec:

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

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

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

And a more complex example of alternatives invocation from sendmail.spec, slightly edited:

Requires(post): %{_sbindir}/update-alternatives
Requires(postun): %{_sbindir}/update-alternatives
Requires(preun): %{_sbindir}/update-alternatives
...
%install
...
# rename files for alternative usage
mv %{buildroot}%{_sbindir}/sendmail %{buildroot}%{_sbindir}/sendmail.sendmail
touch %{buildroot}%{_sbindir}/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`" == "%{_sbindir}/sendmail.sendmail" ]; then
		%{_sbindir}/alternatives --set mta %{_sbindir}/sendmail.sendmail
	fi
fi

%post
# Set up the alternatives files for MTAs.
%{_sbindir}/update-alternatives --install %{_sbindir}/sendmail mta %{_sbindir}/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
	%{_sbindir}/update-alternatives --remove mta %{_sbindir}/sendmail.sendmail
fi
...

%files
...
%ghost %{_sbindir}/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

%{_sbindir}/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

Motivation

Current usage of alternatives is inconsistent, and rpm -qf /some/file will often say the file is unowned, even if it's been created by some package, which is especially misleading and annoying in case of binaries.

Existing practice

Packages using this solution:

  • antlr
  • cdrkit
  • classpathx-jaf
  • classpathx-mail
  • ettercap
  • jakarta-commons-dbcp
  • java-1.5.0-gcj
  • OpenEXR_Viewers
  • pinentry
  • saxon
  • xalan-j2
  • xemacs
  • xerces-j2

Packages that need fixing:

  • cups
  • emacs
  • esmtp
  • exim
  • fedora-usermgmt
  • gcin
  • gridengine
  • ibus
  • imsettings
  • java-1.6.0-openjdk
  • kinput2
  • libextractor
  • mx4j
  • nabi
  • openmpi
  • postfix
  • scim
  • sendmail
  • ssmtp
  • tomcat5
  • uim
  • unison213
  • unison227
  • ushare