dpkg --dry-run option is not simulating installation properly

5,260

Solution 1

To determine whether a package can be installed without needing other dependencies to be installed too, your best bet is to use the “simulate” mode with apt:

apt -s install ./mysql-workbench_6.2.3+dfsg-7_armhf.deb

(note the ./ which is significant). This will output the dpkg operations which would be performed by the real installation. Package installations are marked with Inst; if there’s more than one of these, the package can’t be installed on its own.

Now, on to the meaty part... You can’t use dpkg for this, not because dpkg doesn’t know about dependencies (it most definitely does), but because dependencies aren’t strong enough. When a package depends on another, the dependency doesn’t prevent the package from being installed if it’s not satisfied, it prevents it from being configured. See section 7.2 of Debian Policy:

A Depends field takes effect only when a package is to be configured. It does not prevent a package being on the system in an unconfigured state while its dependencies are unsatisfied, and it is possible to replace a package whose dependencies are satisfied and which is properly installed with a different version whose dependencies are not and cannot be satisfied; when this is done the depending package will be left unconfigured (since attempts to configure it will give errors) and will not function properly.

You can see this in your own test: the process fails with

dpkg: dependency problems prevent configuration of mysql-workbench

Note “configuration”, not “installation”. If you look at the output of dpkg -l mysql-workbench, you should see iU, which means the package is installed but not configured.

When you enable “simulate” mode in dpkg, it basically runs in read-only mode. It does this by setting a f_noact flag; you can look for this in the source code. When installing packages, simulation goes through the installation motions (without writing anything), and proceeds to the configuration phase; but that just fakes success, which is the only thing that a simulation can do — configuration involves running maintainer scripts in the package, and it would be difficult to ensure that those scripts didn’t make changes, or ensure that their success could be determined without allowing them to make changes. So in your case, the simulation installs the package, which succeeds (as in your non-simulated test), and fakes the configuration. Thus no error is detected...

Solution 2

While this isn't technically an answer, it was a good question.

If we look at man dpkg, this is what it says about the options to test. If any real Debian experts can provide a more authoritative response, that would be good. Or edit mine if it has errors in it.

   --no-act, --dry-run, --simulate
          Do everything which is supposed to be done, but don't write any changes. This is used to see what would happen with the specified
          action, without actually modifying anything.

I believe, though I'm not certain, that in essence, all dpkg is testing is if the command has any flaws in it. For example, if you did:

#dpkg --dry-run -i nonexistent.deb || echo $?
dpkg: error: cannot access archive 'nonexistent.deb': No such file or directory
2

that's the result. One thing I noted was that dpkg required root even with --dry-run, it complained about not being able to use the log file, which means, --dry-run does not do at all what we expect. With apt-get, you can use --simulate as regular user.

dpkg is a very low level apt tool, and as you can see from its results in your tests, it did not know about the apt database and dependency trees until it actually installed the .deb file. So I would deduce that dpkg --dry-run or --simulate etc simply are testing the actual literal command data, not the dependencies etc.

Which suggests that while it appears to be the same command that works pretty decently, but not perfectly, in apt-get, it is in fact not at all the same. One would have to read the code in dpkg --simulate to see what it actually does.

Researching this issue appears to confirm what I believe is the case:

https://lists.ubuntu.com/archives/ubuntu-devel/2005-November/013049.html

If a feature, is there an automatic way of checking a .deb's dependencies, other than trying to dpkg -i it (and ending up with under-configured packages) or doing a dpkg -f and checking the dependencies one by one by hand?

What I'm looking for is a something like dpkg-buildpackage's 'Unmet build dependencies: ...' check, but for .debs.

There is a new application available called "gdebi" at: http://people.ubuntu.com/~mvo/gdebi/

It should be able to resolve dependencies of deb package directly. It contains gdebi-gtk and gdebi (and cli version). That might be what you want. If not, please let me know and it may be added :) If you use/test it, feedback (via private mail) is very much appreciated.

That's a very old thread, and I'm sure you're not looking for a gui tool, but it is worth noting that the issue existed in 2005 and someone crafted a gui solution that would check dependencies, which suggests that in fact, dpkg --simulate does not. Nor would I expect it to, I have done a lot of automated scripting for Debian apt, and dpkg, and the two act and behave very differently.

Various options to determine dependencies using dpkg

https://lists.debian.org/debian-user/2006/09/msg00292.html

That's an old Debian thread on the same question, again, you can see that dpkg --dry-run doesn't handle dependencies in general.

https://lists.debian.org/debian-user/2006/09/msg00297.html

dpkg-deb -I package.deb

Is the suggestion there. That shows basically the same thing as apt-cache show package-name.

So at least you can verify the dependencies yourself.

 dpkg -I perl_5.26.0-8_i386.deb
 ....
 Pre-Depends: dpkg (>= 1.17.17)
 Depends: perl-base (= 5.26.0-8), perl-modules-5.26 (>= 5.26.0-8), libperl5.26 (= 5.26.0-8)
....

https://lists.debian.org/debian-user/2006/09/msg00312.html

If you use dpkg --control pkg_file, then it will show you all of the control information for the package, including dependencies.

I tested that, but it shows nothing, it may be obsolete, I don't know.

As you can see, Debian devs had several suggestions, but none of them suggested that there was a way to make dpgk --dry-run do what you want.

Conclusion

You have a few options, one, determine the dependencies manually, and this will certainly apply to your future case of creating your own debs, and then install those dependencies using a scripted install or whatever you find works for you, then install the .deb package after that.

Using the vm is a good option too, with snapshots, for testing.

Share:
5,260

Related videos on Youtube

Arpith
Author by

Arpith

Senior Software Engineer with MobileIron, Inc. Previously, Software Developer with Cisco Systems, Inc. and Frog Design, Inc.

Updated on September 18, 2022

Comments

  • Arpith
    Arpith over 1 year

    Given a random .DEB file, how do we check if installation will be successfully completed without actually installation on device? Please see the following snippet:

    root@VirtualBox:/Folder# dpkg -i mysql-workbench_6.2.3+dfsg-7_armhf.deb 
    Selecting previously unselected package mysql-workbench.
    (Reading database ... 48937 files and directories currently installed.)
    Preparing to unpack mysql-workbench_6.2.3+dfsg-7_armhf.deb ...
    Unpacking mysql-workbench (6.2.3+dfsg-7) ...
    dpkg: dependency problems prevent configuration of mysql-workbench:
     mysql-workbench depends on libatkmm-1.6-1 (>= 2.22.1); however:
      Package libatkmm-1.6-1 is not installed.
     mysql-workbench depends on libcairo2 (>= 1.14.0); however:
      Package libcairo2 is not installed.
     mysql-workbench depends on libcairomm-1.0-1 (>= 1.6.4); however:
      Package libcairomm-1.0-1 is not installed.
     mysql-workbench depends on libctemplate2; however:
      Package libctemplate2 is not installed.
     mysql-workbench depends on libgdal1h (>= 1.8.0); however:
      Package libgdal1h is not installed.
     mysql-workbench depends on libgdk-pixbuf2.0-0 (>= 2.22.0); however:
      Package libgdk-pixbuf2.0-0 is not installed.
     mysql-workbench depends on libgl1-mesa-glx | libgl1; however:
      Package libgl1-mesa-glx is not installed.
      Package libgl1 is not installed.
     mysql-workbench depends on libglibmm-2.4-1c2a (>= 2.42.0); however:
      Package libglibmm-2.4-1c2a is not installed.
     mysql-workbench depends on libgnome-keyring0 (>= 2.22.2); however:
      Package l
    dpkg: error processing package mysql-workbench (--install):
     dependency problems - leaving unconfigured
    Processing triggers for mime-support (3.58) ...
    Processing triggers for shared-mime-info (1.3-1) ...
    Errors were encountered while processing:
     mysql-workbench
    root@VirtualBox:/Folder# echo $?
    1
    root@VirtualBox:/Folder# dpkg --dry-run -i mysql-workbench_6.2.3+dfsg-7_armhf.deb 
    (Reading database ... 49115 files and directories currently installed.)
    Preparing to unpack mysql-workbench_6.2.3+dfsg-7_armhf.deb ...
    root@VirtualBox:/Folder# echo $?
    0
    root@VirtualBox:/Folder# dpkg --dry-run --simulate -i mysql-workbench_6.2.3+dfsg-7_armhf.deb 
    (Reading database ... 49115 files and directories currently installed.)
    Preparing to unpack mysql-workbench_6.2.3+dfsg-7_armhf.deb ...
    root@VirtualBox:/Folder# echo $?
    0
    root@VirtualBox:/Folder# 
    

    When I use the dpkg -i option, the command fails with a return value of 1, but the same command as a --dry-run returns zero. Adding the --simulate option also doesn't seem to change behaviour. Any pointers on how to consistently check if installation of a .DEB file will go through properly, without actually installing the package?

    I am running this on a Raspberry Pi emulator.

    root@VirtualBox:/Folder# cat /etc/os-release
    PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
    NAME="Raspbian GNU/Linux"
    VERSION_ID="8"
    VERSION="8 (jessie)"
    ID=raspbian
    ID_LIKE=debian
    HOME_URL="http://www.raspbian.org/"
    SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
    BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
    
    • Pankaj Goyal
      Pankaj Goyal over 6 years
      It's a VM. Take a snapshot, and roll back if it fails.
    • Arpith
      Arpith over 6 years
      @DopeGhoti: Not what I asked.
    • Arpith
      Arpith over 6 years
      @Lizardx: Is there no way that I can do a dry-run for the debian files? I am currently trying this out with standard pool debians, but would want to extend this to custom debian files later on.
    • Lizardx
      Lizardx over 6 years
      It's a good question, but I believe it simply devolves to the fact that dpkg --simulate doesn't actually do what you expected it to do. It seems it never has, it's probably outside of the scope of dpkg. I did provide an upvote because it's a good question, and a sort of pseudo-answer. Only reading the dpkg code could provide a real answer.
    • Lizardx
      Lizardx over 6 years
      I'm glad Stephen Kitt looked into it more. While it's obvious that --simulate and dpkg won't do what the person wanted, it's always interesting poking into the internals of apt and dpkg, which remain as far as I'm concerned the best by far package management system, along with the strict Debian lintian rules, in the GNU/LInux ecosystem. After using these tools as long as I have, you tend to have a sense of what won't work, like dpkg --simulate, so it's something I never even tried.
  • Lizardx
    Lizardx over 6 years
    I believe there is one more thing, because this error when run as regular user: "dpkg: could not open log '/var/log/dpkg.log': Permission denied". So even there it's not acting the same as apt-get --simulate, which has no requirements for anything related to root permissions. I'm glad someone looked into the guts of dpkg though to find the actual answer, I've simply never thought to use dpkg --simulate because it didn't seem like it would or could work, as we see in the above poster's example.
  • Stephen Kitt
    Stephen Kitt over 6 years
    The log is opened for writing in all cases, which explains the error — logging doesn’t come under the “make no changes” umbrella ;-).
  • Lizardx
    Lizardx over 6 years
    Yes, that was my point, I think, the --simulate obviously doesn't need logging yet it attempts to do it because it always does it, which points I think to the fact that the --simulate flag isn't really designed to do what the original poster thought it would do. That's sort of a bug in the dpkg man page now that I think of it, the differences should be made clear there, with a better explanation of what --simulate/--dry-run is actually good for, it's actual purpose, that is. Reading just the text of the man item would make most people conclude that it will test the install with dependencies.
  • Arpith
    Arpith over 6 years
    This explained a lot. Also the apt alternative you suggested worked much better towards my purpose. Thank you so much.