ovirt ansible module and osx delegate_to: localhost

When running an ansible playbook using the ovirt module on os x (and maybe any os) and using delegate_to: localhost I kept getting the following error:

ovirtsdk4 version 4.2.4 or higher is required for this module

That’s even after I had installed ovirtsdk using pip3 (my ansible runs using python3). Turns out when ansible runs under delegate_to: localhost it doesn’t use the normal python path, using the python_requirements_facts module you can check what the actual path to python ansible was using when running under delegate_to: localhost, here is the output from my python requirement facts:

"python": "/usr/local/Cellar/ansible/2.7.10/libexec/bin/python3.7",
"python_system_path": [
"/tmp/ansible_python_requirements_facts_payload_bt3it94z/ansible_python_requirements_facts_payload.zip",
"/usr/local/Cellar/ansible/2.7.10/libexec/lib/python37.zip",
"/usr/local/Cellar/ansible/2.7.10/libexec/lib/python3.7",
"/usr/local/Cellar/ansible/2.7.10/libexec/lib/python3.7/lib-dynload",
"/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7",
"/usr/local/Cellar/ansible/2.7.10/libexec/lib/python3.7/site-packages"

So checking if ovirt module was installed in this path showed it wasn’t

/usr/local/Cellar/ansible/2.7.10/libexec/bin/pip3 list | grep ovirt

So I had to install ovirtsdk into the ‘local’ ansible path (making sure it could access the libxml2 header files):

/usr/local/Cellar/ansible/2.7.10/libexec/bin/pip3 install --global-option=build_ext --global-option="-I/usr/local/Cellar/libxml2/2.9.7/include/libxml2" ovirt-engine-sdk-python

I then tested to make sure it could run the ovirtSDK, I created the following script to test:

#!/usr/local/Cellar/ansible/2.7.10/libexec/bin/python3

from distutils.version import LooseVersion
from enum import Enum
import ovirtsdk4 as sdk
import ovirtsdk4.version as sdk_version
HAS_SDK = (LooseVersion(sdk_version.VERSION) >= LooseVersion('4.2.4'))
if HAS_SDK:
  print("Version OK")
else:
  print("Version FAIL")

I ran this and got:

ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)

OK, so my pycurl module needs to be built with openssl support:

/usr/local/Cellar/ansible/2.7.10/libexec/bin/pip3 uninstall pycurl
export CPPFLAGS=-I/usr/local/opt/openssl/include
export LDFLAGS=-L/usr/local/opt/openssl/lib
/usr/local/Cellar/ansible/2.7.10/libexec/bin/pip3 install pycurl --global-option="--with-openssl"

After this running my test script was successful and I am able to use the ovirt ansible module using delegate_to: localhost!

 

 

Ansible and the lookup file module removes line endings from file

The lookup file module is useful for reading in local files (not remote ones) and saving the contents into a variable. One gotcha that caught me recently was the default action to run rstrip() which according to the documentation removes whitespace from the end of the looked up file. What it doesn’t mention is that is also removes the trailing newline ‘\n’ character from the file. Normally this isn’t a problem except I was using it to read in a ssl certificate and send it to a fluentd server which then wouldn’t complete it’s startup and listen on ports – it just hung. Checking the certificate with openssl showed that at least openssl thought the certificate file was valid, and so did ruby (tested with OpenSSL::PKey::RSA.new() and File.read()). Turns out fluentd specifically checked for the newline character at the end of the ssl certificate file.

So until we upgrade to the very latest version of fluentd with this fix, we need to run the lookup module with the rstrip=False parameter like so:

lookup('file', '/etc/foo.txt', rstrip=False)