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

Right now I have the following in my Vagrantfile:
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "cookbooks"
chef.add_recipe "apt"
chef.add_recipe "build-essential"
chef.add_recipe "chef-redis::source"
chef.add_recipe "openssl"
chef.add_recipe "git"
chef.add_recipe "postgresql::server"
chef.add_recipe "postgresql::client"
end
In order to install the software added to my recipe_list, I need to get the VM to issue an apt-get update before installing the other software.
I was under the impression that this was one of the features of the 'apt' recipe - that it would run the update first thing.
The output when I do a vagrant provision is:
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: *** Chef 0.10.2 ***
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Setting the run_list to ["recipe[apt]", "recipe[build-essential]", "recipe[chef-redis::source]", "recipe[openssl]", "recipe[git]", "recipe[postgresql::server]", "recipe[postgresql::client]", "recipe[vagrant-main]"] from JSON
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Run List is [recipe[apt], recipe[build-essential], recipe[chef-redis::source], recipe[openssl], recipe[git], recipe[postgresql::server], recipe[postgresql::client], recipe[vagrant-main]]
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Run List expands to [apt, build-essential, chef-redis::source, openssl, git, postgresql::server, postgresql::client, vagrant-main]
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Starting Chef Run for lucid32
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Processing package[postgresql-client] action install (postgresql::client line 37)
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: package[postgresql-client] (postgresql::client line 37) has had an error
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: Running exception handlers
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: Exception handlers complete
[Sat, 11 Feb 2012 22:20:04 -0800] FATAL: Stacktrace dumped to /tmp/vagrant-chef-1/chef-stacktrace.out
[Sat, 11 Feb 2012 22:20:04 -0800] FATAL: Chef::Exceptions::Exec: package[postgresql-client] (postgresql::client line 37) had an error: apt-get -q -y install postgresql-client=8.4.8-0ubuntu0.10.04 returned 100, expected 0

You can include the apt recipe in the very beginning:
include_recipe 'apt'
this will run the update command.

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

There are three resources that will do this nicely on an ubuntu system, specifically in use on 12.04 precise 64 bit by me.
run apt-get-update at will when other recipes require
install update-notifier-common package that gives us timestamps on updates
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

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.

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'

I seem to have been able to solve the issue by applying the following patch:
https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81

The simplest and most direct way to solve the problem is by applying the following patch (h/t #ashchristopher):
https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81
The problem is that the postgresql::client recipe runs the install action on the package resources at postgresql/recipes/client.rb:39 and 44 at compile-time rather than run-time like normal (h/t Tim Potter), causing them to be evaluated by Chef (and thus installed) before anything else runs.
pg_packages.each do |pg_pack|
package pg_pack do
action :nothing
end.run_action(:install)
end
gem_package "pg" do
action :nothing
end.run_action(:install)
I believe this is done in service of the database cookbook's postgres provider, which depends on the postgresql cookbook and relies on the pg gem being installed before it will compile. Applying the above patch may break the database cookbook.
The other alternative solution would be to create a recipe which runs apt-get update also at compile time and put it in your run_list before the postgresql cookbook. In its simplest form that would probably be something like:
execute "apt-get update" do
action :nothing
end.run_action(:install)

Without patching, this is a generic approach to the problem that will update on every run:
bash "update-apt-repository" do
user "root"
code <<-EOH
apt-get update
EOH
end
It may be worth considering that such a run, on every run, ties up a fair bit of system resources for about 30 seconds; you may want to have a special recipe named recipe::update_apt that you have run via cron or via some other event i.e.
chef-client -o "recipe[yourrecipe::update_apt]"

To run apt-get update at compile time, do:
e = execute "apt-get update" do
action :nothing
end
e.run_action(:run)
check https://wiki.opscode.com/display/chef/Evaluate+and+Run+Resources+at+Compile+Time

I had the same situation, and in my case, apt cookbook was second after the one which called installation of package. Just leaving it here so maybe someone will benefit from it. Check the order of cookbooks in your runlist, role or wherever else.

just a friendly reminder that adding all those recipes inside the vagrant provision can quickly become unmanageable.
A better pattern is to create a chef role chef/my-fancy-role.rb
# Name of the role should match the name of the file
name "my-fancy-role"
# Run list function we mentioned earlier
run_list(
"recipe[apt]",
"recipe[build-essential]",
"recipe[chef-redis::source]",
"recipe[openssl]"
)
And then add this role to the Vagrantfile provisioning section:
config.vm.provision :chef_solo do |chef|
chef.roles_path = "chef/roles"
chef.cookbooks_path = ["chef/site-cookbooks", "chef/cookbooks"]
chef.add_role "my-fancy-role"
end

For the recent Chef version, i.e version 14.
You could also use https://docs.chef.io/resource_apt_update.html
apt_update
The below output was my experiment running that resource for chef_14.5.33 in local mode (zero):
curl -O https://packages.chef.io/files/stable/chef/14.5.33/ubuntu/18.04/chef_14.5.33-1_amd64.de
sudo dpkg -i chef_14.5.33-1_amd64.deb
mkdir -p cookbooks/hello/recipes/ && echo "apt_update" > cookbooks/hello/recipes/default.rb
sudo sh -c 'chef-client -z -o hello'
[2018-10-12T10:25:30+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 14.5.33
[2018-10-12T10:25:32+00:00] WARN: Run List override has been provided.
[2018-10-12T10:25:32+00:00] WARN: Run List override has been provided.
[2018-10-12T10:25:32+00:00] WARN: Original Run List: []
[2018-10-12T10:25:32+00:00] WARN: Original Run List: []
[2018-10-12T10:25:32+00:00] WARN: Overridden Run List: [recipe[hello]]
[2018-10-12T10:25:32+00:00] WARN: Overridden Run List: [recipe[hello]]
resolving cookbooks for run list: ["hello"]
Synchronizing Cookbooks:
- hello (0.0.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: hello::default
* apt_update[] action periodic (up to date)
[2018-10-12T10:25:32+00:00] WARN: Skipping final node save because override_runlist was given
[2018-10-12T10:25:32+00:00] WARN: Skipping final node save because override_runlist was given
Running handlers:
Running handlers complete
Chef Client finished, 0/1 resources updated in 01 seconds

Related

Install a particular Ruby version using chef-run

I have been trying to install a particular (latest) version of Ruby using Chef Workstation and its included chef-run CLI.
This is the recipe I'm using for Ruby:
package 'ruby' do
version '2.5.3'
action :install
end
Which, running with the command line
chef-run -i /path-to/private_key user#host ruby.rb
Produces the not very helpful message:
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✖] Applying ruby from ruby.rb to target.
└── [✖] [127.0.0.1] Failed to converge ruby.
The converge of the remote host failed for the
following reason:
Expected process to exit with [0], but received '100'
I have tried to run it with the -V flag, or look for a log file, but I can't seem to find it. Any idea?
raise the log_level by setting it to debug in the chef-workstation configuration
$ cat ~/.chef-workstation/config.toml
[log]
level="debug"

Chef: Recipe Compile Error in /var/chef/cache/cookbooks/couchbase/libraries/helper.rb cannot load such file -- chef/rest

I have vagrant : Vagrant 1.7.4, and a devbox cookbook, when I do vagrant up is showing me a compile error :
Recipe Compile Error in /var/chef/cache/cookbooks/couchbase/libraries/helper.rb cannot load such file -- chef/rest .
With same setup, same cookbook is working for all other machines.
full logs : https://s3-eu-west-1.amazonaws.com/uploads-eu.hipchat.com/102620/3335846/qsb5ZamnZGZ7Rdf/log.txt
Can some help?
Thank you
Check if you're using the Chef 13 pre release that went up today. If so, that file is indeed removed and the cookbook needs to be updated. The official Chef 13 release will be on Monday and it will take some time for even a reasonable number of cookbooks to port to it.

Chef/Vagrant/Serverspec: specs ensuring that packages are installed fail, but they are installed

From the docs it seems like using Serverspec to verify that packages are installed should be pretty straight-forward, but I'm having some interesting problems with vim and ag (the_silver_searcher).
I am using Test Kitchen with the kitchen-vagrant plugin and have two platforms: ubuntu-1404 and centos-72. All of my specs pass for Ubuntu, and two of them fail for Centos: vim and ag.
vim
The Chef code that handles this installation is super simple:
package "vim"
And here is the spec:
describe "Vim" do
describe package("vim") do
it { should be_installed }
end
end
Again, very straight-forward. However, it fails on my Centos build with this error:
2) Vim Package "vim" should be installed
Failure/Error: it { should be_installed }
expected Package "vim" to be installed
/bin/sh -c rpm\ -q\ vim
package vim is not installed
Yet if I login to the server, it most definitely is installed:
▶ kitchen login all-centos-72
Last login: Sat Jul 2 17:53:30 2016 from 10.0.2.2
[vagrant#all-centos-72 ~]$ vim --version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Jun 10 2014 06:55:55)
[vagrant#all-centos-72 ~]$ which vim
/usr/bin/vim
[vagrant#all-centos-72 ~]$ sudo yum install -y vim
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: distro.ibiblio.org
* extras: mirror.us.leaseweb.net
* updates: mirror.eboundhost.com
Package 2:vim-enhanced-7.4.160-1.el7.x86_64 already installed and latest version
Nothing to do
ag
ag is more complicated in that the installation requires building from source on Centos whereas on Ubuntu it's available with apt-get. Here is the relevant part of the recipe:
bash "install Development Tools" do
code "yum -y groupinstall \"Development Tools\""
end
package %w(pcre-devel xz-devel)
target_dir = File.join("/", "usr", "local", "the_silver_searcher")
git "clone the ag repo" do
repo "https://github.com/ggreer/the_silver_searcher/"
revision "master"
destination target_dir
end
bash "install ag" do
not_if system("hash ag")
cwd target_dir
code <<-EOF
./build.sh
make install
EOF
end
And here is the spec:
describe "The Silver Searcher" do
if host_inventory["platform"] == "ubuntu"
describe package("silversearcher-ag") do
it { should be_installed }
end
else
describe package("the_silver_searcher") do
it { should be_installed }
end
end
end
The Centos failure:
1) The Silver Searcher Package "the_silver_searcher" should be installed
Failure/Error: it { should be_installed }
expected Package "the_silver_searcher" to be installed
/bin/sh -c rpm\ -q\ the_silver_searcher
package the_silver_searcher is not installed
Likewise, if I log into the Centos VM I can use ag:
[vagrant#all-centos-72 ~]$ ag --version
ag version 0.32.0
[vagrant#all-centos-72 ~]$ which ag
/usr/local/bin/ag
These commands also work if I switch to root user.
I've tried to cheat the system by writing my specs in different ways for the Centos platform:
describe command("ag") do
its(:stderr) { should match /Usage: ag/ }
end
The above also doesn't work, even though typing ag when logged in (exit status 1) does produce that usage content. My last attempt was:
describe file("/usr/local/bin/ag") do
it { should exist }
end
This works but feels super hacky and like it shouldn't be necessary.
Anyone have recommendations here? Is there something I'm missing/doing wrong with these packages? I initially thought that the ag problem was only because it was installed from source rather than a package manager, but vim was installed with a package manager and still has the same problem as ag.
The answer to the question has two parts, one dealing with the way Serverspec works and the other with how various Linux distributions handle packages.
1) Serverspec users shouldn't assume any behavior that isn't literally implied by the name of the package resource. Applications that are installed by any means other than the system's package manager will not be picked up and their successful installation should be tested by other means. This could include, as in the question, testing for the existence of a binary file.
2) When the developer has installed an application with a package manager, he/she must be aware that package managers on different Linux distributions sometimes (often?) have different names for the same package. A classic example of this is apache2 on Debian systems vs. httpd on RedHat systems. In the specific case mentioned in the question, vim is recognized on CentOS as vim-enhanced even though yum accepts vim as the name when installing it (thanks to #matt-schuchard for pointing out that they are linked).
Also wanted to credit #Karen B for helping me reach these conclusions in the comments to the question.
You aren't installing ag via a package so it's not a "hack" for that to not work.

Installing puppetlabs/apt fails with '302 Found'

So I have a vagrant / puppet setup for my project* and am running Ubuntu 14.04 on it. It just broke, without changing anything. puppet module install puppetlabs-apt inside the VM fails with the following lines:
Error: Could not execute operation for 'puppetlabs/apt'
The server being queried was https://forge.puppetlabs.com
The HTTP response we received was '302 Found'
Check the author and module names are correct.
I'm using this module for quite some time and it seems like it just stopped working for no reason. Any advice appreciated.
-- Edit: answer question
running it with --debug doesn't help much I guess
Notice: Preparing to install into /home/vagrant/.puppet/modules ...
Notice: Created target directory /home/vagrant/.puppet/modules
Notice: Downloading from https://forge.puppetlabs.com ...
Error: Could not execute operation for 'puppetlabs/apt'
The server being queried was https://forge.puppetlabs.com
The HTTP response we received was '302 Found'
Check the author and module names are correct.
*Link: https://github.com/dwalldorf/owTracker
vagrant up / vagrant ssh and puppet module install puppetlabs-apt
This should be fixed. You can check FORGE-327 for more information
https://forge.puppetlabs.com/puppetlabs/apt redirect to https://forge.puppet.com/puppetlabs/apt
you can force it to use the correct forge by appending --module_repository https://forge.puppet.com/ so it will become
puppet module install puppetlabs-apt --module_repository https://forge.puppet.com/
not sure exactly why it wants to download from https://forge.puppetlabs.com at first place, you could check your puppet.conf

Vagrant & Chef: uninitialized constant Chef::Resource::LWRPBase

I get this error when i try to run "vagrant provision":
Running chef-solo...
stdin: is not a tty
[2014-05-15T12:21:41+00:00] INFO: *** Chef 10.14.2 ***
[2014-05-15T12:21:41+00:00] INFO: Setting the run_list to ["recipe[apt]", "recipe[build-essential]", "recipe[vim]", "recipe[git]", "recipe[mysql::server]", "recipe[apache2]", "recipe[php]", "recipe[vhosts]", "recipe[apache2::mod_php5]", "recipe[php::module_mysql]", "recipe[php::module_apc]", "recipe[php::module_curl]", "recipe[phpmyadmin]", "recipe[phpredis]", "recipe[redis-package::server]", "recipe[nodejs]", "recipe[composer]", "recipe[couchbase::server]", "recipe[symfony2_stuff]"] from JSON
[2014-05-15T12:21:41+00:00] INFO: Run List is [recipe[apt], recipe[build-essential], recipe[vim], recipe[git], recipe[mysql::server], recipe[apache2], recipe[php], recipe[vhosts], recipe[apache2::mod_php5], recipe[php::module_mysql], recipe[php::module_apc], recipe[php::module_curl], recipe[phpmyadmin], recipe[phpredis], recipe[redis-package::server], recipe[nodejs], recipe[composer], recipe[couchbase::server], recipe[symfony2_stuff]]
[2014-05-15T12:21:41+00:00] INFO: Run List expands to [apt, build-essential, vim, git, mysql::server, apache2, php, vhosts, apache2::mod_php5, php::module_mysql, php::module_apc, php::module_curl, phpmyadmin, phpredis, redis-package::server, nodejs, composer, couchbase::server, symfony2_stuff]
[2014-05-15T12:21:41+00:00] INFO: Starting Chef Run for precise64
[2014-05-15T12:21:41+00:00] INFO: Running start handlers
[2014-05-15T12:21:41+00:00] INFO: Start handlers complete.
================================================================================
Recipe Compile Error in /tmp/vagrant-chef-1/chef-solo-1/cookbooks/build-essential/libraries/xcode_command_line_tools.rb
================================================================================
NameError
---------
uninitialized constant Chef::Resource::LWRPBase
Cookbook Trace:
---------------
/tmp/vagrant-chef-1/chef-solo-1/cookbooks/build-essential/libraries/xcode_command_line_tools.rb:21
Relevant File Content:
----------------------
/tmp/vagrant-chef-1/chef-solo-1/cookbooks/build-essential/libraries/xcode_command_line_tools.rb:
1: #
2: # Cookbook Name:: build-essential
3: # Library:: xcode_command_line_tools
4: #
5: # Copyright 2014, Chef Software, Inc.
6: #
7: # Licensed under the Apache License, Version 2.0 (the "License");
8: # you may not use this file except in compliance with the License.
9: # You may obtain a copy of the License at
[2014-05-15T12:21:42+00:00] ERROR: Running exception handlers
[2014-05-15T12:21:42+00:00] ERROR: Exception handlers complete
[2014-05-15T12:21:42+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2014-05-15T12:21:42+00:00] FATAL: NameError: uninitialized constant Chef::Resource::LWRPBase
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
Installed Xcode & the Command Line Tools. I already updated Chef and Vagrant - so any ideas?
Box: https://bitbucket.org/creativebrains/box
I search for the term "LWRPBase" but didnt find any answers for it.
This stackoverflow thread helped me to run my Vagrantfile with the latest Chef version (which was the problem):
How to control the version of Chef that Vagrant uses to provision VMs?
What version of build_essential cookbook are you using? You seem to be on a pretty old version of Chef (10.14.2) and I wonder if you're running into: https://tickets.opscode.com/browse/COOK-4441

Resources