URL: https://github.com/freeipa/freeipa/pull/117
Author: stlaz
 Title: #117: Make ipa-replica-install run in interactive mode
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/117/head:pr117
git checkout pr117
From b16ce42e7c0ec6611f71a1c4d0da22349ee33148 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Mon, 26 Sep 2016 12:43:24 +0200
Subject: [PATCH] replicainstall: run in interactive mode

Tweaks to replica installation to support interactive mode:
 - modified man to better document what actually happens
 - added principal/password prompt for unattended mode
   of ipa-replica-install if no credentials are set
 - made ipa-client-install run in interactive mode during
   replica promotion if it is itself not run in unattended mode

https://fedorahosted.org/freeipa/ticket/6068
---
 install/tools/man/ipa-replica-install.1    |   4 +-
 ipaserver/install/server/replicainstall.py | 116 +++++++++++++++++++----------
 2 files changed, 78 insertions(+), 42 deletions(-)

diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
index af37b07..f94098d 100644
--- a/install/tools/man/ipa-replica-install.1
+++ b/install/tools/man/ipa-replica-install.1
@@ -49,7 +49,7 @@ A replica should only be installed on the same or higher version of IPA on the r
 The user principal which will be used to promote the client to the replica and enroll the client itself, if necessary.
 .TP
 \fB\-w\fR, \fB\-\-admin\-password\fR
-The Kerberos password for the given principal.
+The Kerberos password for the given principal. If no principal is supplied with \-\-principal, "admin" is assumed.
 
 .SS "DOMAIN LEVEL 1 CLIENT ENROLLMENT OPTIONS"
 To install client and promote it to replica using a host keytab or One Time Password, the host needs to be a member of ipaservers group. This requires to create a host entry and add it to the host group prior replica installation.
@@ -58,7 +58,7 @@ To install client and promote it to replica using a host keytab or One Time Pass
 
 .TP
 \fB\-p\fR \fIPASSWORD\fR, \fB\-\-password\fR=\fIPASSWORD\fR
-One Time Password for joining a machine to the IPA realm.
+One Time Password for joining a machine to the IPA realm. If the \-\-principal option is used, this is assumed a password for that principal.
 .TP
 \fB\-k\fR, \fB\-\-keytab\fR
 Path to host keytab.
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index b0cf28f..91d4ee6 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -13,6 +13,7 @@
 import socket
 import tempfile
 import traceback
+import getpass
 
 from pkg_resources import parse_version
 import six
@@ -862,46 +863,50 @@ def install_check(installer):
 
 
 def ensure_enrolled(installer):
-    # Call client install script
-    service.print_msg("Configuring client side components")
+    # Prepare options for the installer script
+    args = [paths.IPA_CLIENT_INSTALL, "--no-ntp"]
+    nolog = ()
+
+    if installer.unattended:
+        args.append("--unattended")
+    if installer.domain_name:
+        args.extend(["--domain", installer.domain_name])
+    if installer.server:
+        args.extend(["--server", installer.server])
+    if installer.realm_name:
+        args.extend(["--realm", installer.realm_name])
+    if installer.host_name:
+        args.extend(["--hostname", installer.host_name])
+    if installer.password:
+        args.extend(["--password", installer.password])
+    else:
+        if installer.admin_password:
+            # Always set principal if password was set explicitly.
+            # This is the behaviour from domain level 0 so we're keeping it
+            args.extend(["--principal", installer.principal or "admin"])
+            nolog = (installer.admin_password, )
+            args.extend(["--password", installer.admin_password])
+        if installer.keytab:
+            args.extend(["--keytab", installer.keytab])
+
+    if installer.no_dns_sshfp:
+        args.append("--no-dns-sshfp")
+    if installer.ssh_trust_dns:
+        args.append("--ssh-trust-dns")
+    if installer.no_ssh:
+        args.append("--no-ssh")
+    if installer.no_sshd:
+        args.append("--no-sshd")
+    if installer.mkhomedir:
+        args.append("--mkhomedir")
+
     try:
+        service.print_msg("Configuring client side components")
+        # Set _enrollment_performed to True so that any mess left behind in
+        # case of an enrollment failure gets cleaned
         installer._enrollment_performed = True
-
-        args = [paths.IPA_CLIENT_INSTALL, "--unattended", "--no-ntp"]
-        stdin = None
-
-        if installer.domain_name:
-            args.extend(["--domain", installer.domain_name])
-        if installer.server:
-            args.extend(["--server", installer.server])
-        if installer.realm_name:
-            args.extend(["--realm", installer.realm_name])
-        if installer.host_name:
-            args.extend(["--hostname", installer.host_name])
-
-        if installer.password:
-            args.extend(["--password", installer.password])
-        else:
-            if installer.admin_password:
-                # Always set principal if password was set explicitly,
-                # the password itself gets passed directly via stdin
-                args.extend(["--principal", installer.principal or "admin"])
-                stdin = installer.admin_password
-            if installer.keytab:
-                args.extend(["--keytab", installer.keytab])
-
-        if installer.no_dns_sshfp:
-            args.append("--no-dns-sshfp")
-        if installer.ssh_trust_dns:
-            args.append("--ssh-trust-dns")
-        if installer.no_ssh:
-            args.append("--no-ssh")
-        if installer.no_sshd:
-            args.append("--no-sshd")
-        if installer.mkhomedir:
-            args.append("--mkhomedir")
-
-        ipautil.run(args, stdin=stdin, redirect_output=True)
+        # Call client install script
+        ipautil.run(args, nolog=nolog, redirect_output=True)
         print()
     except Exception:
         raise ScriptError("Configuration of client side components failed!")
@@ -1447,6 +1452,7 @@ def install(installer):
 
 
 def init(installer):
+    installer._ccache = os.environ.get('KRB5CCNAME')
     installer.unattended = not installer.interactive
     installer.promote = installer.replica_file is None
 
@@ -1456,11 +1462,41 @@ def init(installer):
         installer.server = None
     if installer.replica_file is None:
         installer.password = installer.host_password
+        # unless some credentials are given, we need to have at least
+        # an admin principal and its password so these are not asked for
+        # twice (first in client-install, then in conncheck)
+        # TODO: remove when client-install is performed as a function call
+        if (not installer.unattended and installer.password is None and
+                installer.keytab is None and
+                installer.admin_password is None and
+                installer._ccache is None):
+            if not installer.principal:
+                try:
+                    # get the principal interactively, can't be empty
+                    installer.principal = ipautil.user_input(
+                            "User authorized to enroll computers",
+                            allow_empty=False)
+                    root_logger.debug(
+                            "will use principal provided as option: %s",
+                            installer.principal)
+                except Exception as e:
+                    print()
+                    # higher-level error so script usage is not printed
+                    raise ScriptError(str(e))
+            # the principal is set now, we need its password
+            try:
+                installer.admin_password = getpass.getpass(
+                    "Password for {}: ".format(installer.principal))
+            except EOFError:
+                print()
+                installer.admin_password = None
+            if not installer.admin_password:
+                # higher-level error so script usage is not printed
+                raise ScriptError("Password must be provided for %s." %
+                                  installer.principal)
     else:
         installer.password = installer.dm_password
 
-    installer._ccache = os.environ.get('KRB5CCNAME')
-
     installer._top_dir = None
     installer._config = None
     installer._update_hosts_file = False
-- 
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