To avoid cluttering our main Git repository with Debian source and binary packages, we have set an APT repository up.
Overview
We use one single APT repository hosting multiple suites:
- We have a (read-only) suite for every past release:
0.9,0.10.1, etc. - We have a suite for each main branch:
stable,testing,devel - We have a suite for each topic branch:
bugfix/*,feature/*. Important note: the APT suite corresponding to a given Git topic branch contains only the packages this branch adds to the tag or main branch it diverged from. - We also have a less formal
unstablesuite, that should not be used by any Tails git branch; it can be used as hosting space for other packaging work we might do, e.g. acting as upstream or Debian maintainers. - We also have a
debomatic-squeeze-backports-mozillasuite, used (hopefully temporarily) import build-deps for our web browser, that are not available elsewhere (anymore). This suite is used by thesqueeze-backports-mozillachroot in our [[contribute/Debian package builder]].
The suite(s) to use as sources for APT, during the build and inside
the resulting system, are determined at Tails build time
(auto/config). See details in the Build system section bellow.
We manage our APT repository with reprepro.
The Puppet modules used to manage this part of our infrastructure are listed on our Git page.
Basically, a cronjob fetches and scans the Tails Git repository every few minutes, detects new branches, and accordingly:
- generates
conf/distributions - generates
conf/incoming - create new suites in the APT repository
Build system
The build system adds the relevant APT sources:
- if the version in
debian/changelogwas released already (i.e. a matching tag exists), then add the suite corresponding to this release (e.g.0.10or0.10.1); - else, if building from the
testingbranch, add thetestingsuite - else, if building from the
experimentalbranch, add theexperimentalsuite - else, if building from the
develbranch, add its own suite
Also, if we're building from a bugfix or feature branch, add its own suite.
SSH access
One must configure their SSH client to connect to the APT server:
Host incoming.deb.tails.boum.org
Port 3003
HTTP access
This is the http:// public APT repository used at Tails
build time. The tails::reprepro Puppet class sets nginx up to
serve that.
Workflow
Creating a new branch
Push your branch to Git and wait a few minutes for the new APT suite to appear.
Importing a new package
Building a package
Make sure the Distribution: field in your .changes file matches
the suite you want the package to land in (e.g.
pass --changes-option=-DDistribution=feature-torbrowser to
pdebuild's --debbuildopts).
Make sure to have the .changes file include the original source
archive (.orig.tar.{gz,bz2,xz}) if it is not already in our APT
repository; this can be done by passing -sa to pdebuild's
--debbuildopts.
Configuring an upload tool
Configuring dupload
Add this configuration snippet to your dupload configuration:
$config::cfg{'tails'} = {
fqdn => "incoming.deb.tails.boum.org",
method => "scp",
login => "reprepro",
incoming => "/srv/reprepro/incoming/",
dinstall_runs => 1,
};
Confuguring dput
Add this to .dput.cf:
[tails]
fqdn = incoming.deb.tails.boum.org
method = scp
login = reprepro
incoming = /srv/reprepro/incoming/
run_dinstall = 0
Uploading and importing process
Carefully prepare and build your package. Usual precautions, (Lintian etc.) apply.
Carefully check the .changes file (especially the Distribution
control field, and the included files list; the former can be fixed
with the changestool(1) command, from reprepro).
Sign the .changes file with a key that is in the uploaders list:
$ debsign $CHANGES_FILE
Upload the files to the incoming queue:
$ dupload --to tails $CHANGES_FILE
reprepro will automatically notice the new files and import them into
the suite specified in your .changes file.
Check the result:
$ ssh reprepro@incoming.deb.tails.boum.org reprepro list $SUITE $PACKAGENAME
Merging a topic branch
When a Git topic branch is merged into a main branch, the corresponding operation must be done on the APT suites.
Example:
$ git checkout devel
$ git merge feature/icedove
$ ssh reprepro@incoming.deb.tails.boum.org \
tails-merge-suite feature-icedove devel
$ git push
(Note that unfortunately, contrary to what whoever with a Git background would guess, the reprepro operation called pull is not what we want: it pulls from all other suites into the ones specified on the command-line.)
Merging a main branch
When a Git main branch (devel, experimental, testing,
stable) is merged into another main branch, the corresponding
operation must be done on the APT suites.
- Save the list of packages currently present in the APT suite we
want to merge into, e.g.
reprepro list experimental. - Make sure you are not going to overwrite newer packages with older ones.
- Merge the APT suites the same way as when we merge a topic branch.
- Make sure not to re-add, into the branch we merge into, any package
that was removed from it, but still is in the branch we merge from:
e.g. when merging
develintoexperimental, it may be thatexperimentalhad some packages removed (e.g. due to previously merging a topic branch into it, whose purpose is to remove custom packages). To this end, compare the resulting list of (package, version) in theexperimentalAPT suite with the one saved before the merge (hint: use thetails-diff-suitesscript), check Git merges history if needed, apply common sense, and remove fromexperimentalthe packages that were removed from it a while ago, and were just erroneously re-added by the merge operation.
Resetting a suite to the state of another one
. First, set some environment variables:
# the suite to reset OLD=testing # the final state it should be in NEW=devel. Then, empty the
OLDsuite:ssh reprepro@incoming.deb.tails.boum.org \ reprepro removematched $OLD '\*'. Finally, merge
NEWintoOLDssh reprepro@incoming.deb.tails.boum.org \ tails-merge-suite $NEW $OLD
Freezing devel into testing
- Merge
develbranch intotestingin Git - (Manually) hard reset the
testingsuite to the current state of thedevelone.
Tagging a new Tails release
Once the new release's Git tag is pushed, a cronjob should create
a new APT suite on the APT repository's side within a few minutes.
This new APT suite is called the same as the new release version.
One may check it has appeared in ~reprepro/conf/distributions.
Then, the APT suite corresponding to the branch that was used to prepare the release must be copied to the new empty APT suite that just appeared:
If this is a major release:
$ ssh reprepro@incoming.deb.tails.boum.org \
tails-merge-suite testing $TAG
Else, if this is a point-release:
$ ssh reprepro@incoming.deb.tails.boum.org \
tails-merge-suite stable $TAG
After a new Tails release is out
If you just put out a final release:
- merge
stableortestingintodevel - increment the version number in devel's
debian/changelogto match the next major release, so that next builds from thedevelbranch do not use the APT suite meant for the last release - increment the version number in devel's
debian/changelogto match the next point release, so that next builds from thestablebranch do not use the APT suite meant for the last release
If you just released a RC:
- add a dummy changelog entry (for the upcoming, non-RC version) in
the branch used for the release (
stableortesting), so that the next builds from it do not use the APT suite meant for the RC - add a dummy changelog entry (for the release after the one you
released a RC for) in the branch used for the release (
stableortesting), so that the next builds from it do not use the APT suite meant for the RC
If the release was a major one, then reset the stable APT suite to the state of the testing one.
Giving access to a core developer
- Give SSH access to the
repreprouser on the system that hosts reprepro (using thessh_authorized_keyPuppet resource). - Import the developer's public GnuPG key into the
repreprouser's GnuPG keyring -- should be doable using Puppet, some day - Add the developer's OpenPGP key ID to
$reprepro_uploadersin ourtails::repreproPuppet module. Deploy.
Contributing without privileged access
Non-core developers without access to the "private" APT infrastructure would add the .deb they want to their Git branch as we have been doing until now, push the result on repo.or.cz or whatever... and at merge time, we would rewrite their history to remove the .deb, and import it into our APT repo.
