On 09/24/2014 02:07 PM, Petr Viktorin wrote:
On 09/24/2014 01:54 PM, Petr Spacek wrote:
On 24.9.2014 13:47, Petr Viktorin wrote:
On 09/23/2014 06:00 PM, Petr Spacek wrote:
On 22.9.2014 14:09, Petr Viktorin wrote:
On 09/22/2014 01:48 PM, Petr Spacek wrote:
On 22.9.2014 10:38, Martin Kosek wrote:
On 09/22/2014 10:31 AM, Petr Spacek wrote:
On 22.9.2014 10:14, Martin Kosek wrote:
On 09/19/2014 07:29 PM, Petr Viktorin wrote:

See ticket & commit message for details.

Shouldn't we add a 1 sec sleep between tries? Wouldn't current
version just
hammer DNS server with as many DNS queries as it can send?


LGTM except one nitpick I didn't see before:

+        if not options.wait_for_dns or self.check_dns(replica_fqdn):
+            self.log.debug('%s A/AAAA record resolvable', replica_fqdn)
+            return

This will print message
'%s A/AAAA record resolvable', replica_fqdn
even if I use switch --no-wait-for-dns

This is sooo minor detail that it can be deferred, please open a ticket
if you don't plan to send new version of the patch.

You're right.
Let's do it correctly now; this isn't worth the overhead of a ticket.

Based on discussion more with Petr, I extended the list of handled exceptions.

From 8832e243297a8ab5f265798350fd30dfbc3a710f Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 19 Sep 2014 15:57:44 +0200
Subject: [PATCH] ipa-replica-prepare: Wait for the DNS entry to be resolvable

It takes some time after the DNS record is added until it propagates
to Bind. In automated installations, it might happen that
replica-install is attempted before the hostname is resolvable;
in that case the connection check would fail.

Wait for the name to be resolvable at the end of replica-prepare.
Mention that this can be interrupted (Ctrl+C).
Provide an option to skip the wait.

In case DNS is not managed by IPA, this reminds the admin of the necessary
configuration and checks their work, but it's possible to skip (either by
interrupting it interactively, or by the option).

 ipaserver/install/ipa_replica_prepare.py | 53 ++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index 7762614a1174208db0915d4e882212b3f578476e..c8d2e64c2ffc9addbb8cffbd13317ac2f82be5f6 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -21,9 +21,12 @@
 import os
 import shutil
 import tempfile
+import time
 from optparse import OptionGroup
 from ConfigParser import SafeConfigParser
+import dns.resolver
 from ipaserver.install import certs, installutils, bindinstance, dsinstance
 from ipaserver.install.replication import enable_replication_version_checking
 from ipaserver.plugins.ldap2 import ldap2
@@ -64,6 +67,9 @@ def add_options(cls, parser):
         parser.add_option("--ca", dest="ca_file", default=paths.CACERT_P12,
             help="location of CA PKCS#12 file, default /root/cacert.p12")
+        parser.add_option('--no-wait-for-dns', dest='wait_for_dns',
+            action='store_false', default=True,
+            help="do not wait until the replica is resolvable in DNS")
         group = OptionGroup(parser, "SSL certificate options",
             "Only used if the server was installed using custom SSL certificates")
@@ -290,6 +296,9 @@ def run(self):
         if options.ip_address:
+        if options.wait_for_dns:
+            self.wait_for_dns()
     def copy_ds_certificate(self):
         options = self.options
@@ -451,6 +460,50 @@ def add_dns_records(self):
                 raise admintool.ScriptError(
                     "Could not add reverse DNS record for the replica: %s" % e)
+    def check_dns(self, replica_fqdn):
+        """Return true if the replica hostname is resolvable"""
+        resolver = dns.resolver.Resolver()
+        exceptions = (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer,
+                      dns.resolver.Timeout, dns.resolver.NoNameservers)
+        try:
+            dns_answer = resolver.query(replica_fqdn, 'A', 'IN')
+        except exceptions:
+            try:
+                dns_answer = resolver.query(replica_fqdn, 'AAAA', 'IN')
+            except exceptions:
+                return False
+        except Exception as e:
+            self.log.warn('Exception while waiting for DNS record: %s: %s',
+                          type(e).__name__, e)
+        return True
+    def wait_for_dns(self):
+        options = self.options
+        # Make sure replica_fqdn has a trailing dot, so the
+        # 'search' directive in /etc/resolv.conf doesn't apply
+        replica_fqdn = self.replica_fqdn
+        if not replica_fqdn.endswith('.'):
+            replica_fqdn += '.'
+        if self.check_dns(replica_fqdn):
+            self.log.debug('%s A/AAAA record resolvable', replica_fqdn)
+            return
+        self.log.info('Waiting for %s A or AAAA record to be resolvable',
+                      replica_fqdn)
+        print 'This can be safely interrupted (Ctrl+C)'
+        try:
+            while not self.check_dns(replica_fqdn):
+                time.sleep(1)
+        except KeyboardInterrupt:
+            self.log.info('Interrupted')
+        else:
+            self.log.debug('%s A/AAAA record resolvable', replica_fqdn)
     def copy_info_file(self, source, dest):
         """Copy a file into the info directory

Freeipa-devel mailing list

Reply via email to