Replace wsgi package conflict with config file

Instead of a package conflict, freeIPA now uses an Apache config file to
enforce the correct wsgi module. The workaround only applies to Fedora
since it is the only platform that permits parallel installation of
Python 2 and Python 3 mod_wsgi modules. RHEL 7 has only Python 2 and
Debian doesn't permit installation of both variants.

See: https://pagure.io/freeipa/issue/7161
Fixes: https://pagure.io/freeipa/issue/7394
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Christian Heimes 2018-02-06 10:05:49 +01:00
parent 73f61ce214
commit 1785a3e17b
12 changed files with 75 additions and 5 deletions

View File

@ -332,14 +332,12 @@ Requires(postun): python3
Requires: python3-gssapi >= 1.2.0-5
Requires: python3-systemd
Requires: python3-mod_wsgi
Conflicts: mod_wsgi
%else
Requires(preun): python2
Requires(postun): python2
Requires: python2-gssapi >= 1.2.0-5
Requires: python2-systemd
Requires: mod_wsgi
Conflicts: python3-mod_wsgi
%endif
Requires: mod_auth_gssapi >= 1.5.0
# 1.0.14-3: https://bugzilla.redhat.com/show_bug.cgi?id=1431206

View File

@ -85,6 +85,7 @@ dist_app_DATA = \
kdcproxy-enable.uldif \
kdcproxy-disable.uldif \
ipa-httpd.conf.template \
ipa-httpd-wsgi.conf.template \
gssapi.login \
gssproxy.conf.template \
kdcproxy.wsgi \

View File

@ -0,0 +1,7 @@
# Do not edit. Created by IPA installer.
# Some platforms allow parallel installation of Python 2 and 3 mod_wsgi
# modules, but the modules can't coexist. Enforce loading of correct
# WSGI module before the package's default config.
LoadModule wsgi_module $WSGI_MODULE

View File

@ -39,5 +39,9 @@ class BaseConstantsNamespace(object):
SSSD_USER = "sssd"
# sql (new format), dbm (old format)
NSS_DEFAULT_DBTYPE = 'dbm'
# WSGI module override, only used on Fedora
MOD_WSGI_PYTHON2 = None
MOD_WSGI_PYTHON3 = None
constants = BaseConstantsNamespace()

View File

@ -50,6 +50,8 @@ class BasePathNamespace(object):
HTTPD_IPA_CONF = "/etc/httpd/conf.d/ipa.conf"
HTTPD_NSS_CONF = "/etc/httpd/conf.d/nss.conf"
HTTPD_SSL_CONF = "/etc/httpd/conf.d/ssl.conf"
# only used on Fedora
HTTPD_IPA_WSGI_MODULES_CONF = None
OLD_IPA_KEYTAB = "/etc/httpd/conf/ipa.keytab"
HTTP_KEYTAB = "/var/lib/ipa/gssproxy/http.keytab"
HTTPD_PASSWORD_CONF = "/etc/httpd/conf/password.conf"

View File

@ -211,6 +211,10 @@ class BaseTaskNamespace(object):
"""Remove configuration of httpd service of IPA"""
raise NotImplementedError()
def configure_httpd_wsgi_conf(self):
"""Configure WSGI for correct Python version"""
raise NotImplementedError()
def is_fips_enabled(self):
return False

View File

@ -47,4 +47,9 @@ class DebianTaskNamespace(RedHatTaskNamespace):
def parse_ipa_version(version):
return BaseTaskNamespace.parse_ipa_version(version)
def configure_httpd_wsgi_conf(self):
# Debian doesn't require special mod_wsgi configuration
pass
tasks = DebianTaskNamespace()

View File

@ -11,6 +11,10 @@ from ipaplatform.redhat.constants import RedHatConstantsNamespace
class FedoraConstantsNamespace(RedHatConstantsNamespace):
pass
# Fedora allows installation of Python 2 and 3 mod_wsgi, but the modules
# can't coexist. For Apache to load correct module.
MOD_WSGI_PYTHON2 = "modules/mod_wsgi.so"
MOD_WSGI_PYTHON3 = "modules/mod_wsgi_python3.so"
constants = FedoraConstantsNamespace()

View File

@ -27,7 +27,9 @@ from ipaplatform.redhat.paths import RedHatPathNamespace
class FedoraPathNamespace(RedHatPathNamespace):
pass
HTTPD_IPA_WSGI_MODULES_CONF = (
"/etc/httpd/conf.modules.d/02-ipa-wsgi.conf"
)
paths = FedoraPathNamespace()

View File

@ -30,6 +30,7 @@ import os
import socket
import traceback
import errno
import sys
from ctypes.util import find_library
from functools import total_ordering
@ -484,6 +485,36 @@ class RedHatTaskNamespace(BaseTaskNamespace):
os.chmod(paths.GSSPROXY_CONF, 0o600)
self.restore_context(paths.GSSPROXY_CONF)
def configure_httpd_wsgi_conf(self):
"""Configure WSGI for correct Python version (Fedora)
See https://pagure.io/freeipa/issue/7394
"""
conf = paths.HTTPD_IPA_WSGI_MODULES_CONF
if sys.version_info.major == 2:
wsgi_module = constants.MOD_WSGI_PYTHON2
else:
wsgi_module = constants.MOD_WSGI_PYTHON3
if conf is None or wsgi_module is None:
logger.info("Nothing to do for configure_httpd_wsgi_conf")
return
confdir = os.path.dirname(conf)
if not os.path.isdir(confdir):
os.makedirs(confdir)
ipautil.copy_template_file(
os.path.join(
paths.USR_SHARE_IPA_DIR, 'ipa-httpd-wsgi.conf.template'
),
conf,
dict(WSGI_MODULE=wsgi_module)
)
os.chmod(conf, 0o644)
self.restore_context(conf)
def remove_httpd_service_ipa_conf(self):
"""Remove systemd config for httpd service of IPA"""
try:

View File

@ -213,6 +213,7 @@ class HTTPInstance(service.Service):
def __configure_http(self):
self.update_httpd_service_ipa_conf()
self.update_httpd_wsgi_conf()
target_fname = paths.HTTPD_IPA_CONF
http_txt = ipautil.template_file(
@ -508,6 +509,9 @@ class HTTPInstance(service.Service):
def update_httpd_service_ipa_conf(self):
tasks.configure_httpd_service_ipa_conf()
def update_httpd_wsgi_conf(self):
tasks.configure_httpd_wsgi_conf()
def uninstall(self):
if self.is_configured():
self.print_msg("Unconfiguring web server")
@ -564,7 +568,8 @@ class HTTPInstance(service.Service):
installutils.remove_file(paths.HTTPD_IPA_PKI_PROXY_CONF)
installutils.remove_file(paths.HTTPD_IPA_KDCPROXY_CONF_SYMLINK)
installutils.remove_file(paths.HTTPD_IPA_KDCPROXY_CONF)
tasks.remove_httpd_service_ipa_conf()
if paths.HTTPD_IPA_WSGI_MODULES_CONF is not None:
installutils.remove_file(paths.HTTPD_IPA_WSGI_MODULES_CONF)
# Restore SELinux boolean states
boolean_states = {name: self.restore_state(name)

View File

@ -1458,11 +1458,17 @@ def update_mod_nss_cipher_suite(http):
'cipher_suite_updated',
httpinstance.NSS_CIPHER_REVISION)
def update_ipa_httpd_service_conf(http):
logger.info('[Updating HTTPD service IPA configuration]')
http.update_httpd_service_ipa_conf()
def update_ipa_http_wsgi_conf(http):
logger.info('[Updating HTTPD service IPA WSGI configuration]')
http.update_httpd_wsgi_conf()
def update_http_keytab(http):
logger.info('[Moving HTTPD service keytab to gssproxy]')
if os.path.exists(paths.OLD_IPA_KEYTAB):
@ -1782,6 +1788,7 @@ def upgrade_configuration():
http.stop()
disable_httpd_system_trust(http)
update_ipa_httpd_service_conf(http)
update_ipa_http_wsgi_conf(http)
update_mod_nss_protocol(http)
update_mod_nss_cipher_suite(http)
disable_mod_nss_ocsp(http)