I had to figure out this command to restore some of our reprepro mirrors, add notes on it. Cleanup some other things I noticed; quotes around REPREPRO command, clarify the situation with pointing mirrors at the RO/RW volumes and refactor discussion. Change-Id: I3e3f763929bf74e0c4faf29b13973dcf1df36975
6.2 KiB
- title
-
reprepro
Reprepro
Debian package mirroring tool
At a Glance
- Hosts
- Puppet
-
modules/openstack_project/manifests/mirror_update.pp
- Projects
- Documentation
- Bugs
Overview
reprepro is the tool we use to mirror Debian repositories (including Ubuntu) to the AFS mirrors.
Repository signing
Note our repositories are not signed. apt
will require
--no-check-gpg
or similar settings in configuration to use
OpenStack mirrors.
Normal operation
Repository syncs are driven from cron
on the
mirror-update.openstack.org
host using the
/usr/local/bin/reprepro-mirror-update
script. Repositories
will update, remove old references and perform the
vos release
.
Advanced Recovery Techniques
For a small repository, corruption is probably best handled by removing the entire repository and re-syncing. This is undesirable for larger repositories, however.
Note
Be careful with vos release
which is done as part of
/usr/local/bin/reprepo-mirror-update
to avoid inadvertently
releasing in progress work. Also be aware the commands in that script by
default run under timeout
which you may not want in
recovery.
Corrupt reprepo
databases will halt mirroring with often
obscure symptoms. For example, this has been seen in production with
reprepo
ending up hung in an silent infinite loop. In this
case, using strace
revealed the last operation was on a
file-descriptor related to a .db
file, which gave a clue
the databases were corrupt. Other failures may be possible, of
course.
The following assumes you have a root shell with the correct AFS permissions for the mirror volumes, drop into something like:
k5start -t -f /etc/reprepro.keytab service/reprepro -- bash
We will use the Ubuntu repository as an example below.
In a crisis, you want to stop the cron job running to update the
repo. You can either edit it out with crontab -e
and put
the host in the emergency file (so puppet doesn't replace it) or, in a
pinch, take the lock in a infinite loop like :
flock -n /var/run/reprepro/ubuntu.lock bash -c while true; do sleep 1000; done
Firstly check in dmesg
for AFS related errors. It is
quite likely any corruption has happened due to issues at this layer, so
ensure stability here before continuing to further recovery.
The databases are in the db
directory in the mirror:
# ls /afs/.openstack.org/mirror/ubuntu/db
checksums.db contents.cache.db packages.db references.db release.caches.db version
It is best to make backup copies before any recovery operations.
Although AFS /should/ keep up, you should do any recovery of the
db
directory on a local copy to avoid any intermittent
issues there further corrupting the database, then copy back the updated
files when complete.:
# cp -r /afs/.openstack.org/mirror/ubuntu/db ~/db
For convenience, setup the common reprepo
options for
verbose logging, the configuration directory and to work on the local
database:
# export REPREPRO="reprepro -VVV --confdir /etc/reprepro/ubuntu --dbdir ~/db"
From the upstream recovery document, the references.db
can be removed and recreated quickly with:
$REPREPRO rereference
The checksums.db
can also be recreated. You can rebuild
with:
cd /afs/.openstack.org/mirror/ubuntu
find -type f -printf "pool/%P\n" > /tmp/file-list
$REPREPRO -b . _detect < /tmp/file-list
- This will take several hours (~6 hours in 2017) as it touches all the repo files.
Note that if the .deb
files on disk are corrupt, this
may lead to errors on update about mismatching checksums which have been
stored in the database. Likely you want to remove these files from disk
and from the checksums database with a command similar to:
$REPREPRO _forget pool/main/p/package/the_package_1.2.3.deb
rm pool/main/p/package/the_package_1.2.3.deb
They should come back with the next update.
In some situations where things are very out of sync, it may be
easier to remove and replace an entire section of the repository. For
example, if during updates files within xenial-security
are
seen to be corrupt, you can remove xenial-security
from
/etc/reprepro/ubuntu/distributions
and run the
following:
# remove old
$REPREPRO --delete clearvanished
# run an update
$REPREPRO update
You can then re-add the entries and run another update, which should resync everything from fresh.
You may also see errors relating to individual packages not being referenced correctly:
checking references to 'bionic|main|arm64' for 'texlive-latex-base': pool/main/t/texlive-base/texlive-latex-base_2017.20180305-1_all.deb
Missing reference to 'pool/main/t/texlive-base/texlive-latex-base_2017.20180305-1_all.deb' by 'bionic|main|arm64'
...
There have been errors!
In this case, the _addreference
command can be useful.
The parameters are the filekey, which is the path to the file,
and the identifier, which is the tuple
bionic|main|arm64
above. To restore the reference try:
# $REPREPRO _addreference pool/main/t/texlive-base/texlive-latex-base_2017.20180305-1_all.deb 'bionic|main|arm64'
Adding reference to 'pool/main/t/texlive-base/texlive-latex-base_2017.20180305-1_all.deb' by 'bionic|main|arm64'
Remember to put the databases back in place:
# mv /afs/.openstack.org/mirror/ubuntu/db /afs/.openstack.org/mirror/ubuntu/db.old
# cp -r ~/db /afs/.openstack.org/mirror/ubuntu/
To stage a recovery prior to release, you can modify the
mirror_root
argument in
openstack_project::mirror
puppet to point Apache to the RW
mirror /afs/.openstack.org/mirror
where fixes are deployed,
rather than the released RO /afs/openstack.org/mirror
. This
way you can avoid having to release the RO mirror and switch back
quickly if things don't work.
When fixed, you can either manually run vos release
, or
restore cron and let the next reprepro-mirror-update
run do
it.