URL: https://github.com/freeipa/freeipa/pull/764 Author: rcritten Title: #764: Basic uninstaller for the CA Action: opened
PR body: """ This in response to watching users flounder with repeated failed replica installations and ipa-ca-install attempts that require a complete uninstall. Review it with whatever priority you desire. This is meant ONLY to be able to re-try an installation if the CA cloning fails for some reason. It is not intended to be used to remove the CA as a service on a given master. This is to avoid having to stand up a whole new master just because the CA installation failed. https://pagure.io/freeipa/issue/6595 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/764/head:pr764 git checkout pr764
From da470e73eb3100777e983cc31a3566390e66efc2 Mon Sep 17 00:00:00 2001 From: Rob Crittenden <rcrit...@redhat.com> Date: Thu, 4 May 2017 14:45:49 -0400 Subject: [PATCH] Basic uninstaller for the CA This is meant ONLY to be able to re-try an installation if the CA cloning fails for some reason. It is not intended to be used to remove the CA as a service on a given master. This is to avoid having to stand up a whole new master just because the CA installation failed. https://pagure.io/freeipa/issue/6595 --- install/tools/ipa-ca-install | 72 ++++++++++++++++++++++++++++++++++++++++- ipaserver/install/cainstance.py | 10 ++++-- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install index 60261aa..97e9959 100755 --- a/install/tools/ipa-ca-install +++ b/install/tools/ipa-ca-install @@ -24,6 +24,7 @@ import shutil import tempfile from ipalib.install.kinit import kinit_keytab +from ipapython.dn import DN from ipapython import ipautil from ipaserver.install import installutils @@ -31,12 +32,14 @@ from ipaserver.install.installutils import create_replica_config from ipaserver.install.installutils import check_creds, ReplicaConfig from ipaserver.install import dsinstance, ca from ipaserver.install import cainstance, service +from ipaserver.install import krainstance from ipapython import version -from ipalib import api +from ipalib import api, errors from ipalib.constants import DOMAIN_LEVEL_0 from ipapython.config import IPAOptionParser from ipapython.ipa_log_manager import root_logger, standard_logging_setup from ipaplatform.paths import paths +from ipaplatform import services log_file_name = paths.IPAREPLICA_CA_INSTALL_LOG REPLICA_INFO_TOP_DIR = None @@ -44,6 +47,8 @@ REPLICA_INFO_TOP_DIR = None def parse_options(): usage = "%prog [options] REPLICA_FILE" parser = IPAOptionParser(usage=usage, version=version.VERSION) + parser.add_option("--uninstall", dest="uninstall", action="store_true", + default=False, help="uninstall the CA") parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False, help="gather extra debugging information") parser.add_option("-p", "--password", dest="password", sensitive=True, @@ -254,6 +259,67 @@ def install(safe_options, options, filename): pass +def uninstall(options): + # Uninstaller meant only for blown replica installations. + + # Does NOT remove replication agreements or the ipaca backend. + + ca_instance = cainstance.CAInstance(api.env.realm) + + if not cainstance.is_ca_installed_locally(): + ca_instance.print_msg( + "CA does not appear to be installed on this host." + ) + + kra = krainstance.KRAInstance(api.env.realm) + if kra.is_installed(): + sys.exit("Cannot deal with KRA at this time.") + + if options.unattended: + ca_instance.print_msg( + "Ignoring unattended uninstall request.\n" + ) + ca_instance.print_msg( + "This is for failed installs only, do not use otherwise." + ) + if not ipautil.user_input("Are you sure you want to continue with the " + "uninstall procedure?", False): + ca_instance.print_msg("Aborting uninstall operation.") + sys.exit(0) + + # Note that I'm completely ignoring the replication agreement so it + # doesn't matter what domain level this is. This is based on the + # (bad) assumption that this is only being executed to fix a blown + # install and not to remove the CA as a component. + + # TODO: Figure out what is going on with serial # ranges + + ca_instance.print_msg("Shutting down CA") + ca_instance.stop_instance() + + try: + ca.uninstall() + except Exception as e: + root_logger.debug("CA uninstall failed with %s", e) + + # certmonger is stopped as a side-effect of unintalling the CA + cmonger = services.knownservices.certmonger + cmonger.start() + + ca_instance.print_msg("Removing CA from list of services") + dn = DN(('cn', 'CA'), ('cn', api.env.host), ('cn', 'masters'), + ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) + try: + api.Backend.ldap2.delete(dn) + except errors.NotFound: + pass + + # Remove the old services list file so pki-tomcatd isn't managed + installutils.remove_file(paths.SVC_LIST_FILE) + + sys.exit(0) + + def promote(safe_options, options, filename): options.promote = True @@ -282,6 +348,7 @@ def main(): sys.exit("IPA server is not configured on this system.\n") if (not options.external_cert_files and + not options.uninstall and cainstance.is_ca_installed_locally()): sys.exit("CA is already installed on this host.") @@ -299,6 +366,9 @@ def main(): api.finalize() api.Backend.ldap2.connect() + if options.uninstall: + uninstall(options) + domain_level = dsinstance.get_domain_level(api) if domain_level > DOMAIN_LEVEL_0: promote(safe_options, options, filename) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index d72feb8..169f566 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -1160,7 +1160,10 @@ def __create_ds_db(self): ) entry['nsslapd-state'] = ['Backend'] entry['nsslapd-backend'] = [backend] - api.Backend.ldap2.add_entry(entry) + try: + api.Backend.ldap2.add_entry(entry) + except errors.DuplicateEntry: + pass # database dn = DN(('cn', 'ipaca'), ('cn', 'ldbm database'), ('cn', 'plugins'), @@ -1171,7 +1174,10 @@ def __create_ds_db(self): cn=[backend], ) entry['nsslapd-suffix'] = [suffix] - api.Backend.ldap2.add_entry(entry) + try: + api.Backend.ldap2.add_entry(entry) + except errors.DuplicateEntry: + pass def __setup_replication(self):
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code