3

If one thinks of a better title for this question: Please change it accordingly.

Environment:

  • Debian jessie 8.5
  • puppet master: 3.8.5
  • puppet agent: 3.7.2
  • apt: 1.0.9.8.3

Problem:

A specific package is installed already on the node, let's take needrestart for example:

# dpkg -l | grep needrestart
ii  needrestart                     1.2-8+deb8u1

Using the following code:

package{[
  'needrestart',
]:
  ensure          => installed, # latest won't work, either
  install_options => ['-t', 'jessie-backports']
}

I would expect that needrestart is reinstalled / upgraded to the version out of jessie-backports. However, this doesn't happen, there is no reinstall / upgrade happening. Inside the (debug) logs there's nothing worth to be shown regarding this.

Solution:

In case this is not intended: Anyone knows a clever way around this?

4 Answers 4

2
+100

Your problem is, that your install_options will only be used if the package resource is actually installing your packages. You have a few options:

  • Use ensure => latest and hope for a package update (or trigger one yourself) - probably not what you want.
  • Upgrading to Puppet 4.x. Since version 4, Puppet has reinstall_on_refresh, which allows a reinstall on a notify event, if the provider supports reinstallable. While this works on Debian, this option is probably not useable for you.
  • Trick Puppet into thinking the package is uninstalled - this would need a puppet patch on your local installation, not recommended.
  • Patch Puppet with reinstallation capabilities: In this bug report from a few years ago, Aggelos Economopoulos supplied a patch for some version of puppet, which looks rather simple. This should get you started. I do not recommend patching your puppet agent installations, though.
  • Reinstall it yourself: Probably the only option you have for now: Write something along these lines:

    exec { "apt-get reinstall $package $your_options":
        user   => 'root',
        onlyif => 'dpkg -s $package| grep 'Version $your_version'
    }
    

    Depending on the differences of the packages with and without options, this can be arbitrarily hard. If only a handful of packages are affected, it can be managable.

  • Write your own provider and add it to package, or establish something like package_reinstall: It is surprisingly easy, can be managed and versioned via a module, and works without a Puppet update. I suggest starting with provider/package/apt.rb. This might be your best option after all.

1
  • 1
    Thanks for your answer, back then. I'm using APT pinning since a while quite extensively, with great success, and it solve{d,s} the problem in a nice and elegant manner.
    – gxx
    Jun 2, 2017 at 19:52
0

I believe ensure => installed will only make sure it is installed, but it won't upgrade if there is a newer version. Use latest to do that. It will also only upgrade if there is a newer version. If that is a preferred version you want that is older than the version that is currently installed, you will have to find a way to work around that. Perhaps an exec that will check if current installed version is different than the version in that other repo, then uninstall if it is, and let the package resource install the correct version after.

4
  • Thanks for your comment! Regarding ensure => latest: I've tested this before, doesn't work, forgot to note this - sorry! Regarding exec: Yeah, this would be a possibility, but it feels quite 'hackish', doesn't it? I wonder if there isn't a better option / way / route ...
    – gxx
    Sep 2, 2016 at 13:28
  • Well, I'm not familiar with apt, but with yum, downgrades don't work that well, because it may have a lot of dependencies that require downgrading. You end up having to manually downgrade any dependencies also. I'm not sure there is a way (with the package providers that are provided) to do that. It is possible that ensure => latest doesn't use the parameters to check, only to do the actual install.
    – lsd
    Sep 2, 2016 at 14:39
  • Actually, it's (at least in my case) a upgrade, and not a downgrade, still the disadvantages (might) apply. In Debian, the backports mechanism is a way to get more recent versions of software into the stable release. So, a quite common situation is: There is a machine, which a specific software and version installed. Now, a more recent version get's available via backports. It would be nice if there would be a way to then pull in the package out of the backports repo, but I'm not sure if this is possible at all. Maybe I'll have to ask on the mailing list...
    – gxx
    Sep 2, 2016 at 15:20
  • Yeah, the only thing I'm guessing is that it doesn't apply the options to the check, only to the actual install/upgrade.
    – lsd
    Sep 2, 2016 at 16:26
0

You will need to trigger the install action for the install_options to take effect. A possible workaround is to first ensure => absent, and then once the package is removed you can ensure => present or ensure => 1.2-8+deb8u1 and the subsequent install will honor install_options.

1
  • This would involve changing the code two times, in my opinion not really a "clever" way for which I'm looking. Besides: If the package in question is a daemon, it's not really possible to first remove it and afterwards install it again, because then the service is interrupted for a longer time, than just an upgrade.
    – gxx
    Sep 3, 2016 at 8:17
0

I'm using APT pinning quite extensively since a while, and I believe this is (one of) the cleanest solutions out there, especially if combined with unattended upgrades and / or a regular apt-get dist-upgrade.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .