.. only:: html

 piuparts(1)
 ===========
 :doctype: manpage
 :revdate: 2023-01-18

.. program:: piuparts

SYNOPSIS
--------
**piuparts** [:option:`-a` :option:`-p` :option:`-v` :option:`-V`] [:option:`-d` *distro*] [:option:`-i` *filename*] [:option:`-I` *regexp*] [:option:`-l` *logfile*] [:option:`-m` *URL*] [:option:`--bindmount` *dir*] [*package* ...] [*changes\_file* ...]

DESCRIPTION
-----------
:program:`piuparts` tests that Debian packages handle installation, upgrading, and removal correctly. It does this by creating a minimal Debian installation in a chroot, and installing, upgrading, and removing packages in that environment, and comparing the state of the directory tree before and after. :program:`piuparts` reports any files that have been added, removed, or modified during this process.

:program:`piuparts` is meant as a quality assurance tool for people who create Debian packages to test them before they upload them to the Debian package
archive.

By default, piuparts can do three different tests:

* A simple install-purge test within one Debian distribution (chosen with the :option:`-d` option, unstable by default). It sets up the chroot with the desired distribution, then installs and purges the packages, and reports problems.

* A simple install-upgrade-purge test within one Debian distribution. This test is like the install-purge test, but it installs the packages first via :program:`apt-get` and then upgrades them with the package files given on the command line. If the command line has package names (option :option:`--apt` used), or no tested package is known to :program:`apt-get` (new packages), this test is skipped, otherwise it is performed automatically.

* An upgrade test between Debian releases. This test is enabled by using the :option:`-d` option multiple times and disables the other two tests. It sets up the chroot with the first distribution named, then upgrades it to each successive one, and then remembers the directory tree state at the end. After this, it starts over with the chroot of the first distribution, installs the desired packages (via :command:`apt-get install`), and does the successive upgrading (via :command:`apt-get dist-upgrade`). Then, if package files (and not just package names) were given on the command line, it installs them. Finally, it reports problems against the state of the directory tree at the last distribution compared with the state without the packages having been installed. This test can be quite slow to execute. Note that this does not work with experimental, because :program:`apt-get` does not automatically upgrade to packages in experimental. To test a particular package or group of packages in experimental, use the second test.


Command line arguments are the paths to package files (e.g., ``piuparts_1.0-1_all.deb``), paths to changes files (e.g., ``piuparts_1.0-1_i386.changes``), or names of packages, if the :option:`--apt` option is given.

When processing changes files, by default, all packages in a changes file will be processed together with all individual packages given on the command line. Then each package given on the command line is processed in a single group. If :option:`--single-changes-list` is used, the packages in all changes files are processed together along with any individual packages that were given on the command line. To avoid this behaviour, it is possible to specify :option:`--single-packages`.

:program:`piuparts` outputs to the standard output some log messages to show what is going on. If a log file is used, the messages go there as well.

:program:`piuparts` requires root rights to test packages. It does not have to be run in the initial namespace though. When running it as non-root, it'll create a new Linux namespace and rerun itself as root inside said namespace. For this to work, your user needs have an subuid range (which happens by default since a few years) and you need to install the `uidmap` package to provide setuid helpers :program:`newuidmap` and :program:`newgidmap`.

OPTIONS
-------
Options must come before the other command line arguments.

.. option:: -a, --apt

  The package arguments on the command line are to be treated as package names and installed via :command:`apt-get install` instead of being names of package files, to be installed via :command:`dpkg -i`.

.. option:: --allow-database

  Allow starting MySQL and PostgreSQL database servers in the chroot for
  packages requiring database access in their maintainer scripts.
  Do not use this option if there is already a database server running on the
  system running :program:`piuparts` (or :program:`piuparts-slave`)!
  In master-slave setups with multiple slaves running on one host collisions
  may occur, these will be detected by :program:`detect_piuparts_issues` and the
  affected packages will be tested again.

.. option:: --arch arch

  Create chroot and run tests for (non-default) architecture *arch*. The default is the output from :command:`dpkg --print-architecture`.

.. option:: -b tarball, --basetgz tarball

  Use :file:`tarball` as the contents of the initial chroot, instead of building a new one with :program:`debootstrap`.

  The tarball can be created with the :option:`-s` option, or you can use one that :program:`pbuilder` has created (see :option:`-p`). If you create one manually, make sure the root of the chroot is the root of the tarball. Despite the option name implying gzip compression, the compression scheme is deduced by :program:`tar` from the filename suffix.

.. option:: --bindmount dir

  Bind-mount a directory inside the chroot.

.. option:: --bootstrapcmd cmd

  Set alternative chroot bootstrap command (including command line options). The default is ``debootstrap --variant=minbase``. Needs to be compatible with typical ``debootstrap`` command line options such as ``--arch`` and ``--include``. For ``mmdebstrap`` use: ``--bootstrapcmd=mmdebstrap --skip=check/empty --variant=minbase``.

.. option:: -d name, --distribution name

  Which Debian distribution to use: a code name (for example ``bullseye``, ``bookworm`` or ``sid``) or ``experimental``. The default is ``sid`` (= ``unstable``).

.. option:: -D flavor, --defaults flavor

  Use default settings suitable for a particular flavor of Debian: either ``debian`` or ``ubuntu``. The default is ``debian``.

.. option:: --do-not-verify-signatures

  Do not verify signatures from the Release files when running debootstrap. Also set ``APT::Get::AllowUnauthenticated`` accordingly in :file:`/etc/apt/apt.conf` in the chroots.

.. option:: --dpkg-force-confdef

  Make :program:`dpkg` use ``--force-confdef``, which lets :program:`dpkg` always choose the default action when a modified conffile is found. This option will make :program:`piuparts` ignore errors it was designed to report and therefore should only be used to hide problems in depending packages. *This option shall normally not be used.* (See `#466118 <https://bugs.debian.org/466118>`_.)

.. option:: --dpkg-noforce-unsafe-io

  Prevent running :program:`dpkg` with ``--force-unsafe-io``.  ``--force-unsafe-io`` causes :program:`dpkg` to skip certain file system syncs known to cause substantial performance degradation on some filesystems.  Thus, including this option reverts to safe but slower behavior.  The :option:`--dpkg-noforce-unsafe-io` is required for running tests on distributions older than squeeze.

.. option:: --no-eatmydata

  Prevent use of eatmydata.  The --no-eatmydata option is required for running tests on squeeze or older distributions.

.. option:: --extra-old-packages pkg1[,pkg2]...

  Install additional old packages before upgrading.  Allows testing package renames/merges where the old package is no longer available in the new distribution and the new one utilizes Conflicts/Replaces.  The argument is a comma separated list of package names and the option can be given multiple times.
  For install/purge tests these packages will be installed before the package
  that is to be tested.

.. option:: -e dirname, --existing-chroot dirname

  Use the specified directory as source for the new chroot, instead of building
  a new one with debootstrap. This is similar to :option:`--basetgz`, but the contents
  are not archived. See also the :option:`--hard-link` option.

.. option:: --distupgrade-to-testdebs

  Use the "testdebs" repository to override the packages in the distupgrade
  target distribution. This allows one to test complex upgrade paths before the
  packages enter the archive.

.. option:: --extra-repo deb-line

  Provide an additional (unparsed) line to be appended to :file:`sources.list`, for example::

    'deb <URL> <distrib> <components>'
     or
    'deb file:// </bind/mount> ./'

  Useful for e.g. backports, security or local repositories that cannot be
  handled by :option:`--mirror`. May be repeated to add more than one line.

.. option:: --fake-essential-packages pkg1[,pkg2]...

  Install additional packages in the base chroot that are not removed after
  the test. These are available during purge and for checking against
  mistreatment.
  Takes a comma separated list of package names and can be given multiple
  times.

.. option:: --hard-link

  When the :option:`--existing-chroot` option is used, and the source directory is on the
  same filesystem, hard-link files instead of copying them. This is faster, but
  any modifications to files will be reflected in the originals.

.. option:: -i filename, --ignore filename

  Add a filename to the list of filenames to be ignored when comparing changes
  before and after installation. By default, :program:`piuparts` ignores files that always
  change during a package installation and uninstallation, such as :program:`dpkg`
  status files. The filename should be relative to the root of the chroot
  (e.g., :file:`var/lib/dpkg/status`).
  Filenames prefixed with a ``:`` will be logged verbosely if found.
  This option can be used as many times as necessary.

.. option:: -I regexp, --ignore-regexp regexp

  Add a regular expression pattern to the list of patterns for filenames to be
  ignored when comparing changes before and after installation.
  Patterns prefixed with a ``:`` will log verbosely all matching files.
  This option can be used as many times as necessary.

.. option:: --install-purge-install

  Purge package after installation and reinstall. All dependencies are available during purge.

.. option:: --install-recommends

  Enable installation of Recommends.

.. option:: --install-suggests

  Enable installation of Suggests.

.. option:: --install-remove-install

  Remove package after installation and reinstall. For testing installation in config-files-remaining state.

.. option:: -k, --keep-env

  Depending on which option is passed, keep the environment used for testing after the program ends

   * By default it doesn't remove the temporary directory for the chroot,
   * or if :option:`--schroot` is used, the schroot session is not terminated,
   * or if :option:`--docker-image` is used, the container created is not destroyed.

.. option:: -K filename, --keyring filename

 Use :file:`filename` as the keyring to use with debootstrap when creating chroots.

.. option:: --keep-sources-list

  Don't modify the chroot's :file:`/etc/apt/sources.list`.

.. option:: --list-installed-files

  List the files added to the chroot after the installation of the package and after the installation of the package dependencies.

.. option:: --lvm-volume lvm-volume

  Use the specified *lvm-volume* as source for the chroot, instead of building a
  new one with debootstrap. This creates a snapshot of the given LVM volume and
  mounts it to the chroot path.

.. option:: --lvm-snapshot-size snapshot-size

  Use the specified *snapshot-size* as snapshot size when creating a new LVM
  snapshot (default: 1G)

.. option:: -l filename, --log-file filename

  Append log file to :file:`filename` in addition to the standard output.

.. option:: --log-level level

  Display messages from loglevel *level*, possible values are: *error*, *info*, *dump*, *debug*. The default is *dump*.

.. option:: --max-command-output-size size

  Set the maximum permitted command output to *size* (in MB) for debugging
  runs exceeding the default of 8 MB.

.. option:: --merged-usr

  When using debootstrap to create the chroot, use the ``--merged-usr`` option
  to create a chroot with :file:`/bin`, :file:`/lib`, :file:`/sbin` being symlinks to their :file:`/usr`
  counterparts.

.. option:: --no-merged-usr

  When using debootstrap to create the chroot, use the ``--no-merged-usr`` option.

.. option:: -m URL, --mirror URL

  Which Debian mirror to use. The default is the first mirror named in :file:`/etc/apt/sources.list` or ``http://deb.debian.org/debian`` if none is found. This option may be used multiple times to use multiple mirrors. Only the first mirror is used with :program:`debootstrap`.

  The 'components' that are used for a mirror can also be set with this option: a space separated list within the same argument (so you need to quote the entire argument in the shell). If no components are given explicitly, the usual Debian components are used (*main*, *contrib*, *non-free* and *non-free-firmware*). For the mirrors read from :file:`/etc/apt/sources.list`, the components are read from the same place.

 Note that ``file:`` addresses work if the directories are made accessible from within the chroot with :option:`--bindmount`.

.. option:: --no-adequate

  Don't run :program:`adequate` after installation. The default is to run :program:`adequate`, provided it is installed.

.. option:: --no-check-valid-until

  Set :program:`apt` option ``Acquire::Check-Valid-Until=false`` in the chroot to ignore the
  expiration of Release files. This is needed for testing archived releases.

.. option:: --no-diversions

  Don't check for broken diversions.

.. option:: -n, --no-ignores

  Forget all built-in and other ignores that have been set so far. Any :option:`-i` or :option:`-I` arguments that come after this one will be obeyed, but none of the ones that come before.

.. option:: -N, --no-symlinks

  Don't check for broken symlinks.

.. option:: --fail-if-inadequate

  Fail on inadequate results from running :program:`adequate`. The default is to just issue those errors as warnings.

.. option:: --fail-on-broken-symlinks

  Fail on broken symlinks. The default is to just issue those errors as warnings.

.. option:: --no-upgrade-test

  Skip testing upgrade from an existing version in the archive.

.. option:: --no-install-purge-test

  Skip the install and purge test.

.. option:: -p, --pbuilder

  Use :file:`/var/cache/pbuilder/base.tgz` as the base tarball. This is a shorthand so that you don't need to use :option:`-b` for it.

.. option:: --pedantic-purge-test

  Be pedantic when checking if a purged package leaves files behind. If this option is not set, files left in :file:`/tmp` are ignored.

.. option:: --proxy URL

  Use the proxy at *URL* to access the Debian mirror(s). Takes precedence over
  the :envvar:`http_proxy` environment variable. Using a local proxy is recommended
  because :program:`piuparts` may use large amounts of bandwidth to repeatedly download
  the same files.

.. option:: -s filename, --save filename

  Save the chroot, after it has been set up, as a tarball into :file:`filename`. It can then be used with :option:`-b`.

.. option:: -B filename, --end-meta filename

  Load chroot package selection and file meta data from :file:`filename`. See the function :func:`install_and_upgrade_between_distros` in :file:`piuparts.py` for defaults. Mostly useful for large scale distro upgrade tests.

.. option:: -S filename, --save-end-meta filename

  Save chroot package selection and file meta data in :file:`filename` for later use. See the function :func:`install_and_upgrade_between_distros` in :file:`piuparts.py` for defaults. Mostly useful for large scale distro upgrade tests.

.. option:: --scriptsdir directory

  Directory where are custom scripts are placed. By default, this is not set. For more information about this, read :file:`README_server.txt`

.. option:: --schroot SCHROOT-NAME

  Use schroot session named *SCHROOT-NAME* for the testing environment, instead of building a new one with :program:`debootstrap`.

.. option:: --docker-image DOCKER-IMAGE

  Use a container created from the docker image *DOCKER-IMAGE* for the testing environment, instead of building a new one with :program:`debootstrap`.
  This only supports ``overlay2`` for now and it uses the ``MergedDir`` layer where :program:`piuparts` can access, add, edit and remove files easily by directly accessing the directory.

.. option:: --single-changes-list

  When processing changes files, :program:`piuparts` will process the packages in each individual changes file separately. This option will set :program:`piuparts` to scan the packages of all changes files together along with any individual package files that may have been given on the command line.

.. option:: --single-packages

  Process every package file or package name individually, thus :program:`piuparts` process runs multiple times. This option can be useful with conflicting packages.

.. option:: --shell-on-error

  Start an interactive shell in the chroot after an error occurred.
  This should help debugging failures directly inside the :program:`piuparts` test environment.
  The chroot cleanup will continue after the shell terminates.
  Note: This does not work if the :program:`piuparts` command is prefixed with 'timeout',
  which is usually the case in command lines directly copied from logfiles
  from a master-slave setup. Removing the 'timeout' part is sufficient.

.. option:: --skip-minimize

  Allow skip minimize chroot step. This is useful when you want to test several packages with :program:`piuparts`. You can prepare a tarball already minimized and skip this step in all the tests. This is the default now.

.. option:: --minimize

  Minimize the chroot with debfoster. This used to be the default until `#539142 <https://bugs.debian.org/539142>`_ was fixed.

.. option:: --skip-cronfiles-test

  Skip testing the output from the cron files left in the system after remove a package.

.. option:: --skip-logrotatefiles-test

  Skip testing the output from the logrotate files left in the system after remove a package.

.. option:: --testdebs-repo deb-line

  Provide an additional line to be appended to sources.list, for example::

    'deb [ trusted=yes ] <URL> <distrib> <components>'
     or
    'deb [ trusted=yes ] file:// </bind/mount> ./'

  If only an URL or local path is given as argument, ``deb [ trusted=yes ]``,
  ``file://``, and ``./`` will be prepended/appended as needed.
  The "testdebs" repository provides the packages to be tested (and some
  additional dependencies, if needed, e.g. all packages built from the same
  source package as the (binary) package being tested) and can be used for
  testing complex installation and upgrade scenarios involving dependencies
  that are not yet in the archive. This repository will be available only
  for installing the target packages. Dependency resolution will be done by
  :program:`apt-get`. The packages to be tested can be passed as ``.deb``\ s or as package
  names (with :option:`--apt`).

  The ``trusted=yes`` option causes this (and only this) repository to be
  trustworthy even if the Packages file is not signed, such that a
  (globally acting) :option:`--do-not-verify-signatures` will not be needed.

.. option:: -t directory, --tmpdir directory

  Use *directory* as the place where temporary files and directories are created. The default is the environment variable :envvar:`TMPDIR`, or :file:`/tmp` if not set.
  Note: the temporary directory must *not* be mounted with the *nodev* or *nosuid* mount option.

.. option:: --update-retries num-retries

  Rerun :command:`apt-get update` up to *num-retries* times.
  Useful to work around temporary network failures and hashsum mismatch errors.

.. option:: --upgrade-before-dist-upgrade

  Perform two-stage upgrades: :command:`apt-get upgrade && apt-get dist-upgrade`.

.. option:: -v, --verbose

  This option no longer has any meaning, but it is still accepted for backwards compatibility.

.. option:: -V, --version

  Write out the version number of the program.

.. option:: --warn-on-debsums-errors

  Print a warning rather than failing if debsums reports modified files.

.. option:: --warn-on-leftovers-after-purge

  Print a warning rather than failing if files are left behind after purge.

.. option:: --warn-on-others

  Print a warning rather than failing if files are left behind, modified, or removed by a package that was not given on the command-line.

  This way, you can basically isolate the purge test to your own packages. If a package that is brought in as a dependency doesn't purge cleanly, the test will not fail because of it (but a warning message will be printed).

  Behavior with multiple packages given on the command-line could be problematic, particularly if the dependency tree of one package in the list includes another in the list. Therefore, it is recommended to use this option with one package at a time.

.. option:: --warn-on-usr-move disabled|warn|fail

  Whether to enable the test (with a warning or a failure) that checks if files are moved between :file:`/\{bin|sbin|lib*\}` and :file:`/usr/\{bin|sbin|lib*\}`.
  Accepted values: *disabled* (default), *warn*, *fail*.



EXAMPLES
--------
Assume that you have just built a new version of your Debian package, to be uploaded to Debian unstable. It is in ``../foo_1.0-2_i386.deb`` and you would like to know whether it installs and uninstalls properly. Here's what you would do::

  piuparts ../foo_1.0-2_i386.deb

If the package exists in the Debian archive already, the above command also tests that it upgrades properly.

To do the same test, but using a particular mirror, and only the main component, you would do this::

  piuparts -m 'http://gytha/debian main' ../foo_1.0-2_i386.deb

If you want to do the same as above but for your changes files, pass in your changes files when running :program:`piuparts`, and :program:`piuparts` will process each package in the changes files as though you had passed all those packages on the command line to :program:`piuparts` yourself. For example::

  piuparts ../foo_1.0-2_i386.changes

  piuparts -m 'http://gytha/debian main' ../foo_1.0-2_i386.changes

If you want to test that a package installs properly in the stable (currently bullseye) Debian release, then can be upgraded to the testing (currently bookworm) and unstable (sid) versions, and then uninstalled without problems, you would give the following command::

  piuparts -a -d bullseye -d bookworm -d sid foo

ENVIRONMENT
-----------
.. envvar:: TMPDIR

  Location for temporary files and directories. If not set, use :file:`/tmp`. See also the :option:`--tmpdir` option.

NOTES
-----
Output of commands run by :program:`piuparts` is limited to three megabytes. To change this limit, the source code needs to be edited.
Commands exceeding this limit will be aborted.

SEE ALSO
--------
:manpage:`pbuilder(1)`, :manpage:`debootstrap(8)`

AUTHOR
------
Lars Wirzenius (liw@iki.fi) and others
