A client uses OneLogin for their single-sign on services. We're building their website hosted on Heroku. We needed to build that SSO integration, and fortunately the folks over at OneLogin have released a very adaptable and well demonstrated toolkit for writing SAML SSO integration in Python. Heroku was the hard part.
The python-saml library requires several binary libraries: libxml2, libxmlsec1, and SWIG (a library for writing thin wrappers around C libraries in scripting languages). Out of those, only libxml2 is installed in the standard Heroku Cedar-14 stack. The latter two have to be installed by a buildpack.
Ex-Herokuling David Dollar, builder of several of the canonical buildpacks, authored a buildpack to install additional packages from the Ubuntu Trusty apt repositories. When combined with the Heroku multi-buildpack, a meta-buildpack that runs multiple buildpack compiles for a single project (also originally authored by Dollar), this buildpack will install the required packages to
$BUILD_DIR/.apt and set appropriate build environment variables (like
LD_LIBRARY_PATH) for later buildpacks to use. All we have to do is make two files:
But it only sounds that way. We run into a few problems right off the bat.
First, the standard Heroku buildpack for Python unsets and stomps on the environment variables that would allow the compiler to find our apt-installed headers and for the linker to find our apt-installed libraries. Second, even if it didn't, the environment variables set by the apt buildpack are invalid for the Python buildpack. The Python buildpack moves your
/app during the build process and moves it back afterward - so the paths that the apt buildpack set referecing the original
$BUILD_DIR are invalid and don't exist at compile-time. Third, the dm.xmlsec.binding library uses
xmlsec1-config to determine its cflags and libs flags. The
xmlsec1-config utility answers based on the path that the package was configured to be installed to, using
/usr as its base path; we need it to report
/app/.apt/usr instead. Finally, the M2Crypto library uses SWIG and
swig -swiglib reports the path for its configuration files to be where it was built to be installed to, which is
/usr/share/swig2.0 - correspondingly we need it to report
To finally get our Heroku app through the build process, we had to make the following changes:
SWIG_LIB=/app/.apt/usr/share/swig2.0into the environment - this changes the base path that
requirements.txt- in it, we merely modified the
setup.pyto acknowledge an environment variable
XMLSEC_CONFIGto which we set to
--base /app/.apt/usrand passed that variable value along to
setup.py's execution of
/app/.aptbefore compile, removed the symlink after compile, and preserved the existing environment variable values for compiler and linker directives like
Once all of that was done, it built like a charm. But I'm really not thrilled with the custom buildpack and the custom setup script. But if you're likewise beating your head against the wall trying to get python-saml installed on Heroku and can't because of compile errors in building dm.xmlsec.binding, hope this helps.Share on Twitter Share on Facebook