Search code examples
rubycentosvagrantchef-infraserverspec

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.


Solution

  • 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.