Skip to content

Commit

Permalink
timesync
Browse files Browse the repository at this point in the history
  • Loading branch information
mlichvar authored and larskarlitski committed Apr 28, 2017
0 parents commit 33a1a8c
Show file tree
Hide file tree
Showing 22 changed files with 589 additions and 0 deletions.
19 changes: 19 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2017 Red Hat, Inc.

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.
108 changes: 108 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
timesync
========

This role installs and configures an NTP and/or PTP implementation to operate
as an NTP client and/or PTP slave in order to synchronize the system clock with
NTP servers and/or grandmasters in PTP domains. Supported NTP/PTP
implementations are chrony, ntp (the reference implementation) and linuxptp.

Role Variables
--------------

The variables that can be passed to this role are as follows:

```
# List of NTP servers
ntp_servers:
- hostname: foo.example.com # Hostname or address of the server
minpoll: 4 # Minimum polling interval (default 6)
maxpoll: 8 # Maximum polling interval (default 10)
iburst: yes # Flag enabling fast initial synchronization
# (default no)
pool: no # Flag indicating that each resolved address
# of the hostname is a separate NTP server
# (default no)
# List of PTP domains
ptp_domains:
- number: 0 # PTP domain number
interfaces: [ eth0 ] # List of interfaces in the domain
delay: 0.000010 # Assumed maximum network delay to the
# grandmaster in seconds
# (default 100 microsecond)
transport: UDPv4 # Network transport: UDPv4, UDPv6, L2
# (default UDPv4)
udp_ttl: 1 # TTL for UDPv4 and UDPv6 transports
# (default 1)
# Flag enabling use of NTP servers provided by DHCP (default no)
dhcp_ntp_servers: no
# Minimum offset of the clock which can be corrected by stepping (default is
# specific to NTP/PTP implementation: chrony 1.0, ntp 0.128, linuxptp 0.00002).
# Zero threshold disables all steps.
clock_step_threshold: 1.0
# Minimum number of selectable time sources required to allow synchronization
# of the clock (default 1)
min_time_sources: 1
```

Example Playbook
----------------

Install and configure ntp to synchronize the system clock with three NTP servers:

```
- hosts: targets
vars:
ntp_servers:
- hostname: foo.example.com
iburst: yes
- hostname: bar.example.com
iburst: yes
- hostname: baz.example.com
iburst: yes
roles:
- timesync
```

Install and configure linuxptp to synchronize the system clock with a
grandmaster in PTP domain number 0, which is accessible on interface eth0:

```
- hosts: targets
vars:
ptp_domains:
- number: 0
interfaces: [ eth0 ]
roles:
- timesync
```

Install and configure chrony and linuxptp to synchronize the system clock with
multiple NTP servers and PTP domains for a highly accurate and resilient
synchronization:

```
- hosts: targets
vars:
ntp_servers:
- hostname: foo.example.com
maxpoll: 6
- hostname: bar.example.com
maxpoll: 6
- hostname: baz.example.com
maxpoll: 6
ptp_domains:
- number: 0
interfaces: [ eth0, eth1 ]
transport: L2
delay: 0.000010
- number: 1
interfaces: [ eth2 ]
transport: UDPv4
delay: 0.000010
roles:
- timesync
```
6 changes: 6 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
ntp_servers: []
ptp_domains: []
dhcp_ntp_servers: false
clock_step_threshold: -1.0
min_time_sources: 1
11 changes: 11 additions & 0 deletions handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
- name: restart chronyd
service: "name=chronyd state=restarted"
- name: restart ntpd
service: "name=ntpd state=restarted"
- name: restart ptp4l
service: "name=ptp4l state=restarted"
- name: restart phc2sys
service: "name=phc2sys state=restarted"
- name: restart timemaster
service: "name=timemaster state=restarted"
12 changes: 12 additions & 0 deletions meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
galaxy_info:
author: Miroslav Lichvar <[email protected]>
description: Configure NTP and/or PTP
galaxy_tags: [ 'system', 'beta' ]
company: Red Hat, Inc.
license: MIT
min_ansible_version: 2.2
platforms:
- name: Fedora
versions: [ 24, 25 ]
- name: EL
versions: [ 6, 7 ]
17 changes: 17 additions & 0 deletions run-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# Run integration test for this repository. It fetches the test harness from
# docker.io, which is built from
#
# http://github.com/linux-system-roles/test-harness

set -xeuf -o pipefail

CACHEDIR=${CACHEDIR:-$PWD/.image-cache}
mkdir -p $CACHEDIR

docker run --privileged \
--rm \
--volume $PWD:/role \
--volume $CACHEDIR:/cache \
cockpit/linux-system-roles-test
22 changes: 22 additions & 0 deletions semaphore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# Run integration tests on semaphoreci.com.

set -xeuf -o pipefail

prepare() {
# install qemu because its post install script sets up /dev/kvm
sudo apt-get update
sudo apt-get install -q -y qemu-system-x86
sudo chmod a+rw /dev/kvm
}

run() {
docker-cache restore

CACHEDIR=$SEMAPHORE_CACHE_DIR ./run-tests.sh | tee

docker-cache snapshot
}

"$@"
165 changes: 165 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---

- name: Check if only NTP is needed
set_fact:
sync_mode: 1
when: ptp_domains|length == 0

- name: Check if single PTP is needed
set_fact:
sync_mode: 2
when: sync_mode is not defined and (ntp_servers|length == 0) and ptp_domains|length == 1 and ptp_domains[0].interfaces|length == 1

- name: Check if both NTP and PTP are needed
set_fact:
sync_mode: 3
when: sync_mode is not defined

- name: Select NTP implementation
set_fact:
ntp_implementation: "{{ 'ntp' if ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_version|version_compare('6.8', '<') else 'chrony' }}"
when: sync_mode != 2

- name: Install chrony
package: name=chrony state=present
when: sync_mode != 2 and ntp_implementation == 'chrony'

- name: Install ntp
package: name=ntp state=present
when: sync_mode != 2 and ntp_implementation == 'ntp'

- name: Install linuxptp
package: name=linuxptp state=present
when: sync_mode != 1

- name: Run phc_ctl on PTP interface
command: phc_ctl -q {{ ptp_domains[0].interfaces[0] }}
register: phc_ctl_output
changed_when: False
when: sync_mode == 2
ignore_errors: yes

- name: Check if PTP interface supports HW timestamping
set_fact:
mode2_hwts: "{{ phc_ctl_output.rc == 0 }}"
when: sync_mode == 2

- name: Get chrony version
command: rpm -q --qf '%{version}' chrony
args:
warn: no
register: chrony_version
changed_when: False
when: sync_mode != 2 and ntp_implementation == 'chrony'

- name: Get ntp version
command: rpm -q --qf '%{version}' ntp
args:
warn: no
register: ntp_version
changed_when: False
when: sync_mode != 2 and ntp_implementation == 'ntp'

- name: Generate chrony.conf file
template: src=chrony.conf.j2 dest=/etc/chrony.conf backup=yes mode=0644
notify: restart {{ 'chronyd' if sync_mode == 1 else 'timemaster' }}
when: sync_mode != 2 and ntp_implementation == 'chrony'

- name: Generate chronyd sysconfig file
template: src=chronyd.sysconfig.j2 dest=/etc/sysconfig/chronyd backup=yes mode=0644
notify: restart chronyd
when: sync_mode == 1 and ntp_implementation == 'chrony'

- name: Generate ntp.conf file
template: src=ntp.conf.j2 dest=/etc/ntp.conf backup=yes mode=0644
notify: restart {{ 'ntpd' if sync_mode == 1 else 'timemaster' }}
when: sync_mode != 2 and ntp_implementation == 'ntp'

- name: Generate ntpd sysconfig file
template: src=ntpd.sysconfig.j2 dest=/etc/sysconfig/ntpd backup=yes mode=0644
notify: restart ntpd
when: sync_mode == 1 and ntp_implementation == 'ntp'

- name: Generate ptp4l.conf file
template: src=ptp4l.conf.j2 dest=/etc/ptp4l.conf backup=yes mode=0644
notify: restart ptp4l
when: sync_mode == 2

- name: Generate ptp4l sysconfig file
template: src=ptp4l.sysconfig.j2 dest=/etc/sysconfig/ptp4l backup=yes mode=0644
notify: restart ptp4l
when: sync_mode == 2

- name: Generate phc2sys sysconfig file
template: src=phc2sys.sysconfig.j2 dest=/etc/sysconfig/phc2sys backup=yes mode=0644
notify: restart phc2sys
when: sync_mode == 2 and mode2_hwts

- name: Generate timemaster.conf file
template: src=timemaster.conf.j2 dest=/etc/timemaster.conf backup=yes mode=0644
notify: restart timemaster
when: sync_mode == 3

- name: Update network sysconfig file
lineinfile:
dest: /etc/sysconfig/network
create: yes
mode: 0644
regexp: '^PEERNTP='
line: 'PEERNTP=no'
state: "{{ 'absent' if dhcp_ntp_servers else 'present' }}"
notify: restart {{ ntp_implementation + 'd' }}
when: sync_mode == 1

- name: Disable chronyd
service: name=chronyd state=stopped enabled=no
when: sync_mode != 1 or ntp_implementation != 'chrony'
ignore_errors: yes

- name: Disable ntpd
service: name=ntpd state=stopped enabled=no
when: sync_mode != 1 or ntp_implementation != 'ntp'
ignore_errors: yes

- name: Disable ntpdate
service: name=ntpdate state=stopped enabled=no
ignore_errors: yes

- name: Disable sntp
service: name=sntp state=stopped enabled=no
ignore_errors: yes

- name: Disable ptp4l
service: name=ptp4l state=stopped enabled=no
when: sync_mode != 2
ignore_errors: yes

- name: Disable phc2sys
service: name=phc2sys state=stopped enabled=no
when: sync_mode != 2 or not mode2_hwts
ignore_errors: yes

- name: Disable timemaster
service: name=timemaster state=stopped enabled=no
when: sync_mode != 3
ignore_errors: yes

- name: Enable chronyd
service: name=chronyd state=started enabled=yes
when: sync_mode == 1 and ntp_implementation == 'chrony'

- name: Enable ntpd
service: name=ntpd state=started enabled=yes
when: sync_mode == 1 and ntp_implementation == 'ntp'

- name: Enable ptp4l
service: name=ptp4l state=started enabled=yes
when: sync_mode == 2

- name: Enable phc2sys
service: name=phc2sys state=started enabled=yes
when: sync_mode == 2 and mode2_hwts

- name: Enable timemaster
service: name=timemaster state=started enabled=yes
when: sync_mode == 3
Loading

0 comments on commit 33a1a8c

Please sign in to comment.