Skip to content

add easyblock to install OpenSSL wrapper for OpenSSL installed in OS, or build and install OpenSSL from source if not available in OS#2429

Merged
boegel merged 29 commits intoeasybuilders:developfrom
lexming:sslwrap
May 20, 2021
Merged

add easyblock to install OpenSSL wrapper for OpenSSL installed in OS, or build and install OpenSSL from source if not available in OS#2429
boegel merged 29 commits intoeasybuilders:developfrom
lexming:sslwrap

Conversation

@lexming
Copy link
Copy Markdown
Contributor

@lexming lexming commented May 16, 2021

Fixes issue easybuilders/easybuild-easyconfigs#11895

This easyblock looks for the installation files of OpenSSL in the host system to wrap them in the EB installation directory with symlinks

  • it searches the library in the host system by loading the respective libssl.so in Python and retrieve the path to the library file using dlinfo in Linux and ctypes.macholib.dyld.dyld_find in Mac OS.
  • it searches the headers of the required version of OpenSSL (v1.0.x or v1.1.x) in the include paths of gcc in the system.

This method does not need to crawl through any environment variables, is resilient to installations in exotic paths and integrates well within the EB environment.

Why symlinking?

  • it provides a transparent way to update OpenSSL without breaking dynamic links and probably without breaking rpaths either. Any packages build with the wrappers in place should use the paths to the installation directory of the wrapper, not the actual libraries in the system or EB.

If the host system lacks the libs or headers of the required version of OpenSSL, the easyblock builds and installs any component included in the easyconfig bundle (EB_OpenSSL_wrapper is based on Bundle). This approach has the advantage of automatically disabling the installation of a fallback OpenSSL in EB if the host system already has the required files. Moreover, if the fallback is installed, the result is identical to any other installation of OpenSSL in EB.

Easyconfigs can be found in easybuilders/easybuild-easyconfigs#12858

edit: requires easybuilders/easybuild-framework#3682 + easybuilders/easybuild-framework#3683

@lexming lexming added the new label May 16, 2021
# verify that the headers match our OpenSSL version
for include in ssl_include_dirs:
opensslv = read_file(os.path.join(include, 'opensslv.h'))
header_majmin_version = re.search("SHLIB_VERSION_NUMBER\s\"([0-9]+\.[0-9]+)", opensslv, re.M)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this regex seems fine to me

@boegel
Copy link
Copy Markdown
Member

boegel commented May 16, 2021

@lexming Fails for me with:

$ eb --from-pr 12858 --include-easyblocks-from-pr 2429
...
ERROR: Traceback (most recent call last):
  File "/data/gent/400/vsc40023/easybuild_easy_installed/lib/python2.7/site-packages/easybuild_framework-4.3.5.dev0-py2.7.egg/easybuild/main.py", line 117, in build_and_install_software
    (ec_res['success'], app_log, err) = build_and_install_one(ec, init_env)
  File "/data/gent/400/vsc40023/easybuild_easy_installed/lib/python2.7/site-packages/easybuild_framework-4.3.5.dev0-py2.7.egg/easybuild/framework/easyblock.py", line 3371, in build_and_install_one
    app = app_class(ecdict['ec'])
  File "/tmp/eb-wb7k98av/included-easyblocks-u3uhdwkv/easybuild/easyblocks/openssl_wrapper.py", line 132, in __init__
    os.path.join(lib_dir, self.openssl_engines[self.version]),
  File "/usr/lib64/python3.6/posixpath.py", line 94, in join
    genericpath._check_arg_types('join', a, *p)
  File "/usr/lib64/python3.6/genericpath.py", line 151, in _check_arg_types
    raise TypeError("Can't mix strings and bytes in path components") from None
TypeError: Can't mix strings and bytes in path components

Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
@boegel
Copy link
Copy Markdown
Member

boegel commented May 16, 2021

Let's see if a close/re-open wakes up GitHub Actions...

@boegel boegel closed this May 16, 2021
@boegel boegel reopened this May 16, 2021
@Micket
Copy link
Copy Markdown
Contributor

Micket commented May 16, 2021

Soo.. do we not want this to find the CentOS7 openssl11 packages? Because they are intentionally not installed into a standard path, since that would break the rest of the system?

@boegel
Copy link
Copy Markdown
Member

boegel commented May 16, 2021

Soo.. do we not want this to find the CentOS7 openssl11 packages? Because they are intentionally not installed into a standard path, since that would break the rest of the system?

We could enhance this easyblock to make sure those are found too, but you would need to specify where to find them of course (and we could include the CentOS 7 location as a default in the easyblock)?

@Micket
Copy link
Copy Markdown
Contributor

Micket commented May 16, 2021

Right, well, I'm not sure how to really suggest adding those paths, and, it's pretty much a mix here. We've got

  1. /usr/bin/openssl11
  2. /usr/lib64/openssl11/ (or /usr/lib64/libssl.so.1.1)
  3. /usr/include/openssl11/
    So, optional system_ssl_binary, system_ssl_libpath, ssl_ssl_includepath? I think it's preferable for these to be set by default on centos/rhel 7 systems since it would be to easy to miss for a large portion or users.

Also, the automatic fallback method here; there isn't a practical way to update ever update it without having to revert to a live rebuild (ouch)? (as opposed to the more atomic change like with Java and modulerc)

Copy link
Copy Markdown
Contributor

@Micket Micket left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this might suffice for finding system openssl11 on CentOS/RHEL 7

Comment thread easybuild/easyblocks/o/openssl_wrapper.py
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
@lexming
Copy link
Copy Markdown
Contributor Author

lexming commented May 16, 2021

@Micket hardcoding paths into the easyblock should not be necessary. If the host system is configured to use OpenSSL 1.1 then the libs and headers will be found. If OpenSSL 1.1 is not part of the environment, we should never link to it by default. I don't want EB to catch any rogue .so in my system. In my opinion, all we can do to cover that case is to provide an extra option so that the user can manually add extra paths to be checked by the easyblock.

Regarding the fallback method, a modulerc is not an option because it does not preserve the paths to the libraries. It automatically re-loads the real OpenSSL module, so paths to libs change accordingly. In case of an upgrade of OpenSSL, the process is actually simpler with this wrapper as you only have to rebuild the wrapper with the new version, instead of installing the new OpenSSL version + updating the modulerc.

@Micket
Copy link
Copy Markdown
Contributor

Micket commented May 17, 2021

I always considered rebuilding to be the worst case scenario, especially for a common dependency, as it means a large section of software is going to break for over a minute during rebuilds (assuming the new build even succeeds).
(A wrapper that symlinks to existing EB installs could work to minimize this, though somewhat messier (and impractical here))

But I really think we should automatically symlink to EPEL7s openssl11/openssl11-devel if present by default. In fact, that has been my only goal from all along, and what I think should be the recommended approach for all centos7 users. The only non-standard thing is an alternative include path and binary name (since there are 2 OS versions). The library itself is found in the standard paths (/usr/lib64/libssl.so.1.1)

Micket
Micket previously requested changes May 17, 2021
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
…or unversioned libraries, minor code cleanup
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
boegel
boegel previously approved these changes May 17, 2021
@lexming
Copy link
Copy Markdown
Contributor Author

lexming commented May 17, 2021

With the addition of multiple library names per system/version, I moved the code loading and finding the library to its own function in systemtools. See easybuilders/easybuild-framework#3683

Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
Comment thread easybuild/easyblocks/o/openssl_wrapper.py Outdated
@boegel
Copy link
Copy Markdown
Member

boegel commented May 19, 2021

@lexming Another crash when OpenSSL-1.0.eb is being built from source after your last update:

ERROR: Traceback (most recent call last):
  File "/home/centos/easybuild/easybuild-framework/easybuild/main.py", line 117, in build_and_install_software
    (ec_res['success'], app_log, err) = build_and_install_one(ec, init_env)
  File "/home/centos/easybuild/easybuild-framework/easybuild/framework/easyblock.py", line 3571, in build_and_install_one
    result = app.run_all_steps(run_test_cases=run_test_cases)
  File "/home/centos/easybuild/easybuild-framework/easybuild/framework/easyblock.py", line 3465, in run_all_steps
    self.run_step(step_name, step_methods)
  File "/home/centos/easybuild/easybuild-framework/easybuild/framework/easyblock.py", line 3320, in run_step
    step_method(self)()
  File "/tmp/eb-t7009csl/included-easyblocks-lj9yuliv/easybuild/easyblocks/openssl_wrapper.py", line 252, in sanity_check_step
    ssl_files.extend(os.path.join('lib', libso) for libso in self.openssl_libs)
  File "/tmp/eb-t7009csl/included-easyblocks-lj9yuliv/easybuild/easyblocks/openssl_wrapper.py", line 252, in <genexpr>
    ssl_files.extend(os.path.join('lib', libso) for libso in self.openssl_libs)
  File "/usr/lib64/python3.6/posixpath.py", line 94, in join
    genericpath._check_arg_types('join', a, *p)
  File "/usr/lib64/python3.6/genericpath.py", line 149, in _check_arg_types
    (funcname, s.__class__.__name__)) from None
TypeError: join() argument must be str or bytes, not 'list'

@lexming
Copy link
Copy Markdown
Contributor Author

lexming commented May 19, 2021

@boegel will you stop breaking it? I'll have to ban your username from this easyblock...

In fact, I introduced this bug in my last commit. I'll make a better fix 👍

@lexming
Copy link
Copy Markdown
Contributor Author

lexming commented May 19, 2021

@boegel fixed in fd425a2. I replaced the changing list of OpenSSL libraries in self.openssl_libs into two separate variables, where the target libraries of the installation are always held in a simple list (self.target_ssl_libs). This fixes the last two errors.

I repeated all my previous tests and they are good.

boegel and others added 2 commits May 20, 2021 10:30
…yBuild if something is missing in host system
more logging in OpenSSL wrapper, actually fall back to OpenSSL in EasyBuild if something is missing in host system
@boegel boegel dismissed Micket’s stale review May 20, 2021 17:41

all good now

@boegel boegel changed the title add wrapper for OpenSSL add easyblock to install OpenSSL wrapper for OpenSSL installed in OS, or build and install OpenSSL from source if not available in OS May 20, 2021
@boegel
Copy link
Copy Markdown
Member

boegel commented May 20, 2021

Tested extensively with easybuilders/easybuild-easyconfigs#12858 across a range of different systems, operating systems, and CPU architectures.

@lexming: Thanks a lot for your efforts on this!

@boegel boegel merged commit b9c31fa into easybuilders:develop May 20, 2021
@lexming lexming deleted the sslwrap branch May 20, 2021 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants