RPi-Distro / pi-gen

Tool used to create the official Raspberry Pi OS images
BSD 3-Clause "New" or "Revised" License
2.58k stars 1.61k forks source link

How to lock package versions. #665

Open murrellr opened 1 year ago

murrellr commented 1 year ago

I am using pi-gen to build a custom image for a PI Compute Module 4 to be used in an industrial product. As the build is running, I see many packages being loaded by Apt from remote locations. For product stability and tracking, once we release the product, we want to lock the versions of all the packages. If I rebuild the image at a later date, I want to use the package versions from the original release of our software, not the latest. I would only want to use the latest package versions when we do a major release, not a minor one.

Is it possible to do this?

XECDesign commented 1 year ago

Debian has snapshots of their repo which you can find here: https://snapshot.debian.org/

Raspbian has something similar, but it's having some issues. Normally it can be found here: http://snapshot.raspbian.org/ However, it seems to have stopped working a while back and what I assume is a temporary working version can be found here: http://snapshot-mm.raspbian.org/

That leaves the archive.raspberrypi.org packages, which don't have snapshots.

You could mirror and snapshot it yourself accordingly.

Or, maybe there's a way to configure apt-cacher-ng to only fetch files once without refreshing them until you're ready to move to a new major release.

I know apt-cacher-ng can be configured to redirect to different locations. So you could point it to the appropriate snapshot URLs. Or, modify the sources.list files instead.

In short, yes there are a few alternative ways of achieving the desired behaviour, but it's somewhat fiddly and depends on what works best for you.

I would use debmirror to mirror all the repos to a local server and use apt-cacher-ng to install from there. Then when I'm ready for a new major release, update the mirrors. The downside is that it would use a huge amount of disk space. If that's not an option, then I'd try to do something a bit more clever with apt-cacher-ng to only save the files used for the install and not the whole repo.

XECDesign commented 1 year ago

Just found that acng has an 'Offlinemode' option. So you could run a pi-gen build. Then set Offlinemode to prevent future builds from fetching newer versions of packages.

Again, lots of different options.

murrellr commented 1 year ago

I know of a package called reprepro that creates a local apt repositories from remote ones to speed up access. Perhaps between the two I can achieve this. Thanks for the information.

svet-b commented 1 year ago

Wanted to piggy-back on this, as I have a similar question. Though in my case I would like to lock the versions of just a couple of packages, rather than all. Specifically, the kernel and firmware packages. [The context is that we have an upgrade mechanism where the root partition is upgraded but boot is usually left intact. So I'd like to be able to generate new root partitions that match the kernel/firmware version in previously created boot partitions]

A couple of approaches I'm considering:

  1. Pinning the package versions via a config in /etc/apt/preferences (as suggested in https://serverfault.com/a/435416)
  2. "Vendoring" the relevant .debs (at the desired version) within my repo and installing them directly with dpkg rather than apt

The first approach seems more elegant - but I guess prone to failure in the longer run, if/when the relevant package versions are no longer available from the respective APT repos. I suppose I could work around that by using a snapshot repo (or mirroring locally) as @XECDesign suggested, but that's probably not a justified level of complexity if I'm only doing it for the sake of a couple of packages.

Would approach (2) then make more sense? Or am I likely to end up in some kind of dependency hell? (in my experience most packages don't depend strongly on kernel version but who knows)

Also open to other suggestions of course!