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 devscripts
packagedpkg-checkbuilddeps
: Found in the dpkg-dev
packagemk-build-deps
: Found in the devscripts
packagedquilt
: This is an alias around quilt
, found in the quilt
packagedch
: Found in the devscripts
packagedpkg-buildpackage
: Found in the dpkg-dev
packagescp
: Found in the openssh-client
packageGenerally, 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. stretch
).
From the sidebar on the right, select under "Download Source Package" the
link to the .dsc
file. The URL should look something like:
http://http.debian.net/debian/pool/main/e/evince/evince_3.14.2-1.dsc
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.
Using the .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
),
then use dquilt
/quilt
to create your patch. This can be done by running
dquilt new <patch-name>.patch
to start a patch, dquilt edit <file>
, and
then 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 dquilt
.
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 4.3.0-1~ocf1
.
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 1.3.1-7ocf1
.
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 apt
(currently fallingrocks
):
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 <dist>
:
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 reprepro
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.