• Aucun résultat trouvé

Interacting with the package database

Dans le document SYSTEM DEBIAN (Page 144-151)

The Debian package management system

5.3 Dealing with packages: dpkg

5.3.4 Interacting with the package database

dpkgmeticulously keeps track of all the packages it installs, and even remembers packages that were once installed but previously removed.

In the current incarnation ofdpkg, the package database is spread across a number of flat files. These are found in/var/lib/dpkg, which I will call thedpkgdatabase directory. Unless stated otherwise, all files and directories in the following reside below this directory.

The package database stores the following data for packages:

The state of the package (see below). These data are stored in thestatusfile.

If the package is installed (or removed, but not purged), the database contains the package’s full control information (following the state information in the statusfile).

The alternatives database (see chapter 6.1.4) inalternatives.

The permission override database (see chapter 6.1.2) instatoverride.

Belowinfo/, it keeps a record of each package’s installed files in*.listas well as itsconffiles (in*.conffiles). Also, it stores the four hook control script (*.*inst and*.*rm).

Optionally,dpkgstoresMD5sums of all files a package provides in info/*.md5-sums. See chapter 5.11.1 for more information.

debconfdata is also kept ininfo/:*.configand*.templates. See chapter 5.8 for more information.

Inavailable, dpkgstores the list of available packages, which is used only by dselect(see chapter 5.3.9).

cmethoptand themethodsdirectory are throwbacks from the days whendpkg integrated various acquisition means (e.g.FTP, HTTP). This is now handled byAPT, which is the only default acquisition method ofdpkg.

One ofdpkg’s main problems is performance, and the main culprit is the package database. Flat files scale linearly (at best) with the number of installed packages.

Among the to-do list entries fordpkgis the replacement of the database with a more powerful database format (which would scale logarithmically).

Now let us use the package database. A list of the installed packages can be ob-tained with the commanddpkg --list:

˜$ dpkg --list

Desired=Unknown/Install/Remove/Purge/Hold

| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed

|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)

||/ Name Version Description

+++-==============-==============-============================================

ii adduser 3.57 Add and remove users and groups ii apt 0.6.25 Advanced front-end for dpkg ii apt-doc 0.6.25 Documentation for APT ii apt-utils 0.6.25 APT utility programs

ii at 3.1.8-11 Delayed job execution and batch processing [...]

Each line corresponding to a package starts with three columns showing the status of the package. The first column identifies the status desired by the user and is limited to the following five states:

u The desired state is unknown, meaning that the package is not installed (and has never been) and the user did not request its installation.

i The user requested the installation of the package.

r The user requested the removal of the package.

p The user requested the purging of the package.

h The user requested that this package should be held at its current version and no automatic upgrades should be attempted.

In the second column, the current state of the package is encoded. The column may list any of the six states. If there is a serious problem (see below),dpkg-query uses an upper-case letter to indicate it.

n The package is not installed.

i The package is installed and fully configured.

c The package was previously installed and has since been removed, but its configuration files remain on the system.

u The package has been unpacked but not yet configured.

f The configuration of the package has been attempted but failed.

h The package was installed but the installation failed to complete.

Finally, the third column indicates error conditions and can assume one of four states. The first state indicates no problems and is not marked with a symbol. The other three symbols indicate problems.

h The package is on enforced hold because another package required in a ver-sioned dependency cannot be upgraded due to a hold.

r The package is broken and requires reinstallation before normal interaction is possible (including removal).

x The package is both broken and on enforced hold.

Inspecting single packages

Thedpkg --listcommand also accepts standard filename patterns (see your shell manual) to limit the output to matching packages. The filename patterns may need to be escaped or enclosed in quotes to prevent the shell from interfering:

˜$ dpkg --list ssh [...]

ii ssh 3.8.1p1-8.sarg Secure rlogin/rsh/rcp replacement (OpenSSH)

˜$ dpkg --list \*finger\* [...]

un cfingerd <none> (no description available) ii efingerd 1.6.2 Another finger daemon for unix un ffingerd <none> (no description available) un finger <none> (no description available) un fingerd <none> (no description available) un xfingerd <none> (no description available)

˜$ dpkg --list \?fingerd [...]

un cfingerd <none> (no description available) ii efingerd 1.6.2 Another finger daemon for unix un ffingerd <none> (no description available) un xfingerd <none> (no description available)

˜$ dpkg --list ’[ec]fingerd’

[...]

un cfingerd <none> (no description available) ii efingerd 1.6.2 Another finger daemon for unix

Many people use the output ofdpkg --listin scripts. For instance, the following command should purge all packages that have been previously removed (rc: the package should be removed but still has configuration files on the system).

˜# dpkg --list | grep ˆrc | awk ’{print $2}’ | xargs dpkg -P [...]

If you try the above, you are likely to see an error. The output ofdpkg --listis squeezed into the width available on the calling terminal, even if a pipe is attached.

Therefore, some package names will not be complete causing the above command to fail. To illustrate this, in the following, a field parser will only be able to obtain

“module-init-to” rather than the complete package namemodule-init-tools:

˜$ dpkg --list | grep module-init 1>&2 | awk ’{print $2} ii module-init-to 3.1-pre2-2 tools for managing ...

module-init-to

The solution is to override the column width using the $COLUMNS variable. Each line can then be forced to a certain length. Squeezing whitespace characters in the output withtrproduces usable output since the first three fields are guaranteed not to contain whitespace:

˜$ COLUMNS=1000 dpkg --list | grep module-init \

| tr -s ’ ’ 1>&2 | awk ’{print $2}

ii module-init-tools 3.1-pre2-2 tools for managing ...

module-init-tools

Especially for scripts, a query interface provided only bydpkg-queryis more useful as the displayed fields can be selected individually. If no format is specified, the package name is printed by default:

˜$ dpkg-query --show postfix postfix

˜$ dpkg-query --show --showformat=’${Package}\t${Status}\n’ mc postfix install ok installed

In the last example, the status corresponds to the first three columns in thedpkg --listoutput, though the second and third column are reversed: ii (with an empty third column to indicate “ok”).

Table 5.2:

Thus, a better way to purge all previously removed packages is:

˜# dpkg-query --show --showformat=’${Status} ${Package}\n’ \

| grep ˆdeinstall | cut -f4 | xargs dpkg -P

Speaking of fields, there is an easier way to access the information for an installed package. As you may guess, the field names in front of the colon on (almost) every line in the output of the following command are the same as you can use in --showformat.

˜$ dpkg --status postfix Package: postfix

Status: install ok installed Priority: extra

Section: mail [...]

Conffiles:

/etc/init.d/postfix 5fe44b0a0f8e510d10d1633d96b251b4 [...]

Essentially, the output ofdpkg --show postfixcorresponds to the output ofdpkg --info postfix.deb. The first includes some information relevant to the installed package (such as the status), while the second shows some data that only make sense in the context of a DEB file (such as the control files the package file provides).

Along similar lines, the functionality ofdpkg --contents postfix.debis also avail-able for the installedpostfix package:

˜$ dpkg --listfiles postfix [...]

/usr/sbin/postfix [...]

/var/spool/postfix [...]

Another useful tool isdpkg-awk, available in the package by the same name. It supports searching for packages which meet certain criteria, and optionally sorts the results. For instance, to print out the package name and status of packages with version numbers 0.01, 0.1, 0.02, or 0.2, sorted by section:

˜$ dpkg-awk --sort Section Version:ˆ0.0?[12]- -- Package Status Package: ed

Status: install ok installed Package: libtextwrap1 Status: install ok installed [...]

Searching the list of installed files

Since the package management tools track each file they install, you can query the database of installed files to figure out which package owns which file. This

comes in handy when you need to figure out why a file is on one but not another system, or to find the package and thuse.g.its documentation from a single file.

The command to search the database also accepts patterns to identify multiple files:

˜$ dpkg --search /usr/lib/postfix/*d postfix: /usr/lib/postfix/qmqpd postfix: /usr/lib/postfix/smtpd

˜$ dpkg --search bin/gawk gawk: /usr/bin/gawk

Hence, dpkg --search \* will list all files installed and managed by the Debian package management tools.

Even though its development stopped years ago,dlocateremains to be useful. It claims to be a fast alternative todpkg --listanddpkg --search, and provides a set of useful additional functionalities.

dpkg’s options--list,--search, and--listfilesare directly available as-l,-S, and-L respectively, which happen to be the same as the short options todpkg. The main advantage ofdlocateis its ability to feed sets of filenames (all the files in a package, just theconffiles, or all the manpages) to tools such asls,du, andmd5sum. For instance, the long listing of allconffilesis easily obtained:

˜# dlocate -lsconf postfix

-rwxr-xr-x 1 root root 2347 Oct 31 04:37 /etc/init.d/postfix*

-rwxr-xr-x 1 root root 21207 Oct 31 04:37 /etc/postfix/post-install*

-rw-r--r-- 1 root root 16114 Oct 31 04:37 /etc/postfix/postfix-files [...]

Furthermore,dlocateallows you to display and verify theMD5sums of installed packages. The following indicates that/etc/init.d/postfixdiffers from the version installed by the package (which is to be not an anomaly since the file is aconffile).

˜# dlocate -md5sum postfix

79ac631ecb6e3cbb1d8684aa6de101fc etc/init.d/postfix 0f6d12880a5f95b96037f15d658cecb0 etc/ppp/ip-up.d/postfix 0758469f9f1c073a53df50d9dc43c8eb etc/ppp/ip-down.d/postfix [...]

˜# dlocate -md5check postfix /etc/init.d/postfix FAILED /etc/ppp/ip-up.d/postfix OK /etc/ppp/ip-down.d/postfix OK

Putting a hold on packages

Packages can be put on hold to prevent their automatic upgrade. In addition, the package management tools may enforce a package hold because the dependencies

of an updated version cannot (yet) be satisfied. Manually putting packages on hold requires a little more than a single command, we will get to know higher-level tools to automate this process soon (see chapter 5.3.9 and chapter 5.4.11), as well as other methods better suited to the task (see chapter 8.2.1). Please note that a hold only affects automatic upgrades. If you explicitly request a held package to be upgraded,dpkgwill happily comply.

Recall the purpose of the first column in thedpkg --listoutput: to denote the de-sired (or requested) state of a package. A hold on a package is one of these dede-sired states, and it is possible to manipulate the requested state of each package with dpkg, withoutdpkgimmediately jumping to meet the request. The tuple linking the package to a desired state is referred to as a “selection” indpkg-parlance. We can usedpkgto get the table of selections corresponding to the current status of the packages. Without arguments,dpkg --get-selectionsreturns all packages which it knows about (i.e.all packages that are currently installed, or were installed at one point and removed later):

˜$ dpkg --get-selections apt-doc apt-utils at

apt-doc deinstall

apt-utils install

at hold

Manipulating the desired states of packages thus simply requires the appropri-ate modification to the second column for the line corresponding to the package whose status is to be changed. You can either export the list to a text file with dpkg --get-selections, modify the file as you wish, and then feed that modified version intodpkg --set-selections, or you can simply echo the requests intodpkg --set-selections:

˜# dpkg --list postfix [...]

ii postfix 2.1.5-1 A high-performance

˜# echo postfix hold | dpkg --set-selections

˜# dpkg --list postfix [...]

hi postfix 2.1.5-1 A high-performance

Dans le document SYSTEM DEBIAN (Page 144-151)