import chrony-3.5-1.el8

This commit is contained in:
CentOS Sources 2019-11-05 16:27:18 -05:00 committed by Andrew Lukoshko
parent baacba79d5
commit f4debe48a5
9 changed files with 176 additions and 229 deletions

View File

@ -1,2 +1,2 @@
42fbb94450e50e15aac33aabc563e052ea111f0f SOURCES/chrony-3.3.tar.gz 79e9aeace143550300387a99f17bff04b45673f7 SOURCES/chrony-3.5.tar.gz
eb8c2fb0cf7f8b75132878563182090651986a01 SOURCES/clknetsim-5b4d14.tar.gz 84d41ec6da2317dab5e41d9b73ec028c78325700 SOURCES/clknetsim-3f5ef9.tar.gz

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/chrony-3.3.tar.gz SOURCES/chrony-3.5.tar.gz
SOURCES/clknetsim-5b4d14.tar.gz SOURCES/clknetsim-3f5ef9.tar.gz

View File

@ -1,34 +0,0 @@
commit 7c5bd948bb7e21fa0ee22f29e97748b2d0360319
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu May 17 14:16:58 2018 +0200
util: fall back to reading /dev/urandom when getrandom() blocks
With recent changes in the Linux kernel, the getrandom() system call may
block for a long time after boot on machines that don't have enough
entropy. It blocks the chronyd's initialization before it can detach
from the terminal and may cause a chronyd service to fail to start due
to a timeout.
At least for now, enable the GRND_NONBLOCK flag to make the system call
non-blocking and let the code fall back to reading /dev/urandom (which
never blocks) if the system call failed with EAGAIN or any other error.
This makes the start of chronyd non-deterministic with respect to files
that it needs to open and possibly also makes it slightly easier to
guess the transmit/receive timestamp in client requests until the
urandom source is fully initialized.
diff --git a/util.c b/util.c
index 4b3e455..76417d5 100644
--- a/util.c
+++ b/util.c
@@ -1224,7 +1224,7 @@ get_random_bytes_getrandom(char *buf, unsigned int len)
if (disabled)
break;
- if (getrandom(rand_buf, sizeof (rand_buf), 0) != sizeof (rand_buf)) {
+ if (getrandom(rand_buf, sizeof (rand_buf), GRND_NONBLOCK) != sizeof (rand_buf)) {
disabled = 1;
break;
}

View File

@ -1,85 +0,0 @@
commit 26e08abe71fe66703e06afae1168144dd1eecf3f
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Jun 7 16:43:59 2018 +0200
main: create directories before writing pidfile
This makes it possible to save pidfile in /var/run/chrony.
diff --git a/main.c b/main.c
index a2202e9..e538cc5 100644
--- a/main.c
+++ b/main.c
@@ -530,9 +530,6 @@ int main
/* Check whether another chronyd may already be running */
check_pidfile();
- /* Write our pidfile to prevent other chronyds running */
- write_pidfile();
-
if (!user)
user = CNF_GetUser();
@@ -543,6 +540,9 @@ int main
/* Create directories for sockets, log files, and dump files */
CNF_CreateDirs(pw->pw_uid, pw->pw_gid);
+ /* Write our pidfile to prevent other instances from running */
+ write_pidfile();
+
PRV_Initialise();
LCL_Initialise();
SCH_Initialise();
commit e50dc739d88feca6e0da034406034f3d3cf60ca4
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Jun 7 16:54:59 2018 +0200
configure: move default pidfile to /var/run/chrony
This allows chronyd to remove its pidfile on exit after dropping the
root privileges in order to prevent another chronyd instance from
failing to start, e.g. due to a wrong SELinux label from chronyd -q.
diff --git a/configure b/configure
index 25773de..c5de5ea 100755
--- a/configure
+++ b/configure
@@ -108,7 +108,7 @@ For better control, use the options below.
since 1970-01-01 [50*365 days ago]
--with-user=USER Specify default chronyd user [root]
--with-hwclockfile=PATH Specify default path to hwclock(8) adjtime file
- --with-pidfile=PATH Specify default pidfile [/var/run/chronyd.pid]
+ --with-pidfile=PATH Specify default pidfile [/var/run/chrony/chronyd.pid]
--with-rtcdevice=PATH Specify default path to RTC device [/dev/rtc]
--with-sendmail=PATH Path to sendmail binary [/usr/lib/sendmail]
--enable-debug Enable debugging support
@@ -229,7 +229,7 @@ feat_ntp_signd=0
ntp_era_split=""
default_user="root"
default_hwclockfile=""
-default_pidfile="/var/run/chronyd.pid"
+default_pidfile="/var/run/chrony/chronyd.pid"
default_rtcdevice="/dev/rtc"
mail_program="/usr/lib/sendmail"
commit 10150bfcab76141b3a9c33b95ad71904fe8ecca2
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Jun 7 17:43:57 2018 +0200
examples: update pidfile in chronyd.service
diff --git a/examples/chronyd.service b/examples/chronyd.service
index 4ffe3b1..1777413 100644
--- a/examples/chronyd.service
+++ b/examples/chronyd.service
@@ -7,7 +7,7 @@ ConditionCapability=CAP_SYS_TIME
[Service]
Type=forking
-PIDFile=/var/run/chronyd.pid
+PIDFile=/var/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
PrivateTmp=yes

View File

@ -1,8 +1,8 @@
diff -up chrony-3.1/examples/chronyd.service.service-helper chrony-3.1/examples/chronyd.service diff -up chrony-3.5/examples/chronyd.service.service-helper chrony-3.5/examples/chronyd.service
--- chrony-3.1/examples/chronyd.service.service-helper 2017-01-31 12:12:01.863772826 +0100 --- chrony-3.5/examples/chronyd.service.service-helper 2019-05-10 12:22:57.000000000 +0200
+++ chrony-3.1/examples/chronyd.service 2017-01-31 12:12:30.371860064 +0100 +++ chrony-3.5/examples/chronyd.service 2019-05-14 13:42:38.069516800 +0200
@@ -10,6 +10,7 @@ Type=forking @@ -10,6 +10,7 @@ Type=forking
PIDFile=/var/run/chrony/chronyd.pid PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS ExecStart=/usr/sbin/chronyd $OPTIONS
+ExecStartPost=/usr/libexec/chrony-helper update-daemon +ExecStartPost=/usr/libexec/chrony-helper update-daemon

View File

@ -3,18 +3,18 @@
SERVERFILE=$SAVEDIR/chrony.servers.$interface SERVERFILE=$SAVEDIR/chrony.servers.$interface
chrony_config() { chrony_config() {
rm -f $SERVERFILE rm -f "$SERVERFILE"
if [ "$PEERNTP" != "no" ]; then if [ "$PEERNTP" != "no" ]; then
for server in $new_ntp_servers; do for server in $new_ntp_servers; do
echo "$server ${NTPSERVERARGS:-iburst}" >> $SERVERFILE echo "$server ${NTPSERVERARGS:-iburst}" >> "$SERVERFILE"
done done
/usr/libexec/chrony-helper update-daemon || : /usr/libexec/chrony-helper update-daemon || :
fi fi
} }
chrony_restore() { chrony_restore() {
if [ -f $SERVERFILE ]; then if [ -f "$SERVERFILE" ]; then
rm -f $SERVERFILE rm -f "$SERVERFILE"
/usr/libexec/chrony-helper update-daemon || : /usr/libexec/chrony-helper update-daemon || :
fi fi
} }

View File

@ -12,8 +12,8 @@ helper_dir=/var/run/chrony-helper
added_servers_file=$helper_dir/added_servers added_servers_file=$helper_dir/added_servers
network_sysconfig_file=/etc/sysconfig/network network_sysconfig_file=/etc/sysconfig/network
dhclient_servers_files=/var/lib/dhclient/chrony.servers.* dhclient_servers_files="/var/lib/dhclient/chrony.servers.*"
dnssrv_servers_files=$helper_dir/dnssrv@* dnssrv_servers_files="$helper_dir/dnssrv@*"
dnssrv_timer_prefix=chrony-dnssrv@ dnssrv_timer_prefix=chrony-dnssrv@
. $network_sysconfig_file &> /dev/null . $network_sysconfig_file &> /dev/null
@ -50,27 +50,30 @@ update_daemon() {
all_servers=$( all_servers=$(
echo "$all_servers_with_args" | echo "$all_servers_with_args" |
while read server serverargs; do while read -r server serverargs; do
echo "$server" echo "$server"
done | sort -u) done | sort -u)
added_servers=$( ( added_servers=$( (
cat $added_servers_file 2> /dev/null cat $added_servers_file 2> /dev/null
echo "$all_servers_with_args" | echo "$all_servers_with_args" |
while read server serverargs; do while read -r server serverargs; do
[ -z "$server" ] && continue [ -z "$server" ] && continue
chrony_command "add server $server $serverargs" &> /dev/null && chrony_command "add server $server $serverargs" &> /dev/null &&
echo "$server" echo "$server"
done) | sort -u) done) | sort -u)
comm -23 <(echo -n "$added_servers") <(echo -n "$all_servers") | comm -23 <(echo -n "$added_servers") <(echo -n "$all_servers") |
while read server; do while read -r server; do
chrony_command "delete $server" &> /dev/null chrony_command "delete $server" &> /dev/null
done done
added_servers=$(comm -12 <(echo -n "$added_servers") <(echo -n "$all_servers")) added_servers=$(comm -12 <(echo -n "$added_servers") <(echo -n "$all_servers"))
[ -n "$added_servers" ] && echo "$added_servers" > $added_servers_file || if [ -n "$added_servers" ]; then
echo "$added_servers" > $added_servers_file
else
rm -f $added_servers_file rm -f $added_servers_file
fi
} }
get_dnssrv_servers() { get_dnssrv_servers() {
@ -81,10 +84,9 @@ get_dnssrv_servers() {
return 1 return 1
fi fi
output=$(dig "$name" srv +short +ndots=2 +search 2> /dev/null) output=$(dig "$name" srv +short +ndots=2 +search 2> /dev/null) || return 0
[ $? -ne 0 ] && return 0
echo "$output" | while read prio weight port target; do echo "$output" | while read -r _ _ port target; do
server=${target%.} server=${target%.}
[ -z "$server" ] && continue [ -z "$server" ] && continue
echo "$server port $port ${NTPSERVERARGS:-iburst}" echo "$server port $port ${NTPSERVERARGS:-iburst}"
@ -112,13 +114,19 @@ update_dnssrv_servers() {
check_dnssrv_name "$name" || return 1 check_dnssrv_name "$name" || return 1
servers=$(get_dnssrv_servers "$name") servers=$(get_dnssrv_servers "$name")
[ -n "$servers" ] && echo "$servers" > "$srv_file" || rm -f "$srv_file" if [ -n "$servers" ]; then
echo "$servers" > "$srv_file"
else
rm -f "$srv_file"
fi
} }
set_dnssrv_timer() { set_dnssrv_timer() {
local state=$1 name=$2 local state=$1 name=$2
local srv_file=$helper_dir/dnssrv@$name servers local srv_file=$helper_dir/dnssrv@$name servers
local timer=$dnssrv_timer_prefix$(systemd-escape "$name").timer local timer
timer=$dnssrv_timer_prefix$(systemd-escape "$name").timer || return 1
check_dnssrv_name "$name" || return 1 check_dnssrv_name "$name" || return 1
@ -155,8 +163,10 @@ is_source_line() {
} }
list_static_sources() { list_static_sources() {
while read line; do while read -r line; do
is_source_line "$line" && echo "$line" || : if is_source_line "$line"; then
echo "$line"
fi
done < $chrony_conf done < $chrony_conf
} }
@ -165,11 +175,11 @@ set_static_sources() {
new_config=$( new_config=$(
sources=$( sources=$(
while read line; do while read -r line; do
is_source_line "$line" && echo "$line" is_source_line "$line" && echo "$line"
done) done)
while read line; do while read -r line; do
if ! is_source_line "$line"; then if ! is_source_line "$line"; then
echo "$line" echo "$line"
continue continue
@ -178,9 +188,12 @@ set_static_sources() {
tmp_sources=$( tmp_sources=$(
local removed=0 local removed=0
echo "$sources" | while read line2; do echo "$sources" | while read -r line2; do
[ "$removed" -ne 0 -o "$line" != "$line2" ] && \ if [ "$removed" -ne 0 ] || [ "$line" != "$line2" ]; then
echo "$line2" || removed=1 echo "$line2"
else
removed=1
fi
done) done)
[ "$sources" == "$tmp_sources" ] && continue [ "$sources" == "$tmp_sources" ] && continue

View File

@ -2,24 +2,31 @@
# #
# Convert ntp configuration to chrony # Convert ntp configuration to chrony
# #
# Copyright (C) 2018 Miroslav Lichvar <mlichvar@redhat.com> # Copyright (C) 2018-2019 Miroslav Lichvar <mlichvar@redhat.com>
# #
# This program is free software; you can redistribute it and/or modify # Permission is hereby granted, free of charge, to any person obtaining
# it under the terms of the GNU General Public License as published by # a copy of this software and associated documentation files (the
# the Free Software Foundation; either version 2 of the License, or # "Software"), to deal in the Software without restriction, including
# (at your option) any later version. # without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# #
# This program is distributed in the hope that it will be useful, # The above copyright notice and this permission notice shall be included
# but WITHOUT ANY WARRANTY; without even the implied warranty of # in all copies or substantial portions of the Software.
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# along with this program. If not, see <http://www.gnu.org/licenses/>. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import argparse import argparse
import ipaddress import ipaddress
import logging
import os import os
import os.path import os.path
import re import re
@ -33,12 +40,13 @@ if sys.version_info[0] < 3:
sys.setdefaultencoding("utf-8") sys.setdefaultencoding("utf-8")
class NtpConfiguration(object): class NtpConfiguration(object):
def __init__(self, root_dir, ntp_conf, step_tickers, verbose): def __init__(self, root_dir, ntp_conf, step_tickers):
self.root_dir = root_dir if root_dir != "/" else "" self.root_dir = root_dir if root_dir != "/" else ""
self.ntp_conf_path = ntp_conf self.ntp_conf_path = ntp_conf
self.step_tickers_path = step_tickers self.step_tickers_path = step_tickers
self.verbose = verbose
# Read and write files using an 8-bit transparent encoding
self.file_encoding = "latin-1"
self.enabled_services = set() self.enabled_services = set()
self.step_tickers = [] self.step_tickers = []
self.time_sources = [] self.time_sources = []
@ -54,7 +62,7 @@ class NtpConfiguration(object):
self.driftfile = "" self.driftfile = ""
self.statistics = [] self.statistics = []
self.leapfile = "" self.leapfile = ""
self.tos_options = [] self.tos_options = {}
self.ignored_directives = set() self.ignored_directives = set()
self.ignored_lines = [] self.ignored_lines = []
@ -67,21 +75,19 @@ class NtpConfiguration(object):
if os.path.islink("{}/etc/systemd/system/multi-user.target.wants/{}.service" if os.path.islink("{}/etc/systemd/system/multi-user.target.wants/{}.service"
.format(self.root_dir, service)): .format(self.root_dir, service)):
self.enabled_services.add(service) self.enabled_services.add(service)
if self.verbose > 0: logging.info("Enabled services found in /etc/systemd/system: %s",
print("Enabled services found in /etc/systemd/system: " +
" ".join(self.enabled_services)) " ".join(self.enabled_services))
def parse_step_tickers(self): def parse_step_tickers(self):
if not self.step_tickers_path: if not self.step_tickers_path:
return return
path = self.root_dir + self.step_tickers_path path = os.path.join(self.root_dir, self.step_tickers_path)
if not os.path.isfile(path): if not os.path.isfile(path):
if self.verbose > 0: logging.info("Missing %s", path)
print("Missing " + path)
return return
with open(path, encoding="latin-1") as f: with open(path, encoding=self.file_encoding) as f:
for line in f: for line in f:
line = line[:line.find('#')] line = line[:line.find('#')]
@ -94,11 +100,10 @@ class NtpConfiguration(object):
def parse_ntp_conf(self, path=None): def parse_ntp_conf(self, path=None):
if path is None: if path is None:
path = self.root_dir + self.ntp_conf_path path = os.path.join(self.root_dir, self.ntp_conf_path)
with open(path, encoding="latin-1") as f: with open(path, encoding=self.file_encoding) as f:
if self.verbose > 0: logging.info("Reading %s", path)
print("Reading " + path)
for line in f: for line in f:
line = line[:line.find('#')] line = line[:line.find('#')]
@ -146,11 +151,11 @@ class NtpConfiguration(object):
return True return True
def parse_source(self, type, words): def parse_source(self, source_type, words):
ipv4_only = False ipv4_only = False
ipv6_only = False ipv6_only = False
source = { source = {
"type": type, "type": source_type,
"options": [] "options": []
} }
@ -198,8 +203,12 @@ class NtpConfiguration(object):
options = {} options = {}
while words: while words:
if len(words) >= 2: if len(words) >= 2 and words[0] in ["stratum"]:
options[words[0]] = words[1] if not words[1].isdigit():
return False
options[words[0]] = int(words[1])
words = words[2:]
elif len(words) >= 2:
words = words[2:] words = words[2:]
else: else:
return False return False
@ -262,20 +271,28 @@ class NtpConfiguration(object):
return True return True
def parse_tos(self, words): def parse_tos(self, words):
options = [] options = {}
while words: while words:
if len(words) >= 2 and words[0] in ["minsane", "maxdist", "orphan"]: if len(words) >= 2 and words[0] in ["minsane", "orphan"]:
options.append((words[0], words[1])) if not words[1].isdigit():
return False
options[words[0]] = int(words[1])
words = words[2:]
elif len(words) >= 2 and words[0] in ["maxdist"]:
# Check if it is a float value
if not words[1].replace('.', '', 1).isdigit():
return False
options[words[0]] = float(words[1])
words = words[2:] words = words[2:]
else: else:
return False return False
self.tos_options.extend(options) self.tos_options.update(options)
return True return True
def parse_includefile(self, words): def parse_includefile(self, words):
path = self.root_dir + words[0] path = os.path.join(self.root_dir, words[0])
if not os.path.isfile(path): if not os.path.isfile(path):
return False return False
@ -284,15 +301,13 @@ class NtpConfiguration(object):
def parse_keys(self, words): def parse_keys(self, words):
keyfile = words[0] keyfile = words[0]
path = self.root_dir + keyfile path = os.path.join(self.root_dir, keyfile)
if not os.path.isfile(path): if not os.path.isfile(path):
if self.verbose > 0: logging.info("Missing %s", path)
print("Missing file " + path)
return False return False
with open(path, encoding="latin-1") as f: with open(path, encoding=self.file_encoding) as f:
if self.verbose > 0: logging.info("Reading %s", path)
print("Reading " + path)
keys = [] keys = []
for line in f: for line in f:
words = line.split() words = line.split()
@ -322,20 +337,57 @@ class NtpConfiguration(object):
def write_chrony_configuration(self, chrony_conf_path, chrony_keys_path, def write_chrony_configuration(self, chrony_conf_path, chrony_keys_path,
dry_run=False, backup=False): dry_run=False, backup=False):
chrony_conf = self.get_chrony_conf(chrony_keys_path) chrony_conf = self.get_chrony_conf(chrony_keys_path)
if self.verbose > 1: logging.debug("Generated %s:\n%s", chrony_conf_path, chrony_conf)
print("Generated {}:\n{}".format(chrony_conf_path, chrony_conf))
if not dry_run: if not dry_run:
self.write_file(chrony_conf_path, 0o644, chrony_conf, backup) self.write_file(chrony_conf_path, 0o644, chrony_conf, backup)
chrony_keys = self.get_chrony_keys() chrony_keys = self.get_chrony_keys()
if chrony_keys: if chrony_keys:
if self.verbose > 1: logging.debug("Generated %s:\n%s", chrony_keys_path, chrony_keys)
print("Generated {}:\n{}".format(chrony_keys_path, chrony_keys))
if not dry_run: if not dry_run:
self.write_file(chrony_keys_path, 0o640, chrony_keys, backup) self.write_file(chrony_keys_path, 0o640, chrony_keys, backup)
def get_processed_time_sources(self):
# Convert {0,1,2,3}.*pool.ntp.org servers to 2.*pool.ntp.org pools
# Make shallow copies of all sources (only type will be modified)
time_sources = [s.copy() for s in self.time_sources]
pools = {}
for source in time_sources:
if source["type"] != "server":
continue
m = re.match("^([0123])(\\.\\w+)?\\.pool\\.ntp\\.org$", source["address"])
if m is None:
continue
number = m.group(1)
zone = m.group(2)
if zone not in pools:
pools[zone] = []
pools[zone].append((int(number), source))
remove_servers = set()
for zone, pool in pools.items():
# sort and skip all pools not in [0, 3] range
pool.sort()
if [number for number, source in pool] != [0, 1, 2, 3]:
# only exact group of 4 servers can be converted, nothing to do here
continue
# verify that parameters are the same for all servers in the pool
if not all([p[1]["options"] == pool[0][1]["options"] for p in pool]):
break
remove_servers.update([pool[i][1]["address"] for i in [0, 1, 3]])
pool[2][1]["type"] = "pool"
processed_sources = []
for source in time_sources:
if source["type"] == "server" and source["address"] in remove_servers:
continue
processed_sources.append(source)
return processed_sources
def get_chrony_conf_sources(self): def get_chrony_conf_sources(self):
conf = "" conf = ""
@ -346,11 +398,12 @@ class NtpConfiguration(object):
conf += "# Specify time sources.\n" conf += "# Specify time sources.\n"
for source in self.time_sources: for source in self.get_processed_time_sources():
address = source["address"] address = source["address"]
if address.startswith("127.127."): if address.startswith("127.127."):
if address.startswith("127.127.1."): if address.startswith("127.127.1."):
continue continue
# No other refclocks are expected from the parser
assert False assert False
else: else:
conf += "{} {}".format(source["type"], address) conf += "{} {}".format(source["type"], address)
@ -363,6 +416,7 @@ class NtpConfiguration(object):
elif option[0] == "true": elif option[0] == "true":
conf += " trust" conf += " trust"
else: else:
# No other options are expected from the parser
assert False assert False
conf += "\n" conf += "\n"
conf += "\n" conf += "\n"
@ -424,19 +478,16 @@ class NtpConfiguration(object):
address = source["address"] address = source["address"]
if address.startswith("127.127.1."): if address.startswith("127.127.1."):
if address in self.fudges and "stratum" in self.fudges[address]: if address in self.fudges and "stratum" in self.fudges[address]:
local_stratum = int(self.fudges[address]["stratum"]) local_stratum = self.fudges[address]["stratum"]
else: else:
local_stratum = 5 local_stratum = 5
for tos in self.tos_options: if "maxdist" in self.tos_options:
if tos[0] == "maxdist": maxdistance = self.tos_options["maxdist"]
maxdistance = float(tos[1]) if "minsane" in self.tos_options:
elif tos[0] == "minsane": minsources = self.tos_options["minsane"]
minsources = int(tos[1]) if "orphan" in self.tos_options:
elif tos[0] == "orphan": orphan_stratum = self.tos_options["orphan"]
orphan_stratum = int(tos[1])
else:
assert False
if "clockstats" in self.statistics: if "clockstats" in self.statistics:
logs.append("refclocks"); logs.append("refclocks");
@ -536,19 +587,19 @@ class NtpConfiguration(object):
keys += "\n" keys += "\n"
for key in self.keys: for key in self.keys:
id = key[0] key_id = key[0]
type = key[1] key_type = key[1]
password = key[2] password = key[2]
if type in ["m", "M"]: if key_type in ["m", "M"]:
type = "MD5" key_type = "MD5"
elif type not in ["MD5", "SHA1", "SHA256", "SHA384", "SHA512"]: elif key_type not in ["MD5", "SHA1", "SHA256", "SHA384", "SHA512"]:
continue continue
prefix = "ASCII" if len(password) <= 20 else "HEX" prefix = "ASCII" if len(password) <= 20 else "HEX"
for first, last in self.trusted_keys: for first, last in self.trusted_keys:
if first <= id <= last: if first <= key_id <= last:
trusted = True trusted = True
break break
else: else:
@ -558,7 +609,7 @@ class NtpConfiguration(object):
if not trusted: if not trusted:
keys += "#" keys += "#"
keys += "{} {} {}:{}\n".format(id, type, prefix, password) keys += "{} {} {}:{}\n".format(key_id, key_type, prefix, password)
return keys return keys
@ -568,9 +619,8 @@ class NtpConfiguration(object):
os.rename(path, path + ".old") os.rename(path, path + ".old")
with open(os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, mode), "w", with open(os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, mode), "w",
encoding="latin-1") as f: encoding=self.file_encoding) as f:
if self.verbose > 0: logging.info("Writing %s", path)
print("Writing " + path)
f.write(u"" + content) f.write(u"" + content)
# Fix SELinux context if restorecon is installed # Fix SELinux context if restorecon is installed
@ -601,8 +651,11 @@ def main():
args = parser.parse_args() args = parser.parse_args()
logging.basicConfig(format="%(message)s",
level=[logging.ERROR, logging.INFO, logging.DEBUG][min(args.verbose, 2)])
for root in args.roots: for root in args.roots:
conf = NtpConfiguration(root, args.ntp_conf, args.step_tickers, args.verbose) conf = NtpConfiguration(root, args.ntp_conf, args.step_tickers)
if args.ignored_lines: if args.ignored_lines:
for line in conf.ignored_lines: for line in conf.ignored_lines:

View File

@ -1,11 +1,11 @@
%global _hardened_build 1 %global _hardened_build 1
%global clknetsim_ver 5b4d14 %global clknetsim_ver 3f5ef9
%global ntp2chrony_ver 982426 %global ntp2chrony_ver 2a0512
%bcond_without debug %bcond_without debug
Name: chrony Name: chrony
Version: 3.3 Version: 3.5
Release: 3%{?dist} Release: 1%{?dist}
Summary: An NTP client/server Summary: An NTP client/server
Group: System Environment/Daemons Group: System Environment/Daemons
@ -19,21 +19,18 @@ Source4: chrony-dnssrv@.timer
# simulator for test suite # simulator for test suite
Source10: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz Source10: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
# script for converting ntp configuration to chrony # script for converting ntp configuration to chrony
Source11: https://github.com/mlichvar/ntp2chrony/raw/%{ntp2chrony_ver}/ntp2chrony.py Source11: https://github.com/mlichvar/ntp2chrony/raw/%{ntp2chrony_ver}/ntp2chrony/ntp2chrony.py
%{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz} %{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz}
# move pidfile to /var/run/chrony to allow chronyd to remove it on exit
Patch1: chrony-pidfile.patch
# add NTP servers from DHCP when starting service # add NTP servers from DHCP when starting service
Patch2: chrony-service-helper.patch Patch2: chrony-service-helper.patch
# avoid blocking in getrandom system call
Patch3: chrony-getrandom.patch
BuildRequires: libcap-devel libedit-devel nettle-devel pps-tools-devel BuildRequires: libcap-devel libedit-devel nettle-devel pps-tools-devel
%ifarch %{ix86} x86_64 %{arm} aarch64 mipsel mips64el ppc64 ppc64le s390 s390x %ifarch %{ix86} x86_64 %{arm} aarch64 mipsel mips64el ppc64 ppc64le s390 s390x
BuildRequires: libseccomp-devel BuildRequires: libseccomp-devel
%endif %endif
BuildRequires: gcc bison systemd BuildRequires: gcc bison systemd
BuildRequires: kernel-headers > 4.18.0-87
Requires(pre): shadow-utils Requires(pre): shadow-utils
%{?systemd_requires} %{?systemd_requires}
@ -58,9 +55,7 @@ service to other computers in the network.
%prep %prep
%setup -q -n %{name}-%{version}%{?prerelease} -a 10 %setup -q -n %{name}-%{version}%{?prerelease} -a 10
%{?gitpatch:%patch0 -p1} %{?gitpatch:%patch0 -p1}
%patch1 -p1 -b .pidfile
%patch2 -p1 -b .service-helper %patch2 -p1 -b .service-helper
%patch3 -p1 -b .getrandom
%{?gitpatch: echo %{version}-%{gitpatch} > version.txt} %{?gitpatch: echo %{version}-%{gitpatch} > version.txt}
@ -68,10 +63,10 @@ service to other computers in the network.
md5sum -c <<-EOF | (! grep -v 'OK$') md5sum -c <<-EOF | (! grep -v 'OK$')
47ad7eccc410b981d2f2101cf5682616 examples/chrony-wait.service 47ad7eccc410b981d2f2101cf5682616 examples/chrony-wait.service
e473a9fab7fe200cacce3dca8b66290b examples/chrony.conf.example2 e473a9fab7fe200cacce3dca8b66290b examples/chrony.conf.example2
ba6bb05c50e03f6b5ab54a2b7914800d examples/chrony.keys.example 96999221eeef476bd49fe97b97503126 examples/chrony.keys.example
6a3178c4670de7de393d9365e2793740 examples/chrony.logrotate 6a3178c4670de7de393d9365e2793740 examples/chrony.logrotate
63e0781f84e89ba6029d93ef0722c4ce examples/chrony.nm-dispatcher 8748a663f0b1943ea491858f414a6b26 examples/chrony.nm-dispatcher
921b354e94f5e3db124cb50d11cd560f examples/chronyd.service b23bcc3bd78e195ca2849459e459f3ed examples/chronyd.service
EOF EOF
# don't allow packaging without vendor zone # don't allow packaging without vendor zone
@ -203,6 +198,11 @@ fi
%dir %attr(-,chrony,chrony) %{_localstatedir}/log/chrony %dir %attr(-,chrony,chrony) %{_localstatedir}/log/chrony
%changelog %changelog
* Tue May 21 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-1
- update to 3.5 (#1685469 #1677218)
- fix shellcheck warnings in helper scripts (#1711948)
- update ntp2chrony script
* Mon Aug 13 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-3 * Mon Aug 13 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-3
- fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2 - fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2
(#1614800) (#1614800)