Drop the AGPL license in favor of a source-available license. See the blog post [1] for details. [1] https://www.scylladb.com/2024/12/18/why-were-moving-to-a-source-available-license/
120 lines
3.8 KiB
Python
Executable File
120 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright 2018-present ScyllaDB
|
|
#
|
|
|
|
#
|
|
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import re
|
|
import distro
|
|
import shutil
|
|
|
|
from scylla_util import *
|
|
from subprocess import run
|
|
from pathlib import Path
|
|
|
|
def get_chrony_unit():
|
|
try:
|
|
unit = systemd_unit('chronyd')
|
|
except:
|
|
unit = systemd_unit('chrony')
|
|
return unit
|
|
|
|
def get_chrony_conf():
|
|
p = Path('/etc/chrony/chrony.conf')
|
|
if p.exists():
|
|
return p
|
|
p = Path('/etc/chrony.conf')
|
|
if p.exists():
|
|
return p
|
|
raise FileNotFoundError('chrony.conf not found')
|
|
|
|
def get_ntp_unit():
|
|
try:
|
|
unit = systemd_unit('ntpd')
|
|
except:
|
|
unit = systemd_unit('ntp')
|
|
return unit
|
|
|
|
if __name__ == '__main__':
|
|
if os.getuid() > 0:
|
|
print('Requires root permission.')
|
|
sys.exit(1)
|
|
|
|
parser = argparse.ArgumentParser(description='Optimize NTP client setting for Scylla.')
|
|
parser.add_argument('--subdomain',
|
|
help='specify subdomain of pool.ntp.org (ex: centos, fedora or amazon)')
|
|
args = parser.parse_args()
|
|
|
|
target = None
|
|
if os.path.exists('/lib/systemd/systemd-timesyncd'):
|
|
if systemd_unit('systemd-timesyncd').is_active() == 'active':
|
|
print('ntp is already configured, skip setup')
|
|
sys.exit(0)
|
|
target = 'systemd-timesyncd'
|
|
if shutil.which('chronyd'):
|
|
if get_chrony_unit().is_active() == 'active':
|
|
print('ntp is already configured, skip setup')
|
|
sys.exit(0)
|
|
if not target:
|
|
target = 'chrony'
|
|
if shutil.which('ntpd'):
|
|
if get_ntp_unit().is_active() == 'active':
|
|
print('ntp is already configured, skip setup')
|
|
sys.exit(0)
|
|
if not target:
|
|
target = 'ntp'
|
|
if not target:
|
|
if is_redhat_variant():
|
|
target = 'chrony'
|
|
else:
|
|
target = 'systemd-timesyncd'
|
|
|
|
print(f'Use {target} to configure ntp')
|
|
if target == 'systemd-timesyncd':
|
|
if not os.path.exists('/lib/systemd/systemd-timesyncd'):
|
|
# On some distribution, systemd-timesyncd is part of systemd package,
|
|
# but we can ignore it since systemd must be installed by default.
|
|
pkg_install('systemd-timesyncd')
|
|
run('timedatectl set-ntp true', shell=True, check=True)
|
|
elif target == 'chrony':
|
|
if not shutil.which('chronyd'):
|
|
pkg_install('chrony')
|
|
confp = get_chrony_conf()
|
|
with confp.open() as f:
|
|
conf = f.read()
|
|
if args.subdomain:
|
|
conf2 = re.sub(r'pool\s+([0-9]+)\.(\S+)\.pool\.ntp\.org', 'pool \\1.{}.pool.ntp.org'.format(args.subdomain), conf, flags=re.MULTILINE)
|
|
with confp.open(confpath, 'w') as f:
|
|
f.write(conf2)
|
|
conf = conf2
|
|
chronyd = get_chrony_unit()
|
|
chronyd.enable()
|
|
chronyd.restart()
|
|
run('chronyc -a makestep', shell=True, check=True)
|
|
elif target == 'ntp':
|
|
if not shutil.which('ntpd'):
|
|
pkg_install('ntp')
|
|
if not shutil.which('ntpdate'):
|
|
pkg_install('ntpdate')
|
|
confp = Path('/etc/ntp.conf')
|
|
with confp.open() as f:
|
|
conf = f.read()
|
|
if args.subdomain:
|
|
conf2 = re.sub(r'(server|pool)\s+([0-9]+)\.(\S+)\.pool\.ntp\.org', '\\1 \\2.{}.pool.ntp.org'.format(args.subdomain), conf, flags=re.MULTILINE)
|
|
with confp.open(confpath, 'w') as f:
|
|
f.write(conf2)
|
|
conf = conf2
|
|
match = re.search(r'^(server|pool)\s+(\S*)(\s+\S+)?', conf, flags=re.MULTILINE)
|
|
server = match.group(2)
|
|
ntpd = get_ntpd_unit()
|
|
ntpd.stop()
|
|
run(f'ntpdate {server}', shell=True, check=True)
|
|
ntpd.enable()
|
|
ntpd.start()
|