Shape a Debian Packages Index with deb-override
A deb-override file tells dpkg-scanpackages which priority, section, and maintainer to write for chosen packages in the generated Packages index. Allow about fifteen minutes for a small local repository. This is metadata generation only: no .deb gets rebuilt, its embedded control file is untouched, and nothing gets installed. The examples use dpkg-dev 1.22.6ubuntu6.6 and dpkg-scanpackages version 1.22.6, both installed on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need:
dpkg-dev, a directory of Debian binary packages, and write access to generate the index beside it. - Keep them separate until you have checked the result: the original packages and the new index are not the same thing.
1. Check the installed tool and package tree
Start with ordinary, unprivileged checks, and use the real root of your package tree in place of the example directory:
$ command -v dpkg-scanpackages
/usr/bin/dpkg-scanpackages
$ dpkg-scanpackages --version
Debian dpkg-scanpackages version 1.22.6.
$ find /srv/repo/pool -type f -name '*.deb' -print
The first argument to dpkg-scanpackages is the path it scans, and the manual recommends making it relative to the archive root, because that path becomes the start of every Filename field in the index. A directory such as repo/binary-amd64 is a typical shape; do not quietly swap in whatever directory happens to hold your override file instead.
Checkpoint
Confirm the package files you expect actually sit under the path you are about to scan. Get the path wrong and you get an index that looks fine but lists the wrong packages.
2. Write the override entries
One whitespace-delimited entry per line, comments starting with #. Four fields: package name, priority, section, and an optional maintainer action:
# Package Priority Section Maintainer action
example-tool optional utils Example Maintainer <[email protected]>
example-data extra misc
example-renamed optional admin Old Maintainer <[email protected]> => New Maintainer <[email protected]>
- Use binary package names. Not source package names, not filenames.
- Priority and section are archive-specific.
optional,extra,utils,misc, andadminabove are illustrative; use the vocabulary your actual distribution or repository accepts. - The maintainer field has two shapes. A bare name is an unconditional replacement. Writing
old-maintainer => new-maintainerperforms a substitution, and the old value has to match the package's real metadata for it to take effect. - Keep the whole maintainer value on one line. Whitespace separates the fields, but the maintainer field itself is allowed spaces of its own.
Save this as /srv/repo/override, or wherever is readable by the account generating the index. No root privilege needed while the repository is yours to write.
3. Generate Packages with the override file
Run from the archive root and redirect standard output to a new index:
$ cd /srv/repo
$ dpkg-scanpackages binary-amd64 override > Packages.new
dpkg-scanpackages: info: Wrote 3 entries to output Packages file.
$ test -s Packages.new && echo 'Packages.new is non-empty'
Packages.new is non-empty
The command's output is the index itself, so the redirection is not optional. Its third argument, if you give one, is a path prefix for Filename fields; leave it out when the scanned path is already relative to the archive root and you have no specific prefix to add.
Read the warnings before you replace a live index. The installed manual documents warnings for packages in the wrong subdirectory, duplicates, a pre-existing Filename field, packages missing from the override, and a maintainer substitution that never matched. None of them prove the generated file is fit for your repository; they just tell you where to look.
Checkpoint
Inspect the stanzas without touching the source packages:
$ sed -n '1,80p' Packages.new
$ grep -E '^(Package|Priority|Section|Maintainer|Filename):' Packages.new
For each overridden package, check Priority and Section show what you intended, and check Maintainer only where you supplied a replacement. If a substitution failed to apply, compare the old maintainer text in the package metadata against your override line rather than guessing at spelling or whitespace.
4. Install the checked index without clobbering the old one
Only replace a live index once the new file has passed your checks. This still changes repository state, but stays unprivileged while you own the directory:
$ cp --preserve=all Packages.new Packages.checked
$ mv Packages.checked Packages
mv replaces the old Packages file outright. If the old index matters, back it up first:
$ cp --preserve=all Packages Packages.backup
Recovery
That backup is your way back. Restore it with mv Packages.backup Packages after stopping anything that might read the index mid-replacement, and keep the backup until clients have successfully read the new one. If the directory belongs to root or sits somewhere protected, ask the administrator to do only the final copy or move with the privilege it needs; there is no reason to run the whole scan as root just because publishing needs a privileged directory.
5. Make the index usable by APT when needed
dpkg-scanpackages writes an uncompressed Packages file, and the installed manual says APT normally wants a compressed variant such as Packages.xz, Packages.bz2, or Packages.gz; only local file:// access accepts the uncompressed form. Compress a checked copy, never your only rollback source:
$ gzip -c Packages > Packages.gz
$ test -s Packages.gz && echo 'Packages.gz is non-empty'
Packages.gz is non-empty
None of this configures an APT source or tests network access. A client still needs its own repository layout and source entry pointing here. Change the package set or override values later, and you regenerate both the plain index and the compressed copy from the new checked output.
Common traps
- Package not in the scanned tree. The override line for it is simply ignored; check the package name and scan path together.
- Priority and section aren't free-form. Their allowed values belong to the target distribution archive, not to your imagination.
- An unmatched substitution stays silent. No error tells you the old maintainer text failed to match.
- Do not confuse this with deb-extra-override. That one is used by the separate
--extra-overrideoption and has its own format. - Multiple versions present? This installed
dpkg-scanpackageskeeps only the newest unless you pass--multiversion; same-version architecture duplicates are handled separately.
When you need to regenerate safely: write to a new filename, inspect it, create the compressed copy from that checked file, then replace the live files last. That order keeps a failed scan from truncating the index clients currently rely on.
Done means
- Confirmed the scan path holds the intended
.debfiles and sits relative to the archive root. - Wrote each override entry with the real package name and archive-valid priority and section, with any maintainer action verified.
- Generated a non-empty
Packagesindex with no unexplained warnings. - Checked the stanzas show the priority, section, and maintainer you expected.
- Compressed a matching index for APT if the repository is not local
file://access. - Kept the previous index recoverable until the new one was tested.