It seems like we often either need a newer version of a package, or to apply our own patch to some package. We have an apt repo to which we upload these packages.
There is a useful Debian wiki page SimpleBackportCreation but we'll cover everything you need to know here.
Additionally, some of the commands on this page are found in packages not typically installed on OCF machines. In order of appearance on this page:
dget: Found in the
dpkg-checkbuilddeps: Found in the
mk-build-deps: Found in the
dquilt: This is an alias around
quilt, found in the
dch: Found in the
dpkg-buildpackage: Found in the
scp: Found in the
Generally, it's a good idea to build packages in Docker containers so that any build dependencies or build tools are not left still installed after the package is built. In total, you only generally need to run:
sudo apt install packaging-dev debian-keyring devscripts equivs openssh-client
to get started with building packages (
packaging-dev installs a bunch of the
packages above as dependencies). This is along with any build dependencies the
packages you are working on might have, but this is discussed more later.
Go to packages.debian.org and find the package you desire.
Find the package info page
(example), and make sure you're
on the correct distribution (select at the top-right, e.g.
From the sidebar on the right, select under "Download Source Package" the
link to the
.dsc file. The URL should look something like:
Log on to a system which has the release you want to eventually install the package on. (For example, if you're backporting a package from buster to stretch, you should do these steps on stretch.) Generally, a Docker container works quite well because any extra build dependencies you install will not remain on the system once the package is built. pbuilder can also be used to a similar effect.
.dsc link from above, download the source package:
dget -x http://http.debian.net/debian/pool/main/e/evince/evince_3.14.2-1.dsc
dpkg-checkbuilddeps, and install any dependencies that are missing. If you'd like to install missing dependencies automatically, you can use
sudo mk-build-deps -ir.
If you're patching the package (and not just backporting), here is where you
make your changes. You should first apply all the patches (
dquilt push -a),
quilt to create your patch. This can be done by running
dquilt new <patch-name>.patch to start a patch,
dquilt edit <file>, and
dquilt refresh to generate the patch file from the modified file. You
can also just modify the source if you don't care about quality, but you
should ensure all the Debian patches are applied first using
Decide on your version number, using one of the categories below:
For backports, we like to add append
~ocfN to the end, where
N is an
integer starting at 1. The final version might look like
Use a command like:
dch --local ~ocf --distribution stretch-backports 'Backported by OCF for stretch.'
The squiggle makes your backport inferior to the official package, so that it will be replaced during an upgrade. This is desired, since with a backport no changes have been made to the package itself, just a newer version brought to an older distribution version.
For packages we apply patches to, we like to append
ocfN to the end. This is
similar to what Ubuntu does for packages it patches from Debian. The final
version might look like
Use a command like:
dch --local ocf --distribution stretch 'Patched by OCF to not delete $HOME on login.'
Unlike backporting, this version number means that upgrades will not affect this package, since it will not be inferior to any new versions pushed to Debian package repos. This is usually desired because the patch applied should not be automatically overwritten by any other changes to the package.
Build the package with
dpkg-buildpackage -us -uc -sa. The
.deb file will
pop out in your parent directory along with some other files to send to the apt
repo (the original source, any modifications, the changelog, etc.).
If this is something that we will be building often (e.g. ocfweb or ocflib), you probably want to set it up inside Jenkins to automatically test and upload to apt.
For one-off uploads:
Copy all the necessary files to
scp *.tar.gz *.tar.bz2 *.debian.tar.xz *.dsc *.changes *.deb you@apt:/tmp/yourpackage
Generally putting these in a new directory in
/tmp is a good way to go,
since if you put them in your home directory, the
ocfapt user will not be
able to read them.
Include the package files in the suitable distribution. If this is just a
backport (no patches), use
<dist>-backports, otherwise just use
sudo -u ocfapt /opt/apt/bin/reprepro include <dist> /tmp/mypackage.changes
For more options for
reprepro, see the comments at the top of
/opt/apt/bin/reprepro, which is a wrapper script around the
command to avoid messing up paths and permissions.
Test the package by installing it on one host and see if it behaves how you
would expect. Make sure to run
sudo apt update first so that the host you
are testing on knows about the package you have added.