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

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

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: PUP 6.8.0
    • Fix Version/s: PUP 6.8.1
    • Component/s: None
    • Template:
      PUP Bug Template
    • Method Found:
      Needs Assessment
    • Release Notes:
      Bug Fix
    • Release Notes Summary:
      Removed the feature for virtual package support for dpkg provider.
    • QA Risk Assessment:
      Needs Assessment

      Description

      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

      dpkg.rb

            if @resource.allow_virtual?
              output = dpkgquery(
                "-W",
                "--showformat",
                self.class::DPKG_QUERY_PROVIDES_FORMAT_STRING
              ).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]
              end
            end
      

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

      dpkg.rb

        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.

        Attachments

          Issue Links

            Activity

              jsd-sla-details-panel

                People

                • Assignee:
                  alexandru.popa Alexandru Popa
                  Reporter:
                  mhoermann Matthias Hörmann
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: