On 06/17/2016 01:01 PM, Petr Vobornik wrote:
On 17.6.2016 12:12, Stanislav Laznicka wrote:
On 06/17/2016 09:51 AM, Petr Vobornik wrote:
On 17.6.2016 09:24, Stanislav Laznicka wrote:
On 06/17/2016 08:48 AM, Petr Spacek wrote:
On 17.6.2016 08:43, Stanislav Laznicka wrote:
On 06/17/2016 07:45 AM, Petr Spacek wrote:
On 16.6.2016 17:33, Stanislav Laznicka wrote:
Hello,

This patch removes most sys.exits() from installer modules and
scripts and
replaces them with ScriptError. I only left sys.exits at places
where the user
decides yes/no on continuation of the script.
I wonder if yes/no should be replaced with KeyboardInterrupt or some
other
exception, too...

I'm not sure, it seems more clear to just really exit if the user
desires it
and it's what we say we'll do (with possible cleanup beforehand). Do
you think
we could benefit somehow by raising an exception here?
I'm just thinking out loud.

It seemed to me that it is easier to share cleanup on one except block
instead
of having if (interrupt): cleanup; if (interrupt2): same_cleanup;

etc.

Again, just wondering out loud.

If the cleanup is the same, or similar it might be more beneficial to
have it in a function where you could pass what was set up already and
therefore needs cleanup. But that's just an opinion coming from thinking
out loud as well. I went through the code to see if there's much cleanup
after these user actions and it seems that usually there's nothing much
if anything. However, thinking in advance may save us much trouble in
the future, of course.

Btw the original scope of the ticket is to replace sys.exit calls ONLY
in installer modules. Please don't waste time with debugging other use
cases before 4.4 is out.

I might have gotten carried away a bit. Would you suggest keeping the
sys.exits replaced only in ipaserver/install/server/replicainstall.py,
ipaserver/install/server/install.py modules which are the installer
modules managed by AdminTool? I considered the modules in
ipaserver/install/ to also be installer modules as they are heavily used
during installation and the sys.exits there mainly occur in functions
called from install()/install_check() methods. The *-install scripts
were perhaps really obviously over the scope.
Yes, modules:
  ipaserver/install/bindinstance.py          |  2 +-
  ipaserver/install/ca.py                    | 19 +++---
  ipaserver/install/cainstance.py            |  5 +-
  ipaserver/install/dns.py                   |  5 +-
  ipaserver/install/dsinstance.py            |  3 +-
  ipaserver/install/installutils.py          | 16 +++---
  ipaserver/install/ipa_ldap_updater.py      |  2 +-
  ipaserver/install/krainstance.py           |  3 +-
  ipaserver/install/replication.py           | 10 ++--
  ipaserver/install/server/install.py        | 64 +++++++++++----------
  ipaserver/install/server/replicainstall.py | 92

not modules:
install/tools/ipa-adtrust-install | 17 +++---
install/tools/ipa-ca-install | 23 ++++----
install/tools/ipa-compat-manage | 11 ++--
install/tools/ipa-dns-install | 3 +-

I'll keep the sys.exit replaces that won't make it here on the side, we
may want to do them later.
I'm a bit worried that the patch might change some behavior. Maybe I'm
wrong.

Attached is the patch with correct modules with sys.exits replaced.

I double-checked the changes and I believe the behavior shouldn't really change.

From 08648ce78aef1e0868d6fbaffd23ed643fd49486 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Fri, 17 Jun 2016 13:14:49 +0200
Subject: [PATCH] Remove sys.exit from install modules and scripts

sys.exit() calls sometimes make it hard to find bugs and mask code that
does not always work properly.

https://fedorahosted.org/freeipa/ticket/5750
---
 ipaserver/install/bindinstance.py          |  2 +-
 ipaserver/install/ca.py                    | 19 +++---
 ipaserver/install/cainstance.py            |  5 +-
 ipaserver/install/dns.py                   |  5 +-
 ipaserver/install/dsinstance.py            |  3 +-
 ipaserver/install/installutils.py          | 16 +++---
 ipaserver/install/ipa_ldap_updater.py      |  2 +-
 ipaserver/install/krainstance.py           |  3 +-
 ipaserver/install/replication.py           | 10 ++--
 ipaserver/install/server/install.py        | 64 +++++++++++----------
 ipaserver/install/server/replicainstall.py | 92 ++++++++++++++++--------------
 11 files changed, 118 insertions(+), 103 deletions(-)

diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 78e75359266bbefe7954242b98922272fb0c9194..c9e528856414371ce2e5e54df3642907c89d2856 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -466,7 +466,7 @@ def check_reverse_zones(ip_addresses, reverse_zones, options, unattended,
             except ValueError as e:
                 msg = "Reverse zone %s will not be used: %s" % (rz, e)
                 if unattended:
-                    sys.exit(msg)
+                    raise RuntimeError(msg)
                 else:
                     root_logger.warning(msg)
                 continue
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index ac72c76883fda00e2f258a9ecfe9925722041fe9..b83555270d37a04117627a11b51214e25e80779d 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -8,6 +8,7 @@ import sys
 
 from ipaserver.install import cainstance, dsinstance, bindinstance
 from ipapython import ipautil, certdb
+from ipapython.admintool import ScriptError
 from ipaplatform import services
 from ipaplatform.paths import paths
 from ipaserver.install import installutils, certs
@@ -30,12 +31,12 @@ def install_check(standalone, replica_config, options):
 
     if replica_config is not None:
         if standalone and api.env.ra_plugin == 'selfsign':
-            sys.exit('A selfsign CA can not be added')
+            raise ScriptError('A selfsign CA can not be added')
 
         if ((not options.promote
              and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))):
             print('CA cannot be installed in CA-less setup.')
-            sys.exit(1)
+            raise ScriptError
 
         if standalone and not options.skip_conncheck:
             principal = options.principal
@@ -53,7 +54,7 @@ def install_check(standalone, replica_config, options):
 
     if standalone:
         if api.Command.ca_is_enabled()['result']:
-            sys.exit(
+            raise ScriptError(
                 "One or more CA masters are already present in IPA realm "
                 "'%s'.\nIf you wish to replicate CA to this host, please "
                 "re-run 'ipa-ca-install'\nwith a replica file generated on "
@@ -67,7 +68,7 @@ def install_check(standalone, replica_config, options):
             print("CA is not installed yet. To install with an external CA "
                   "is a two-stage process.\nFirst run the installer with "
                   "--external-ca.")
-            sys.exit(1)
+            raise ScriptError
 
         external_cert_file, external_ca_file = installutils.load_external_cert(
             options.external_cert_files, options.subject)
@@ -75,17 +76,17 @@ def install_check(standalone, replica_config, options):
         if cainstance.is_step_one_done():
             print("CA is already installed.\nRun the installer with "
                   "--external-cert-file.")
-            sys.exit(1)
+            raise ScriptError
         if ipautil.file_exists(paths.ROOT_IPA_CSR):
             print(("CA CSR file %s already exists.\nIn order to continue "
                   "remove the file and run the installer again." %
                   paths.ROOT_IPA_CSR))
-            sys.exit(1)
+            raise ScriptError
 
     if not options.external_cert_files:
         if not cainstance.check_port():
             print("IPA requires port 8443 for PKI but it is currently in use.")
-            sys.exit("Aborting installation")
+            raise ScriptError("Aborting installation")
 
     if standalone:
         dirname = dsinstance.config_dirname(
@@ -100,7 +101,7 @@ def install_check(standalone, replica_config, options):
                                 'Signing-Cert'):
                     print(("Certificate with nickname %s is present in %s, "
                            "cannot continue." % (nickname, db.secdir)))
-                    sys.exit(1)
+                    raise ScriptError
 
                 cert = db.get_cert_from_db(nickname)
                 if not cert:
@@ -111,7 +112,7 @@ def install_check(standalone, replica_config, options):
                                DN('CN=Object Signing Cert', subject_base)):
                     print(("Certificate with subject %s is present in %s, "
                            "cannot continue." % (subject, db.secdir)))
-                    sys.exit(1)
+                    raise ScriptError
 
 
 def install(standalone, replica_config, options):
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 8dfb71528d2dc020e05ccd7ff42199218a1c0839..26adacd475bd948580390e0ca0c385caac069d78 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -60,6 +60,7 @@ from ipapython.certdb import get_ca_nickname
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import log_mgr,\
     standard_logging_setup, root_logger
+from ipapython.admintool import ScriptError
 from ipapython.secrets.kem import IPAKEMKeys
 
 from ipaserver.install import certs
@@ -588,7 +589,7 @@ class CAInstance(DogtagInstance):
         if self.external == 1:
             print("The next step is to get %s signed by your CA and re-run %s as:" % (self.csr_file, sys.argv[0]))
             print("%s --external-cert-file=/path/to/signed_certificate --external-cert-file=/path/to/external_ca_certificate" % sys.argv[0])
-            sys.exit(0)
+            raise ScriptError(rval=0)
         else:
             shutil.move(paths.CA_BACKUP_KEYS_P12,
                         paths.CACERT_P12)
@@ -1494,7 +1495,7 @@ def install_replica_ca(config, postinstall=False, ra_p12=None):
         return ca
 
     if ca.is_installed():
-        sys.exit("A CA is already configured on this system.")
+        raise ScriptError("A CA is already configured on this system.")
 
     if postinstall:
         # If installing this afterward the Apache NSS database already
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
index 0fb869a7bab5b38f0a543b74220b2bb74888357f..c5544baf9e50dcb1d75885ba68d824c3e77dda89 100644
--- a/ipaserver/install/dns.py
+++ b/ipaserver/install/dns.py
@@ -22,6 +22,7 @@ from ipapython import sysrestore
 from ipapython import dnsutil
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import root_logger
+from ipapython.admintool import ScriptError
 from ipapython.ipaldap import AUTOBIND_ENABLED
 from ipapython.ipautil import user_input
 from ipaserver.install.installutils import get_server_ip_address
@@ -207,8 +208,8 @@ def install_check(standalone, api, replica, options, hostname):
         # we can reinstall current server if it is dnssec master
         if dnssec_masters and api.env.host not in dnssec_masters:
             print("DNSSEC key master(s):", u','.join(dnssec_masters))
-            sys.exit("Only one DNSSEC key master is supported in current "
-                     "version.")
+            raise ScriptError(
+                "Only one DNSSEC key master is supported in current version.")
 
         if options.kasp_db_file:
             dnskeysyncd = services.service('ipa-dnskeysyncd')
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index c93b3b4ff58c4102a9de448247966ad3dd8e4e7c..996d69ba7aa82917d20a13639dbb72f8228310d4 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -48,6 +48,7 @@ from ipaplatform.constants import constants as platformconstants
 from ipaplatform.tasks import tasks
 from ipalib.constants import CACERT
 from ipapython.dn import DN
+from ipapython.admintool import ScriptError
 from ipaplatform import services
 from ipaplatform.paths import paths
 
@@ -620,7 +621,7 @@ class DsInstance(service.Service):
             super(DsInstance, self).restart(instance)
             if not is_ds_running(instance):
                 root_logger.critical("Failed to restart the directory server. See the installation log for details.")
-                sys.exit(1)
+                raise ScriptError
         except SystemExit as e:
             raise e
         except Exception as e:
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index b8ce068a86ddc0498c9bd46fe400c54bcb48c6f8..653bb61e6cb0e2fd1db42b3cd784a48a3f746427 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -470,7 +470,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
         print("The KDC service does not listen on localhost", file=sys.stderr)
         print("", file=sys.stderr)
         print("Please fix your /etc/hosts file and restart the setup program", file=sys.stderr)
-        sys.exit(1)
+        raise ScriptError
 
     ips = []
     if len(hostaddr):
@@ -497,11 +497,11 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
                 print("or /etc/hosts file and restart the installation.", file=sys.stderr)
                 print("Provided but not resolved address(es): %s" % \
                                     ", ".join(str(ip) for ip in (set(ip_addresses) - set(ips))), file=sys.stderr)
-                sys.exit(1)
+                raise ScriptError
 
     if not ips:
         print("No usable IP address provided nor resolved.", file=sys.stderr)
-        sys.exit(1)
+        raise ScriptError
 
     for ip_address in ips:
         # check /etc/hosts sanity
@@ -516,7 +516,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
                 print("Chosen hostname %s does not match configured canonical hostname %s" \
                         % (host_name, primary_host), file=sys.stderr)
                 print("Please fix your /etc/hosts file and restart the installation.", file=sys.stderr)
-                sys.exit(1)
+                raise ScriptError
 
     return ips
 
@@ -597,7 +597,7 @@ def create_replica_config(dirman_password, filename, options):
         root_logger.error("Failed to decrypt or open the replica file.")
         print("ERROR: Failed to decrypt or open the replica file.")
         print("Verify you entered the correct Directory Manager password.")
-        sys.exit(1)
+        raise ScriptError
     config = ReplicaConfig(top_dir)
     read_replica_info(dir, config)
     root_logger.debug(
@@ -607,13 +607,13 @@ def create_replica_config(dirman_password, filename, options):
         root_logger.error(
             'A replica file from a newer release (%d) cannot be installed on an older version (%d)',
             config.version, version.NUM_VERSION)
-        sys.exit(1)
+        raise ScriptError
     config.dirman_password = dirman_password
     try:
         host = get_host_name(options.no_host_dns)
     except BadHostError as e:
         root_logger.error(str(e))
-        sys.exit(1)
+        raise ScriptError
     if config.host_name != host:
         try:
             print("This replica was created for '%s' but this machine is named '%s'" % (config.host_name, host))
@@ -627,7 +627,7 @@ def create_replica_config(dirman_password, filename, options):
             print("")
         except KeyboardInterrupt:
             root_logger.debug("Keyboard Interrupt")
-            sys.exit(0)
+            raise ScriptError(rval=0)
     config.dir = dir
     config.ca_ds_port = read_replica_info_dogtag_port(config.dir)
     return config
diff --git a/ipaserver/install/ipa_ldap_updater.py b/ipaserver/install/ipa_ldap_updater.py
index 2f91a830ff5f8fd9e61f47b4df963118102f7a02..c38fc13010b64111df33b46b03d3a66126872ec5 100644
--- a/ipaserver/install/ipa_ldap_updater.py
+++ b/ipaserver/install/ipa_ldap_updater.py
@@ -83,7 +83,7 @@ class LDAPUpdater(admintool.AdminTool):
             installutils.check_server_configuration()
         except RuntimeError as e:
             print(unicode(e))
-            sys.exit(1)
+            raise admintool.ScriptError
 
     def setup_logging(self):
         super(LDAPUpdater, self).setup_logging(log_file_mode='a')
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index 67ad6544c16734a0f0a9fcb1355499daeec48642..64090cfb7c09d90a01caa47bba1deff848e446f8 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -33,6 +33,7 @@ from ipaplatform.paths import paths
 from ipapython import certdb
 from ipapython import ipautil
 from ipapython.dn import DN
+from ipapython.admintool import ScriptError
 from ipaserver.install import certs
 from ipaserver.install import cainstance
 from ipaserver.install import installutils
@@ -424,7 +425,7 @@ def install_replica_kra(config, postinstall=False):
     _kra.dm_password = config.dirman_password
     _kra.subject_base = config.subject_base
     if _kra.is_installed():
-        sys.exit("A KRA is already configured on this system.")
+        raise ScriptError("A KRA is already configured on this system.")
 
     _kra.configure_instance(config.realm_name, config.host_name,
                             config.dirman_password, config.dirman_password,
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index a4fd97def8150382880f1cf7f66fec1735d32e82..7b54f27f7d299910f62c102a8c327a2008a22013 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -32,6 +32,7 @@ from ipalib.constants import CACERT
 from ipalib.util import create_topology_graph, get_topology_connection_errors
 from ipapython.ipa_log_manager import root_logger
 from ipapython import ipautil, ipaldap
+from ipapython.admintool import ScriptError
 from ipapython.dn import DN
 from ipaplatform import services
 from ipaplatform.paths import paths
@@ -72,7 +73,7 @@ def replica_conn_check(master_host, host_name, realm, check_ca,
     Check the ports used by the replica both locally and remotely to be sure
     that replication will work.
 
-    Does not return a value, will sys.exit() on failure.
+    Does not return a value, will raise ScriptError on failure.
     """
     print("Run connection check to master")
     args = [paths.IPA_REPLICA_CONNCHECK, "--master", master_host,
@@ -97,9 +98,10 @@ def replica_conn_check(master_host, host_name, realm, check_ca,
         args, raiseonerr=False, capture_output=False, nolog=nolog)
 
     if result.returncode != 0:
-        sys.exit("Connection check failed!" +
-                 "\nPlease fix your network settings according to error messages above." +
-                 "\nIf the check results are not valid it can be skipped with --skip-conncheck parameter.")
+        raise ScriptError(
+            "Connection check failed!"
+            "\nPlease fix your network settings according to error messages above."
+            "\nIf the check results are not valid it can be skipped with --skip-conncheck parameter.")
     else:
         print("Connection check OK")
 
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 46b7190dc899dc85daa109af4850206cf5343d5c..c9b158fd0b1072858eb972d7e15415cb1a106309 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -24,6 +24,7 @@ from ipapython.install.core import Knob
 from ipapython.ipa_log_manager import root_logger
 from ipapython.ipautil import (
     decrypt_file, format_netloc, ipa_generate_password, run, user_input)
+from ipapython.admintool import ScriptError
 from ipaplatform import services
 from ipaplatform.paths import paths
 from ipaplatform.tasks import tasks
@@ -193,7 +194,7 @@ def read_realm_name(domain_name, unattended):
                           " as realm name?", True):
             print("")
             print("An upper-case realm name is required. Unable to continue.")
-            sys.exit(1)
+            raise ScriptError
         else:
             realm_name = upper_dom
         print("")
@@ -235,7 +236,7 @@ def check_dirsrv(unattended):
             print("\t389")
         if not ds_secure:
             print("\t636")
-        sys.exit(1)
+        raise ScriptError
 
 
 def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
@@ -277,7 +278,7 @@ def common_cleanup(func):
                         root_logger.error("Failed to remove DS instance. You "
                                           "may need to remove instance data "
                                           "manually")
-            sys.exit(1)
+            raise ScriptError
         finally:
             if not success and installer._installation_cleanup:
                 # Do a cautious clean up as we don't know what failed and
@@ -403,7 +404,7 @@ def check_master_deleted(api, masters, interactive):
               "already removed from topology.")
         if (interactive and not user_input("Proceed with uninstallation?", False)):
             print("Aborted")
-            sys.exit(1)
+            raise ScriptError
 
         return False
 
@@ -419,7 +420,7 @@ def check_topology_connectivity(api, masters):
         print("Uninstallation leads to disconnected topology")
         print("Use '--ignore-topology-disconnect' to skip this check")
         print("Aborting uninstallation")
-        sys.exit(1)
+        raise ScriptError
 
 
 @common_cleanup
@@ -451,16 +452,18 @@ def install_check(installer):
     if (not options.external_ca and not options.external_cert_files and
             is_ipa_configured()):
         installer._installation_cleanup = False
-        sys.exit("IPA server is already configured on this system.\n"
-                 "If you want to reinstall the IPA server, please uninstall "
-                 "it first using 'ipa-server-install --uninstall'.")
+        raise ScriptError(
+            "IPA server is already configured on this system.\n"
+            "If you want to reinstall the IPA server, please uninstall "
+            "it first using 'ipa-server-install --uninstall'.")
 
     client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
     if client_fstore.has_files():
         installer._installation_cleanup = False
-        sys.exit("IPA client is already configured on this system.\n"
-                 "Please uninstall it before configuring the IPA server, "
-                 "using 'ipa-client-install --uninstall'")
+        raise ScriptError(
+            "IPA client is already configured on this system.\n"
+            "Please uninstall it before configuring the IPA server, "
+            "using 'ipa-client-install --uninstall'")
 
     fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
     sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)
@@ -472,7 +475,7 @@ def install_check(installer):
         else:
             dm_password = read_password("Directory Manager", confirm=False)
         if dm_password is None:
-            sys.exit("Directory Manager password required")
+            raise ScriptError("Directory Manager password required")
         try:
             cache_vars = read_cache(dm_password)
             options.__dict__.update(cache_vars)
@@ -480,7 +483,7 @@ def install_check(installer):
                 options.external_ca = False
                 options.interactive = False
         except Exception as e:
-            sys.exit("Cannot process the cache file: %s" % str(e))
+            raise ScriptError("Cannot process the cache file: %s" % str(e))
 
     # We only set up the CA if the PKCS#12 options are not given.
     if options.dirsrv_cert_files:
@@ -535,7 +538,7 @@ def install_check(installer):
 
     # Check to see if httpd is already configured to listen on 443
     if httpinstance.httpd_443_configured():
-        sys.exit("Aborting installation")
+        raise ScriptError("Aborting installation")
 
     if not options.setup_dns and installer.interactive:
         if ipautil.user_input("Do you want to configure integrated DNS "
@@ -565,7 +568,7 @@ def install_check(installer):
         else:
             host_name = read_host_name(host_default, options.no_host_dns)
     except BadHostError as e:
-        sys.exit(str(e) + "\n")
+        raise ScriptError(e)
 
     host_name = host_name.lower()
     root_logger.debug("will use host_name: %s\n" % host_name)
@@ -577,7 +580,7 @@ def install_check(installer):
         try:
             validate_domain_name(domain_name)
         except ValueError as e:
-            sys.exit("Invalid domain name: %s" % unicode(e))
+            raise ScriptError("Invalid domain name: %s" % unicode(e))
     else:
         domain_name = options.domain_name
 
@@ -598,7 +601,7 @@ def install_check(installer):
                 "Enter Apache Server private key unlock",
                 confirm=False, validate=False)
             if options.http_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Apache Server private key unlock password required")
         http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
             cert_files=options.http_cert_files,
@@ -614,7 +617,7 @@ def install_check(installer):
                 "Enter Directory Server private key unlock",
                 confirm=False, validate=False)
             if options.dirsrv_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Directory Server private key unlock password required")
         dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
             cert_files=options.dirsrv_cert_files,
@@ -630,7 +633,7 @@ def install_check(installer):
                 "Enter Kerberos KDC private key unlock",
                 confirm=False, validate=False)
             if options.pkinit_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Kerberos KDC private key unlock password required")
         pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
             cert_files=options.pkinit_cert_files,
@@ -642,14 +645,15 @@ def install_check(installer):
 
     if (options.http_cert_files and options.dirsrv_cert_files and
             http_ca_cert != dirsrv_ca_cert):
-        sys.exit("Apache Server SSL certificate and Directory Server SSL "
-                 "certificate are not signed by the same CA certificate")
+        raise ScriptError(
+            "Apache Server SSL certificate and Directory Server SSL "
+            "certificate are not signed by the same CA certificate")
 
     if not options.dm_password:
         dm_password = read_dm_password()
 
         if dm_password is None:
-            sys.exit("Directory Manager password required")
+            raise ScriptError("Directory Manager password required")
     else:
         dm_password = options.dm_password
 
@@ -661,7 +665,7 @@ def install_check(installer):
     if not options.admin_password:
         admin_password = read_admin_password()
         if admin_password is None:
-            sys.exit("IPA admin password required")
+            raise ScriptError("IPA admin password required")
     else:
         admin_password = options.admin_password
 
@@ -757,7 +761,7 @@ def install_check(installer):
 
     if installer.interactive and not user_input(
             "Continue to configure the system with these values?", False):
-        sys.exit("Installation aborted")
+        raise ScriptError("Installation aborted")
 
     options.realm_name = realm_name
     options.domain_name = domain_name
@@ -1005,8 +1009,8 @@ def install(installer):
             args.append("--mkhomedir")
         run(args, redirect_output=True)
         print()
-    except Exception as e:
-        sys.exit("Configuration of client side components failed!")
+    except Exception:
+        raise ScriptError("Configuration of client side components failed!")
 
     # Everything installed properly, activate ipa service.
     services.knownservices.ipa.enable()
@@ -1092,7 +1096,7 @@ def uninstall_check(installer):
                           "uninstall procedure?", False):
             print("")
             print("Aborting uninstall operation.")
-            sys.exit(1)
+            raise ScriptError
 
     try:
         conn = ipaldap.IPAdmin(
@@ -1118,7 +1122,7 @@ def uninstall_check(installer):
                 "procedure?", False)):
             print("")
             print("Aborting uninstall operation.")
-            sys.exit(1)
+            raise ScriptError
     else:
         dns.uninstall_check(options)
 
@@ -1149,7 +1153,7 @@ def uninstall_check(installer):
                                        " the uninstall procedure?", False)):
                     print("")
                     print("Aborting uninstall operation.")
-                    sys.exit(1)
+                    raise ScriptError
         else:
             masters = api.Command.server_find(
                 sizelimit=0, no_members=False)['result']
@@ -1164,7 +1168,7 @@ def uninstall_check(installer):
                 if (not options.unattended and not user_input(
                         "Do you want to continue uninstallation?", False)):
                     print("Aborted")
-                    sys.exit(1)
+                    raise ScriptError
 
                 if not options.ignore_topology_disconnect:
                     check_topology_connectivity(api, masters)
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index f597880471eb3710ebc7163f771d4e6dc9f1e3d6..2bb0f8305239afd405a4ee8161a83db4afd77bb5 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -22,6 +22,7 @@ from ipapython.dn import DN
 from ipapython.install.common import step
 from ipapython.install.core import Knob
 from ipapython.ipa_log_manager import root_logger
+from ipapython.admintool import ScriptError
 from ipaplatform import services
 from ipaplatform.tasks import tasks
 from ipaplatform.paths import paths
@@ -157,7 +158,7 @@ def install_ca_cert(ldap, base_dn, realm, cafile):
         os.chmod(constants.CACERT, 0o444)
     except Exception as e:
         print("error copying files: " + str(e))
-        sys.exit(1)
+        raise ScriptError
 
 
 def install_http(config, auto_redirect, ca_is_configured, promote=False,
@@ -232,7 +233,7 @@ def check_dirsrv():
             print("\t389")
         if not ds_secure:
             print("\t636")
-        sys.exit(1)
+        raise ScriptError
 
 
 def check_dns_resolution(host_name, dns_servers):
@@ -331,7 +332,7 @@ def configure_certmonger():
         messagebus.start()
     except Exception as e:
         print("Messagebus service unavailable: %s" % str(e))
-        sys.exit(3)
+        raise ScriptError(rval=3)
 
     # Ensure that certmonger has been started at least once to generate the
     # cas files in /var/lib/certmonger/cas.
@@ -340,13 +341,13 @@ def configure_certmonger():
         cmonger.restart()
     except Exception as e:
         print("Certmonger service unavailable: %s" % str(e))
-        sys.exit(3)
+        raise ScriptError(rval=3)
 
     try:
         cmonger.enable()
     except Exception as e:
         print("Failed to enable Certmonger: %s" % str(e))
-        sys.exit(3)
+        raise ScriptError(rval=3)
 
 
 def remove_replica_info_dir(installer):
@@ -367,7 +368,7 @@ def common_cleanup(func):
                 remove_replica_info_dir(installer)
                 raise
         except KeyboardInterrupt:
-            sys.exit(1)
+            raise ScriptError
         except Exception:
             print(
                 "Your system may be partly configured.\n"
@@ -488,15 +489,17 @@ def install_check(installer):
     tasks.check_selinux_status()
 
     if is_ipa_configured():
-        sys.exit("IPA server is already configured on this system.\n"
-                 "If you want to reinstall the IPA server, please uninstall "
-                 "it first using 'ipa-server-install --uninstall'.")
+        raise ScriptError(
+            "IPA server is already configured on this system.\n"
+            "If you want to reinstall the IPA server, please uninstall "
+            "it first using 'ipa-server-install --uninstall'.")
 
     client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
     if client_fstore.has_files():
-        sys.exit("IPA client is already configured on this system.\n"
-                 "Please uninstall it first before configuring the replica, "
-                 "using 'ipa-client-install --uninstall'.")
+        raise ScriptError(
+            "IPA client is already configured on this system.\n"
+            "Please uninstall it first before configuring the replica, "
+            "using 'ipa-client-install --uninstall'.")
 
     sstore = sysrestore.StateFile(paths.SYSRESTORE)
 
@@ -504,7 +507,7 @@ def install_check(installer):
 
     # Check to see if httpd is already configured to listen on 443
     if httpinstance.httpd_443_configured():
-        sys.exit("Aborting installation")
+        raise ScriptError("Aborting installation")
 
     check_dirsrv()
 
@@ -525,9 +528,9 @@ def install_check(installer):
         try:
             dirman_password = get_dirman_password()
         except KeyboardInterrupt:
-            sys.exit(0)
+            raise ScriptError(rval=0)
         if dirman_password is None:
-            sys.exit("Directory Manager password required")
+            raise ScriptError("Directory Manager password required")
 
     config = create_replica_config(dirman_password, filename, options)
     installer._top_dir = config.top_dir
@@ -628,7 +631,7 @@ def install_check(installer):
             print("Run this on the master that generated the info file:")
             print(("    %% ipa-replica-manage del %s --force" %
                   config.host_name))
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         # Detect the current domain level
         try:
@@ -660,7 +663,7 @@ def install_check(installer):
                        "within this domain.")
             root_logger.error(message)
             print(message)
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         # Check pre-existing host entry
         try:
@@ -676,7 +679,7 @@ def install_check(installer):
                   config.host_name))
             print("You should remove it before proceeding:")
             print("    %% ipa host-del %s" % config.host_name)
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         dns_masters = remote_api.Object['dnsrecord'].get_dns_masters()
         if dns_masters:
@@ -688,7 +691,7 @@ def install_check(installer):
                     check_dns_resolution(config.host_name, dns_masters))
                 if not resolution_ok and installer.interactive:
                     if not ipautil.user_input("Continue?", False):
-                        sys.exit(0)
+                        raise ScriptError(rval=0)
         else:
             root_logger.debug('No IPA DNS servers, '
                               'skipping forward/reverse resolution check')
@@ -704,7 +707,7 @@ def install_check(installer):
                 kra.install_check(remote_api, config, options)
             except RuntimeError as e:
                 print(str(e))
-                sys.exit(1)
+                raise ScriptError
 
         if options.setup_dns:
             dns.install_check(False, remote_api, True, options,
@@ -716,11 +719,11 @@ def install_check(installer):
                 options.ip_addresses)
 
     except errors.ACIError:
-        sys.exit("\nThe password provided is incorrect for LDAP server "
-                 "%s" % config.master_host_name)
+        raise ScriptError("\nThe password provided is incorrect for LDAP server "
+                          "%s" % config.master_host_name)
     except errors.LDAPError:
-        sys.exit("\nUnable to connect to LDAP server %s" %
-                 config.master_host_name)
+        raise ScriptError("\nUnable to connect to LDAP server %s" %
+                          config.master_host_name)
     finally:
         if replman and replman.conn:
             replman.conn.unbind()
@@ -927,7 +930,7 @@ def ensure_enrolled(installer):
         ipautil.run(args, stdin=stdin, redirect_output=True)
         print()
     except Exception:
-        sys.exit("Configuration of client side components failed!")
+        raise ScriptError("Configuration of client side components failed!")
 
 @common_cleanup
 @preserve_enrollment_state
@@ -940,9 +943,10 @@ def promote_check(installer):
     tasks.check_selinux_status()
 
     if is_ipa_configured():
-        sys.exit("IPA server is already configured on this system.\n"
-                 "If you want to reinstall the IPA server, please uninstall "
-                 "it first using 'ipa-server-install --uninstall'.")
+        raise ScriptError(
+            "IPA server is already configured on this system.\n"
+            "If you want to reinstall the IPA server, please uninstall "
+            "it first using 'ipa-server-install --uninstall'.")
 
     client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
     if not client_fstore.has_files():
@@ -960,7 +964,7 @@ def promote_check(installer):
 
     # Check to see if httpd is already configured to listen on 443
     if httpinstance.httpd_443_configured():
-        sys.exit("Aborting installation")
+        raise ScriptError("Aborting installation")
 
     check_dirsrv()
 
@@ -1001,7 +1005,7 @@ def promote_check(installer):
                 "Enter Apache Server private key unlock",
                 confirm=False, validate=False)
             if options.http_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Apache Server private key unlock password required")
         http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
             cert_files=options.http_cert_files,
@@ -1017,7 +1021,7 @@ def promote_check(installer):
                 "Enter Directory Server private key unlock",
                 confirm=False, validate=False)
             if options.dirsrv_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Directory Server private key unlock password required")
         dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
             cert_files=options.dirsrv_cert_files,
@@ -1033,7 +1037,7 @@ def promote_check(installer):
                 "Enter Kerberos KDC private key unlock",
                 confirm=False, validate=False)
             if options.pkinit_pin is None:
-                sys.exit(
+                raise ScriptError(
                     "Kerberos KDC private key unlock password required")
         pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
             cert_files=options.pkinit_cert_files,
@@ -1141,7 +1145,7 @@ def promote_check(installer):
             print("Run this command:")
             print("    %% ipa-replica-manage del %s --force" %
                   config.host_name)
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         # Detect if current level is out of supported range
         # for this IPA version
@@ -1156,7 +1160,7 @@ def promote_check(installer):
                        "this version is allowed to be installed "
                        "within this domain.")
             root_logger.error(message)
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         # Detect if the other master can handle replication managers
         # cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX
@@ -1172,7 +1176,7 @@ def promote_check(installer):
                    "command on the master and use a prep file to install "
                    "this replica.")
             root_logger.error(msg)
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         dns_masters = remote_api.Object['dnsrecord'].get_dns_masters()
         if dns_masters:
@@ -1184,7 +1188,7 @@ def promote_check(installer):
                     check_dns_resolution(config.host_name, dns_masters))
                 if not resolution_ok and installer.interactive:
                     if not ipautil.user_input("Continue?", False):
-                        sys.exit(0)
+                        raise ScriptError(rval=0)
         else:
             root_logger.debug('No IPA DNS servers, '
                               'skipping forward/reverse resolution check')
@@ -1202,7 +1206,7 @@ def promote_check(installer):
             if options.dirsrv_cert_files:
                 root_logger.error("Certificates could not be provided when "
                                   "CA is present on some master.")
-                sys.exit(3)
+                raise ScriptError(rval=3)
         else:
             ca_enabled = False
             if not options.dirsrv_cert_files:
@@ -1210,20 +1214,20 @@ def promote_check(installer):
                                   "installed. Use the --http-cert-file, "
                                   "--dirsrv-cert-file options to provide "
                                   "custom certificates.")
-                sys.exit(3)
+                raise ScriptError(rval=3)
 
         config.kra_host_name = service.find_providing_server('KRA', conn,
                                                              api.env.server)
         if options.setup_kra and config.kra_host_name is None:
             root_logger.error("There is no KRA server in the domain, can't "
                               "setup a KRA clone")
-            sys.exit(3)
+            raise ScriptError(rval=3)
 
         if options.setup_ca:
             if not ca_enabled:
                 root_logger.error("The remote master does not have a CA "
                                   "installed, can't set up CA")
-                sys.exit(3)
+                raise ScriptError(rval=3)
 
             options.realm_name = config.realm_name
             options.host_name = config.host_name
@@ -1235,7 +1239,7 @@ def promote_check(installer):
                 kra.install_check(remote_api, config, options)
             except RuntimeError as e:
                 print(str(e))
-                sys.exit(1)
+                raise ScriptError
 
         if options.setup_dns:
             dns.install_check(False, remote_api, True, options,
@@ -1246,10 +1250,10 @@ def promote_check(installer):
                 False, options.ip_addresses)
 
     except errors.ACIError:
-        sys.exit("\nInsufficient privileges to promote the server.")
+        raise ScriptError("\nInsufficient privileges to promote the server.")
     except errors.LDAPError:
-        sys.exit("\nUnable to connect to LDAP server %s" %
-                 config.master_host_name)
+        raise ScriptError("\nUnable to connect to LDAP server %s" %
+                          config.master_host_name)
     finally:
         if replman and replman.conn:
             replman.conn.unbind()
-- 
2.5.5

-- 
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

Reply via email to