update gerrit list
[openafs-wiki.git] / devel / HowToBuildOpenAfsRpmPackages.mdwn
index 752dce2..ef21719 100644 (file)
-# Building RPM packages for OpenAFS
+[[!toc  levels=2]]
 
-This pages describes how to build OpenAFS client and server packages for RHEL
-and CentOS using the contributed RPM spec file available in the OpenAFS source
-tree.  Packages may be built from the OpenAFS release tar files or from a clone
-of the OpenAFS git repository.
+# Introduction
 
-## How to build release packages from an OpenAFS source distribution
+This guide shows how to build OpenAFS RPM packages for Red Hat Enterprise
+Linux, CentOS, and Fedora, using the contributed RPM spec file provided with
+the OpenAFS source code.
 
-The OpenAFS project provides a source code distributions of [releases][3]. A
-source RPM (src.rpm) file can be built from a source distribution release,
-which can then be used to build rpm packages.
+## Prerequisites
 
-Step 1. Download the source distribution files.
+Upgrade your kernel to the most recent version.
 
-Four files are provided; source tarball, documentation tarball, release notes,
-and a change log.
+    $ sudo yum update kernel
+    $ sudo reboot  # if updated
 
-    $ wget https://www.openafs.org/dl/openafs/1.8.5/openafs-1.8.5-src.tar.bz2
-    $ wget https://www.openafs.org/dl/openafs/1.8.5/openafs-1.8.5-doc.tar.bz2
-    $ wget https://www.openafs.org/dl/openafs/1.8.5/RELNOTES-1.8.5
-    $ wget https://www.openafs.org/dl/openafs/1.8.5/ChangeLog
+After rebooting (if neeed), install the kernel headers for your current kernel
+version.
 
-Step 2. Extract the packaging files.
+    $ sudo yum install "kernel-devel-uname-r == $(uname -r)"
 
-Extract packaging files contained in the source tarball.
+Install the `elfutils-devel` package if building on RHEL 8/CentOS 8.
 
-    $ tar xf openafs-1.8.5-src.tar.bz2 openafs-1.8.5/src/packaging/RedHat
+    $ sudo yum install elfutils-devel  # if RHEL/CentOS 8
 
-Step 3. Run the `makesrpm.pl` script to build the source rpm.
+Install the packages required to build the OpenAFS source RPM.
 
-    $ ./openafs-1.8.5/src/packaging/RedHat/makesrpm.pl \
-      openafs-1.8.5-src.tar.bz2 \
-      openafs-1.8.5-doc.tar.bz2 \
-      RELNOTES-1.8.5 \
-      ChangeLog
-    ...
-    SRPM is openafs-1.8.5-1.src.rpm
+    $ sudo yum install rpm-build yum-utils make perl libtool bzip2 wget
+
+The OpenAFS build dependencies will be installed after the source RPM file is
+generated in the steps below.
+
+# Building OpenAFS RPMs
+
+## Method 1: Building from source code distribution
+
+The OpenAFS Release Team provides software releases as source code
+distributions. A source RPM file can easily be built from a source
+distribution release with the `makesrpm.pl` script provided in the source tree.
+
+Download the source distribution files from [openafs.org][3].  Four files are
+provided in a release; a source tarball, a documentation tarball, release
+notes, and a change log.
+
+    $ VERSION=1.8.6  # for example
+    $ wget https://www.openafs.org/dl/openafs/${VERSION}/openafs-${VERSION}-src.tar.bz2
+    $ wget https://www.openafs.org/dl/openafs/${VERSION}/openafs-${VERSION}-doc.tar.bz2
+    $ wget https://www.openafs.org/dl/openafs/${VERSION}/RELNOTES-${VERSION}
+    $ wget https://www.openafs.org/dl/openafs/${VERSION}/ChangeLog
+
+Extract the `makesrpm.pl` script from the source tarball and then run it to
+generate the source RPM. The resulting source RPM will be placed in the current
+directory.
+
+    $ tar xf openafs-${VERSION}-src.tar.bz2 --strip-components=4 '*/makesrpm.pl'
+    $ perl makesrpm.pl openafs-${VERSION}-src.tar.bz2 openafs-${VERSION}-doc.tar.bz2 RELNOTES-${VERSION} ChangeLog
 
-Step 4: Build the rpm packages.
+Install the OpenAFS build dependencies with `yum-builddep`. This command will
+retrieve the required packages from the rpm spec file inside the source RPM.
 
-    $ rpmbuild --rebuild -bb --define "_topdir $(pwd)/rpmbuild" openafs-1.8.5-1.src.rpm
+    $ sudo yum-builddep openafs-${VERSION}-1.src.rpm
 
+Finally, run `rpmbuild` to build the binary RPMs.  The resulting RPMs will be
+placed in `$HOME/rpmbuild/RPMS`.
 
-## How to build release packages from git
+    $ rpmbuild --rebuild openafs-${VERSION}-1.src.rpm
 
-The following commands show how to build RPM packages from a git checkout of a
-released version of OpenAFS.  The following commands build RPM packages from a
-release tag.
+## Method 2: Building from a git checkout
+
+This method can be used to build rpms for OpenAFS from a git checkout of a
+release tag or the current stable or development branch.  A downside to this
+method is the release notes and change log provided in the OpenAFS source
+distribution releases are not included in the generated source RPM.
+
+When building packages from a git checkout, be sure to always build in a clean
+directory. In particular be sure the 'packages' directory is absent or empty
+before building rpms. Also, be sure there are no uncommitted source code
+changes. This method will only package code which has been committed, any
+uncommitted changes will not be packaged.
+
+The OpenAFS makefile includes the `make srpm` target to build a source RPM from
+a git checkout of a release or pre-release tag.  As of OpenAFS version 1.9.0,
+the OpenAFS makefile includes the `make rpm` tag.
+
+First, install the following packages needed to generate the makefile.
+
+    $ sudo yum install git make krb5-devel
+
+Create a local git clone of the OpenAFS git repository and checkout the tag or
+branch to be packaged.
 
     $ git clone git://git.openafs.org/openafs.git
     $ cd openafs
-    $ git checkout <openafs-release-tag>  # e.g., openafs-stable-1_8_5
+    $ git checkout <branch-or-tag>  # e.g., openafs-stable-1_8_5, openafs-devel-1_9_x, master
+
+Run the `regen.sh` tool to generate the `configure` script, then run
+`configure` to generate the OpenAFS makefile.  Make the `dist` and `srpm`
+targets to generate the source RPM. The resulting source RPM will be placed in
+the `./packages` directory.  (Note: The `configure` options given in this step
+are not used to generate the binaries. The actual configure options are defined
+in the spec file `openafs.spec.in`.)
+
+    $ ./regen.sh -q
+    $ ./configure --disable-kernel-module
+    $ make dist srpm
+
+Install the OpenAFS build dependencies with `yum-builddep`. This command will
+retrieve the required packages from the rpm spec file inside the source RPM.
+
+    $ sudo yum-builddep ./packages/openafs-*.src.rpm
+
+Build the binary RPMs with `rpmbuild`. By default, packages will be placed in
+`$HOME/rpmbuild/RPMS`. See **rpmbuild options** below for various rpmbuild
+options.
+
+    $ rpmbuild --rebuild packages/openafs-*.src.rpm
+
+The `make rpm` target is available as of OpenAFS 1.9.0.  This target will build
+the source distribution, source RPM, and binary RPM files. The rpm files will
+be placed in the `./packages/rpmbuild/RPMS` directory. If the build
+dependencies are already installed, the rpm files can be built with a single
+`make rpm` command after generating the `Makefile`.
+
+    $ ./regen.sh -q
+    $ ./configure --disable-kernel-module  # generate the Makefile
+    $ make rpm                             # create the source and binary rpm files
+
+## rpmbuild options
+
+The OpenAFS spec file provides several options to select which packages are to
+be built by `rpmbuild` and to enable certain build-time features in the
+binaries. These options are specified as `rpmbuild`  command line arguments.
+
+The `build_userspace` and `build_modules` defines control when the kernel
+module packages are to be built. Userspace packages includes all of the
+packages except the kernel module package, including the servers and the
+OpenAFS client Dynamic Kernel Module System (DKMS) package. By default,
+both the userspace and kernel modules are built.
+
+To build all of the packages except the OpenAFS kernel module:
+
+    $ rpmbuild \
+      --rebuild \
+      --define "build_userspace 1" \
+      --define "build_modules 0" \
+      ./packages/openafs-*.src.rpm
+
+To build only the OpenAFS kernel module for the currently running kernel:
+
+    $ rpmbuild \
+      --rebuild \
+      --define "build_userspace 0" \
+      --define "build_modules 1" \
+      ./packages/openafs-*.src.rpm
+
+Specify the `kernvers` option to build kernel modules for specific kernel
+versions.  Install `kernel-devel` packages for the versions you wish to build.
+You may need to configure and enable the CentOS Vault "update" repositories for
+older kernel versions.
+
+    # Install an older kernel-devel version.
+    $ sudo yum install kernel-devel-uname-r == "3.10.0-957.27.2.el7.x86_64"
+
+    $ rpm -qa kernel-devel
+    kernel-devel-3.10.0-957.27.2.el7.x86_64
+    kernel-devel-3.10.0-1062.12.1.el7.x86_64
+
+    $ rpm -i ./packages/openafs-*.src.rpm
+
+    $ rpmbuild \
+      -bb \
+      --define "build_userspace 0" \
+      --define "build_modules 1" \
+      --define "kernvers 3.10.0-957.27.2.el7.x86_64" \
+      ~/rpmbuild/SPECS/openafs.spec
+
+    $ rpmbuild \
+      --bb \
+      --define "build_userspace 0" \
+      --define "build_modules 1" \
+      --define "kernvers 3.10.0-1062.12.1.el7.x86_64" \
+      ~/rpmbuild/SPECS/openafs.spec
+
+Additional `rpmbuild` options provided by the OpenAFS spec file are:
+
+* `--without authlibs`  Disable authlibs package
+* `--without krb5`  Disable krb5 support
+* `--with bitmap-later` Enable "bitmap later" support
+* `--with bos-restricted` Enable "bos restricted" mode
+* `--with supergroups`   Enable "supergroups"
+* `--with kauth`  Build the obsolete kaserver and related programs
+
+## Common errors
 
-    $ ./regen.sh
-    $ ./configure  # configure options are not required here.
-    $ make dist    # creates the source distribution in ./packages
-    $ make srpm    # get the source rpm name from the output
+Avoid kernel module build errors by ensuring you have a kernel-devel package
+installed which matches the running kernel.
 
-    $ rpmbuild --rebuild -ba --define "_topdir $(pwd)/packages/rpmbuild" packages/<name>.src.rpm
+    $ uname -r
+    4.18.0-147.5.1.el8_1.x86_64
+    $ rpm -qP kernel-devel | grep uname
+    kernel-devel-uname-r = 4.18.0-147.5.1.el8_1.x86_64
 
-The RPM packages will be created in the `packages/rpmbuild/RPMS` directory.  See
-the RPM spec file in src/packaging/RedHat for `--define` options for optional
-features and packages.
+Your build may fail with the error:
 
-Note: One downside to this method is the RELNOTES and ChangeLog from the
-OpenAFS release download page are not included in the built packages.
+    + /usr/lib/rpm/check-rpaths
+    ...
+    ERROR   0001: file '/usr/lib64/libafsauthent.so.2.0.0' contains a standard rpath '/usr/lib64' in [/usr/lib64]
+
+This check fails because the OpenAFS spec hardcoded the `/usr/lib64` standard
+paths for some binaries. The Linux dynamic loader automatically loads shared
+objects from this system default path, so the path specified in the spec file is
+redundant.
+
+To disable this `check-rpath` check, set the `QA_RPATHS` environment variable
+to `0x0001` before running rpmbuild.
+
+    $ export QA_RPATHS=0x0001
+    $ rpmbuild -bb ~/rpmbuild/SPECS/openafs.spec
+
+# Installing OpenAFS RPMs
+
+## Installing client RPMs with the Dynamic Kernel Module System (DKMS)
+
+The Dynamic Kernel Module System (DKMS) kernel modules take longer to install,
+but are automatically rebuilt after the kernel is upgraded on the target
+system. Unless you are maintaining, or have access to, a yum repository which
+tracks kernel updates and builds matching OpenAFS kernel modules for each
+update, you will want to use the DKMS method to install the OpenAFS kernel
+module.
+
+Add the EPEL yum repository, which provides the DKMS system.  Install the
+Kerberos5 workstation package, which provides the `kinit` program. Install the
+OpenAFS DKMS and openafs Kerberos5 support packages with `yum`. This will take
+some time as the kernel-module is built from source.  Be sure to install the
+openafs-client and  packages in a single `yum install` invocation.
+
+    $ cd ~/rpmbuild/RPMS/x86_64
+    $ sudo yum install epel-release
+    $ sudo yum install make
+    $ sudo yum install "kernel-devel-uname-r == $(uname -r)"
+    $ sudo yum install \
+        krb5-workstation \
+        openafs-1.8.5-1.el8.x86_64.rpm \
+        openafs-docs-1.8.5-1.el8.x86_64.rpm \
+        openafs-krb5-1.8.5-1.el8.x86_64.rpm \
+        openafs-client-1.8.5-1.el8.x86_64.rpm \
+        dkms-openafs-1.8.5-1.el8.x86_64.rpm
+
+## Installing client RPMs with a pre-built kernel module (kmod)
+
+Install the kmod which matches your currently running kernel version.  Be sure
+to install the openafs-client and kmod-openafs packages in a single `yum
+install` invocation.
+
+    $ cd ~/rpmbuild/RPMS/x86_64
+    $ sudo yum install \
+        krb5-workstation \
+        openafs-1.8.5-1.el8.x86_64.rpm \
+        openafs-docs-1.8.5-1.el8.x86_64.rpm \
+        openafs-krb5-1.8.5-1.el8.x86_64.rpm \
+        openafs-client-1.8.5-1.el8.x86_64.rpm \
+        kmod-openafs-1.8.5-1.4.18.0_147.5.1.el8_1.x86_64.rpm
+
+## Installing server RPMs
+
+Install the server package with:
+
+    $ cd ~/rpmbuild/RPMS/x86_64
+    $ sudo yum install \
+        openafs-1.8.5-1.el8.x86_64.rpm \
+        openafs-docs-1.8.5-1.el8.x86_64.rpm \
+        openafs-server-1.8.5-1.el8.x86_64.rpm
+
+# Advanced topics
+
+## Building RPMs with mock
+
+[Mock][4] is a tool for building packages in a chroot. The mock chroot
+isolation makes it makes it easier to build a large number of kernel module
+versions on a single build host. In addition, mock provides a clean build
+environment for each build and mock will automatically install the build
+requirements specified by the openafs.spec file in the temporary mock chroot.
+
+Mock also provides the ability to build RPMs for different distributions on one
+machine. For example, one could build RPMs targeted for CentOS 6, 7, and 8 on
+single CentOS 8 build host. Although it is possible to build RPMs for other
+distributions with mock, it not possible to build RPMs for other architectures
+since mock does not support cross-compiling.
+
+Install mock and add yourself to the 'mock' group.
+
+    $ sudo yum install mock
+    $ sudo usermod -a -G mock $USER
+    $ newgrp - mock
 
-## How to build release packages with afsutil
+To build OpenAFS rpms with mock, first create the OpenAFS source RPM as shown
+above, then run the mock commands to build the packages using the mock system.
 
-The contributed `afsutil`[1] script can be used to build packages from a git
-checkout. This tool is a front-end with various options to support building
-client and server packages from release tags as well as non-release commits.
-`afsutil` is available on [PyPI][2] and [github][1]
+    $ mock --rebuild ./packages/openafs-*.src.rpm
 
+## Building RPMs with afsutil
 
-    $ pip install afsutil
+[afsutil][5] is a python tool to facilitate OpenAFS development.  The `afsutil
+package` command is a front-end tool for building RPMs from a git checkout,
+with or without mock.  When used with mock, `afsutil` will, by default, build
+kernel modules for every kernel-devel version discovered in the enabled yum
+repositories within the mock chroot.
 
+OpenAFS packages require a copy of the CellServDB client configuration file.
+`afsutil package` will automatically download the CellServDB version specified
+in the spec file from grand.central.org. An alternate CellServDB file can be
+specified by url or local path with the `--csdb` option.
+
+RPM packages for `afsutil` are available. This is the preferred installation
+method on CentOS.  Alternatively, `afsutil` may be installed with `pip` or
+from source.
+
+### Method 1: Installing afsutil with yum
+
+Create the yum configuration file `/etc/yum.repos.d/sna-openafs-contrib.repo`:
+
+    [sna-openafs-contrib]
+    name=Sine Nomine Associates: Contributed Extras for OpenAFS
+    baseurl=https://download.sinenomine.net/openafs/contrib/packages/CentOS/$releasever
+    enabled=1
+    gpgcheck=0
+
+Install `afsutil` with `yum`:
+
+    $ sudo yum install afsutil
+
+### Method 2: Installing afsutil with pip
+
+    $ sudo yum install epel-release   # if RHEL/CentOS
+    $ sudo yum install python2-pip    # if RHEL/CentOS 8
+    $ sudo yum install python-pip     # if RHEL/CentOS 7 or earlier
+    $ pip install --user afsutil
+
+### Method 3: Installing afsutil from source
+
+    $ git clone https://github.com/openafs-contrib/afsutil
+    $ cd afsutil
+    $ python configure.py  # or, python2 configure.py on RHEL/CentOS 8
+    $ make install-user
+
+### Building RPMs with afsutil
+
+To build OpenAFS packages from a git checkout:
+
+    $ sudo afsutil getdeps  # Install build dependencies
     $ git clone git://git.openafs.org/openafs.git
     $ cd openafs
-    $ git checkout <tag>  # e.g., openafs-stable-1_8_5
+    $ afsutil package
 
-    $ afsutil package [options]
+The `afsutil package` command will build packages for the userspace and kernel
+modules by default. See the `--build` option to build these separately.
 
-The RPM packages will be created in the `packages/rpmbuild/RPMS` directory.
+If you installed `mock` (see above), specify the `--mock` option to build the
+packages in the mock chroot. Mock will automatically install the build
+dependencies.
 
-Some commonly used `afsutil package` options are:
+Build the server, client, and kernel module for the local machine with:
 
-    --version=<custom-version> # for testing or building custom versions
-    --csdb=<path-to-custom-CellServDB-file>
-    --spec=<path-to-custom-openafs-spec-file>
-    --build=<what to build, one of: all, sources, srpm, userspace, kmods>
-    --kernel-version=<kernel-version> # may be given more than once
+    $ afsutil package --mock --kernel="$(uname -r)"
 
-See `afsutil package --help` for a complete list of options.
+`afsutil package --mock` will query the yum repositories configured for the
+mock chroot to discover the kernel-devel kernel versions available.  You can
+add local yum repositories to your mock configurations in `/etc/mock/` to
+provide kernel-devel packages for older kernel versions.
 
+To list kernel versions available in the mock chroot:
 
-## A note about version strings
+    $ afsutil package --mock --list 2>/tmp/error
+    3.10.0-1062.4.2.el7
+    3.10.0-1062.4.3.el7
+    3.10.0-1062.9.1.el7
+    3.10.0-1062.12.1.el7
+    ...
 
-RPM packages require a valid version string and package release number.  If you
-are building packages for a non-release version (or not a pre-release), you
-will need to set a customized version string in the spec file.
+Specify the --kernel option to build a kmod for specific kernel version. This
+option may be given more than once to build multiple kernel modules.
 
-For example, perhaps you want to make changes and build packages for testing,
-or perhaps you wish to deploy packages with custom changes or fixes. In these
-cases you will need to provide a customized version string.
+   $ afsutil package --mock --build=kmods --kernel=3.10.0-1062.4.3.el7
 
-Specify your customer version string in the `.version` file to generate a
-`openafs.spec` file with your desired version.  If you are using the `afsutil
-package` contributed script, use the `--version` option to specify your custom
-version.
+To build all kernel module versions:
+
+    $ afsutil package --mock --build=kmods
+
+If the afsutil package command is interrupted and then restarted, builds for
+any already completed kmod-openafs RPMs will be skipped. Use the the --clobber
+option to override this and force all of the RPMs to be rebuilt.
+
+See `afsutil package --help` for the available options.  Default values for
+options may be specified in the `.afsutil.cfg` configuration file. See
+the [afsutil README][5] for more information.
+
+# See also
+
+* [RPM Packaging Guide][6]
 
 
 [1]: https://github.com/openafs-contrib/afsutil
 [2]: https://pypi.org/project/afsutil/
 [3]: https://www.openafs.org/release/
+[4]: https://github.com/rpm-software-management/mock/wiki
+[5]: https://github.com/openafs-contrib/afsutil
+[6]: https://rpm-packaging-guide.github.io/