Table of Contents
This chapter describes the framework known as pkginstall
, whose key features are:
Generic installation and manipulation of directories
and files outside the pkgsrc-handled tree, LOCALBASE
.
Automatic handling of configuration files during installation, provided that packages are correctly designed.
Generation and installation of system startup scripts.
Registration of system users and groups.
Registration of system shells.
Automatic updating of fonts databases.
The following sections inspect each of the above points in detail.
You may be thinking that many of the things described here
could be easily done with simple code in the package's
post-installation target (post-install
). This
is incorrect, as the code in them is only executed
when building from source. Machines using binary packages could
not benefit from it at all (as the code itself could be
unavailable). Therefore, the only way to achieve any of the
items described above is by means of the installation scripts,
which are automatically generated by pkginstall.
As you already know, the PLIST
file holds a list of files and
directories that belong to a package. The names used in it
are relative to the installation prefix (${PREFIX}
), which means that it cannot
register files outside this directory (absolute path names
are not allowed). Despite this restriction, some packages
need to install files outside this location; e.g., under
${VARBASE}
or ${PKG_SYSCONFDIR}
.
The only way to achieve this is to create such files
during installation time by using the installation scripts.
These scripts can run arbitrary commands, so they have the
potential to create and manage files anywhere in the file
system. Here is where pkginstall comes into play: it provides
generic scripts to abstract the manipulation of such files
and directories based on variables set in the package's
Makefile
. The rest of this section
describes these variables.
The following variables can be set to request the creation of directories anywhere in the file system:
MAKE_DIRS
and
OWN_DIRS
contain a list
of directories that should be created and should
attempt to be destroyed by the installation scripts.
The difference between the two is that the latter
prompts the administrator to remove any directories
that may be left after deinstallation (because they
were not empty), while the former does not.
MAKE_DIRS_PERMS
and
OWN_DIRS_PERMS
contain a
list of tuples describing which directories should be
created and should attempt to be destroyed by the
installation scripts. Each tuple holds the following
values, separated by spaces: the directory name, its
owner, its group and its numerical mode. For
example:
MAKE_DIRS_PERMS+= ${VARBASE}/foo/private ${ROOT_USER} ${ROOT_GROUP} 0700
The difference between the two is exactly the same
as their non-PERMS
counterparts.
Creating non-empty files outside the installation prefix
is tricky because the PLIST
forces all files to be inside it.
To overcome this problem, the only solution is to extract
the file in the known place (i.e., inside the installation
prefix) and copy it to the appropriate location during
installation (done by the installation scripts generated by
pkginstall). We will call the former the master file in the following
paragraphs, which describe the variables that can be used
to automatically and consistently handle files outside the
installation prefix:
CONF_FILES
and
SUPPORT_FILES
are pairs
of master and target files. During installation time,
the master file is copied to the target one if and
only if the latter does not exist. Upon
deinstallation, the target file is removed provided
that it was not modified by the installation.
The difference between the two is that the latter prompts the administrator to remove any files that may be left after deinstallation (because they were not empty), while the former does not.
CONF_FILES_PERMS
and
SUPPORT_FILES_PERMS
contain tuples describing master files as well as
their target locations. For each of them, it also
specifies their owner, their group and their numeric
permissions, in this order. For example:
SUPPORT_FILES_PERMS+= ${PREFIX}/share/somefile ${VARBASE}/somefile ${ROOT_USER} ${ROOT_GROUP} 0700
The difference between the two is exactly the same
as their non-PERMS
counterparts.
Configuration files are special in the sense that they are
installed in their own specific directory, PKG_SYSCONFDIR
, and need special treatment
during installation (most of which is automated by
pkginstall). The main concept you must bear in mind is that
files marked as configuration files are automatically copied
to the right place (somewhere inside PKG_SYSCONFDIR
) during installation
if and only if they
didn't exist before. Similarly, they will not be removed if
they have local modifications. This ensures that
administrators never lose any custom changes they may have
made.
As said before, the PKG_SYSCONFDIR
variable specifies where
configuration files shall be installed. Its contents are
set based upon the following variables:
PKG_SYSCONFBASE
: The
configuration's root directory. Defaults to
${PREFIX}/etc
although it may be
overridden by the user to point to his preferred
location (e.g., /etc
, /etc/pkg
, etc.). Packages must not
use it directly.
PKG_SYSCONFSUBDIR
: A
subdirectory of PKG_SYSCONFBASE
under which the
configuration files for the package being built shall
be installed. The definition of this variable only
makes sense in the package's Makefile
(i.e., it is not
user-customizable).
As an example, consider the Apache package,
www/apache2
, which places its
configuration files under the httpd/
subdirectory of PKG_SYSCONFBASE
. This should be set
in the package Makefile.
PKG_SYSCONFVAR
:
Specifies the name of the variable that holds this
package's configuration directory (if different from
PKG_SYSCONFBASE
). It
defaults to PKGBASE
's
value, and is always prefixed with PKG_SYSCONFDIR
.
PKG_SYSCONFDIR.${PKG_SYSCONFVAR}
:
Holds the directory where the configuration files for
the package identified by PKG_SYSCONFVAR
's shall be
placed.
Based on the above variables, pkginstall determines the
value of PKG_SYSCONFDIR
, which
is the only variable
that can be used within a package to refer to its
configuration directory. The algorithm used to set its
value is basically the following:
If PKG_SYSCONFDIR.${PKG_SYSCONFVAR}
is
set, its value is used.
If the previous variable is not defined but
PKG_SYSCONFSUBDIR
is set
in the package's Makefile
, the resulting value is
${PKG_SYSCONFBASE}/${PKG_SYSCONFSUBDIR}
.
Otherwise, it is set to ${PKG_SYSCONFBASE}
.
It is worth mentioning that ${PKG_SYSCONFDIR}
is automatically added
to OWN_DIRS
. See Section 12.1.1,
“Directory manipulation” what this
means.
Given that pkgsrc (and users!) expect configuration files to be in a known place, you need to teach each package where it shall install its files. In some cases you will have to patch the package Makefiles to achieve it. If you are lucky, though, it may be as easy as passing an extra flag to the configuration script; this is the case of GNU Autoconf- generated files:
CONFIGURE_ARGS+= --sysconfdir=${PKG_SYSCONFDIR}
Note that this specifies where the package has to look for its configuration files, not where they will be originally installed (although the difference is never explicit, unfortunately).
As said before, pkginstall automatically handles
configuration files. This means that the packages themselves must not touch the
contents of ${PKG_SYSCONFDIR}
directly. Bad news is that many software
installation scripts will, out of the box, mess with the
contents of that directory. So what is the correct
procedure to fix this issue?
You must teach the package (usually by manually patching
it) to install any configuration files under the examples
hierarchy, share/examples/${PKGBASE}/
. This way, the
PLIST
registers them and the
administrator always has the original copies available.
Once the required configuration files are in place
(i.e., under the examples hierarchy), the pkginstall
framework can use them as master copies during the package
installation to update what is in ${PKG_SYSCONFDIR}
. To achieve this, the
variables CONF_FILES
and
CONF_FILES_PERMS
are used.
Check out Section 12.1.2,
“File manipulation” for information about
their syntax and their purpose. Here is an example, taken
from the mail/mutt
package:
EGDIR= ${PREFIX}/share/doc/mutt/samples CONF_FILES= ${EGDIR}/Muttrc ${PKG_SYSCONFDIR}/Muttrc
Note that the EGDIR
variable is specific to that package and has no meaning
outside it.
System startup scripts are special files because they must be installed in a place known by the underlying OS, usually outside the installation prefix. Therefore, the same rules described in Section 12.1, “Files and directories outside the installation prefix” apply, and the same solutions can be used. However, pkginstall provides a special mechanism to handle these files.
In order to provide system startup scripts, the package has to:
Store the script inside ${FILESDIR}
, with the .sh
suffix appended. Considering the
print/cups
package as an example,
it has a cupsd.sh
in its files directory.
Tell pkginstall to handle it, appending the name of
the script, without its extension, to the RCD_SCRIPTS
variable. Continuing the
previous example:
RCD_SCRIPTS+= cupsd
Once this is done, pkginstall will do the following steps for each script in an automated fashion:
Process the file found in the files directory
applying all the substitutions described in the
FILES_SUBST
variable.
Copy the script from the files directory to the
examples hierarchy, ${PREFIX}/share/examples/rc.d/
. Note
that this master file must be explicitly registered in
the PLIST
.
Add code to the installation scripts to copy the startup script from the examples hierarchy into the system-wide startup scripts directory.
The automatic copying of config files can be toggled by
setting the environment variable PKG_RCD_SCRIPTS
prior to package
installation. Note that the scripts will be always copied
inside the examples hierarchy, ${PREFIX}/share/examples/rc.d/
, no matter
what the value of this variable is.
If a package needs to create special users and/or groups during installation, it can do so by using the pkginstall framework.
Users can be created by adding entries to the PKG_USERS
variable. Each entry has the
following syntax, which mimics /etc/passwd
:
user:group[:[userid][:[descr][:[home][:shell]]]]
Only the user and group are required; everything else is
optional, but the colons must be in the right places when
specifying optional bits. By default, a new user will have
home directory /nonexistent
, and login shell /sbin/nologin
unless they are specified as
part of the user element. Note that if the description
contains spaces, then spaces should be backslash-escaped, as
in:
foo:foogrp::The\ Foomister
Similarly, groups can be created using the PKG_GROUPS
variable, whose syntax is:
group[:groupid]
As before, only the group name is required; the numeric identifier is optional.
Packages that install system shells should register them
in the shell database, /etc/shells
, to make things easier to the
administrator. This must be done from the installation
scripts to keep binary packages working on any system.
pkginstall provides an easy way to accomplish this task.
When a package provides a shell interpreter, it has to set
the PKG_SHELL
variable to its
absolute file name. This will add some hooks to the
installation scripts to handle it. Consider the following
example, taken from shells/zsh
:
PKG_SHELL= ${PREFIX}/bin/zsh
Packages that install X11 fonts should update the database files that index the fonts within each fonts directory. This can easily be accomplished within the pkginstall framework.
When a package installs X11 fonts, it must list the
directories in which fonts are installed in the FONTS_DIRS.
variables, where
type
type
can be one of
“ttf”,
“type1” or
“x11”. This will add
hooks to the installation scripts to run the appropriate
commands to update the fonts database files within each of
those directories. For convenience, if the directory path is
relative, it is taken to be relative to the package's
installation prefix. Consider the following example, taken
from fonts/dbz-ttf
:
FONTS_DIRS.ttf= ${PREFIX}/lib/X11/fonts/TTF