Package: dpkg Version: 1.21.22 Exact text of error:
$ sudo dpkg -i etx8-web-2.0.0-29a5f09-b1443.deb dpkg: warning: downgrading etx8-web from 2.1.0 to 2.0.0 (Reading database ... 35531 files and directories currently installed.) Preparing to unpack etx8-web-2.0.0-29a5f09-b1443.deb ... Checking upgrade/ downgrade compatibility... Migrating network config in prerm New version 2.0.0 < 2.1.0 Migrating network config 'down'. found v46 network config: static 10.0.42.33/23 Aborting migration - Static network configuration is incomplete. System will default to DHCP. Archiving pre-downgrade network configs as '15-etx8-v4v6.network.backup'. Current configuration: address='10.0.42.33/23', gateway=''; dns='' dpkg: warning: old etx8-web package pre-removal script subprocess returned error exit status 1 dpkg: trying script from the new package instead ... dpkg: ... it looks like that went OK Unpacking etx8-web (2.0.0) over (2.1.0) ... Incorrect behavior: The package maintainer script workflow does not provide a mechanism for a newer installed package to prevent downgrading to an older version of the same package, for scenarios where the downgrade is impossible. In every case where one of the scripts from the currently installed package can signal an abort with a non-zero exit status, the workflow then runs the corresponding script from the target package. If that script succeeds, then installation continues. This is confirmed by reviewing the flowchart at https://www.debian.org/doc/debian-policy/ap-flowcharts.html. When the target package is older than the currently installed package, its maintainer scripts have no knowledge of incompatible downgrade scenarios; they are likely to decide to proceed when there is no path to a working outcome. Expected behavior: During a downgrade, the older package should not have the final say in whether to abort or continue. That responsibility should always belong to the newer package, regardless of which is installed or being overwritten. This workflow seems to assume that nobody will ever need to revert to an older version of a package after they discover issues with a newer version. Suggested fixes: Option 1: Allow different classes of exit status, that signal dpkg on whether to try the older version of a given script or not. For example, positive exit status could signal that dpkg should always try the alternate version of the script, while negative status could signal that dpkg should only try the alternate version of the script if the target version is greater than the installed version. The rational is that only a newer version should be expected to have knowledge of requirements that did not exist at the time the current version was released. Option 2: Offer an abort command that any maintainer script can call that definitively puts the in-progress installation into an abort state. All other maintainer scripts that run after abort has been signaled will get a parameter indicating that an abort is in progress, and they should only what they can to support as graceful of a bail-out as possible. Versions of package dependencies: not applicable, dpkg is the chicken, packages are the eggs Kernel & C library version: Linux voltserv-fe02 5.19.9-voltserver.1 #5 SMP Wed Jan 31 23:29:58 UTC 2024 armv7l GNU/Linux -rwxr-xr-x 1 root root 1102644 Apr 19 16:34 /lib/arm-linux-gnueabihf/libc.so.6 Details of the configuration of the program with the problem: None, the problem is with dpkg itself Relevant hardware details: None, although FWIW we are running on ARM32 Additional detail: Here is a summary of our specific case (some details have been factored out that are not relevant to the issue). The latest version, 2.1, of our application that runs our hardware product on an embedded Linux system offers new network configuration. Specifically, 2.1 allows users to omit the IP default gateway or DNS server, b/c our devices may be on an isolated management network does not have them. We have a new config file format to support all of the new options. During package install, maintainer scripts convert between old and new config file formats. There is no way to write a valid 2.0 configuration file without a default gateway or DNS server - the 2.0 UI would crash without them. In this case, our package maintainer scripts (2.1's prerm to be specific) looks for this scenario, and attempts to abort and tell the user what she needs to do before this downgrade is possible. However, dpkg then runs the 2.0 prerm script, which doesn't know about any of this. It succeeds, and then dpkg completes the downgrade, leaving behind a network config file that the newly installed version can't read. Show me: * Start with any package at some version, e.g. 1.0. It can be an empty dummy package if you have one, as long as it has a maintainer script - e.g. preinst * Create a 2.0 version of the package * Let's say that 2.0 can not be downgraded at all to 1.0 * Update preinst to return exit with status 1 * generate the 2.0 .deb file * install 1.0 * install 2.0 * install 1.0 * You are now on version 1.0. The exit 1 from version 2.0 was ignored.