8.7. Avoid Dependency Hell with yum
RPM packages include all the dependency information you need. Each RPM includes headers that list any other RPMs that are required to make it work. For example, when I tried to install the GNU C Compiler (gcc) on Fedora Core 3, I got the following message:
# rpm -i gcc-3.4.2-6.fc3.i386.rpm error: Failed dependencies: glibc-devel >= 2.2.90-12 is needed by gcc-3.4.2-6.fc3.i386
Thanks to the information in the header of the gcc RPM package, I now know that I need a glibc-devel RPM of a certain version or greater. So I download the glibc-devel package from my favorite Fedora mirror, and try to install that:
# rpm -i glibc-devel-2.3.3-74.i386.rpm error: Failed dependencies: glibc-headers is needed by glibc-devel-2.3.3-74.i386 glibc-headers = 2.3.3 is needed by glibc-devel-2.3.3-74.i386
I'm a patient person, so I try again. I download the glibc-headers RPM and try installing that. I get the following result:
# rpm -i glibc-headers-2.3.3-74.i386.rpm error: Failed dependencies: kernel-headers is needed by glibc-headers-2.3.3-74.i386 kernel-headers >= 2.2.1 is needed by glibc-headers-2.3.3-74.i386
This process, which can go on for several levels, is also known as dependency hell.
With the yum command, you can take advantage of the headers to trace back through all dependencies automatically. Because yum repositories collect these headers in a database, you can install the GNU C Compiler and all dependent packages with the following command:
yum install gcc
This command searches through the repositories configured in your /etc/yum.repos.d directory. As you can see from the following excerpt, the command searches through the headers for each dependency and lists the packages to be downloaded and installed with the GNU C Compiler:
--> Processing Conflict: glibc-common conflicts glibc > 2.3.3 --> Processing Dependency: kernel-headers >= 2.2.1 for package: glibc-headers --> Processing Dependency Resolution with new changes. --> Populating transaction set with selected packages. Please wait. ---> Package glibc-common.i386 0:2.3.5-0.fc3.1 set to be updated ---> Downloading header for glibc-kernheaders to pack into transaction set. glibc-kernheaders-2.4-9.1 100% |==================| 71kB 00:00 ---> Package glibc-kernheaders.i386 0:2.4-9.1.87 set to be updated --> Running transaction check Dependencies Resolved Transaction Listing: Install: gcc.i386 0:3.4.3-22.fc3 - updates-released Performing the following to resolve dependencies: Install: glibc-devel.i386 0:2.3.5-0.fc3.1 - updates-released Install: glibc-headers.i386 0:2.3.5-0.fc3.1 - updates-released Install: glibc-kernheaders.i386 0:2.4-9.1.87 - base Install: cpp.i386 0:3.4.3-22.fc3 - updates-released Install: glibc.i686 0:2.3.5-0.fc3.1 - updates-released Install: glibc-common.i386 0:2.3.5-0.fc3.1 - updates-released Install: libgcc.i386 0:3.4.3-22.fc3 - updates-released Total download size: 28M Is this ok [y/N]:
But to optimize how yum works on your system, you should customize the related configuration files, understand different yum subcommands, configure a nightly update, and create your own yum repository. To customize the related configuration files, read the previous annoyance.
8.7.1. The yum Subcommands
There are a substantial number of yum subcommands. Run the yum command by itself to see the variety of options available. I've illustrated my output in Fedora Core 5:
[michael@FedoraCore64 ~]$ yum Loading "installonlyn" plugin You need to give some command usage: yum [options] < update | install | info | remove | list | clean | provides | search | check-update | groupinstall | groupupdate | grouplist | groupinfo | groupremove | makecache | localinstall | erase | upgrade | whatprovides | localupdate | resolvedep | shell | deplist > options: -h, --help show this help message and exit -t, --tolerant be tolerant of errors -C run entirely from cache, don't update cache -c [config file] config file location -R [minutes] maximum command wait time -d [debug level] debugging output level -e [error level] error output level -y answer yes for all questions --version show Yum version and exit --installroot=[path] set install root --enablerepo=[repo] enable one or more repositories (wildcards allowed) --disablerepo=[repo] disable one or more repositories (wildcards allowed) --exclude=[package] exclude package(s) by name or glob --obsoletes enable obsoletes processing during updates --noplugins disable Yum plugins [michael@FedoraCore64 ~]$
I'll explain some of the more important options here. For more information, see the yum HOWTO at http://www.phy.duke.edu/~rgb/General/yum_HOWTO/:
There are several yum commands related to groups, which are listed in the comps.xml file in the /usr/share/comps/`uname -i` directory. You can install or remove all of the mandatory and default packages in a group, along with dependencies. The details are beyond the scope of this annoyance.
8.7.2. Configuring a Nightly yum Update
The yum RPM includes its own cron job, which you can modify and activate to keep your system updated on a nightly basis. The job is located in the yum.cron file in the /etc/cron.daily directory. As defined in /etc/crontab, jobs in this directory are automatically run at 4:02 A.M. The default version of yum.cron includes some simple commands:
if [ -f /var/lock/subsys/yum ]; then /usr/bin/yum -R 120 -e 0 -d 0 -y update yum /usr/bin/yum -R 10 -e 0 -d 0 -y shell /etc/yum/yum-daily.yum fi
In other words, as long as no other yum command is already running at the noted time, this job first checks for an update of the yum package within the preceding two hours (-R 120). The second command, within the first 10 minutes (-R 10), updates the repository, as directed in yum-daily.yum. It proceeds to show only critical errors (-e 0), disable debugging (-d 0), and answer all prompts (including those that download and install) with a yes (-y).
The default directives in /etc/yum/yum-daily.yum (update, ts run, and exit) download all updates from your configured update repositories, use those updates to upgrade appropriate RPMs, and exit the yum shell.
If you want to exercise more control over certain updates, you may want to add an --exclude switch. For example, if you substitute the following for the first yum command, kernel-related packages are excluded from the update:
/usr/bin/yum -R 120 -e 0 -d 0 -y --exclude=kernel* update
Once you're satisfied with the cron job, you can let it run the next time your system is active at 4:02 A.M.; all you need to do is activate the yum daemon with the following command:
chkconfig yum on
8.7.3. Preparing Your Repository for Yum
In "Too Many Computers to Update over the Internet" in Chapter 11, I'll show how you can create your own Fedora repository from an available mirror. If you already have the packages you need, you can make it yum-aware; in other words, you can prepare your repository for yum with the right command.
Until recently, the standard for yum mifying a repository has been the yum-arch command. It's already a part of current yum RPMs. Starting with Fedora Core 3, Red Hat has adapted the createrepo command, which is part of an RPM of the same name.
The commands are simple; all you need to do is navigate to the directory with the RPMs that you want to configure as a yum repository and then run one of the following commands:
yum-arch . createrepo .
The yum-arch command separates the headers from the RPMs and collects them in a headers/ subdirectory. The createrepo command takes the headers, collects them in XML format, and then compresses them in the repodata/ subdirectory.
Once complete, you can share this directory using NFS, HTTP, or FTP, and connect to it from the clients of your choice.