Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-9974

Regression: allow_virtual => true matches too much for dpkg provider



    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • PUP 6.8.0
    • PUP 6.8.1
    • None
    • Needs Assessment
    • Bug Fix
    • Removed the feature for virtual package support for dpkg provider.
    • Needs Assessment


      Puppet Version: 6.8.0
      Puppet Server Version: 6.5.0
      OS Name/Version: Debian buster (10.x)

      Since the change of allow_virtual to true in Puppet 6.8.0 some of our package resources behaved strangely and required to change the parameter back to the old default. At first we thought this only affected packages where the name and a provides value are identical (e.g. a resource to uninstall vim and install vim-nox now tried to unistall vim-nox since it also provides vim).

      After installing a new server with the new Puppet version we noticed that the package bc had not been installed. It is defined with the simplest of package resources:

      package { 'bc':
          ensure => latest

      Looking at the provider source code we can see the relevant part here


            if @resource.allow_virtual?
              output = dpkgquery(
              ).lines.find {|package| package.match(/\[.*#{@resource[:name]}.*\]/)}
              if output          
                hash = self.class.parse_line(output,self.class::FIELDS_REGEX_WITH_PROVIDES)
                Puppet.info("Package #{@resource[:name]} is virtual, defaulting to #{hash[:name]}")
                @resource[:name] = hash[:name]

      with the constant used being defined further up in the file as


        self::DPKG_QUERY_PROVIDES_FORMAT_STRING = %Q{'${Status} ${Package} ${Version} [${Provides}]\\n'}

      Running the command

      dpkg-query -W --showformat '${Status} ${Package} ${Version} [${Provides}]\n"'

      on the affected system we can see the output the provider processes in the above code, a line might look like one of these

      "install ok installed php-apcu-bc 1.0.4-4 [php7.3-apcu-bc]
      "install ok installed php7.3-bcmath 7.3.4-2 [php-bcmath]
      "install ok installed php7.3-odbc 7.3.4-2 [php-odbc, php-pdo-odbc, php7.3-pdo-odbc]

      It is easy to see that all of these would also match the package resource named bc since the code just matches .name. within the comma-separated list of dpkg provides values, with no concern for matching a full name.

      Desired Behavior:

      Virtual packages (provides values) should only match exactly. The default for allow_virtual should be false for at least the apt and dpkg provider since there are many packages in the apt repositories that have identical names and provides values which leads to broken systems when puppet starts uninstalling packages on ensure => absent.

      Actual Behavior:

      Package resources are currently satisfied that they have found a matching package when they find the resource name as a substring in the list of provides values anywhere.


        Issue Links



              alexandru.popa Alexandru Popa
              mhoermann Matthias Hörmann
              0 Vote for this issue
              3 Start watching this issue



                Zendesk Support