On Thu, 2012-01-05 at 16:36 -0500, Rob Crittenden wrote:
> Martin Kosek wrote:
> > Patches 185-186 are needed to make ipa-replica-install run without
> > crashes.
> >
> > How to test:
> >
> > on server:
> > 1) install the server (ipa.example.com is not resolvable)
> > # ipa-server-install -p kokos123 -a kokos123 --no-host-dns
> > --hostname=ipa.example.com
> >
> > 2) Add a record for replica.example.com to /etc/hosts
> > 3) Prepare the replica (without 188 it refuses to create the replica
> > file)
> > # ipa-replica-prepare replica.example.com
> >
> > on replica:
> > 1) Add a record for ipa.example.com to /etc/hosts
> > 2) Install replica (replica.example.com is not resolvable)
> > # ipa-replica-install --no-host-dns --ip-address=IP_ADDRESS REPLICA_FILE
> >
> > The installer now use IP_ADDRESS to create a record /etc/hosts and make
> > the replica resolvable
> >
> > ----
> > Let ipa-replica-prepare and ipa-replica-install work without
> > proper DNS records as records in /etc/hosts are sufficient for
> > DS replication.
> >
> >    1) ipa-replica-prepare now just checks if the replica hostname
> >       is resolvable (DNS records are not required). It is now able
> >       to prepare a replica file even when the replica IP address is
> >       present in /etc/hosts only.
> >    2) ipa-replica-install is now able to proceed when the hostname
> >       is not resolvable. It uses an IP address passed in a new
> >       option --ip-address to create a record in /etc/hosts in the
> >       same way as ipa-server-install does.
> >
> > https://fedorahosted.org/freeipa/ticket/2139
> 
> NACK on patch 185. The exceptions need to be changed to catch 
> DuplicateEntry instead of ALREADY_EXISTS
> 
> Otherwise looks ok.
> 
> rob

Good catch, Rob! Attaching an updated set of patches.

Martin
>From 67bec667b2046f81015ee2149392588ba7fe63d2 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Wed, 4 Jan 2012 19:47:52 +0100
Subject: [PATCH 1/4] Fix LDAP add calls in replication module

Replace conn.add_s(entry) with conn.addEntry(entry) to avoid
function calls with an invalid number of parameters.

https://fedorahosted.org/freeipa/ticket/2139
---
 ipaserver/install/replication.py |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index a139fd0fbe7168193dcfa6ba5f4d19f20d395c52..74685ef0fdcd2f6a8c56e46619576a1ba74948e7 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -227,8 +227,8 @@ class ReplicationManager(object):
         ent.setValues("sn", "replication manager pseudo user")
 
         try:
-            conn.add_s(ent)
-        except ldap.ALREADY_EXISTS:
+            conn.addEntry(ent)
+        except errors.DuplicateEntry:
             conn.modify_s(dn, [(ldap.MOD_REPLACE, "userpassword", pw)])
             pass
 
@@ -277,7 +277,7 @@ class ReplicationManager(object):
         entry.setValues('nsds5replicabinddn', [replica_binddn])
         entry.setValues('nsds5replicalegacyconsumer', "off")
 
-        conn.add_s(entry)
+        conn.addEntry(entry)
 
     def setup_changelog(self, conn):
         dn = "cn=changelog5, cn=config"
@@ -287,8 +287,8 @@ class ReplicationManager(object):
         entry.setValues('cn', "changelog5")
         entry.setValues('nsslapd-changelogdir', dirpath)
         try:
-            conn.add_s(entry)
-        except ldap.ALREADY_EXISTS:
+            conn.addEntry(entry)
+        except errors.DuplicateEntry:
             return
 
     def setup_chaining_backend(self, conn):
@@ -310,11 +310,11 @@ class ReplicationManager(object):
                 entry.setValues('nsmultiplexorbinddn', self.repl_man_dn)
                 entry.setValues('nsmultiplexorcredentials', self.repl_man_passwd)
 
-                self.conn.add_s(entry)
+                self.conn.addEntry(entry)
                 done = True
-            except ldap.ALREADY_EXISTS:
+            except errors.DuplicateEntry:
                 benum += 1
-            except ldap.LDAPError, e:
+            except errors.ExecutionError, e:
                 print "Could not add backend entry " + dn, e
                 raise
 
@@ -378,7 +378,7 @@ class ReplicationManager(object):
         entry.setValues("objectclass", ["account", "simplesecurityobject"])
         entry.setValues("uid", "passsync")
         entry.setValues("userPassword", password)
-        conn.add_s(entry)
+        conn.addEntry(entry)
 
         # Add it to the list of users allowed to bypass password policy
         extop_dn = "cn=ipa_pwd_extop,cn=plugins,cn=config"
@@ -476,7 +476,7 @@ class ReplicationManager(object):
         if iswinsync:
             self.setup_winsync_agmt(entry, win_subtree)
 
-        a_conn.add_s(entry)
+        a_conn.addEntry(entry)
 
         try:
             mod = [(ldap.MOD_ADD, 'nsDS5ReplicatedAttributeListTotal',
@@ -765,7 +765,7 @@ class ReplicationManager(object):
         entry.setValues("ipaConfigString", "winsync:%s" % self.hostname)
 
         try:
-            self.conn.add_s(entry)
+            self.conn.addEntry(entry)
         except Exception, e:
             root_logger.info("Failed to create public entry for winsync replica")
 
-- 
1.7.7.5

>From 162d1d5e8829ad8ba365d366ab97fbd6fbef251c Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Wed, 4 Jan 2012 19:53:18 +0100
Subject: [PATCH 2/4] Prevent service restart failures in ipa-replica-install

Call restart() methods of appropriate services instead of calling
the system service restart command directly as service() method
has a capability to wait until the service is fully up. Without
this patch ipa-replica-install crashed on F-16 because krb5kdc
service was started before dirsrv service was fully up.

https://fedorahosted.org/freeipa/ticket/2139
---
 install/tools/ipa-replica-install |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index fd772e5719986bf196cee2278d78a4fc0bb29d19..dcf86620283f5eb1632534e0ba4b476cd95367a4 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -152,6 +152,8 @@ def install_krb(config, setup_pkinit=False):
                        config.domain_name, config.dirman_password,
                        setup_pkinit, pkcs12_info)
 
+    return krb
+
 def install_ca_cert(config):
     cafile = config.dir + "/ca.crt"
     if not ipautil.file_exists(cafile):
@@ -185,6 +187,8 @@ def install_http(config, auto_redirect):
             print "error copying files: " + str(e)
             sys.exit(1)
 
+    return http
+
 def install_bind(config, options):
     api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
                               bind_pw=config.dirman_password)
@@ -420,8 +424,8 @@ def main():
         cs.add_simple_service('dogtagldap/%s@%s' % (config.host_name, config.realm_name))
         cs.add_cert_to_service()
 
-    install_krb(config, setup_pkinit=options.setup_pkinit)
-    install_http(config, auto_redirect=options.ui_redirect)
+    krb = install_krb(config, setup_pkinit=options.setup_pkinit)
+    http = install_http(config, auto_redirect=options.ui_redirect)
     if CA:
         CA.import_ra_cert(dir + "/ra.p12")
         CA.fix_ra_perms()
@@ -435,9 +439,16 @@ def main():
     service.print_msg("Applying LDAP updates")
     ds.apply_updates()
 
-    ipaservices.knownservices.dirsrv.restart()
-    ipaservices.knownservices.krb5kdc.restart()
-    ipaservices.knownservices.httpd.restart()
+    # Restart ds and krb after configurations have been changed
+    service.print_msg("Restarting the directory server")
+    ds.restart()
+
+    service.print_msg("Restarting the KDC")
+    krb.restart()
+
+    # Restart httpd to pick up the new IPA configuration
+    service.print_msg("Restarting the web server")
+    http.restart()
 
     if options.setup_dns:
         install_bind(config, options)
-- 
1.7.7.5

>From a841aea40962bc1655c08824e292b3c051da1e5d Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Wed, 4 Jan 2012 19:58:33 +0100
Subject: [PATCH 3/4] Fix LDAP updates in ipa-replica-install

ipalib API needs to be bootstrapped in 'installer' context otherwise
LDAP update plugins don't get initialized and ipa-replica-install
crashes.

https://fedorahosted.org/freeipa/ticket/2139
---
 install/tools/ipa-replica-install |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index dcf86620283f5eb1632534e0ba4b476cd95367a4..ece60e16d22c87c7c26a194a62aa36882de57833 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -354,7 +354,7 @@ def main():
     finally:
         os.umask(old_umask)
 
-    api.bootstrap(in_server=True)
+    api.bootstrap(in_server=True, context='installer')
     api.finalize()
 
     # Create DS group if it doesn't exist yet
-- 
1.7.7.5

>From a123f2afbe17afb1e840ea8c03998a63a0461d65 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Wed, 4 Jan 2012 20:04:21 +0100
Subject: [PATCH 4/4] Let replicas install without DNS

Let ipa-replica-prepare and ipa-replica-install work without
proper DNS records as records in /etc/hosts are sufficient for
DS replication.

  1) ipa-replica-prepare now just checks if the replica hostname
     is resolvable (DNS records are not required). It is now able
     to prepare a replica file even when the replica IP address is
     present in /etc/hosts only.
  2) ipa-replica-install is now able to proceed when the hostname
     is not resolvable. It uses an IP address passed in a new
     option --ip-address to create a record in /etc/hosts in the
     same way as ipa-server-install does.

https://fedorahosted.org/freeipa/ticket/2139
---
 install/tools/ipa-replica-install       |    9 ++++
 install/tools/ipa-replica-prepare       |    6 ---
 install/tools/ipa-server-install        |   58 +----------------------------
 install/tools/man/ipa-replica-install.1 |    3 +
 install/tools/man/ipa-server-install.1  |    2 +-
 ipaserver/install/installutils.py       |   62 +++++++++++++++++++++++++++++++
 6 files changed, 76 insertions(+), 64 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index ece60e16d22c87c7c26a194a62aa36882de57833..34c787b1919b89bd1e9ad4aaec1ace7daaebc36e 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -52,6 +52,9 @@ def parse_options():
     basic_group = OptionGroup(parser, "basic options")
     basic_group.add_option("--setup-ca", dest="setup_ca", action="store_true",
                       default=False, help="configure a dogtag CA")
+    basic_group.add_option("--ip-address", dest="ip_address",
+                      type="ip", ip_local=True,
+                      help="Replica server IP Address")
     basic_group.add_option("-p", "--password", dest="password", sensitive=True,
                       help="Directory Manager (existing master) password")
     basic_group.add_option("-w", "--admin-password", dest="admin_password", sensitive=True,
@@ -284,6 +287,9 @@ def main():
     global sstore
     sstore = sysrestore.StateFile('/var/lib/ipa/sysrestore')
 
+    global fstore
+    fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
+
     # check the bind is installed
     if options.setup_dns:
         check_bind()
@@ -334,6 +340,9 @@ def main():
     if not options.skip_conncheck:
         replica_conn_check(config.master_host_name, config.host_name, config.realm_name, options.setup_ca, options.admin_password)
 
+    # check replica host IP resolution
+    ip = installutils.get_server_ip_address(config.host_name, fstore, True, options)
+
     # Create the management framework config file
     # Note: We must do this before bootstraping and finalizing ipalib.api
     old_umask = os.umask(022)   # must be readable for httpd
diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index 269fe5f46bb5784f83e7405b50cdad678aae2ba6..c54aa62b8e0e49fcc30d1359423dfa8615cc9cfe 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -298,12 +298,6 @@ def main():
 
     check_ipa_configuration(api.env.realm)
 
-    if not options.ip_address:
-        try:
-            api.Command['dns_resolve'](replica_fqdn.decode('utf-8'))
-        except errors.NotFound:
-            sys.exit("Neither an A nor AAAA record for host '%s' does not exist in DNS.\nUse the --ip-address option to add DNS entries for the replica." % replica_fqdn)
-
     if api.env.host == replica_fqdn:
         print "You can't create a replica on itself"
         sys.exit(1)
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 7a2e2aa1d5f2f3acb753581aff5db5d5b26d0592..b91343850c016428b059faefa1d36de1ff10fe51 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -730,65 +730,9 @@ def main():
 
     domain_name = domain_name.lower()
 
-    # Check we have a public IP that is associated with the hostname
-    try:
-        hostaddr = resolve_host(host_name)
-    except HostnameLocalhost:
-        print >> sys.stderr, "The hostname resolves to the localhost address (127.0.0.1/::1)"
-        print >> sys.stderr, "Please change your /etc/hosts file so that the hostname"
-        print >> sys.stderr, "resolves to the ip address of your network interface."
-        print >> sys.stderr, "The KDC service does not listen on localhost"
-        print >> sys.stderr, ""
-        print >> sys.stderr, "Please fix your /etc/hosts file and restart the setup program"
-        sys.exit(1)
-
-    ip_add_to_hosts = False
-    if hostaddr is not None:
-        ip = CheckedIPAddress(hostaddr, match_local=True)
-    else:
-        # hostname is not resolvable
-        ip = options.ip_address
-        ip_add_to_hosts = True
-
-    if ip is None:
-        print "Unable to resolve IP address for host name"
-        if options.unattended:
-            sys.exit(1)
-
-    if options.ip_address:
-        if options.ip_address != ip and not options.setup_dns:
-            print >>sys.stderr, "Error: the hostname resolves to an IP address that is different"
-            print >>sys.stderr, "from the one provided on the command line.  Please fix your DNS"
-            print >>sys.stderr, "or /etc/hosts file and restart the installation."
-            return 1
-
-        ip = options.ip_address
-
-    if ip is None:
-        ip = read_ip_address(host_name, fstore)
-        root_logger.debug("read ip_address: %s\n" % str(ip))
-
+    ip = get_server_ip_address(host_name, fstore, options.unattended, options)
     ip_address = str(ip)
 
-    # check /etc/hosts sanity, add a record when needed
-    hosts_record = record_in_hosts(ip_address)
-
-    if hosts_record is None:
-        if ip_add_to_hosts:
-            print "Adding ["+ip_address+" "+host_name+"] to your /etc/hosts file"
-            fstore.backup_file("/etc/hosts")
-            add_record_to_hosts(ip_address, host_name)
-    else:
-        primary_host = hosts_record[1][0]
-        if primary_host != host_name:
-            print >>sys.stderr, "Error: there is already a record in /etc/hosts for IP address %s:" \
-                    % ip_address
-            print >>sys.stderr, hosts_record[0], " ".join(hosts_record[1])
-            print >>sys.stderr, "Chosen hostname %s does not match configured canonical hostname %s" \
-                    % (host_name, primary_host)
-            print >>sys.stderr, "Please fix your /etc/hosts file and restart the installation."
-            return 1
-
     if options.reverse_zone and not bindinstance.verify_reverse_zone(options.reverse_zone, ip):
         sys.exit(1)
 
diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
index c82b4a6b01f384cdbf060a4ed4d61cec6d04277e..f8fa148d076b2e4a53682b1d48e08e57380892d7 100644
--- a/install/tools/man/ipa-replica-install.1
+++ b/install/tools/man/ipa-replica-install.1
@@ -32,6 +32,9 @@ The replica_file is created using the ipa\-replica\-prepare utility.
 Install and configure a CA on this replica. If a CA is not configured then
 certificate operations will be forwarded to a master with a CA installed.
 .TP
+\fB\-\-ip\-address\fR=\fIIP_ADDRESS\fR
+The IP address of this server. If this address does not match the address the host resolves to and --setup-dns is not selected the installation will fail. If the server hostname is not resolvable, a record for the hostname and IP_ADDRESS is added to /etc/hosts.
+.TP
 \fB\-p\fR \fIDM_PASSWORD\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR
 Directory Manager (existing master) password
 .TP
diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
index 920c1345007cf65fae1b8bb57e9a28cac3d36b96..6f1e59e75dfd016361dd5865ae99407b10b99a54 100644
--- a/install/tools/man/ipa-server-install.1
+++ b/install/tools/man/ipa-server-install.1
@@ -46,7 +46,7 @@ The password for the IPA admin user
 The fully\-qualified DNS name of this server. If the hostname does not match system hostname, the system hostname will be updated accordingly to prevent service failures.
 .TP
 \fB\-\-ip\-address\fR=\fIIP_ADDRESS\fR
-The IP address of this server. If this address does not match the address the host resolves to and --setup-dns is not selected the installation will fail.
+The IP address of this server. If this address does not match the address the host resolves to and --setup-dns is not selected the installation will fail. If the server hostname is not resolvable, a record for the hostname and IP_ADDRESS is added to /etc/hosts.
 .TP
 \fB\-N\fR, \fB\-\-no\-ntp\fR
 Do not configure NTP
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 817308f1d22e3970e72d2d9ffbcc685d7759e6e6..e2cabf69b6d90c20daf8848d69a062b301b2204e 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -520,6 +520,68 @@ def get_host_name(no_host_dns):
     verify_fqdn(hostname, no_host_dns)
     return hostname
 
+def get_server_ip_address(host_name, fstore, unattended, options):
+    # Check we have a public IP that is associated with the hostname
+    try:
+        hostaddr = resolve_host(host_name)
+    except HostnameLocalhost:
+        print >> sys.stderr, "The hostname resolves to the localhost address (127.0.0.1/::1)"
+        print >> sys.stderr, "Please change your /etc/hosts file so that the hostname"
+        print >> sys.stderr, "resolves to the ip address of your network interface."
+        print >> sys.stderr, "The KDC service does not listen on localhost"
+        print >> sys.stderr, ""
+        print >> sys.stderr, "Please fix your /etc/hosts file and restart the setup program"
+        sys.exit(1)
+
+    ip_add_to_hosts = False
+    if hostaddr is not None:
+        ip = ipautil.CheckedIPAddress(hostaddr, match_local=True)
+    else:
+        # hostname is not resolvable
+        ip = options.ip_address
+        ip_add_to_hosts = True
+
+    if ip is None:
+        print "Unable to resolve IP address for host name"
+        if unattended:
+            sys.exit(1)
+
+    if options.ip_address:
+        if options.ip_address != ip and not options.setup_dns:
+            print >>sys.stderr, "Error: the hostname resolves to an IP address that is different"
+            print >>sys.stderr, "from the one provided on the command line.  Please fix your DNS"
+            print >>sys.stderr, "or /etc/hosts file and restart the installation."
+            sys.exit(1)
+
+        ip = options.ip_address
+
+    if ip is None:
+        ip = read_ip_address(host_name, fstore)
+        root_logger.debug("read ip_address: %s\n" % str(ip))
+
+    ip_address = str(ip)
+
+    # check /etc/hosts sanity, add a record when needed
+    hosts_record = record_in_hosts(ip_address)
+
+    if hosts_record is None:
+        if ip_add_to_hosts:
+            print "Adding ["+ip_address+" "+host_name+"] to your /etc/hosts file"
+            fstore.backup_file("/etc/hosts")
+            add_record_to_hosts(ip_address, host_name)
+    else:
+        primary_host = hosts_record[1][0]
+        if primary_host != host_name:
+            print >>sys.stderr, "Error: there is already a record in /etc/hosts for IP address %s:" \
+                    % ip_address
+            print >>sys.stderr, hosts_record[0], " ".join(hosts_record[1])
+            print >>sys.stderr, "Chosen hostname %s does not match configured canonical hostname %s" \
+                    % (host_name, primary_host)
+            print >>sys.stderr, "Please fix your /etc/hosts file and restart the installation."
+            sys.exit(1)
+
+    return ip
+
 def expand_replica_info(filename, password):
     """
     Decrypt and expand a replica installation file into a temporary
-- 
1.7.7.5

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to