Skip to content

Package version comparisons generated by the debian generator are broken #455

@meyerj

Description

@meyerj

The debian generator of bloom translates version dependencies found in package.xml files to version restrictions in the Debian control file, without any interpretation of the version string: generators/debian/generator.py:197.

While this approach works fine in the common case of depending on a minimum version of a ROS package like in

<depend version_gte="1.12.12">roscpp</depend>

which is translated to

Depends: ros-kinetic-roscpp (>= 1.12.12)

for the control file, it is basically broken for version_lte, version_eq or version_gt because only very few Debian or Ubuntu packages have version numbers that exactly follow the major.minor.patch version scheme. Version specification and comparison on Debian packages is more complex, see https://www.debian.org/doc/debian-policy/#s-f-version for reference.

Examples that would fail or behave unexpectedly:

  • Equality:

    <depend version_eq="1.12.12">roscpp</depend>
    Depends: ros-kinetic-roscpp (= 1.12.12)
    

    is not satisfied by ros-kinetic-roscpp=1.12.12-0xenial-20171116-193322-0800 because it's not equal to 1.12.12:

    dpkg: dependency problems prevent configuration of foo:
     foo depends on ros-kinetic-roscpp (= 1.12.12); however:
      Version of ros-kinetic-roscpp on system is 1.12.12-0xenial-20171116-193322-0800.
  • Earlier or equal:

    <depend version_lte="1.12.12">roscpp</depend>
    Depends: ros-kinetic-roscpp (<= 1.12.12)
    

    would be satisfied by ros-kinetic-roscpp=1.12.7-0xenial-20170613-165746-0800, but but not by ros-kinetic-roscpp=1.12.12-0xenial-20171116-193322-0800 because it's greater than 1.12.12:

    dpkg: dependency problems prevent configuration of foo:
     foo depends on ros-kinetic-roscpp (<= 1.12.12); however:
      Version of ros-kinetic-roscpp on system is 1.12.12-0xenial-20171116-193322-0800.
  • Later:

    <depend version_gt="1.12.12">roscpp</depend>
    Depends: ros-kinetic-roscpp (>> 1.12.12)
    

    would unexpectedly be satisfied by ros-kinetic-roscpp=1.12.12-0xenial-20171116-193322-0800 because it's greater than 1.12.12:

    $ dpkg-query -s foo ros-kinetic-roscpp
    Package: foo
    Status: install ok installed
    Priority: optional
    Section: misc
    Installed-Size: 9
    Maintainer: Johannes Meyer <[email protected]>
    Architecture: all
    Multi-Arch: foreign
    Version: 1.0
    Depends: ros-kinetic-roscpp (>> 1.12.12)
    Description: Dummy package to fulfill package dependencies
     This is a dummy package that makes Debian's package management
     system believe that equivalents to packages on which other
     packages depend on are actually installed.  Deinstallation of
     this package is only possible when all pending dependency issues
     are properly resolved in some other way.
     .
     Please note that this is a crude hack and if thoughtlessly used
     might possibly do damage to your packaging system.  And please
     note as well that using it is not the recommended way of dealing
     with broken dependencies.  It is better to file a bug report.
    
    Package: ros-kinetic-roscpp
    Status: install ok installed
    Priority: extra
    Section: misc
    Installed-Size: 2420
    Maintainer: Dirk Thomas <[email protected]>
    Architecture: amd64
    Version: 1.12.12-0xenial-20171116-193322-0800
    Depends: libboost-filesystem1.58.0, libboost-system1.58.0, libboost-thread1.58.0, libc6 (>= 2.14), libgcc1 (>= 1:3.0), libstdc++6 (>= 5.2), ros-kinetic-cpp-common (>= 0.3.17), ros-kinetic-message-runtime, ros-kinetic-rosconsole, ros-kinetic-roscpp-serialization, ros-kinetic-roscpp-traits (>= 0.3.17), ros-kinetic-rosgraph-msgs (>= 1.10.3), ros-kinetic-rostime (>= 0.6.4), ros-kinetic-std-msgs, ros-kinetic-xmlrpcpp
    Description: roscpp is a C++ implementation of ROS.
     It provides a client library that enables C++ programmers to quickly interface with ROS Topics, Services, and Parameters. roscpp is the most widely used ROS client library and is designed to be the high-performance library for ROS.
    Homepage: http://ros.org/wiki/roscpp
  • Later, with or without equal, in combination with non-zero epoch numbers:
    <depend version_gte="9.9.9">zlib</depend>
    Depends: zlib1g-dev (>= 9.9.9)
    
    would be satisfied by zlib1g-dev=1:1.2.8.dfsg-2ubuntu4.1 because the epoch number before the colon is greater than zero, the default epoch assumed if none is specified like for 9.9.9:
    1:1.2.8.dfsg-2ubuntu4.1
    $ dpkg-query -s foo zlib1g-dev
    Package: foo
    Status: install ok installed
    Priority: optional
    Section: misc
    Installed-Size: 9
    Maintainer: Johannes Meyer <[email protected]>
    Architecture: all
    Multi-Arch: foreign
    Version: 1.0
    Depends: zlib1g-dev (>= 9.9.9)
    Description: Dummy package to fulfill package dependencies
     This is a dummy package that makes Debian's package management
     system believe that equivalents to packages on which other
     packages depend on are actually installed.  Deinstallation of
     this package is only possible when all pending dependency issues
     are properly resolved in some other way.
     .
     Please note that this is a crude hack and if thoughtlessly used
     might possibly do damage to your packaging system.  And please
     note as well that using it is not the recommended way of dealing
     with broken dependencies.  It is better to file a bug report.
    
    Package: zlib1g-dev
    Status: install ok installed
    Priority: optional
    Section: libdevel
    Installed-Size: 415
    Maintainer: Ubuntu Developers <[email protected]>
    Architecture: amd64
    Multi-Arch: same
    Source: zlib
    Version: 1:1.2.8.dfsg-2ubuntu4.1
    Provides: libz-dev
    Depends: zlib1g (= 1:1.2.8.dfsg-2ubuntu4.1), libc6-dev | libc-dev
    Conflicts: zlib1-dev
    Description: compression library - development
     zlib is a library implementing the deflate compression method found
     in gzip and PKZIP.  This package includes the development support
     files.
    Homepage: http://zlib.net/
    Original-Maintainer: Mark Brown <[email protected]>
    

(The dummy package foo has been generated with equivs to emulate a control file generated by bloom.)

In the version_gte or version_lt case the generated comparison probably behaves as expected for most packages, but only in case the respective Debian version does have a zero or unspecified epoch.

Am I missing something here? Or is it allowed to specify exact Debian version strings in package.xml? The latter would break platform-independence and probably some other tools.

I am not sure what would be the best way to fix this, but maybe bloom should at least emit a warning if a package specifies version_eq or version_lte dependencies because they most likely cannot be satisfied and the generated debian package cannot be installed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions