From b6c7247319575a376ac9a480ae6ceda39a2bd968 Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Tue, 1 Sep 2015 19:05:01 +0200 Subject: [PATCH] Installer: do not modify /etc/hosts before user agreement https://fedorahosted.org/freeipa/ticket/4561 As side effect this also fixes: https://fedorahosted.org/freeipa/ticket/5266 Reviewed-By: David Kupka --- ipaserver/install/dns.py | 9 ++++++-- ipaserver/install/installutils.py | 36 +++++++++++++++++++----------- ipaserver/install/server/install.py | 14 ++++++++++-- ipaserver/install/server/replicainstall.py | 12 +++++++++- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py index 538e99fbe01a34cee627f1cebd938be19777c134..099e35dc331722607c8ca02cdbc7a0e66f8c4754 100644 --- a/ipaserver/install/dns.py +++ b/ipaserver/install/dns.py @@ -19,6 +19,7 @@ from ipapython.ipaldap import AUTOBIND_ENABLED from ipapython.ipautil import user_input from ipaserver.install.installutils import get_server_ip_address from ipaserver.install.installutils import read_dns_forwarders +from ipaserver.install.installutils import update_hosts_file from ipaserver.install import bindinstance from ipaserver.install import dnskeysyncinstance from ipaserver.install import ntpinstance @@ -225,8 +226,8 @@ def install_check(standalone, replica, options, hostname): "the original kasp.db file." % ", ".join([str(zone) for zone in dnssec_zones])) - ip_addresses = get_server_ip_address( - hostname, fstore, options.unattended, True, options.ip_addresses) + ip_addresses = get_server_ip_address(hostname, options.unattended, + True, options.ip_addresses) if options.no_forwarders: dns_forwarders = () @@ -277,6 +278,10 @@ def install(standalone, replica, options): conf_ntp = ntpinstance.NTPInstance(fstore).is_enabled() + if standalone: + # otherwise this is done by server/replica installer + update_hosts_file(ip_addresses, api.env.host, fstore) + bind = bindinstance.BindInstance(fstore, ldapi=True, autobind=AUTOBIND_ENABLED) bind.setup(api.env.host, ip_addresses, api.env.realm, api.env.domain, diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 02e8526317dbab909ed48a1823000922ce6e6b7a..81a025597c97b41377c35a6714bf1d3001c868cc 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -264,7 +264,8 @@ def read_ip_address(host_name, fstore): return ip_parsed -def read_ip_addresses(host_name, fstore): + +def read_ip_addresses(): ips = [] print "Enter the IP address to use, or press Enter to finish." while True: @@ -470,7 +471,7 @@ def get_host_name(no_host_dns): verify_fqdn(hostname, no_host_dns) return hostname -def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses): +def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses): # Check we have a public IP that is associated with the hostname try: hostaddr = resolve_host(host_name) @@ -483,8 +484,6 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses print >> sys.stderr, "Please fix your /etc/hosts file and restart the setup program" sys.exit(1) - ip_add_to_hosts = False - ips = [] if len(hostaddr): for ha in hostaddr: @@ -495,7 +494,7 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses if not ips and not ip_addresses: if not unattended: - ip_addresses = read_ip_addresses(host_name, fstore) + ip_addresses = read_ip_addresses() if ip_addresses: if setup_dns: @@ -511,22 +510,16 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses print >>sys.stderr, "Provided but not resolved address(es): %s" % \ ", ".join(str(ip) for ip in (set(ip_addresses) - set(ips))) sys.exit(1) - ip_add_to_hosts = True if not ips: print >> sys.stderr, "No usable IP address provided nor resolved." sys.exit(1) for ip_address in ips: - # check /etc/hosts sanity, add a record when needed + # check /etc/hosts sanity hosts_record = record_in_hosts(str(ip_address)) - if hosts_record is None: - if ip_add_to_hosts or setup_dns: - print "Adding ["+str(ip_address)+" "+host_name+"] to your /etc/hosts file" - fstore.backup_file(paths.HOSTS) - add_record_to_hosts(str(ip_address), host_name) - else: + if hosts_record is not None: 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:" \ @@ -539,6 +532,23 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses return ips + +def update_hosts_file(ip_addresses, host_name, fstore): + """ + Update hosts with specified addresses + :param ip_addresses: list of IP addresses + :return: + """ + if not fstore.has_file(paths.HOSTS): + fstore.backup_file(paths.HOSTS) + for ip_address in ip_addresses: + if record_in_hosts(str(ip_address)): + continue + print "Adding [{address!s} {name}] to your /etc/hosts file".format( + address=ip_address, name=host_name) + add_record_to_hosts(str(ip_address), host_name) + + def expand_replica_info(filename, password): """ Decrypt and expand a replica installation file into a temporary diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index ff517513473a458a84f63c5c1308a8cc0b8699f8..9d7036a7786a35e6aa2429254d62c8afb30970db 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -32,7 +32,8 @@ from ipaserver.install import ( otpdinstance, replication, service, sysupgrade) from ipaserver.install.installutils import ( IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address, - is_ipa_configured, load_pkcs12, read_password, verify_fqdn) + is_ipa_configured, load_pkcs12, read_password, verify_fqdn, + update_hosts_file) from ipaserver.plugins.ldap2 import ldap2 try: from ipaserver.install import adtrustinstance @@ -607,10 +608,15 @@ def install_check(installer): dns.install_check(False, False, options, host_name) ip_addresses = dns.ip_addresses else: - ip_addresses = get_server_ip_address(host_name, fstore, + ip_addresses = get_server_ip_address(host_name, not installer.interactive, False, options.ip_addresses) + # installer needs to update hosts file when DNS subsystem will be + # installed or custom addresses are used + if options.ip_addresses or options.setup_dns: + installer._update_hosts_file = True + print print "The IPA Master Server will be configured with:" print "Hostname: %s" % host_name @@ -709,6 +715,9 @@ def install(installer): # configure /etc/sysconfig/network to contain the custom hostname tasks.backup_and_replace_hostname(fstore, sstore, host_name) + if installer._update_hosts_file: + update_hosts_file(ip_addresses, host_name, fstore) + # Create DS user/group if it doesn't exist yet dsinstance.create_ds_user() @@ -1494,6 +1503,7 @@ class Server(common.Installable, common.Interactive, core.Composite): self._external_cert_file = None self._external_ca_file = None self._ca_cert = None + self._update_hosts_file = False #pylint: disable=no-member diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 0725c7763e505ca0cc5a8892414a3c36c557cf1d..6f9a6141fe9af44806244ce52df59c191dc966b0 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -502,11 +502,17 @@ def install_check(installer): if options.setup_dns: dns.install_check(False, True, options, config.host_name) + config.ips = dns.ip_addresses else: config.ips = installutils.get_server_ip_address( - config.host_name, fstore, not installer.interactive, False, + config.host_name, not installer.interactive, False, options.ip_addresses) + # installer needs to update hosts file when DNS subsystem will be + # installed or custom addresses are used + if options.setup_dns or options.ip_addresses: + installer._update_hosts_file = True + # check connection if not options.skip_conncheck: replica_conn_check( @@ -528,6 +534,9 @@ def install(installer): dogtag_constants = dogtag.install_constants + if installer._update_hosts_file: + installutils.update_hosts_file(config.ips, config.host_name, fstore) + # Create DS user/group if it doesn't exist yet dsinstance.create_ds_user() @@ -785,6 +794,7 @@ class Replica(common.Installable, common.Interactive, core.Composite): self._top_dir = None self._config = None + self._update_hosts_file = False #pylint: disable=no-member -- 2.5.1