From 241ee334defda108e22855331d5d9a14f261ce16 Mon Sep 17 00:00:00 2001 From: Martin Kosek Date: Sun, 22 May 2011 19:17:07 +0200 Subject: Connection check program for replica installation When connection between a master machine and future replica is not sane, the replica installation may fail unexpectedly with inconvenient error messages. One common problem is misconfigured firewall. This patch adds a program ipa-replica-conncheck which tests the connection using the following procedure: 1) Execute the on-replica check testing the connection to master 2) Open required ports on local machine 3) Ask user to run the on-master part of the check OR run it automatically: a) kinit to master as default admin user with given password b) run the on-master part using ssh 4) When master part is executed, it checks connection back to the replica and prints the check result This program is run by ipa-replica-install as mandatory part. It can, however, be skipped using --skip-conncheck option. ipa-replica-install now requires password for admin user to run the command on remote master. https://fedorahosted.org/freeipa/ticket/1107 --- ipapython/ipautil.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'ipapython') diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index acfd70cae..ed8f04af5 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -32,6 +32,7 @@ import copy import stat import shutil import urllib2 +import socket from ipapython import ipavalidate from types import * @@ -1093,3 +1094,75 @@ def chkconfig_add(service_name): def chkconfig_del(service_name): run(["/sbin/chkconfig", "--del", service_name]) +def host_port_open(host, port, socket_stream=True, socket_timeout=None): + families = (socket.AF_INET, socket.AF_INET6) + success = False + + if socket_stream: + socket_type = socket.SOCK_STREAM + else: + socket_type = socket.SOCK_DGRAM + + for family in families: + try: + try: + s = socket.socket(family, socket_type) + except socket.error: + continue + + if socket_timeout is not None: + s.settimeout(socket_timeout) + + s.connect((host, port)) + success = True + except socket.error, e: + pass + finally: + s.close() + + if success: + return True + + return False + +def bind_port_responder(port, socket_stream=True, socket_timeout=None, responder_data=None): + families = (socket.AF_INET, socket.AF_INET6) + + if socket_stream: + socket_type = socket.SOCK_STREAM + else: + socket_type = socket.SOCK_DGRAM + + host = '' # all available interfaces + + for family in families: + try: + s = socket.socket(family, socket_type) + except socket.error, e: + if family == families[-1]: # last available family + raise e + + if socket_timeout is not None: + s.settimeout(socket_timeout) + + if socket_stream: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + try: + s.bind((host, port)) + + if socket_stream: + s.listen(1) + connection, client_address = s.accept() + try: + if responder_data: + connection.sendall(responder_data) #pylint: disable=E1101 + finally: + connection.close() + else: + data, addr = s.recvfrom( 512 ) # buffer size is 1024 bytes + + if responder_data: + s.sendto(responder_data, addr) + finally: + s.close() -- cgit