import chrony-3.5-1.el8
This commit is contained in:
		
						commit
						ceebba24d5
					
				
							
								
								
									
										2
									
								
								.chrony.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.chrony.metadata
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| 79e9aeace143550300387a99f17bff04b45673f7 SOURCES/chrony-3.5.tar.gz | ||||
| 84d41ec6da2317dab5e41d9b73ec028c78325700 SOURCES/clknetsim-3f5ef9.tar.gz | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| SOURCES/chrony-3.5.tar.gz | ||||
| SOURCES/clknetsim-3f5ef9.tar.gz | ||||
							
								
								
									
										8
									
								
								SOURCES/chrony-dnssrv@.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								SOURCES/chrony-dnssrv@.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| [Unit] | ||||
| Description=DNS SRV lookup of %I for chrony | ||||
| After=chronyd.service network-online.target | ||||
| Wants=network-online.target | ||||
| 
 | ||||
| [Service] | ||||
| Type=oneshot | ||||
| ExecStart=/usr/libexec/chrony-helper update-dnssrv-servers %I | ||||
							
								
								
									
										9
									
								
								SOURCES/chrony-dnssrv@.timer
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								SOURCES/chrony-dnssrv@.timer
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| [Unit] | ||||
| Description=Periodic DNS SRV lookup of %I for chrony | ||||
| 
 | ||||
| [Timer] | ||||
| OnActiveSec=0 | ||||
| OnUnitInactiveSec=1h | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=timers.target | ||||
							
								
								
									
										11
									
								
								SOURCES/chrony-service-helper.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								SOURCES/chrony-service-helper.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| diff -up chrony-3.5/examples/chronyd.service.service-helper chrony-3.5/examples/chronyd.service
 | ||||
| --- chrony-3.5/examples/chronyd.service.service-helper	2019-05-10 12:22:57.000000000 +0200
 | ||||
| +++ chrony-3.5/examples/chronyd.service	2019-05-14 13:42:38.069516800 +0200
 | ||||
| @@ -10,6 +10,7 @@ Type=forking
 | ||||
|  PIDFile=/run/chrony/chronyd.pid | ||||
|  EnvironmentFile=-/etc/sysconfig/chronyd | ||||
|  ExecStart=/usr/sbin/chronyd $OPTIONS | ||||
| +ExecStartPost=/usr/libexec/chrony-helper update-daemon
 | ||||
|  PrivateTmp=yes | ||||
|  ProtectHome=yes | ||||
|  ProtectSystem=full | ||||
							
								
								
									
										20
									
								
								SOURCES/chrony.dhclient
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								SOURCES/chrony.dhclient
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| SERVERFILE=$SAVEDIR/chrony.servers.$interface | ||||
| 
 | ||||
| chrony_config() { | ||||
| 	rm -f "$SERVERFILE" | ||||
| 	if [ "$PEERNTP" != "no" ]; then | ||||
| 		for server in $new_ntp_servers; do | ||||
| 			echo "$server ${NTPSERVERARGS:-iburst}" >> "$SERVERFILE" | ||||
| 		done | ||||
| 		/usr/libexec/chrony-helper update-daemon || : | ||||
| 	fi | ||||
| } | ||||
| 
 | ||||
| chrony_restore() { | ||||
| 	if [ -f "$SERVERFILE" ]; then | ||||
| 		rm -f "$SERVERFILE" | ||||
| 		/usr/libexec/chrony-helper update-daemon || : | ||||
| 	fi | ||||
| } | ||||
							
								
								
									
										265
									
								
								SOURCES/chrony.helper
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								SOURCES/chrony.helper
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,265 @@ | ||||
| #!/bin/bash | ||||
| # This script configures running chronyd to use NTP servers obtained from | ||||
| # DHCP and _ntp._udp DNS SRV records. Files with servers from DHCP are managed | ||||
| # externally (e.g. by a dhclient script). Files with servers from DNS SRV | ||||
| # records are updated here using the dig utility. The script can also list | ||||
| # and set static sources in the chronyd configuration file. | ||||
| 
 | ||||
| chronyc=/usr/bin/chronyc | ||||
| chrony_conf=/etc/chrony.conf | ||||
| chrony_service=chronyd.service | ||||
| helper_dir=/var/run/chrony-helper | ||||
| added_servers_file=$helper_dir/added_servers | ||||
| 
 | ||||
| network_sysconfig_file=/etc/sysconfig/network | ||||
| dhclient_servers_files="/var/lib/dhclient/chrony.servers.*" | ||||
| dnssrv_servers_files="$helper_dir/dnssrv@*" | ||||
| dnssrv_timer_prefix=chrony-dnssrv@ | ||||
| 
 | ||||
| . $network_sysconfig_file &> /dev/null | ||||
| 
 | ||||
| chrony_command() { | ||||
|     $chronyc -a -n -m "$1" | ||||
| } | ||||
| 
 | ||||
| is_running() { | ||||
|     chrony_command "tracking" &> /dev/null | ||||
| } | ||||
| 
 | ||||
| get_servers_files() { | ||||
|     [ "$PEERNTP" != "no" ] && echo "$dhclient_servers_files" | ||||
|     echo "$dnssrv_servers_files" | ||||
| } | ||||
| 
 | ||||
| is_update_needed() { | ||||
|     for file in $(get_servers_files) $added_servers_file; do | ||||
|         [ -e "$file" ] && return 0 | ||||
|     done | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| update_daemon() { | ||||
|     local all_servers_with_args all_servers added_servers | ||||
| 
 | ||||
|     if ! is_running; then | ||||
|         rm -f $added_servers_file | ||||
|         return 0 | ||||
|     fi | ||||
| 
 | ||||
|     all_servers_with_args=$(cat $(get_servers_files) 2> /dev/null) | ||||
| 
 | ||||
|     all_servers=$( | ||||
|         echo "$all_servers_with_args" | | ||||
|             while read -r server serverargs; do | ||||
|                 echo "$server" | ||||
|             done | sort -u) | ||||
|     added_servers=$( ( | ||||
|         cat $added_servers_file 2> /dev/null | ||||
|         echo "$all_servers_with_args" | | ||||
|             while read -r server serverargs; do | ||||
|                 [ -z "$server" ] && continue | ||||
|                 chrony_command "add server $server $serverargs" &> /dev/null && | ||||
|                     echo "$server" | ||||
|             done) | sort -u) | ||||
| 
 | ||||
|     comm -23 <(echo -n "$added_servers") <(echo -n "$all_servers") | | ||||
|         while read -r server; do | ||||
|             chrony_command "delete $server" &> /dev/null | ||||
|         done | ||||
| 
 | ||||
|     added_servers=$(comm -12 <(echo -n "$added_servers") <(echo -n "$all_servers")) | ||||
| 
 | ||||
|     if [ -n "$added_servers" ]; then | ||||
|         echo "$added_servers" > $added_servers_file | ||||
|     else | ||||
|         rm -f $added_servers_file | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| get_dnssrv_servers() { | ||||
|     local name=$1 output | ||||
| 
 | ||||
|     if ! command -v dig &> /dev/null; then | ||||
|         echo "Missing dig (DNS lookup utility)" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     output=$(dig "$name" srv +short +ndots=2 +search 2> /dev/null) || return 0 | ||||
| 
 | ||||
|     echo "$output" | while read -r _ _ port target; do | ||||
|         server=${target%.} | ||||
|         [ -z "$server" ] && continue | ||||
|         echo "$server port $port ${NTPSERVERARGS:-iburst}" | ||||
|     done | ||||
| } | ||||
| 
 | ||||
| check_dnssrv_name() { | ||||
|     local name=$1 | ||||
| 
 | ||||
|     if [ -z "$name" ]; then | ||||
|         echo "No DNS SRV name specified" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     if [ "${name:0:9}" != _ntp._udp ]; then | ||||
|         echo "DNS SRV name $name doesn't start with _ntp._udp" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| update_dnssrv_servers() { | ||||
|     local name=$1 | ||||
|     local srv_file=$helper_dir/dnssrv@$name servers | ||||
| 
 | ||||
|     check_dnssrv_name "$name" || return 1 | ||||
| 
 | ||||
|     servers=$(get_dnssrv_servers "$name") | ||||
|     if [ -n "$servers" ]; then | ||||
|         echo "$servers" > "$srv_file" | ||||
|     else | ||||
|         rm -f "$srv_file" | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| set_dnssrv_timer() { | ||||
|     local state=$1 name=$2 | ||||
|     local srv_file=$helper_dir/dnssrv@$name servers | ||||
|     local timer | ||||
| 
 | ||||
|     timer=$dnssrv_timer_prefix$(systemd-escape "$name").timer || return 1 | ||||
| 
 | ||||
|     check_dnssrv_name "$name" || return 1 | ||||
| 
 | ||||
|     if [ "$state" = enable ]; then | ||||
|         systemctl enable "$timer" | ||||
|         systemctl start "$timer" | ||||
|     elif [ "$state" = disable ]; then | ||||
|         systemctl stop "$timer" | ||||
|         systemctl disable "$timer" | ||||
|         rm -f "$srv_file" | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| list_dnssrv_timers() { | ||||
|     systemctl --all --full -t timer list-units | grep "^$dnssrv_timer_prefix" | \ | ||||
|             sed "s|^$dnssrv_timer_prefix\(.*\)\.timer.*|\1|" | | ||||
|         while read -r name; do | ||||
|             systemd-escape --unescape "$name" | ||||
|         done | ||||
| } | ||||
| 
 | ||||
| prepare_helper_dir() { | ||||
|     mkdir -p $helper_dir | ||||
|     exec 100> $helper_dir/lock | ||||
|     if ! flock -w 20 100; then | ||||
|         echo "Failed to lock $helper_dir" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| is_source_line() { | ||||
|     local pattern="^[ \t]*(server|pool|peer|refclock)[ \t]+[^ \t]+" | ||||
|     [[ "$1" =~ $pattern ]] | ||||
| } | ||||
| 
 | ||||
| list_static_sources() { | ||||
|     while read -r line; do | ||||
|         if is_source_line "$line"; then | ||||
|             echo "$line" | ||||
|         fi | ||||
|     done < $chrony_conf | ||||
| } | ||||
| 
 | ||||
| set_static_sources() { | ||||
|     local new_config tmp_conf | ||||
| 
 | ||||
|     new_config=$( | ||||
|         sources=$( | ||||
|             while read -r line; do | ||||
|                 is_source_line "$line" && echo "$line" | ||||
|             done) | ||||
| 
 | ||||
|         while read -r line; do | ||||
|             if ! is_source_line "$line"; then | ||||
|                 echo "$line" | ||||
|                 continue | ||||
|             fi | ||||
| 
 | ||||
|             tmp_sources=$( | ||||
|                 local removed=0 | ||||
| 
 | ||||
|                 echo "$sources" | while read -r line2; do | ||||
|                     if [ "$removed" -ne 0 ] || [ "$line" != "$line2" ]; then | ||||
|                         echo "$line2" | ||||
|                     else | ||||
|                         removed=1 | ||||
|                     fi | ||||
|                 done) | ||||
| 
 | ||||
|             [ "$sources" == "$tmp_sources" ] && continue | ||||
|             sources=$tmp_sources | ||||
|             echo "$line" | ||||
|         done < $chrony_conf | ||||
| 
 | ||||
|         echo "$sources" | ||||
|     ) | ||||
| 
 | ||||
|     tmp_conf=${chrony_conf}.tmp | ||||
| 
 | ||||
|     cp -a $chrony_conf $tmp_conf && | ||||
|         echo "$new_config" > $tmp_conf && | ||||
|         mv $tmp_conf $chrony_conf || return 1 | ||||
| 
 | ||||
|     systemctl try-restart $chrony_service | ||||
| } | ||||
| 
 | ||||
| print_help() { | ||||
|     echo "Usage: $0 COMMAND" | ||||
|     echo | ||||
|     echo "Commands:" | ||||
|     echo "	update-daemon" | ||||
|     echo "	update-dnssrv-servers NAME" | ||||
|     echo "	enable-dnssrv NAME" | ||||
|     echo "	disable-dnssrv NAME" | ||||
|     echo "	list-dnssrv" | ||||
|     echo "	list-static-sources" | ||||
|     echo "	set-static-sources < sources.list" | ||||
|     echo "	is-running" | ||||
|     echo "	command CHRONYC-COMMAND" | ||||
| } | ||||
| 
 | ||||
| case "$1" in | ||||
|     update-daemon|add-dhclient-servers|remove-dhclient-servers) | ||||
|         is_update_needed || exit 0 | ||||
|         prepare_helper_dir && update_daemon | ||||
|         ;; | ||||
|     update-dnssrv-servers) | ||||
|         prepare_helper_dir && update_dnssrv_servers "$2" && update_daemon | ||||
|         ;; | ||||
|     enable-dnssrv) | ||||
|         set_dnssrv_timer enable "$2" | ||||
|         ;; | ||||
|     disable-dnssrv) | ||||
|         set_dnssrv_timer disable "$2" && prepare_helper_dir && update_daemon | ||||
|         ;; | ||||
|     list-dnssrv) | ||||
|         list_dnssrv_timers | ||||
|         ;; | ||||
|     list-static-sources) | ||||
|         list_static_sources | ||||
|         ;; | ||||
|     set-static-sources) | ||||
|         set_static_sources | ||||
|         ;; | ||||
|     is-running) | ||||
|         is_running | ||||
|         ;; | ||||
|     command|forced-command) | ||||
|         chrony_command "$2" | ||||
|         ;; | ||||
|     *) | ||||
|         print_help | ||||
|         exit 2 | ||||
| esac | ||||
| 
 | ||||
| exit $? | ||||
							
								
								
									
										671
									
								
								SOURCES/ntp2chrony.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										671
									
								
								SOURCES/ntp2chrony.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,671 @@ | ||||
| #!/usr/bin/python | ||||
| # | ||||
| # Convert ntp configuration to chrony | ||||
| # | ||||
| # Copyright (C) 2018-2019  Miroslav Lichvar <mlichvar@redhat.com> | ||||
| # | ||||
| # Permission is hereby granted, free of charge, to any person obtaining | ||||
| # a copy of this software and associated documentation files (the | ||||
| # "Software"), to deal in the Software without restriction, including | ||||
| # 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: | ||||
| # | ||||
| # The above copyright notice and this permission notice shall be included | ||||
| # in all copies or substantial portions of the Software. | ||||
| # | ||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| # 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 ipaddress | ||||
| import logging | ||||
| import os | ||||
| import os.path | ||||
| import re | ||||
| import subprocess | ||||
| import sys | ||||
| 
 | ||||
| # python2 compatibility hacks | ||||
| if sys.version_info[0] < 3: | ||||
|     from io import open | ||||
|     reload(sys) | ||||
|     sys.setdefaultencoding("utf-8") | ||||
| 
 | ||||
| class NtpConfiguration(object): | ||||
|     def __init__(self, root_dir, ntp_conf, step_tickers): | ||||
|         self.root_dir = root_dir if root_dir != "/" else "" | ||||
|         self.ntp_conf_path = ntp_conf | ||||
|         self.step_tickers_path = step_tickers | ||||
| 
 | ||||
|         # Read and write files using an 8-bit transparent encoding | ||||
|         self.file_encoding = "latin-1" | ||||
|         self.enabled_services = set() | ||||
|         self.step_tickers = [] | ||||
|         self.time_sources = [] | ||||
|         self.fudges = {} | ||||
|         self.restrictions = { | ||||
|                 # Built-in defaults | ||||
|                 ipaddress.ip_network(u"0.0.0.0/0"): set(), | ||||
|                 ipaddress.ip_network(u"::/0"): set(), | ||||
|         } | ||||
|         self.keyfile = "" | ||||
|         self.keys = [] | ||||
|         self.trusted_keys = [] | ||||
|         self.driftfile = "" | ||||
|         self.statistics = [] | ||||
|         self.leapfile = "" | ||||
|         self.tos_options = {} | ||||
|         self.ignored_directives = set() | ||||
|         self.ignored_lines = [] | ||||
| 
 | ||||
|         #self.detect_enabled_services() | ||||
|         self.parse_step_tickers() | ||||
|         self.parse_ntp_conf() | ||||
| 
 | ||||
|     def detect_enabled_services(self): | ||||
|         for service in ["ntpdate", "ntpd", "ntp-wait"]: | ||||
|             if os.path.islink("{}/etc/systemd/system/multi-user.target.wants/{}.service" | ||||
|                     .format(self.root_dir, service)): | ||||
|                 self.enabled_services.add(service) | ||||
|         logging.info("Enabled services found in /etc/systemd/system: %s", | ||||
|                      " ".join(self.enabled_services)) | ||||
| 
 | ||||
|     def parse_step_tickers(self): | ||||
|         if not self.step_tickers_path: | ||||
|             return | ||||
| 
 | ||||
|         path = os.path.join(self.root_dir, self.step_tickers_path) | ||||
|         if not os.path.isfile(path): | ||||
|             logging.info("Missing %s", path) | ||||
|             return | ||||
| 
 | ||||
|         with open(path, encoding=self.file_encoding) as f: | ||||
|             for line in f: | ||||
|                 line = line[:line.find('#')] | ||||
| 
 | ||||
|                 words = line.split() | ||||
| 
 | ||||
|                 if not words: | ||||
|                     continue | ||||
| 
 | ||||
|                 self.step_tickers.extend(words) | ||||
| 
 | ||||
|     def parse_ntp_conf(self, path=None): | ||||
|         if path is None: | ||||
|             path = os.path.join(self.root_dir, self.ntp_conf_path) | ||||
| 
 | ||||
|         with open(path, encoding=self.file_encoding) as f: | ||||
|             logging.info("Reading %s", path) | ||||
| 
 | ||||
|             for line in f: | ||||
|                 line = line[:line.find('#')] | ||||
| 
 | ||||
|                 words = line.split() | ||||
| 
 | ||||
|                 if not words: | ||||
|                     continue | ||||
| 
 | ||||
|                 if not self.parse_directive(words): | ||||
|                     self.ignored_lines.append(line) | ||||
| 
 | ||||
|     def parse_directive(self, words): | ||||
|         name = words.pop(0) | ||||
|         if name.startswith("logconfig"): | ||||
|             name = "logconfig" | ||||
| 
 | ||||
|         if words: | ||||
|             if name in ["server", "peer", "pool"]: | ||||
|                 return self.parse_source(name, words) | ||||
|             elif name == "fudge": | ||||
|                 return self.parse_fudge(words) | ||||
|             elif name == "restrict": | ||||
|                 return self.parse_restrict(words) | ||||
|             elif name == "tos": | ||||
|                 return self.parse_tos(words) | ||||
|             elif name == "includefile": | ||||
|                 return self.parse_includefile(words) | ||||
|             elif name == "keys": | ||||
|                 return self.parse_keys(words) | ||||
|             elif name == "trustedkey": | ||||
|                 return self.parse_trustedkey(words) | ||||
|             elif name == "driftfile": | ||||
|                 self.driftfile = words[0] | ||||
|             elif name == "statistics": | ||||
|                 self.statistics = words | ||||
|             elif name == "leapfile": | ||||
|                 self.leapfile = words[0] | ||||
|             else: | ||||
|                 self.ignored_directives.add(name) | ||||
|                 return False | ||||
|         else: | ||||
|             self.ignored_directives.add(name) | ||||
|             return False | ||||
| 
 | ||||
|         return True | ||||
| 
 | ||||
|     def parse_source(self, source_type, words): | ||||
|         ipv4_only = False | ||||
|         ipv6_only = False | ||||
|         source = { | ||||
|                 "type": source_type, | ||||
|                 "options": [] | ||||
|         } | ||||
| 
 | ||||
|         if words[0] == "-4": | ||||
|             ipv4_only = True | ||||
|             words.pop(0) | ||||
|         elif words[0] == "-6": | ||||
|             ipv6_only = True | ||||
|             words.pop(0) | ||||
| 
 | ||||
|         if not words: | ||||
|             return False | ||||
| 
 | ||||
|         source["address"] = words.pop(0) | ||||
| 
 | ||||
|         # Check if -4/-6 corresponds to the address and ignore hostnames | ||||
|         if ipv4_only or ipv6_only: | ||||
|             try: | ||||
|                 version = ipaddress.ip_address(source["address"]).version | ||||
|                 if (ipv4_only and version != 4) or (ipv6_only and version != 6): | ||||
|                     return False | ||||
|             except ValueError: | ||||
|                 return False | ||||
| 
 | ||||
|         if source["address"].startswith("127.127."): | ||||
|             if not source["address"].startswith("127.127.1."): | ||||
|                 # Ignore non-LOCAL refclocks | ||||
|                 return False | ||||
| 
 | ||||
|         while words: | ||||
|             if len(words) >= 2 and words[0] in ["minpoll", "maxpoll", "version", "key"]: | ||||
|                 source["options"].append((words[0], words[1])) | ||||
|                 words = words[2:] | ||||
|             elif words[0] in ["burst", "iburst", "noselect", "prefer", "true", "xleave"]: | ||||
|                 source["options"].append((words[0],)) | ||||
|                 words.pop(0) | ||||
|             else: | ||||
|                 return False | ||||
| 
 | ||||
|         self.time_sources.append(source) | ||||
|         return True | ||||
| 
 | ||||
|     def parse_fudge(self, words): | ||||
|         address = words.pop(0) | ||||
|         options = {} | ||||
| 
 | ||||
|         while words: | ||||
|             if len(words) >= 2 and words[0] in ["stratum"]: | ||||
|                 if not words[1].isdigit(): | ||||
|                     return False | ||||
|                 options[words[0]] = int(words[1]) | ||||
|                 words = words[2:] | ||||
|             elif len(words) >= 2: | ||||
|                 words = words[2:] | ||||
|             else: | ||||
|                 return False | ||||
| 
 | ||||
|         self.fudges[address] = options | ||||
|         return True | ||||
| 
 | ||||
|     def parse_restrict(self, words): | ||||
|         ipv4_only = False | ||||
|         ipv6_only = False | ||||
|         flags = set() | ||||
|         mask = "" | ||||
| 
 | ||||
|         if words[0] == "-4": | ||||
|             ipv4_only = True | ||||
|             words.pop(0) | ||||
|         elif words[0] == "-6": | ||||
|             ipv6_only = True | ||||
|             words.pop(0) | ||||
| 
 | ||||
|         if not words: | ||||
|             return False | ||||
| 
 | ||||
|         address = words.pop(0) | ||||
| 
 | ||||
|         while words: | ||||
|             if len(words) >= 2 and words[0] == "mask": | ||||
|                 mask = words[1] | ||||
|                 words = words[2:] | ||||
|             else: | ||||
|                 if words[0] not in ["kod", "nomodify", "notrap", "nopeer", "noquery", | ||||
|                                     "limited", "ignore", "noserve"]: | ||||
|                     return False | ||||
|                 flags.add(words[0]) | ||||
|                 words.pop(0) | ||||
| 
 | ||||
|         # Convert to IP network(s), ignoring restrictions with hostnames | ||||
|         networks = [] | ||||
|         if address == "default" and not mask: | ||||
|             if not ipv6_only: | ||||
|                 networks.append(ipaddress.ip_network(u"0.0.0.0/0")) | ||||
|             if not ipv4_only: | ||||
|                 networks.append(ipaddress.ip_network(u"::/0")) | ||||
|         else: | ||||
|             try: | ||||
|                 if mask: | ||||
|                     networks.append(ipaddress.ip_network(u"{}/{}".format(address, mask))) | ||||
|                 else: | ||||
|                     networks.append(ipaddress.ip_network(address)) | ||||
|             except ValueError: | ||||
|                 return False | ||||
| 
 | ||||
|             if (ipv4_only and networks[-1].version != 4) or \ | ||||
|                     (ipv6_only and networks[-1].version != 6): | ||||
|                 return False | ||||
| 
 | ||||
|         for network in networks: | ||||
|             self.restrictions[network] = flags | ||||
| 
 | ||||
|         return True | ||||
| 
 | ||||
|     def parse_tos(self, words): | ||||
|         options = {} | ||||
|         while words: | ||||
|             if len(words) >= 2 and words[0] in ["minsane", "orphan"]: | ||||
|                 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:] | ||||
|             else: | ||||
|                 return False | ||||
| 
 | ||||
|         self.tos_options.update(options) | ||||
| 
 | ||||
|         return True | ||||
| 
 | ||||
|     def parse_includefile(self, words): | ||||
|         path = os.path.join(self.root_dir, words[0]) | ||||
|         if not os.path.isfile(path): | ||||
|             return False | ||||
| 
 | ||||
|         self.parse_ntp_conf(path) | ||||
|         return True | ||||
| 
 | ||||
|     def parse_keys(self, words): | ||||
|         keyfile = words[0] | ||||
|         path = os.path.join(self.root_dir, keyfile) | ||||
|         if not os.path.isfile(path): | ||||
|             logging.info("Missing %s", path) | ||||
|             return False | ||||
| 
 | ||||
|         with open(path, encoding=self.file_encoding) as f: | ||||
|             logging.info("Reading %s", path) | ||||
|             keys = [] | ||||
|             for line in f: | ||||
|                 words = line.split() | ||||
|                 if len(words) < 3 or not words[0].isdigit(): | ||||
|                     continue | ||||
|                 keys.append((int(words[0]), words[1], words[2])) | ||||
| 
 | ||||
|             self.keyfile = keyfile | ||||
|             self.keys = keys | ||||
| 
 | ||||
|         return True | ||||
| 
 | ||||
|     def parse_trustedkey(self, words): | ||||
|         key_ranges = [] | ||||
|         for word in words: | ||||
|             if word.isdigit(): | ||||
|                 key_ranges.append((int(word), int(word))) | ||||
|             elif re.match("^[0-9]+-[0-9]+$", word): | ||||
|                 first, last = word.split("-") | ||||
|                 key_ranges.append((int(first), int(last))) | ||||
|             else: | ||||
|                 return False | ||||
| 
 | ||||
|         self.trusted_keys = key_ranges | ||||
|         return True | ||||
| 
 | ||||
|     def write_chrony_configuration(self, chrony_conf_path, chrony_keys_path, | ||||
|                                    dry_run=False, backup=False): | ||||
|         chrony_conf = self.get_chrony_conf(chrony_keys_path) | ||||
|         logging.debug("Generated %s:\n%s", chrony_conf_path, chrony_conf) | ||||
| 
 | ||||
|         if not dry_run: | ||||
|             self.write_file(chrony_conf_path, 0o644, chrony_conf, backup) | ||||
| 
 | ||||
|         chrony_keys = self.get_chrony_keys() | ||||
|         if chrony_keys: | ||||
|             logging.debug("Generated %s:\n%s", chrony_keys_path, chrony_keys) | ||||
| 
 | ||||
|         if not dry_run: | ||||
|             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): | ||||
|         conf = "" | ||||
| 
 | ||||
|         if self.step_tickers: | ||||
|             conf += "# Specify NTP servers used for initial correction.\n" | ||||
|             conf += "initstepslew 0.1 {}\n".format(" ".join(self.step_tickers)) | ||||
|             conf += "\n" | ||||
| 
 | ||||
|         conf += "# Specify time sources.\n" | ||||
| 
 | ||||
|         for source in self.get_processed_time_sources(): | ||||
|             address = source["address"] | ||||
|             if address.startswith("127.127."): | ||||
|                 if address.startswith("127.127.1."): | ||||
|                     continue | ||||
|                 # No other refclocks are expected from the parser | ||||
|                 assert False | ||||
|             else: | ||||
|                 conf += "{} {}".format(source["type"], address) | ||||
|                 for option in source["options"]: | ||||
|                     if option[0] in ["minpoll", "maxpoll", "version", "key", | ||||
|                                      "iburst", "noselect", "prefer", "xleave"]: | ||||
|                         conf += " {}".format(" ".join(option)) | ||||
|                     elif option[0] == "burst": | ||||
|                         conf += " presend 6" | ||||
|                     elif option[0] == "true": | ||||
|                         conf += " trust" | ||||
|                     else: | ||||
|                         # No other options are expected from the parser | ||||
|                         assert False | ||||
|                 conf += "\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         return conf | ||||
| 
 | ||||
|     def get_chrony_conf_allows(self): | ||||
|         allowed_networks = filter(lambda n: "ignore" not in self.restrictions[n] and | ||||
|                                     "noserve" not in self.restrictions[n], | ||||
|                                   self.restrictions.keys()) | ||||
| 
 | ||||
|         conf = "" | ||||
|         for network in sorted(allowed_networks, key=lambda n: (n.version, n)): | ||||
|             if network.num_addresses > 1: | ||||
|                 conf += "allow {}\n".format(network) | ||||
|             else: | ||||
|                 conf += "allow {}\n".format(network.network_address) | ||||
| 
 | ||||
|         if conf: | ||||
|             conf = "# Allow NTP client access.\n" + conf | ||||
|             conf += "\n" | ||||
| 
 | ||||
|         return conf | ||||
| 
 | ||||
|     def get_chrony_conf_cmdallows(self): | ||||
|         allowed_networks = filter(lambda n: "ignore" not in self.restrictions[n] and | ||||
|                                     "noquery" not in self.restrictions[n] and | ||||
|                                     n != ipaddress.ip_network(u"127.0.0.1/32") and | ||||
|                                     n != ipaddress.ip_network(u"::1/128"), | ||||
|                                   self.restrictions.keys()) | ||||
| 
 | ||||
|         ip_versions = set() | ||||
|         conf = "" | ||||
|         for network in sorted(allowed_networks, key=lambda n: (n.version, n)): | ||||
|             ip_versions.add(network.version) | ||||
|             if network.num_addresses > 1: | ||||
|                 conf += "cmdallow {}\n".format(network) | ||||
|             else: | ||||
|                 conf += "cmdallow {}\n".format(network.network_address) | ||||
| 
 | ||||
|         if conf: | ||||
|             conf = "# Allow remote monitoring.\n" + conf | ||||
|             if 4 in ip_versions: | ||||
|                 conf += "bindcmdaddress 0.0.0.0\n" | ||||
|             if 6 in ip_versions: | ||||
|                 conf += "bindcmdaddress ::\n" | ||||
|             conf += "\n" | ||||
| 
 | ||||
|         return conf | ||||
| 
 | ||||
|     def get_chrony_conf(self, chrony_keys_path): | ||||
|         local_stratum = 0 | ||||
|         maxdistance = 0.0 | ||||
|         minsources = 1 | ||||
|         orphan_stratum = 0 | ||||
|         logs = [] | ||||
| 
 | ||||
|         for source in self.time_sources: | ||||
|             address = source["address"] | ||||
|             if address.startswith("127.127.1."): | ||||
|                 if address in self.fudges and "stratum" in self.fudges[address]: | ||||
|                     local_stratum = self.fudges[address]["stratum"] | ||||
|                 else: | ||||
|                     local_stratum = 5 | ||||
| 
 | ||||
|         if "maxdist" in self.tos_options: | ||||
|             maxdistance = self.tos_options["maxdist"] | ||||
|         if "minsane" in self.tos_options: | ||||
|             minsources = self.tos_options["minsane"] | ||||
|         if "orphan" in self.tos_options: | ||||
|             orphan_stratum = self.tos_options["orphan"] | ||||
| 
 | ||||
|         if "clockstats" in self.statistics: | ||||
|             logs.append("refclocks"); | ||||
|         if "loopstats" in self.statistics: | ||||
|             logs.append("tracking") | ||||
|         if "peerstats" in self.statistics: | ||||
|             logs.append("statistics"); | ||||
|         if "rawstats" in self.statistics: | ||||
|             logs.append("measurements") | ||||
| 
 | ||||
|         conf = "# This file was converted from {}{}.\n".format( | ||||
|                     self.ntp_conf_path, | ||||
|                     " and " + self.step_tickers_path if self.step_tickers_path else "") | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         if self.ignored_lines: | ||||
|             conf += "# The following directives were ignored in the conversion:\n" | ||||
| 
 | ||||
|             for line in self.ignored_lines: | ||||
|                 # Remove sensitive information | ||||
|                 line = re.sub(r"\s+pw\s+\S+", " pw XXX", line.rstrip()) | ||||
|                 conf += "# " + line + "\n" | ||||
|             conf += "\n" | ||||
| 
 | ||||
|         conf += self.get_chrony_conf_sources() | ||||
| 
 | ||||
|         conf += "# Record the rate at which the system clock gains/losses time.\n" | ||||
|         if not self.driftfile: | ||||
|             conf += "#" | ||||
|         conf += "driftfile /var/lib/chrony/drift\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Allow the system clock to be stepped in the first three updates\n" | ||||
|         conf += "# if its offset is larger than 1 second.\n" | ||||
|         conf += "makestep 1.0 3\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Enable kernel synchronization of the real-time clock (RTC).\n" | ||||
|         conf += "rtcsync\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Enable hardware timestamping on all interfaces that support it.\n" | ||||
|         conf += "#hwtimestamp *\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         if maxdistance > 0.0: | ||||
|             conf += "# Specify the maximum distance of sources to be selectable.\n" | ||||
|             conf += "maxdistance {}\n".format(maxdistance) | ||||
|             conf += "\n" | ||||
| 
 | ||||
|         conf += "# Increase the minimum number of selectable sources required to adjust\n" | ||||
|         conf += "# the system clock.\n" | ||||
|         if minsources > 1: | ||||
|             conf += "minsources {}\n".format(minsources) | ||||
|         else: | ||||
|             conf += "#minsources 2\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += self.get_chrony_conf_allows() | ||||
| 
 | ||||
|         conf += self.get_chrony_conf_cmdallows() | ||||
| 
 | ||||
|         conf += "# Serve time even if not synchronized to a time source.\n" | ||||
|         if orphan_stratum > 0 and orphan_stratum < 16: | ||||
|             conf += "local stratum {} orphan\n".format(orphan_stratum) | ||||
|         elif local_stratum > 0 and local_stratum < 16: | ||||
|             conf += "local stratum {}\n".format(local_stratum) | ||||
|         else: | ||||
|             conf += "#local stratum 10\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Specify file containing keys for NTP authentication.\n" | ||||
|         conf += "keyfile {}\n".format(chrony_keys_path) | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Get TAI-UTC offset and leap seconds from the system tz database.\n" | ||||
|         conf += "leapsectz right/UTC\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Specify directory for log files.\n" | ||||
|         conf += "logdir /var/log/chrony\n" | ||||
|         conf += "\n" | ||||
| 
 | ||||
|         conf += "# Select which information is logged.\n" | ||||
|         if logs: | ||||
|             conf += "log {}\n".format(" ".join(logs)) | ||||
|         else: | ||||
|             conf += "#log measurements statistics tracking\n" | ||||
| 
 | ||||
|         return conf | ||||
| 
 | ||||
|     def get_chrony_keys(self): | ||||
|         if not self.keyfile: | ||||
|             return "" | ||||
| 
 | ||||
|         keys = "# This file was converted from {}.\n".format(self.keyfile) | ||||
|         keys += "\n" | ||||
| 
 | ||||
|         for key in self.keys: | ||||
|             key_id = key[0] | ||||
|             key_type = key[1] | ||||
|             password = key[2] | ||||
| 
 | ||||
|             if key_type in ["m", "M"]: | ||||
|                 key_type = "MD5" | ||||
|             elif key_type not in ["MD5", "SHA1", "SHA256", "SHA384", "SHA512"]: | ||||
|                 continue | ||||
| 
 | ||||
|             prefix = "ASCII" if len(password) <= 20 else "HEX" | ||||
| 
 | ||||
|             for first, last in self.trusted_keys: | ||||
|                 if first <= key_id <= last: | ||||
|                     trusted = True | ||||
|                     break | ||||
|             else: | ||||
|                 trusted = False | ||||
| 
 | ||||
|             # Disable keys that were not marked as trusted | ||||
|             if not trusted: | ||||
|                 keys += "#" | ||||
| 
 | ||||
|             keys += "{} {} {}:{}\n".format(key_id, key_type, prefix, password) | ||||
| 
 | ||||
|         return keys | ||||
| 
 | ||||
|     def write_file(self, path, mode, content, backup): | ||||
|         path = self.root_dir + path | ||||
|         if backup and os.path.isfile(path): | ||||
|             os.rename(path, path + ".old") | ||||
| 
 | ||||
|         with open(os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, mode), "w", | ||||
|                   encoding=self.file_encoding) as f: | ||||
|             logging.info("Writing %s", path) | ||||
|             f.write(u"" + content) | ||||
| 
 | ||||
|         # Fix SELinux context if restorecon is installed | ||||
|         try: | ||||
|             subprocess.call(["restorecon", path]) | ||||
|         except OSError: | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| def main(): | ||||
|     parser = argparse.ArgumentParser(description="Convert ntp configuration to chrony.") | ||||
|     parser.add_argument("-r", "--root", dest="roots", default=["/"], nargs="+", | ||||
|                         metavar="DIR", help="specify root directory (default /)") | ||||
|     parser.add_argument("--ntp-conf", action="store", default="/etc/ntp.conf", | ||||
|                         metavar="FILE", help="specify ntp config (default /etc/ntp.conf)") | ||||
|     parser.add_argument("--step-tickers", action="store", default="", | ||||
|                         metavar="FILE", help="specify ntpdate step-tickers config (no default)") | ||||
|     parser.add_argument("--chrony-conf", action="store", default="/etc/chrony.conf", | ||||
|                         metavar="FILE", help="specify chrony config (default /etc/chrony.conf)") | ||||
|     parser.add_argument("--chrony-keys", action="store", default="/etc/chrony.keys", | ||||
|                         metavar="FILE", help="specify chrony keyfile (default /etc/chrony.keys)") | ||||
|     parser.add_argument("-b", "--backup", action="store_true", help="backup existing configs before writing") | ||||
|     parser.add_argument("-L", "--ignored-lines", action="store_true", help="print ignored lines") | ||||
|     parser.add_argument("-D", "--ignored-directives", action="store_true", | ||||
|                         help="print names of ignored directives") | ||||
|     parser.add_argument("-n", "--dry-run", action="store_true", help="don't make any changes") | ||||
|     parser.add_argument("-v", "--verbose", action="count", default=0, help="increase verbosity") | ||||
| 
 | ||||
|     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: | ||||
|         conf = NtpConfiguration(root, args.ntp_conf, args.step_tickers) | ||||
| 
 | ||||
|         if args.ignored_lines: | ||||
|             for line in conf.ignored_lines: | ||||
|                 print(line) | ||||
| 
 | ||||
|         if args.ignored_directives: | ||||
|             for directive in conf.ignored_directives: | ||||
|                 print(directive) | ||||
| 
 | ||||
|         conf.write_chrony_configuration(args.chrony_conf, args.chrony_keys, args.dry_run, args.backup) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										553
									
								
								SPECS/chrony.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										553
									
								
								SPECS/chrony.spec
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,553 @@ | ||||
| %global _hardened_build 1 | ||||
| %global clknetsim_ver 3f5ef9 | ||||
| %global ntp2chrony_ver 2a0512 | ||||
| %bcond_without debug | ||||
| 
 | ||||
| Name:           chrony | ||||
| Version:        3.5 | ||||
| Release:        1%{?dist} | ||||
| Summary:        An NTP client/server | ||||
| 
 | ||||
| Group:          System Environment/Daemons | ||||
| License:        GPLv2 | ||||
| URL:            https://chrony.tuxfamily.org | ||||
| Source0:        https://download.tuxfamily.org/chrony/chrony-%{version}%{?prerelease}.tar.gz | ||||
| Source1:        chrony.dhclient | ||||
| Source2:        chrony.helper | ||||
| Source3:        chrony-dnssrv@.service | ||||
| Source4:        chrony-dnssrv@.timer | ||||
| # simulator for test suite | ||||
| Source10:       https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz | ||||
| # script for converting ntp configuration to chrony | ||||
| Source11:       https://github.com/mlichvar/ntp2chrony/raw/%{ntp2chrony_ver}/ntp2chrony/ntp2chrony.py | ||||
| %{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz} | ||||
| 
 | ||||
| # add NTP servers from DHCP when starting service | ||||
| Patch2:         chrony-service-helper.patch | ||||
| 
 | ||||
| BuildRequires:  libcap-devel libedit-devel nettle-devel pps-tools-devel | ||||
| %ifarch %{ix86} x86_64 %{arm} aarch64 mipsel mips64el ppc64 ppc64le s390 s390x | ||||
| BuildRequires:  libseccomp-devel | ||||
| %endif | ||||
| BuildRequires:  gcc bison systemd | ||||
| BuildRequires:  kernel-headers > 4.18.0-87 | ||||
| 
 | ||||
| Requires(pre):  shadow-utils | ||||
| %{?systemd_requires} | ||||
| 
 | ||||
| # install timedated implementation that can control chronyd service | ||||
| Recommends:     timedatex | ||||
| 
 | ||||
| # suggest drivers for hardware reference clocks | ||||
| Suggests:       ntp-refclock | ||||
| 
 | ||||
| %description | ||||
| chrony is a versatile implementation of the Network Time Protocol (NTP). | ||||
| It can synchronise the system clock with NTP servers, reference clocks | ||||
| (e.g. GPS receiver), and manual input using wristwatch and keyboard. It | ||||
| can also operate as an NTPv4 (RFC 5905) server and peer to provide a time | ||||
| service to other computers in the network. | ||||
| 
 | ||||
| %if 0%{!?vendorzone:1} | ||||
| %global vendorzone %(source /etc/os-release && echo ${ID}.) | ||||
| %endif | ||||
| 
 | ||||
| %prep | ||||
| %setup -q -n %{name}-%{version}%{?prerelease} -a 10 | ||||
| %{?gitpatch:%patch0 -p1} | ||||
| %patch2 -p1 -b .service-helper | ||||
| 
 | ||||
| %{?gitpatch: echo %{version}-%{gitpatch} > version.txt} | ||||
| 
 | ||||
| # review changes in packaged configuration files and scripts | ||||
| md5sum -c <<-EOF | (! grep -v 'OK$') | ||||
|         47ad7eccc410b981d2f2101cf5682616  examples/chrony-wait.service | ||||
|         e473a9fab7fe200cacce3dca8b66290b  examples/chrony.conf.example2 | ||||
|         96999221eeef476bd49fe97b97503126  examples/chrony.keys.example | ||||
|         6a3178c4670de7de393d9365e2793740  examples/chrony.logrotate | ||||
|         8748a663f0b1943ea491858f414a6b26  examples/chrony.nm-dispatcher | ||||
|         b23bcc3bd78e195ca2849459e459f3ed  examples/chronyd.service | ||||
| EOF | ||||
| 
 | ||||
| # don't allow packaging without vendor zone | ||||
| test -n "%{vendorzone}" | ||||
| 
 | ||||
| # use example chrony.conf as the default config with some modifications: | ||||
| # - use our vendor zone (2.*pool.ntp.org names include IPv6 addresses) | ||||
| # - enable leapsectz to get TAI-UTC offset and leap seconds from tzdata | ||||
| # - enable keyfile | ||||
| sed -e 's|^\(pool \)\(pool.ntp.org\)|\12.%{vendorzone}\2|' \ | ||||
|     -e 's|#\(leapsectz\)|\1|' \ | ||||
|     -e 's|#\(keyfile\)|\1|' \ | ||||
|         < examples/chrony.conf.example2 > chrony.conf | ||||
| 
 | ||||
| touch -r examples/chrony.conf.example2 chrony.conf | ||||
| 
 | ||||
| # regenerate the file from getdate.y | ||||
| rm -f getdate.c | ||||
| 
 | ||||
| mv clknetsim-%{clknetsim_ver}* test/simulation/clknetsim | ||||
| 
 | ||||
| install -m 644 -p %{SOURCE11} ntp2chrony.py | ||||
| 
 | ||||
| %build | ||||
| %configure \ | ||||
| %{?with_debug: --enable-debug} \ | ||||
|         --enable-ntp-signd \ | ||||
|         --enable-scfilter \ | ||||
|         --docdir=%{_docdir} \ | ||||
|         --with-ntp-era=$(date -d '1970-01-01 00:00:00+00:00' +'%s') \ | ||||
|         --with-user=chrony \ | ||||
|         --with-hwclockfile=%{_sysconfdir}/adjtime \ | ||||
|         --with-sendmail=%{_sbindir}/sendmail | ||||
| make %{?_smp_mflags} | ||||
| 
 | ||||
| %install | ||||
| make install DESTDIR=$RPM_BUILD_ROOT | ||||
| 
 | ||||
| rm -rf $RPM_BUILD_ROOT%{_docdir} | ||||
| 
 | ||||
| mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/{sysconfig,logrotate.d} | ||||
| mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/{lib,log}/chrony | ||||
| mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dispatcher.d | ||||
| mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d | ||||
| mkdir -p $RPM_BUILD_ROOT%{_libexecdir} | ||||
| mkdir -p $RPM_BUILD_ROOT{%{_unitdir},%{_prefix}/lib/systemd/ntp-units.d} | ||||
| 
 | ||||
| install -m 644 -p chrony.conf $RPM_BUILD_ROOT%{_sysconfdir}/chrony.conf | ||||
| 
 | ||||
| install -m 640 -p examples/chrony.keys.example \ | ||||
|         $RPM_BUILD_ROOT%{_sysconfdir}/chrony.keys | ||||
| install -m 755 -p examples/chrony.nm-dispatcher \ | ||||
|         $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dispatcher.d/20-chrony | ||||
| install -m 755 -p %{SOURCE1} \ | ||||
|         $RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d/chrony.sh | ||||
| install -m 644 -p examples/chrony.logrotate \ | ||||
|         $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/chrony | ||||
| 
 | ||||
| install -m 644 -p examples/chronyd.service \ | ||||
|         $RPM_BUILD_ROOT%{_unitdir}/chronyd.service | ||||
| install -m 644 -p examples/chrony-wait.service \ | ||||
|         $RPM_BUILD_ROOT%{_unitdir}/chrony-wait.service | ||||
| install -m 644 -p %{SOURCE3} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.service | ||||
| install -m 644 -p %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.timer | ||||
| 
 | ||||
| install -m 755 -p %{SOURCE2} $RPM_BUILD_ROOT%{_libexecdir}/chrony-helper | ||||
| 
 | ||||
| cat > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/chronyd <<EOF | ||||
| # Command-line options for chronyd | ||||
| OPTIONS="" | ||||
| EOF | ||||
| 
 | ||||
| touch $RPM_BUILD_ROOT%{_localstatedir}/lib/chrony/{drift,rtc} | ||||
| 
 | ||||
| echo 'chronyd.service' > \ | ||||
|         $RPM_BUILD_ROOT%{_prefix}/lib/systemd/ntp-units.d/50-chronyd.list | ||||
| 
 | ||||
| %check | ||||
| # set random seed to get deterministic results | ||||
| export CLKNETSIM_RANDOM_SEED=24502 | ||||
| make %{?_smp_mflags} -C test/simulation/clknetsim | ||||
| make quickcheck | ||||
| 
 | ||||
| %pre | ||||
| getent group chrony > /dev/null || /usr/sbin/groupadd -r chrony | ||||
| getent passwd chrony > /dev/null || /usr/sbin/useradd -r -g chrony \ | ||||
|        -d %{_localstatedir}/lib/chrony -s /sbin/nologin chrony | ||||
| : | ||||
| 
 | ||||
| %post | ||||
| # fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2 | ||||
| if grep -q 'PIDFile=%{_localstatedir}/run/chronyd.pid' \ | ||||
|                 %{_sysconfdir}/systemd/system/chronyd.service 2> /dev/null && \ | ||||
|         ! grep -qi '^[ '$'\t'']*pidfile' %{_sysconfdir}/chrony.conf 2> /dev/null | ||||
| then | ||||
|         sed -i '/PIDFile=/s|/run/|/run/chrony/|' \ | ||||
|                 %{_sysconfdir}/systemd/system/chronyd.service | ||||
| fi | ||||
| # workaround for late reload of unit file (#1614751) | ||||
| %{_bindir}/systemctl daemon-reload | ||||
| %systemd_post chronyd.service chrony-wait.service | ||||
| 
 | ||||
| %preun | ||||
| %systemd_preun chronyd.service chrony-wait.service | ||||
| 
 | ||||
| %postun | ||||
| %systemd_postun_with_restart chronyd.service | ||||
| 
 | ||||
| %files | ||||
| %{!?_licensedir:%global license %%doc} | ||||
| %license COPYING | ||||
| %doc FAQ NEWS README ntp2chrony.py | ||||
| %config(noreplace) %{_sysconfdir}/chrony.conf | ||||
| %config(noreplace) %verify(not md5 size mtime) %attr(640,root,chrony) %{_sysconfdir}/chrony.keys | ||||
| %config(noreplace) %{_sysconfdir}/logrotate.d/chrony | ||||
| %config(noreplace) %{_sysconfdir}/sysconfig/chronyd | ||||
| %{_sysconfdir}/NetworkManager/dispatcher.d/20-chrony | ||||
| %{_sysconfdir}/dhcp/dhclient.d/chrony.sh | ||||
| %{_bindir}/chronyc | ||||
| %{_sbindir}/chronyd | ||||
| %{_libexecdir}/chrony-helper | ||||
| %{_prefix}/lib/systemd/ntp-units.d/*.list | ||||
| %{_unitdir}/chrony*.service | ||||
| %{_unitdir}/chrony*.timer | ||||
| %{_mandir}/man[158]/%{name}*.[158]* | ||||
| %dir %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony | ||||
| %ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/drift | ||||
| %ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/rtc | ||||
| %dir %attr(-,chrony,chrony) %{_localstatedir}/log/chrony | ||||
| 
 | ||||
| %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 | ||||
| - fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2 | ||||
|   (#1614800) | ||||
| - add workaround for late reload of unit file (#1614751) | ||||
| 
 | ||||
| * Mon Jun 18 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-2 | ||||
| - move pidfile to /var/run/chrony to allow chronyd to remove it on exit | ||||
|   (#1584585) | ||||
| - avoid blocking in getrandom system call (#1592425) | ||||
| 
 | ||||
| * Thu Apr 05 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-1 | ||||
| - update to 3.3 | ||||
| - enable keyfile by default again | ||||
| - update ntp2chrony script | ||||
| 
 | ||||
| * Mon Mar 19 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-0.2.pre1 | ||||
| - include ntp2chrony script in documentation (#1530987) | ||||
| 
 | ||||
| * Thu Mar 15 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-0.1.pre1 | ||||
| - update to 3.3-pre1 | ||||
| - switch to nettle for crypto hashing | ||||
| - add gcc to build requirements | ||||
| 
 | ||||
| * Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.2-4 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild | ||||
| 
 | ||||
| * Tue Jan 30 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.2-3 | ||||
| - use systemd macro for scriptlet dependencies | ||||
| 
 | ||||
| * Thu Jan 25 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.2-2 | ||||
| - fix chronyc getting stuck in infinite loop after clock step | ||||
| - don't allow packaging without vendor zone | ||||
| - suggest ntp-refclock | ||||
| - remove obsolete dependency | ||||
| - update description | ||||
| 
 | ||||
| * Fri Sep 15 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.2-1 | ||||
| - update to 3.2 | ||||
| - get TAI-UTC offset and leap seconds from tzdata by default | ||||
| 
 | ||||
| * Tue Aug 29 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.2-0.4.pre2 | ||||
| - update to 3.2-pre2 | ||||
| 
 | ||||
| * Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.2-0.3.pre1 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild | ||||
| 
 | ||||
| * Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.2-0.2.pre1 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild | ||||
| 
 | ||||
| * Tue Jul 25 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.2-0.1.pre1 | ||||
| - update to 3.2-pre1 | ||||
| 
 | ||||
| * Thu May 04 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.1-5 | ||||
| - check PEERNTP variable before loading existing dhclient files | ||||
| 
 | ||||
| * Thu Apr 20 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.1-4 | ||||
| - use ID from /etc/os-release to set pool.ntp.org vendor zone (#1443599) | ||||
| - fix seccomp filter for new glibc once again | ||||
| - don't drop PHC samples with zero delay | ||||
| 
 | ||||
| * Mon Mar 13 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.1-3 | ||||
| - fix seccomp filter for new glibc | ||||
| 
 | ||||
| * Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.1-2 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild | ||||
| 
 | ||||
| * Tue Jan 31 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.1-1 | ||||
| - update to 3.1 | ||||
| - enable seccomp support on more archs | ||||
| - package chronyd sysconfig file | ||||
| 
 | ||||
| * Tue Jan 24 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.1-0.1.pre1 | ||||
| - update to 3.1-pre1 | ||||
| 
 | ||||
| * Mon Jan 16 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.0-1 | ||||
| - update to 3.0 | ||||
| 
 | ||||
| * Fri Jan 06 2017 Miroslav Lichvar <mlichvar@redhat.com> 3.0-0.3.pre3 | ||||
| - update to 3.0-pre3 | ||||
| 
 | ||||
| * Thu Dec 15 2016 Miroslav Lichvar <mlichvar@redhat.com> 3.0-0.2.pre2 | ||||
| - update to 3.0-pre2 | ||||
| - enable support for MS-SNTP authentication in Samba | ||||
| 
 | ||||
| * Fri Dec 09 2016 Miroslav Lichvar <mlichvar@redhat.com> 3.0-0.1.pre1 | ||||
| - update to 3.0-pre1 | ||||
| 
 | ||||
| * Mon Nov 21 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4.1-1 | ||||
| - update to 2.4.1 | ||||
| 
 | ||||
| * Thu Oct 27 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4-4 | ||||
| - avoid AVC denials in chrony-wait service (#1350815) | ||||
| 
 | ||||
| * Tue Sep 13 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4-3 | ||||
| - fix chrony-helper to escape names of systemd units (#1374767) | ||||
| 
 | ||||
| * Tue Jun 28 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4-2 | ||||
| - fix chrony-helper to exit with correct status (#1350531) | ||||
| 
 | ||||
| * Tue Jun 07 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4-1 | ||||
| - update to 2.4 | ||||
| - don't require info | ||||
| 
 | ||||
| * Mon May 16 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.4-0.1.pre1 | ||||
| - update to 2.4-pre1 | ||||
| - extend chrony-helper to allow management of static sources (#1331655) | ||||
| 
 | ||||
| * Tue Feb 16 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.3-1 | ||||
| - update to 2.3 | ||||
| 
 | ||||
| * Tue Feb 02 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.3-0.1.pre1 | ||||
| - update to 2.3-pre1 | ||||
| 
 | ||||
| * Thu Jan 21 2016 Miroslav Lichvar <mlichvar@redhat.com> 2.2.1-1 | ||||
| - update to 2.2.1 (CVE-2016-1567) | ||||
| - set NTP era split explicitly | ||||
| 
 | ||||
| * Mon Oct 19 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.2-1 | ||||
| - update to 2.2 | ||||
| 
 | ||||
| * Fri Oct 09 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.2-0.2.pre2 | ||||
| - update to 2.2-pre2 | ||||
| - require libseccomp-devel on supported archs only | ||||
| 
 | ||||
| * Fri Oct 02 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.2-0.1.pre1 | ||||
| - update to 2.2-pre1 | ||||
| - enable seccomp support | ||||
| - use weak dependency for timedatex on Fedora 24 and later | ||||
| 
 | ||||
| * Tue Jun 23 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.1.1-1 | ||||
| - update to 2.1.1 | ||||
| - add -n option to gzip command to not save timestamp | ||||
| 
 | ||||
| * Mon Jun 22 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.1-1 | ||||
| - update to 2.1 | ||||
| - extend chrony-helper to allow using servers from DNS SRV records (#1234406) | ||||
| - set random seed in testing to get deterministic results | ||||
| 
 | ||||
| * Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1-0.2.pre1 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild | ||||
| 
 | ||||
| * Wed Jun 10 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.1-0.1.pre1 | ||||
| - update to 2.1-pre1 | ||||
| 
 | ||||
| * Mon Apr 27 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.0-1 | ||||
| - update to 2.0 | ||||
| 
 | ||||
| * Wed Apr 08 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.0-0.3.pre2 | ||||
| - update to 2.0-pre2 (CVE-2015-1853 CVE-2015-1821 CVE-2015-1822) | ||||
| 
 | ||||
| * Thu Jan 29 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.0-0.2.pre1 | ||||
| - require timedatex (#1136905) | ||||
| 
 | ||||
| * Tue Jan 27 2015 Miroslav Lichvar <mlichvar@redhat.com> 2.0-0.1.pre1 | ||||
| - update to 2.0-pre1 | ||||
| 
 | ||||
| * Thu Sep 11 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.31-1 | ||||
| - update to 1.31 | ||||
| - add servers from DHCP with iburst option by default | ||||
| - use upstream configuration files and scripts | ||||
| - don't package configuration examples | ||||
| - compress chrony.txt | ||||
| 
 | ||||
| * Thu Aug 21 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.31-0.1.pre1 | ||||
| - update to 1.31-pre1 | ||||
| - use license macro if available | ||||
| 
 | ||||
| * Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.30-3 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild | ||||
| 
 | ||||
| * Fri Aug 15 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.30-2 | ||||
| - reconnect client sockets (#1124059) | ||||
| 
 | ||||
| * Tue Jul 01 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.30-1 | ||||
| - update to 1.30 | ||||
| - enable debug messages | ||||
| 
 | ||||
| * Mon Jun 09 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.30-0.1.pre1 | ||||
| - update to 1.30-pre1 | ||||
| - execute test suite | ||||
| - avoid calling systemctl in helper script | ||||
| - call chronyc directly from logrotate and NM dispatcher scripts | ||||
| - add conflict with systemd-timesyncd service | ||||
| 
 | ||||
| * Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.29.1-2 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild | ||||
| 
 | ||||
| * Fri Jan 31 2014 Miroslav Lichvar <mlichvar@redhat.com> 1.29.1-1 | ||||
| - update to 1.29.1 (CVE-2014-0021) | ||||
| - replace hardening build flags with _hardened_build | ||||
| 
 | ||||
| * Tue Nov 19 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.29-3 | ||||
| - let systemd remove pid file (#974305) | ||||
| 
 | ||||
| * Thu Oct 03 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.29-2 | ||||
| - add ordering dependency to not start chronyd before ntpd stopped | ||||
| 
 | ||||
| * Thu Aug 08 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.29-1 | ||||
| - update to 1.29 (CVE-2012-4502, CVE-2012-4503) | ||||
| 
 | ||||
| * Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.28-2 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild | ||||
| 
 | ||||
| * Wed Jul 17 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.28-1 | ||||
| - update to 1.28 | ||||
| - change default makestep limit to 10 seconds | ||||
| 
 | ||||
| * Mon Jun 24 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.28-0.2.pre1 | ||||
| - buildrequire systemd-units | ||||
| 
 | ||||
| * Fri Jun 21 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.28-0.1.pre1 | ||||
| - update to 1.28-pre1 | ||||
| - listen for commands only on localhost by default | ||||
| 
 | ||||
| * Thu May 09 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.27-3 | ||||
| - disable chrony-wait service by default (#961047) | ||||
| - drop old systemd scriptlets | ||||
| - don't own ntp-units.d directory | ||||
| - move files from /lib | ||||
| - remove unncessary dependency on syslog target | ||||
| 
 | ||||
| * Tue Mar 12 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.27-2 | ||||
| - suppress error messages from tr when generating key (#907914) | ||||
| - fix delta calculation with extreme frequency offsets | ||||
| 
 | ||||
| * Fri Feb 01 2013 Miroslav Lichvar <mlichvar@redhat.com> 1.27-1 | ||||
| - update to 1.27 | ||||
| - start chrony-wait service with chronyd | ||||
| - start chronyd service after sntp | ||||
| - remove obsolete macros | ||||
| 
 | ||||
| * Tue Sep 11 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.27-0.5.pre1.git1ca844 | ||||
| - update to git snapshot 1ca844 | ||||
| - update systemd integration (#846303) | ||||
| - use systemd macros if available (#850151) | ||||
| - use correct vendor pool.ntp.org zone on RHEL (#845981) | ||||
| - don't log output of chrony-wait service | ||||
| 
 | ||||
| * Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.27-0.4.pre1 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild | ||||
| 
 | ||||
| * Fri Apr 27 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.27-0.3.pre1 | ||||
| - update service file for systemd-timedated-ntp target (#816493) | ||||
| 
 | ||||
| * Fri Apr 06 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.27-0.2.pre1 | ||||
|   use systemctl is-active instead of status in chrony-helper (#794771) | ||||
| 
 | ||||
| * Tue Feb 28 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.27-0.1.pre1 | ||||
| - update to 1.27-pre1 | ||||
| - generate SHA1 command key instead of MD5 | ||||
| 
 | ||||
| * Wed Feb 15 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.26-6.20110831gitb088b7 | ||||
| - remove old servers on DHCP update (#787042) | ||||
| 
 | ||||
| * Fri Feb 10 2012 Miroslav Lichvar <mlichvar@redhat.com> 1.26-5.20110831gitb088b7 | ||||
| - improve chrony-helper to keep track of servers added from DHCP (#787042) | ||||
| - fix dhclient script to always return with zero exit code (#767859) | ||||
| 
 | ||||
| * Thu Jan 12 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.26-4.20110831gitb088b7 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild | ||||
| 
 | ||||
| * Tue Sep 06 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.26-3.20110831gitb088b7 | ||||
| - update to git snapshot 20110831gitb088b7 | ||||
| - on first start generate password with 16 chars | ||||
| - change systemd service type to forking | ||||
| - add forced-command to chrony-helper (#735821) | ||||
| 
 | ||||
| * Mon Aug 15 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.26-2 | ||||
| - fix iburst with very high jitters and long delays | ||||
| - use timepps header from pps-tools-devel | ||||
| 
 | ||||
| * Wed Jul 13 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.26-1 | ||||
| - update to 1.26 | ||||
| - read options from sysconfig file if it exists | ||||
| 
 | ||||
| * Fri Jun 24 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.26-0.1.pre1 | ||||
| - update to 1.26-pre1 | ||||
| - fix service name in %%triggerun | ||||
| - drop SysV init script | ||||
| - add chrony-wait service | ||||
| 
 | ||||
| * Fri May 06 2011 Bill Nottingham <notting@redhat.com> 1.25-2 | ||||
| - fix systemd scriptlets for the upgrade case | ||||
| 
 | ||||
| * Wed May 04 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.25-1 | ||||
| - update to 1.25 | ||||
| 
 | ||||
| * Wed Apr 20 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.25-0.3.pre2 | ||||
| - update to 1.25-pre2 | ||||
| - link with -Wl,-z,relro,-z,now options | ||||
| 
 | ||||
| * Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25-0.2.pre1 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild | ||||
| 
 | ||||
| * Tue Feb 01 2011 Miroslav Lichvar <mlichvar@redhat.com> 1.25-0.1.pre1 | ||||
| - update to 1.25-pre1 | ||||
| - use iburst, four pool servers, rtcsync, stratumweight in default config | ||||
| - add systemd support | ||||
| - drop sysconfig file  | ||||
| - suppress install-info errors | ||||
| 
 | ||||
| * Thu Apr 29 2010 Miroslav Lichvar <mlichvar@redhat.com> 1.24-4.20100428git73d775 | ||||
| - update to 20100428git73d775 | ||||
| - replace initstepslew directive with makestep in default config | ||||
| - add NetworkManager dispatcher script | ||||
| - add dhclient script | ||||
| - retry server/peer name resolution at least once to workaround | ||||
|   NetworkManager race condition on boot | ||||
| - don't verify chrony.keys | ||||
| 
 | ||||
| * Fri Mar 12 2010 Miroslav Lichvar <mlichvar@redhat.com> 1.24-3.20100302git5fb555 | ||||
| - update to snapshot 20100302git5fb555 | ||||
| - compile with PPS API support | ||||
| 
 | ||||
| * Thu Feb 04 2010 Miroslav Lichvar <mlichvar@redhat.com> 1.24-1 | ||||
| - update to 1.24 (#555367, CVE-2010-0292 CVE-2010-0293 CVE-2010-0294) | ||||
| - modify default config | ||||
|   - step clock on start if it is off by more than 100 seconds | ||||
|   - disable client log | ||||
| - build with -fPIE on sparc | ||||
| 
 | ||||
| * Tue Dec 15 2009 Miroslav Lichvar <mlichvar@redhat.com> 1.24-0.1.pre1 | ||||
| - update to 1.24-pre1 | ||||
| 
 | ||||
| * Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23-7.20081106gitbe42b4 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild | ||||
| 
 | ||||
| * Fri Jul 17 2009 Miroslav Lichvar <mlichvar@redhat.com> 1.23-6.20081106gitbe42b4 | ||||
| - switch to editline | ||||
| - support arbitrary chronyc commands in init script | ||||
| 
 | ||||
| * Mon Jun 08 2009 Dan Horak <dan[at]danny.cz> 1.23-5.20081106gitbe42b4 | ||||
| - add patch with support for s390/s390x | ||||
| 
 | ||||
| * Mon Mar 09 2009 Miroslav Lichvar <mlichvar@redhat.com> 1.23-4.20081106gitbe42b4 | ||||
| - fix building with broken libcap header (#483548) | ||||
| 
 | ||||
| * Mon Feb 23 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23-3.20081106gitbe42b4 | ||||
| - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild | ||||
| 
 | ||||
| * Wed Nov 19 2008 Miroslav Lichvar <mlichvar@redhat.com> 1.23-2.20081106gitbe42b4 | ||||
| - fix info uninstall | ||||
| - generate random command key in init script | ||||
| - support cyclelogs, online, offline commands in init script | ||||
| - add logrotate script | ||||
| 
 | ||||
| * Tue Nov 11 2008 Miroslav Lichvar <mlichvar@redhat.com> 1.23-1.20081106gitbe42b4 | ||||
| - initial release | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user