From 1870c933542d41766dd9e2076deb7db758726864 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 25 Jan 2021 11:40:22 -0500 Subject: [PATCH] Ensure IPA is running (ideally) before uninstalling the KRA The KRA attempts to unregister itself from the security domain which requires that IPA be running for this to succeed. 1. Move the KRA uninstall call prior to stopping all IPA services 2. Try to start IPA if it isn't running and a KRA is configured It isn't mandatory that IPA be running for the KRA uninstall to succeed but it will suppress a pretty scary backtrace and error message. https://pagure.io/freeipa/issue/8550 Signed-off-by: Rob Crittenden Reviewed-By: Florence Blanc-Renaud --- ipaserver/install/ipactl.py | 23 ++++++++++++++++------- ipaserver/install/kra.py | 19 +++++++++++++++++++ ipaserver/install/server/install.py | 8 ++++++-- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/ipaserver/install/ipactl.py b/ipaserver/install/ipactl.py index 545a4843e..7f0361d37 100644 --- a/ipaserver/install/ipactl.py +++ b/ipaserver/install/ipactl.py @@ -306,7 +306,12 @@ def get_config(dirsrv): return deduplicate(ordered_list) -def get_config_from_file(): +def get_config_from_file(rval): + """ + Get the list of configured services from the cached file. + + :param rval: The return value for any exception that is raised. + """ svc_list = [] @@ -316,7 +321,8 @@ def get_config_from_file(): except Exception as e: raise IpactlError( "Unknown error when retrieving list of services from file: %s" - % str(e) + % str(e), + 4 ) # the framework can start/stop a number of related services we are not @@ -427,7 +433,7 @@ def ipa_start(options): def ipa_stop(options): dirsrv = services.knownservices.dirsrv try: - svc_list = get_config_from_file() + svc_list = get_config_from_file(rval=4) except Exception as e: # Issue reading the file ? Let's try to get data from LDAP as a # fallback @@ -509,7 +515,7 @@ def ipa_restart(options): old_svc_list = [] try: - old_svc_list = get_config_from_file() + old_svc_list = get_config_from_file(rval=4) except Exception as e: emit_err("Failed to get service list from file: " + str(e)) # fallback to what's in LDAP @@ -629,13 +635,14 @@ def ipa_status(options): We only really care about 0, 3 and 4. """ + socket_activated = ('ipa-ods-exporter', 'ipa-otpd',) try: dirsrv = services.knownservices.dirsrv if dirsrv.is_running(): svc_list = get_config(dirsrv) else: - svc_list = get_config_from_file() + svc_list = get_config_from_file(rval=1) except IpactlError as e: if os.path.exists(tasks.get_svc_list_file()): raise e @@ -647,12 +654,14 @@ def ipa_status(options): 4 ) + stopped = 0 dirsrv = services.knownservices.dirsrv try: if dirsrv.is_running(): print("Directory Service: RUNNING") else: print("Directory Service: STOPPED") + stopped = 1 except Exception as e: raise IpactlError("Failed to get Directory Service status", 4) @@ -665,7 +674,6 @@ def ipa_status(options): 3, ) - stopped = 0 for svc in svc_list: svchandle = services.service(svc, api=api) try: @@ -673,7 +681,8 @@ def ipa_status(options): print("%s Service: RUNNING" % svc) else: print("%s Service: STOPPED" % svc) - stopped += 1 + if svc not in socket_activated: + stopped += 1 except Exception: emit_err("Failed to get %s Service status" % svc) diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py index c7a097b58..ffed5df14 100644 --- a/ipaserver/install/kra.py +++ b/ipaserver/install/kra.py @@ -8,6 +8,7 @@ KRA installer module from __future__ import absolute_import +import logging import os from ipalib import api @@ -23,6 +24,8 @@ from ipaserver.install import service as _service from . import dogtag +logger = logging.getLogger(__name__) + def install_check(api, replica_config, options): if replica_config is not None and not replica_config.setup_kra: @@ -113,6 +116,22 @@ def install(api, replica_config, options, custodia): named.restart(capture_output=True) +def uninstall_check(options): + """IPA needs to be running so pkidestroy can unregister KRA""" + kra = krainstance.KRAInstance(api.env.realm) + if not kra.is_installed(): + return + + result = ipautil.run([paths.IPACTL, 'status'], + raiseonerr=False) + + if result.returncode not in [0, 4]: + try: + ipautil.run([paths.IPACTL, 'start']) + except Exception: + logger.info("Re-starting IPA failed, continuing uninstall") + + def uninstall(): kra = krainstance.KRAInstance(api.env.realm) kra.stop_tracking_certificates() diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index 103cfccfb..b01fd85a5 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -1098,6 +1098,8 @@ def uninstall_check(installer): "uninstall procedure?", False): raise ScriptError("Aborting uninstall operation.") + kra.uninstall_check(options) + try: api.Backend.ldap2.connect(autobind=True) @@ -1165,6 +1167,10 @@ def uninstall(installer): rv = 0 + # Uninstall the KRA prior to shutting the services down so it + # can un-register with the CA. + kra.uninstall() + print("Shutting down all IPA services") try: services.knownservices.ipa.stop() @@ -1177,8 +1183,6 @@ def uninstall(installer): restore_time_sync(sstore, fstore) - kra.uninstall() - ca.uninstall() dns.uninstall()