1

We have a product based on a Raspberry Pi/Raspbian and use Debian packages to roll out upgrades to the software (written in Python).

I'm having an issue with getting a new package installing correct, specifically with providing a working downgrade path. I'm a regular user of Debian, but new to the world of package management.

Our package has a few files and scripts in /usr/local/bin. However, these files are not part of the DEBIAN folder of the package. They are copied onto the SD card during production of our product.

The package I am creating now needs to replace one of these files, so I created a DEBIAN/usr/local/bin folder in the package with the new file in.

This works fine for upgrading with my new package, but when downgrading, dpkg deletes the new file and tries to delete the /usr/local/bin folder, because as far as it is concerned it they didn't previously exist. The file is required by the old version of the package and so it fails to correctly install and run.

I have tried using the pre\post inst\rm scripts in the new package to make a copy of the file on install and copy it back afterwards on removal, but my understanding is that the ordering of the operations means this will not succeed, as the deletion occurs after the new package has run all of its scripts.

Is there a way to prevent deletion of this file during a downgrade?

I hope I have made the problem clear.

7
  • 1
    While possible, dpkg/apt was never designed with downgrade support in mind. Also, dpkg packages should never touch /usr/local. The reason it tries to remove it because dpkg thinks your package owns all of /usr/local/bin (which it does).
    – jordanm
    Commented Feb 14, 2020 at 17:51
  • Yeah we are certainly abusing it to some extent. Its an embedded system that we're in full control of and that combined with the fact that the original developers were not experts in this domain has led us here.
    – jfowkes
    Commented Feb 14, 2020 at 18:16
  • 1
    Have your package put the files somewhere else (/opt/foo/bin or wherever) and make links or copy them to /usr/local/bin/ in postinst. Then the package won't own the /usr/local/bin directory. Also, are you sure it works "fine for upgrading"? Generally dpkg will not overwrite a file that was not owned by any package, with a file that is now owned by one.
    – muru
    Commented Feb 17, 2020 at 9:50
  • 1
    @muru Thanks, this was a good solution. I'm pretty sure my original attempt worked for upgrading, but since I've moved it to a directory in /opt/ it doesn't matter now anyway. Thanks for the assistance, I'd accept as an answer if it wasn't a comment.
    – jfowkes
    Commented Feb 17, 2020 at 16:06
  • @jfowkes you can post exactly what you did as an answer!
    – muru
    Commented Feb 18, 2020 at 1:40

1 Answer 1

1

My solution was pretty much that suggested by @muru in comments:

  • Put the new files in /opt/appname/bin in the package
  • In postinst, backup files in /usr/local/bin and replace with symlinks to /opt/appname/bin.
  • In postrm, remove the symlinks and restore the backups, if they exist.
1
  • While using /opt certainly works, you could as well use /usr/bin, that way if some package from the distribution you are basing on provides it too, you'll get an explicit file conflict instead of a silent override at run-time depending on which of the bin directories takes precedence in PATH. Commented May 17, 2020 at 23:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .