0

TL;DR;

If somebody installs my deb package with sudo dpkg -i example.deb, is there a way to add some custom actions (shell commands, similar to postinst) in case of installation with failed dependencies (as the package is actually unpacked and present on the target machine)?


Suppose a deb package has some UI dependencies, but the target machine is Ubuntu server.
Running sudo dpkg -i example.deb leads to

(Reading database ... 59708 files and directories currently installed.)
Preparing to unpack ./example.deb ...
Unpacking example (13) over (11) ...
dpkg: dependency problems prevent configuration of example:
 example depends on libappindicator1; however:
  Package libappindicator1 is not installed.

dpkg: error processing package example (--install):
 dependency problems - leaving unconfigured
Processing triggers for mime-support (3.64ubuntu1) ...
Errors were encountered while processing:
 example

The result is - extracted package (I can find the content in /opt), the exit code is 1 (echo $?), but the postinst script is not executed. The software can work without its UI, so this is not a big deal (until I create two separate installers - one with UI and one - without).

The problem is that I have some important steps in the postinst script, but it's not executed at all.

Maybe I need to have some kind of rollback procedure or a way to handle such errors, but I wasn't able to find any way to do this, although it sounds trivial.

An alternative approach would be to execute the required steps after unpacking and before dependency reslution, but I didn't find anything like this as well.

Obviously, I'm missing something fundamental here. Any ideas?


Edit: even more, if the missing package is later present, the installation is also incomplete / broken, as postinst was never actually executed. As this sounds pretty straight forward, I guess there's an easy solution about this, which I can't find.

  • The install command is not sudo dpkg -i example.deb but e.g. sudo gdebi example.deb : Then the dependencies are also installed. – Knud Larsen Apr 27 '20 at 13:58

1 Answers1

2

Your postinst will never be run if the package’s dependencies aren’t present and configured. You could cheat by setting things up in preinst (although that happens before your package is unpacked), but I think a better approach would be to move your GUI dependencies to “Recommends”. Since your package can work without the UI dependencies, it shouldn’t depend on them, it should recommend them; this will allow the package to be configured when they aren’t present.

Stephen Kitt
  • 434,908
  • The steps I need are setting unix permissions (including sticky bit, which is not preserved on copy), so preinst won't help, unfortunately. Sounds very strange to me that there's no way to handle unmet dependencies, which could lead to broken installation - I'd expect ability for some kind of automatic (or custom) rollback procedure in that case.

    Regarding Recommends - sounds like a very good workaround/alternative. Thanks!

    – Kiril Kirov Apr 27 '20 at 13:29
  • Fixing permissions shouldn’t require a postinst; you can ship the appropriate permissions in your package. See this answer for an example. – Stephen Kitt Apr 27 '20 at 13:40
  • As far as an automatic rollback is concerned, the options available to a package are limited: if dependencies aren’t satisfied, dpkg can’t even assume that postinst will work, because postinst is allowed to assume that the dependencies are present. The only viable rollback when an installation fails because of missing dependencies would be to cancel the installation entirely. – Stephen Kitt Apr 27 '20 at 13:42
  • Regarding the permissions - I never actually tried that (my bad), but I assumed I need to set the sticky bit during postinst and setting the permissions in advance won't work. The point is - sticky bit is not preserved on move/copy/rename/etc, as mentioned above. But as I don't really know how dpkg works, I should try that. Thanks a lot for the help! – Kiril Kirov Apr 27 '20 at 14:00
  • Sticky bits are stored in tarballs, and preserved when root extracts them; that’s what matters for a package. – Stephen Kitt Apr 27 '20 at 14:17
  • That's freaking awesome! Thanks a lot, appreciated! – Kiril Kirov Apr 27 '20 at 14:54
  • Hm, looks like override_dh_fixperms is not executed in the case of broken dependencies.
    I also tried setting the correct file permissions before executing dpkg-deb (in other words - using preset file permissions). This also failed - the installed files had standard permissions. This leaves me with nothing more, but using Recommends. Or I'm doing something wrong with the other two options?
    – Kiril Kirov Apr 28 '20 at 13:02
  • dh_fixperms runs during the build, not during installation. Please ask a new question with details of what you’re doing. – Stephen Kitt Apr 28 '20 at 13:08
  • I tried plenty of things, but I didn't make it. Here's a follow up question: https://unix.stackexchange.com/questions/583140/unable-to-set-sticky-bit-and-file-owner-in-debian-package – Kiril Kirov Apr 28 '20 at 16:15