New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The resource `dpkg_package` doesn't allow downgrades #7713

Closed
saveriomiroddi opened this Issue Oct 3, 2018 · 7 comments

Comments

Projects
None yet
3 participants
@saveriomiroddi

saveriomiroddi commented Oct 3, 2018

This bug is similar to #6095, except that it involves dpkg rather than apt.

The problem is related to Chef, not to the packaging tools, since it's Chef who decides whether the package tool should be run or not. This is an example:

WARN: dpkg_package[libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb] libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb has installed version 5.7.23-0ubuntu0.18.04.1, which is newer than available version 5.5.61-0ubuntu0.14.04.1. Skipping...)

Note that dpkg itself will make no fuss when executing --install on a package that will cause a downgrade.

I can't test on RPM, so I don't have hands-on experience on allow_downgrade, however, in the current conditions, downgrade use cases necessarily need this property in order to be executed.

@lamont-granquist

This comment has been minimized.

Contributor

lamont-granquist commented Oct 25, 2018

did af0613a fix this?

@saveriomiroddi

This comment has been minimized.

saveriomiroddi commented Oct 26, 2018

did af0613a fix this?

It seems it didn't:

# chef-client --version
Chef: 14.6.47

# aptitude show libmysqlclient-dev | ag 'Version|State' # not held
Version: 5.7.24-0ubuntu0.18.04.1
State: installed

# chef-client
[...]
  * remote_file[/var/chef/cache/libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb] action create_if_missing
    - create new file /var/chef/cache/libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb
    - update content in file /var/chef/cache/libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb from none to b057db
    (new content is binary, diff output suppressed)
  * dpkg_package[libmysqlclient-dev_5.5.61-0ubuntu0.14.04.1_amd64.deb] action install (up to date)
@lamont-granquist

This comment has been minimized.

Contributor

lamont-granquist commented Oct 26, 2018

Are you explicitly pinning? Because :install is going to see that the package is already installed and without an explicit constraint, that satisfies it so it won't take any actions. I think :upgrade would work or so would using an explicit version property?

@saveriomiroddi

This comment has been minimized.

saveriomiroddi commented Oct 26, 2018

Are you explicitly pinning? Because :install is going to see that the package is already installed and without an explicit constraint, that satisfies it so it won't take any actions. I think :upgrade would work or so would using an explicit version property?

Interesting case! So, in short: thanks, that does the job.

The interesting part is that I've just found two oddities of the version property:

  1. the given package will be installed independently of what's in version:
  dpkg_package package_name do
    source   local_filename
    version  "pizza"
  end
$ aptitude show libmysqlclient-dev | egrep 'State|Version'
Version: 5.7.24-0ubuntu0.18.04.1
State: installed

$ chef-client
# [...]
  * dpkg_package[libmysqlclient-dev] action install
    - install version pizza of package libmysqlclient-dev
  1. AFAIK, Chef, as a general guideline, doesn't perform any action when it determines that a resource is in the desired state. Therefore, I would assume that when a dpkg package is in the version specified by the related property, no :install action should be performed; this is not the case:
$ aptitude show libmysqlclient-dev | egrep 'State|Version'
Version: 5.7.24-0ubuntu0.18.04.1   # look the line below; 5.5 is installed
State: installed (5.5.61-0ubuntu0.14.04.1), upgrade available (5.7.24-0ubuntu0.18.04.1)

$ chef-client
# [...]
  * dpkg_package[libmysqlclient-dev] action install
    - install version 5.5.61-0ubuntu0.14.04.1 of package libmysqlclient-dev

I've checked the help of the resource and dpkg_resource, and there is no explicit mention of the cases above, so I assument the general behavior.

I'm not sure if version is entirely on topic with this issue, so please let me know if I need to open a separate issue (or not!).

@lamont-granquist

This comment has been minimized.

Contributor

lamont-granquist commented Nov 7, 2018

i think that is mostly correct behavior. you want version "pizza" and "5.5.61-0ubuntu0.14.04.1" does not equal "pizza" so it fails your idempotency check, and then takes the action. the fact that the local dpkg doesn't install "pizza" but installs "5.7.24-0ubuntu0.18.04.1" is a much higher level bug. we do not check that after the action is taken that the idempotency check passes. that would be... a lot of wiring to address. also there's no validation on the version string because that always has edge conditions that fail, which prevent people from getting work done and descend into endless whack-a-mole. generally those version strings wind up being passed to commands like "yum install" so we rely on the underlying operating system throwing an error. this is an edge condition where chef is the only consumer of that version string.

so we could fix this but it would introduce a new concept into chef of validating the idempotency action in the resource after every call or something like that, and i don't think this use case is worth it. the fact that the resource is never convergent is enough to tell the user that they need to fix their version string. the other obvious thing is to drop the version string entirely. the dpkg package itself fully specifies the desired state, and using :install or :upgrade should get the desired behavior between install-if-no-version-installed and pin-to-this-exact-version. using the version string to try to validate that you didn't somehow render the package name and that both of those need to get updated separately isn't really that useful.

@lamont-granquist

This comment has been minimized.

Contributor

lamont-granquist commented Nov 7, 2018

The other thing is that using an inspec test that the desired version gets installed is a much better validation check -- either as part of test-kitchen or using the audit cookbook.

@saveriomiroddi

This comment has been minimized.

saveriomiroddi commented Nov 8, 2018

Many thanks for the exhaustive clarification 😄.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment