mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Adding method to ipa-server-upgrade to cleanup ntpd
Removing ntpd configuration files and entry from LDAP. Add parameter and rename method for restoring forced time services. Addressing some requests for change too. Remove unused path for chrony-helper. Resolves: https://pagure.io/freeipa/issue/7024 Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
parent
194518f11f
commit
5d9c749e83
@ -60,7 +60,7 @@ from ipapython.ipautil import (
|
||||
)
|
||||
from ipapython.ssh import SSHPublicKey
|
||||
|
||||
from . import automount, ipadiscovery, ntpconf, sssd
|
||||
from . import automount, ipadiscovery, timeconf, sssd
|
||||
from .ipachangeconf import IPAChangeConf
|
||||
|
||||
NoneType = type(None)
|
||||
@ -1989,8 +1989,8 @@ def install_check(options):
|
||||
|
||||
if options.conf_ntp and not options.force_chrony:
|
||||
try:
|
||||
ntpconf.check_timedate_services()
|
||||
except ntpconf.NTPConflictingService as e:
|
||||
timeconf.check_timedate_services()
|
||||
except timeconf.NTPConflictingService as e:
|
||||
print("WARNING: chronyd time&date synchronization service will not"
|
||||
" be configured as")
|
||||
print("conflicting service ({}) is enabled".format(
|
||||
@ -1998,10 +1998,10 @@ def install_check(options):
|
||||
print("Use --force-chrony option to disable it and force "
|
||||
"use of chronyd")
|
||||
print("")
|
||||
|
||||
# TODO decide what to do if there is conflicting service
|
||||
# configuration of chrony is disabled in this case
|
||||
options.conf_ntp = False
|
||||
except ntpconf.NTPConfigurationError:
|
||||
except timeconf.NTPConfigurationError:
|
||||
pass
|
||||
|
||||
if options.unattended and (
|
||||
@ -2345,18 +2345,21 @@ def update_ipa_nssdb():
|
||||
(nickname, sys_db.secdir, e))
|
||||
|
||||
|
||||
def sync_time(options, fstore, statestore):
|
||||
# We assume that NTP servers are discoverable through SRV records
|
||||
# in the DNS.
|
||||
# If that fails, we try to sync directly with IPA server,
|
||||
# assuming it runs NTP
|
||||
def sync_time(options, fstore, statestore, force):
|
||||
"""
|
||||
Will disable any other time synchronization service if there is
|
||||
--force-chrony option set, and configure chrony with given ntp(chrony)
|
||||
server and/or pool using Augeas in configure_chrony method.
|
||||
If there is no option --ntp-server set IPADiscovery will try to find ntp
|
||||
server in DNS records.
|
||||
"""
|
||||
# We assume that NTP servers are discoverable through SRV records in DNS.
|
||||
|
||||
# disable other time&date services first
|
||||
if options.force_chrony:
|
||||
ntpconf.force_chrony(statestore)
|
||||
if force:
|
||||
timeconf.force_chrony(statestore)
|
||||
|
||||
print("Synchronizing time")
|
||||
print(" [1/1]: Configuring chrony client")
|
||||
logger.info('Synchronizing time with KDC...')
|
||||
|
||||
if not options.ntp_servers:
|
||||
@ -2367,37 +2370,37 @@ def sync_time(options, fstore, statestore):
|
||||
ntp_servers = options.ntp_servers
|
||||
|
||||
if ntp_servers:
|
||||
synced_time = ntpconf.configure_chrony(ntp_servers, options.ntp_pool,
|
||||
fstore, statestore)
|
||||
if timeconf.configure_chrony(ntp_servers, options.ntp_pool,
|
||||
fstore, statestore):
|
||||
print("Done Configuring chrony.")
|
||||
else:
|
||||
print("Warning: IPA Server was unable to sync time with chrony!")
|
||||
print(" Time synchronization is required for IPA Server "
|
||||
"to work correctly")
|
||||
logger.warning(
|
||||
"Unable to sync time with chrony server, assuming the time "
|
||||
"is in sync. Please check that 123 UDP port is opened, "
|
||||
"and any time server is on network.")
|
||||
else:
|
||||
synced_time = False
|
||||
print("Warning: chrony not configured, using default configuration.")
|
||||
logger.warning("No SRV records of NTP servers found nor NTP server "
|
||||
"address was privided. Skipping chrony configuration")
|
||||
|
||||
if not synced_time:
|
||||
print("Warning: IPA Server was unable to sync time with chrony!")
|
||||
print(" Time synchronization is required "
|
||||
"for IPA Server to work correctly")
|
||||
logger.warning(
|
||||
"Unable to sync time with chrony server, assuming the time "
|
||||
"is in sync. Please check that 123 UDP port is opened, "
|
||||
"and any time server is on network.")
|
||||
"address was provided. Skipping chrony configuration, "
|
||||
"default configuration will be used")
|
||||
|
||||
|
||||
def restore_time_sync(statestore, fstore):
|
||||
chrony_configured = statestore.has_state('ntp')
|
||||
if chrony_configured:
|
||||
chrony_enabled = statestore.restore_state('ntp', 'enabled')
|
||||
if statestore.has_state('chrony'):
|
||||
chrony_enabled = statestore.restore_state('chrony', 'enabled')
|
||||
restored = False
|
||||
|
||||
try:
|
||||
# Restore might fail due to file missing in backup
|
||||
# the reason for it might be that freeipa-client was updated
|
||||
# to this version but not unenrolled/enrolled again
|
||||
# In such case it is OK to fail
|
||||
# Restore might fail due to missing file(s) in backup.
|
||||
# One example is if the client was updated from a previous version
|
||||
# not configured with chrony. In such a cast it is OK to fail.
|
||||
restored = fstore.restore_file(paths.CHRONY_CONF)
|
||||
except Exception:
|
||||
pass
|
||||
except ValueError: # this will not handle possivble IOError
|
||||
logger.debug("Configuration file %s was not restored.",
|
||||
paths.CHRONY_CONF)
|
||||
|
||||
if not chrony_enabled:
|
||||
services.knownservices.chronyd.stop()
|
||||
@ -2406,7 +2409,7 @@ def restore_time_sync(statestore, fstore):
|
||||
services.knownservices.chronyd.restart()
|
||||
|
||||
try:
|
||||
ntpconf.restore_forced_chronyd(statestore)
|
||||
timeconf.restore_forced_timeservices(statestore)
|
||||
except CalledProcessError as e:
|
||||
logger.error('Failed to restore time synchronization service: %s', e)
|
||||
|
||||
@ -2458,7 +2461,7 @@ def _install(options):
|
||||
|
||||
if options.conf_ntp:
|
||||
# Attempt to sync time with NTP server (chrony).
|
||||
sync_time(options, fstore, statestore)
|
||||
sync_time(options, fstore, statestore, options.force_chrony)
|
||||
elif options.on_master:
|
||||
# If we're on master skipping the time sync here because it was done
|
||||
# in ipa-server-install
|
||||
@ -3472,6 +3475,7 @@ class ClientInstallInterface(hostname_.HostNameInstallInterface,
|
||||
|
||||
force_ntpd = knob(
|
||||
None, False,
|
||||
deprecated=True,
|
||||
description="Stop and disable any time&date synchronization services "
|
||||
"besides ntpd.\n"
|
||||
"This option has been obsoleted by --force-chrony",
|
||||
|
@ -79,10 +79,10 @@ def configure_chrony(ntp_servers, ntp_pool=None,
|
||||
|
||||
try:
|
||||
aug.save()
|
||||
except Exception as e:
|
||||
except IOError as e:
|
||||
logger.error("Augeas failed to configure file %s", chrony_conf)
|
||||
|
||||
except Exception as e:
|
||||
except RuntimeError as e:
|
||||
logger.error("Configuration failed with: %s", e)
|
||||
finally:
|
||||
aug.close()
|
||||
@ -101,20 +101,19 @@ def configure_chrony(ntp_servers, ntp_pool=None,
|
||||
# 3 attempts means if first immidiate attempt fails
|
||||
# there is 10s delay between next
|
||||
|
||||
cmd = [paths.CHRONYC, 'waitsync', str(sync_attempt_count)]
|
||||
args = [paths.CHRONYC, 'waitsync', str(sync_attempt_count)]
|
||||
|
||||
if debug:
|
||||
cmd.append('-d')
|
||||
args.append('-d')
|
||||
|
||||
try:
|
||||
logger.info('Attempting to sync time using chronyd.')
|
||||
ipautil.run(cmd)
|
||||
logger.info('Time is in sync.')
|
||||
ipautil.run(args)
|
||||
logger.info('Time synchronization was successful.')
|
||||
return True
|
||||
except ipautil.CalledProcessError as e:
|
||||
if e.returncode is 1:
|
||||
logger.warning('Process chronyc waitsync failed to sync time!')
|
||||
logger.warning('Configuration of chrony was changed by installer.')
|
||||
except ipautil.CalledProcessError:
|
||||
logger.warning('Process chronyc waitsync failed to sync time!')
|
||||
logger.warning('Configuration of chrony was changed by installer.')
|
||||
return False
|
||||
|
||||
|
||||
@ -167,13 +166,13 @@ def force_chrony(statestore):
|
||||
instance.disable()
|
||||
|
||||
|
||||
def restore_forced_chronyd(statestore):
|
||||
def restore_forced_timeservices(statestore, skip_service='chronyd'):
|
||||
"""
|
||||
Restore from --force-chronyd installation and enable/start service that
|
||||
were disabled/stopped during installation
|
||||
"""
|
||||
for service in services.timedate_services:
|
||||
if service == 'chronyd':
|
||||
if service == skip_service:
|
||||
continue
|
||||
if statestore.has_state(service):
|
||||
instance = services.service(service, api)
|
@ -230,7 +230,6 @@ class BasePathNamespace(object):
|
||||
NAMED_PKCS11 = "/usr/sbin/named-pkcs11"
|
||||
CHRONYC = "/usr/bin/chronyc"
|
||||
CHRONYD = "/usr/sbin/chronyd"
|
||||
CHRONY_HELPER = "/usr/libexec/chrony-helper"
|
||||
PKIDESTROY = "/usr/sbin/pkidestroy"
|
||||
PKISPAWN = "/usr/sbin/pkispawn"
|
||||
PKI = "/usr/bin/pki"
|
||||
|
@ -162,7 +162,7 @@ class Backup(admintool.AdminTool):
|
||||
paths.IPA_CA_CRT,
|
||||
paths.IPA_DEFAULT_CONF,
|
||||
paths.DS_KEYTAB,
|
||||
paths.NTP_CONF,
|
||||
paths.CHRONY_CONF,
|
||||
paths.SMB_CONF,
|
||||
paths.SAMBA_KEYTAB,
|
||||
paths.DOGTAG_ADMIN_P12,
|
||||
|
@ -31,7 +31,7 @@ from ipalib.util import (
|
||||
validate_domain_name,
|
||||
no_matching_interface_for_ip_address_warning,
|
||||
)
|
||||
import ipaclient.install.ntpconf
|
||||
import ipaclient.install.timeconf
|
||||
from ipaserver.install import (
|
||||
adtrust, bindinstance, ca, dns, dsinstance,
|
||||
httpinstance, installutils, kra, krbinstance,
|
||||
@ -413,13 +413,13 @@ def install_check(installer):
|
||||
|
||||
if not options.no_ntp:
|
||||
try:
|
||||
ipaclient.install.ntpconf.check_timedate_services()
|
||||
except ipaclient.install.ntpconf.NTPConflictingService as e:
|
||||
print("WARNING: conflicting time&date synchronization service '%s'"
|
||||
" will be disabled" % e.conflicting_service)
|
||||
ipaclient.install.timeconf.check_timedate_services()
|
||||
except ipaclient.install.timeconf.NTPConflictingService as e:
|
||||
print("WARNING: conflicting time&date synchronization service '{}'"
|
||||
" will be disabled".format(e.conflicting_service))
|
||||
print("in favor of chronyd")
|
||||
print("")
|
||||
except ipaclient.install.ntpconf.NTPConfigurationError:
|
||||
except ipaclient.install.timeconf.NTPConfigurationError:
|
||||
pass
|
||||
|
||||
if not options.setup_dns and installer.interactive:
|
||||
@ -766,7 +766,8 @@ def install(installer):
|
||||
# chrony will be handled here in uninstall() method as well by invoking
|
||||
# the ipa-server-install --uninstall
|
||||
if not options.no_ntp:
|
||||
ipaclient.install.client.sync_time(options, fstore, sstore)
|
||||
ipaclient.install.client.sync_time(
|
||||
options, fstore, sstore, force=True)
|
||||
|
||||
if options.dirsrv_cert_files:
|
||||
ds = dsinstance.DsInstance(fstore=fstore,
|
||||
@ -1119,7 +1120,7 @@ def uninstall(installer):
|
||||
|
||||
sstore._load()
|
||||
|
||||
ipaclient.install.ntpconf.restore_forced_chronyd(sstore)
|
||||
ipaclient.install.timeconf.restore_forced_timeservices(sstore)
|
||||
|
||||
# Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
|
||||
sstore.restore_state("install", "group_exists")
|
||||
|
@ -23,7 +23,7 @@ from pkg_resources import parse_version
|
||||
import six
|
||||
|
||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||
import ipaclient.install.ntpconf
|
||||
import ipaclient.install.timeconf
|
||||
from ipalib.install import certstore, sysrestore
|
||||
from ipalib.install.kinit import kinit_keytab
|
||||
from ipapython import ipaldap, ipautil
|
||||
@ -581,12 +581,12 @@ def common_check(no_ntp):
|
||||
|
||||
if not no_ntp:
|
||||
try:
|
||||
ipaclient.install.ntpconf.check_timedate_services()
|
||||
except ipaclient.install.ntpconf.NTPConflictingService as e:
|
||||
ipaclient.install.timeconf.check_timedate_services()
|
||||
except ipaclient.install.timeconf.NTPConflictingService as e:
|
||||
print("WARNING: conflicting time&date synchronization service "
|
||||
"'{svc}' will\nbe disabled in favor of chronyd\n"
|
||||
.format(svc=e.conflicting_service))
|
||||
except ipaclient.install.ntpconf.NTPConfigurationError:
|
||||
except ipaclient.install.timeconf.NTPConfigurationError:
|
||||
pass
|
||||
|
||||
|
||||
@ -1391,7 +1391,7 @@ def install(installer):
|
||||
|
||||
if not promote and not options.no_ntp:
|
||||
# in DL1, chrony is already installed
|
||||
ipaclient.install.ntpconf.force_chrony(sstore)
|
||||
ipaclient.install.timeconf.force_chrony(sstore)
|
||||
|
||||
try:
|
||||
if promote:
|
||||
|
@ -20,6 +20,7 @@ from ipalib.install import certmonger, sysrestore
|
||||
import SSSDConfig
|
||||
import ipalib.util
|
||||
import ipalib.errors
|
||||
from ipaclient.install import timeconf
|
||||
from ipaclient.install.client import sssd_enable_service
|
||||
from ipaplatform import services
|
||||
from ipaplatform.tasks import tasks
|
||||
@ -1593,6 +1594,41 @@ def enable_certauth(krb):
|
||||
aug.close()
|
||||
|
||||
|
||||
def ntpd_cleanup(fqdn, fstore):
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
timeconf.restore_forced_timeservices(sstore, 'ntpd')
|
||||
if sstore.has_state('ntp'):
|
||||
instance = services.service('ntpd', api)
|
||||
sstore.restore_state(instance.service_name, 'enabled')
|
||||
sstore.restore_state(instance.service_name, 'running')
|
||||
sstore.restore_state(instance.service_name, 'step-tickers')
|
||||
try:
|
||||
instance.disable()
|
||||
instance.stop()
|
||||
except Exception as e:
|
||||
logger.info("Service ntpd was not disabled or stopped")
|
||||
|
||||
ntpd_files = [paths.NTP_CONF, paths.NTP_STEP_TICKERS, paths.SYSCONFIG_NTPD]
|
||||
for ntpd_file in ntpd_files:
|
||||
try:
|
||||
fstore.untrack_file(ntpd_file)
|
||||
os.remove(ntpd_file)
|
||||
except IOError:
|
||||
logger.warning(
|
||||
"No access to the %s, file could not be deleted.", ntpd_file)
|
||||
except ValueError as e:
|
||||
logger.warning("Error: %s", e)
|
||||
|
||||
connection = api.Backend.ldap2
|
||||
try:
|
||||
connection.delete_entry(DN(('cn', 'NTP'), ('cn', fqdn),
|
||||
api.env.container_masters))
|
||||
except ipalib.errors.NotFound:
|
||||
logger.warning("Warning: NTP service entry was not found in LDAP.")
|
||||
|
||||
sysupgrade.set_upgrade_state('ntpd', 'ntpd_cleaned', True)
|
||||
|
||||
|
||||
def upgrade_configuration():
|
||||
"""
|
||||
Execute configuration upgrade of the IPA services
|
||||
@ -1613,6 +1649,9 @@ def upgrade_configuration():
|
||||
if not ds_running:
|
||||
ds.start(ds_serverid)
|
||||
|
||||
if not sysupgrade.get_upgrade_state('ntpd', 'ntpd_cleaned'):
|
||||
ntpd_cleanup(fqdn, fstore)
|
||||
|
||||
check_certs()
|
||||
|
||||
auto_redirect = find_autoredirect(fqdn)
|
||||
|
Loading…
Reference in New Issue
Block a user