why doesn't 'Package <| provider == "apt" |>' work for me?

39 views
Skip to first unread message

Amos Shapira

unread,
Mar 10, 2015, 11:30:48 PM3/10/15
to puppet...@googlegroups.com
Hi,

I'm running into the common issue of having to force an "apt-get update" before installing packages (in my case - because the base EC2 AMI is old and I need it to pick newer package versions).

I ended up doing the usual:

 exec { 'apt-get update':
   path => '/usr/bin/',
 }
 ->
 Package <| |>

(I can't use "apt::update" because it creates dependency cycles) and it works.

But what baffles me is that I really only need "apt-get update" to execute before "apt" packages get installed, like this:

Package <| provider = "apt" |>

But this doesn't trigger the "apt-get update".

Just as an example, I also have a Gem-provider related exec which works as expected:

  exec { 'Add Ruby Gems repo mirror':
    command => 'gem source --config-file /etc/gemrc -a http://production.cf.rubygems.org/',
    unless  => 'gem source --config-file /etc/gemrc | fgrep -xq http://production.cf.rubygems.org/',
    path    => '/usr/bin:/bin',
  }
  ->
  Package<| provider == 'gem' |>

So why doesn't it work for the "apt" provider?

Thanks.

jcbollinger

unread,
Mar 11, 2015, 9:39:53 AM3/11/15
to puppet...@googlegroups.com


On Tuesday, March 10, 2015 at 10:30:48 PM UTC-5, Amos Shapira wrote:
Hi,

I'm running into the common issue of having to force an "apt-get update" before installing packages (in my case - because the base EC2 AMI is old and I need it to pick newer package versions).

I ended up doing the usual:

 exec { 'apt-get update':
   path => '/usr/bin/',
 }
 ->
 Package <| |>



If you are using PuppetLabs's Apt module, then I think setting the 'always_apt_update => true' on class 'apt' and declaring

Class['Apt'] -> Package <| |>


should take care of it for you.  That module's 'apt::update' class is not really suited to be public, given the way the module uses it.

 
(I can't use "apt::update" because it creates dependency cycles) and it works.

But what baffles me is that I really only need "apt-get update" to execute before "apt" packages get installed, like this:

Package <| provider = "apt" |>

But this doesn't trigger the "apt-get update".

Just as an example, I also have a Gem-provider related exec which works as expected:

  exec { 'Add Ruby Gems repo mirror':
    command => 'gem source --config-file /etc/gemrc -a http://production.cf.rubygems.org/',
    unless  => 'gem source --config-file /etc/gemrc | fgrep -xq http://production.cf.rubygems.org/',
    path    => '/usr/bin:/bin',
  }
  ->
  Package<| provider == 'gem' |>

So why doesn't it work for the "apt" provider?


 
Resource collectors operate during catalog building.  Their selection predicates can see only parameter and property values explicitly declared in your manifests.  It does not know what values will be effective at catalog application time for any other parameters.  In particular, it does not know what provider will be selected during catalog application unless one is specified in the manifest, which is not usual when the system's default provider is expected.

To the best of my knowledge, the "gem" provider is not the default for any system, so you get it only when you specifically ask for it.  That's why you can reliably select gem Packages by provider.  'Apt' is normally the default Package provider on systems that support it at all.  Your selection predicate will not match Package resources that rely 'apt' being selected by default.


John


Amos Shapira

unread,
Mar 11, 2015, 11:02:08 PM3/11/15
to puppet...@googlegroups.com
On Thursday, 12 March 2015 00:39:53 UTC+11, jcbollinger wrote:


On Tuesday, March 10, 2015 at 10:30:48 PM UTC-5, Amos Shapira wrote:
Hi,

I'm running into the common issue of having to force an "apt-get update" before installing packages (in my case - because the base EC2 AMI is old and I need it to pick newer package versions).

I ended up doing the usual:

 exec { 'apt-get update':
   path => '/usr/bin/',
 }
 ->
 Package <| |>



If you are using PuppetLabs's Apt module, then I think setting the 'always_apt_update => true' on class 'apt' and declaring

Class['Apt'] -> Package <| |>


should take care of it for you.  That module's 'apt::update' class is not really suited to be public, given the way the module uses it.


Thanks. I'm aware of the "always_apt_update" option but am worried that it means that puppet will force an "apt-get update" every time it runs (every 30 minutes).  We will eventually move away from puppet agents to immutable images but until then I'm worried that this could stir up a lot of load on our EC2 instances which we wouldn't want.

Perhaps I should reconsider this option.
 
 
(I can't use "apt::update" because it creates dependency cycles) and it works.

But what baffles me is that I really only need "apt-get update" to execute before "apt" packages get installed, like this:

Package <| provider = "apt" |>

But this doesn't trigger the "apt-get update".

Just as an example, I also have a Gem-provider related exec which works as expected:

  exec { 'Add Ruby Gems repo mirror':
    command => 'gem source --config-file /etc/gemrc -a http://production.cf.rubygems.org/',
    unless  => 'gem source --config-file /etc/gemrc | fgrep -xq http://production.cf.rubygems.org/',
    path    => '/usr/bin:/bin',
  }
  ->
  Package<| provider == 'gem' |>

So why doesn't it work for the "apt" provider?


 
Resource collectors operate during catalog building.  Their selection predicates can see only parameter and property values explicitly declared in your manifests.  It does not know what values will be effective at catalog application time for any other parameters.  In particular, it does not know what provider will be selected during catalog application unless one is specified in the manifest, which is not usual when the system's default provider is expected. 

To the best of my knowledge, the "gem" provider is not the default for any system, so you get it only when you specifically ask for it.  That's why you can reliably select gem Packages by provider.  'Apt' is normally the default Package provider on systems that support it at all.  Your selection predicate will not match Package resources that rely 'apt' being selected by default.

Thanks for the explanation. That makes sense. Mystery answered :) 
 


John


jcbollinger

unread,
Mar 12, 2015, 8:50:29 AM3/12/15
to puppet...@googlegroups.com


On Wednesday, March 11, 2015 at 10:02:08 PM UTC-5, Amos Shapira wrote:
On Thursday, 12 March 2015 00:39:53 UTC+11, jcbollinger wrote:


On Tuesday, March 10, 2015 at 10:30:48 PM UTC-5, Amos Shapira wrote:
Hi,

I'm running into the common issue of having to force an "apt-get update" before installing packages (in my case - because the base EC2 AMI is old and I need it to pick newer package versions).

I ended up doing the usual:

 exec { 'apt-get update':
   path => '/usr/bin/',
 }
 ->
 Package <| |>



If you are using PuppetLabs's Apt module, then I think setting the 'always_apt_update => true' on class 'apt' and declaring

Class['Apt'] -> Package <| |>


should take care of it for you.  That module's 'apt::update' class is not really suited to be public, given the way the module uses it.


Thanks. I'm aware of the "always_apt_update" option but am worried that it means that puppet will force an "apt-get update" every time it runs (every 30 minutes).  We will eventually move away from puppet agents to immutable images but until then I'm worried that this could stir up a lot of load on our EC2 instances which we wouldn't want.



Well yes, I would expect 'always_apt_update => true' to cause an "apt-get update" on every Puppet run.  I didn't comment on that before because you get the same thing from the Exec you described using.


John

Reply all
Reply to author
Forward
0 new messages