Troubleshooting apt_get module
I wanted a clean environment, so I went with a Vagrant box that I could build at destroy at will. The vagrantfile reduces to:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/precise64"
config.vm.provision "shell", inline: <<-SHELL
curl "https://cfengine-package-repos.s3.amazonaws.com/pub/gpg.key" | apt-key add -
echo "deb https://cfengine-package-repos.s3.amazonaws.com/pub/apt/packages stable main" > /etc/apt/sources.list.d/cfengine-community.list
apt-get update
apt-get install -y git cfengine-community=3.7.4-1
git checkout -b 3.7 https://github.com/cfengine/masterfiles.git
cd masterfiles
./autogen.sh --without-core --prefix=$HOME/cf_install
make install
#curl -o /var/cfengine/modules/packages/apt_get https://raw.githubusercontent.com/jpvlsmv/masterfiles/jpvlsmv-apt-options/modules/packages/apt_get
cp /vagrant/apt_get /var/cfengine/modules/packages/apt_get
/var/cfengine/bin/cf-promises --version
/var/cfengine/bin/cf-promises -c -I -f $HOME/cf_install/update.cf
/var/cfengine/bin/cf-promises -c -I -f $HOME/cf_install/promises.cf
/var/cfengine/bin/cf-agent -KI /vagrant/testrunner.cf
echo '*******************************************************************************************'
echo 'Test Results:'
echo '---------------'
echo 'These packages should be Installed:'
/usr/bin/apt-cache policy base-files redis-server hello collectd-core x11-apps | grep -e '^[^ ]' -e Installed:
echo '---------------'
echo 'These packages should NOT be Installed:'
/usr/bin/apt-cache policy thispackagedoesnotexist rrdtool nethack-x11 | grep -e '^[^ ]' -e Installed:
echo 'Downloaded file:'
ls -l /var/cache/apt/archives/nethack-x11*
echo '*******************************************************************************************'
SHELL
end
On the provisioning script, everything above the copy from my repository is based on the Travis-ci testing that is done on the masterfiles. It probably does a lot more than is necessary.
I picked some packages more or less at random to test various aspects of the module:
- Make sure base-files is present (It's a base package, can't get far without it)
- Install redis-server from the default repository (This is not part of the base image)
- Try to install "thispackagedoesnotexist" to check error handling
- Local file install
- Install collectd-core. This Recommends: rrdtool (among other things), but I give the promise APT::Install-Recommends=0 to hopefully prevent rrdtool from getting installed.
- Check that rrdtool wasn't installed, but don't remove it if it was
- Pass a single option -qqqqqqq to see just how quiet apt-get can be
- Test the download-only option (nethack-x11) (non-convergent, but an interesting syntax example).
Here's the testrunner.cf file:
body file control
{
# Pull in stdlib definitions
inputs => { "packages.cf", "commands.cf" };
}
body common control
{
bundlesequence => { "verify_pkgs", "testrunner" };
}
bundle agent verify_pkgs
{
commands:
"/usr/bin/apt-cache policy base-files | grep -e '^[^ ]' -e Installed:"
contain => in_shell; # This should be installed.
"/usr/bin/apt-cache policy php7.0 thispackagedoesnotexist hello collectd-core rrdtool x11-apps nethack-x11 | grep -e '^[^ ]' -e Installed:"
contain => in_shell; # None of these should be installed
}
bundle agent testrunner
{
methods:
# Sanity checks (smoke test)
"test_already_installed" usebundle => pkgtest("base-files"); # base-files should be installed on all
# systems, so this should be a noop
"test_repo_newpkg" usebundle => pkgtest("redis-server"); # this is not a default package
"test_404_pkg" usebundle => pkgtest("thispackagedoesnotexist");
"test_file_pkg" usebundle => pkgtest("/vagrant/hello_2.10-1_amd64.deb");
"test_apt_options" usebundle => test_apt_options("collectd-core","rrdtool"); # Verify that options are passed through module
"test_apt_quiet" usebundle => quiet_apt("x11-apps"); # Verify that options are passed through module
"test_download_only" usebundle => download_only("nethack-x11");
}
bundle agent pkgtest(x)
{
packages:
"$(x)"
policy => "present",
package_module => apt_get;
}
bundle agent test_apt_options(good,bad)
{
packages:
"$(good)" # This package has lots of Recommends to carry in
policy => "present",
package_module => apt_get,
options => { "-o", "APT::Install-Recommends=0" }; # We should not get any recommended packages
"$(bad)" # This is recommended by the good package
policy => "absent",
package_module => apt_get,
action => warn_only; # Whine if we find it is installed.
}
bundle agent quiet_apt(x)
{
packages:
"$(x)"
policy => "present",
package_module => apt_get,
options => { "-qqqqqqqqqq" };
}
bundle agent download_only(x)
{
packages:
"$(x)"
policy => "present", # Since we download only, this will never converge.
package_module => apt_get,
options => { "-o", "Apt::Get::Download-Only=1" };
}
For some reason, I did need to duplicate several portions of the CFEngine StdLib in my vagrant workdirectory: commands.cf, common.cf, files.cf, packages.cf, and paths.cf. (Copy them from any masterfiles)
And here's the output from a successful run:
==> default: info: Executing 'no timeout' ... '/usr/bin/apt-cache policy base-files | grep -e '^[^ ]' -e Installed:'
==> default: notice: Q: ".../apt-cache poli": base-files:
==> default: Q: ".../apt-cache poli": Installed: 6.5ubuntu6.8
==> default: info: Last 2 quoted lines were generated by promiser '/usr/bin/apt-cache policy base-files | grep -e '^[^ ]' -e Installed:'
==> default: info: Completed execution of '/usr/bin/apt-cache policy base-files | grep -e '^[^ ]' -e Installed:'
==> default: info: Executing 'no timeout' ... '/usr/bin/apt-cache policy php7.0 thispackagedoesnotexist hello collectd-core rrdtool x11-apps nethack-x11 | grep -e '^[^ ]' -e Installed:'
==> default: notice: Q: ".../apt-cache poli": hello:
==> default: Q: ".../apt-cache poli": Installed: (none)
==> default: Q: ".../apt-cache poli": collectd-core:
==> default: Q: ".../apt-cache poli": Installed: (none)
==> default: Q: ".../apt-cache poli": rrdtool:
==> default: Q: ".../apt-cache poli": Installed: (none)
==> default: Q: ".../apt-cache poli": x11-apps:
==> default: Q: ".../apt-cache poli": Installed: (none)
==> default: Q: ".../apt-cache poli": nethack-x11:
==> default: Q: ".../apt-cache poli": Installed: (none)
==> default: info: Last 10 quoted lines were generated by promiser '/usr/bin/apt-cache policy php7.0 thispackagedoesnotexist hello collectd-core rrdtool x11-apps nethack-x11 | grep -e '^[^ ]' -e Installed:'
==> default: info: Completed execution of '/usr/bin/apt-cache policy php7.0 thispackagedoesnotexist hello collectd-core rrdtool x11-apps nethack-x11 | grep -e '^[^ ]' -e Installed:'
==> default: info: Successfully installed package 'redis-server'
==> default: E
==> default: info: Some error occurred while communicating with package module while installing package.
==> default: error: Error installing package 'thispackagedoesnotexist'
==> default: : Unable to locate package thispackagedoesnotexist
==> default: error: Method 'pkgtest' failed in some repairs
==> default: info: Successfully installed package '/vagrant/hello_2.10-1_amd64.deb'
==> default: Not starting collectd - no configuration (/etc/collectd/collectd.conf) found.
==> default: info: Successfully installed package 'collectd-core'
==> default: info: Successfully installed package 'x11-apps'
==> default: error: Error installing package 'nethack-x11'
==> default: error: Method 'download_only' failed in some repairs
==> default: *******************************************************************************************
==> default: Test Results:
==> default: ---------------
==> default: These packages should be Installed:
==> default: base-files:
==> default: Installed: 6.5ubuntu6.8
==> default: redis-server:
==> default: Installed: 2:2.2.12-1build1
==> default: hello:
==> default: Installed: 2.10-1
==> default: collectd-core:
==> default: Installed: 4.10.1-2.1ubuntu7
==> default: x11-apps:
==> default: Installed: 7.6+5ubuntu1
==> default: ---------------
==> default: These packages should NOT be Installed:
==> default: rrdtool:
==> default: Installed: (none)
==> default: nethack-x11:
==> default: Installed: (none)
==> default: Downloaded file:
==> default: -rw-r--r-- 1 root root 992390 Oct 18 2011 /var/cache/apt/archives/nethack-x11_3.4.3-12.2_amd64.deb
==> default: *******************************************************************************************
Since this module protocol uses stdin and stdout for communication (and anything unexpected is an error, including anything written to stderr) I had to find a different way of printf-debugging my way through the python script (masterfiles/modules/packages/apt_get). I settled on import syslog
and dumping things into the vagrant machine's /var/log/syslog.
And the problem turned out to be that cfengine was talking to my module using "options=foo" and I was expecting "Options=foo".