How can I get Chef to run apt-get update before running other recipes

Solution 1:

You can include the apt recipe in the very beginning:

include_recipe 'apt'

this will run the update command.

Solution 2:

apt-get update should be running first the way you have it. However, the recipe will only update once every 24 hours:

execute "apt-get-update-periodic" do
  command "apt-get update"
  ignore_failure true
  only_if do
    File.exists?('/var/lib/apt/periodic/update-success-stamp') &&
    File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400
  end
end

Solution 3:

There are three resources that will do this nicely on an ubuntu system, specifically in use on 12.04 precise 64 bit by me.

  1. run apt-get-update at will when other recipes require

  2. install update-notifier-common package that gives us timestamps on updates

  3. check the timestamps and update periodically. In this case below after 86400 seconds.

And here's those three recipes.

execute "apt-get-update" do
  command "apt-get update"
  ignore_failure true
  action :nothing
end

package "update-notifier-common" do
  notifies :run, resources(:execute => "apt-get-update"), :immediately
end

execute "apt-get-update-periodic" do
  command "apt-get update"
  ignore_failure true
  only_if do
   File.exists?('/var/lib/apt/periodic/update-success-stamp') &&
   File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400
  end
end

Solution 4:

It looks like the latest version of the opscode apt cookbook allow you to run it at compile time.

config.vm.provision :chef_solo do |chef|
  chef.cookbooks_path = "cookbooks"
  chef.add_recipe "apt"
  chef.json = { "apt" => {"compiletime" => true} }
end

As long as apt is run before other compiletime cookbooks (like postgres) in the run list, this should work.

Solution 5:

A lot of the other answers posted here are likely to cause warnings about resource cloning.

According to the Apt cookbook documentation, you're supposed to be able to make this happen by setting node['apt']['compile_time_update'] = true, however I have never had much luck with this approach myself.

Here's what I do instead:

This will load the original apt-get update resource and ensure that it runs without adding a duplicate entry to the resource collection. This will cause apt-get update to execute during every Chef run during the compile phase:

# First include the apt::default recipe (so that `apt-get update` is added to the collection)
include_recipe 'apt'

# Then load the `apt-get update` resource from the collection and run it
resources(execute: 'apt-get update').run_action(:run)

Obviously, you'll also want to include the apt cookbook in your metadata.rb file:

# ./metadata.rb
depends 'apt'