Vendor Galaxy Roles and Collections
Some checks failed
/ Ansible Lint (push) Failing after 5m45s
/ Ansible Lint (pull_request) Failing after 4m59s

This commit is contained in:
Stefan Bethke 2026-02-06 22:07:16 +01:00
commit 2aed20393f
3553 changed files with 387444 additions and 2 deletions

View file

@ -0,0 +1,19 @@
debops.timesyncd - Manage time synchronization using systemd-timesyncd
Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
Copyright (C) 2023 DebOps <http://debops.org/>
SPDX-License-Identifier: GPL-3.0-only
This Ansible role is part of DebOps.
DebOps is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3, as
published by the Free Software Foundation.
DebOps is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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
along with DebOps. If not, see https://www.gnu.org/licenses/.

View file

@ -0,0 +1,162 @@
---
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
# .. Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
# .. Copyright (C) 2023 DebOps <https://debops.org/>
# .. SPDX-License-Identifier: GPL-3.0-only
# .. _timesyncd__ref_defaults:
# debops.timesyncd default variables
# ==================================
# .. contents:: Sections
# :local:
#
# .. include:: ../../../../includes/global.rst
# General options [[[
# -------------------
# .. envvar:: timesyncd__enabled [[[
#
# Enable or disable management of the :command:`systemd-timesyncd` service using
# DebOps. If the parameter is set to ``False``, the role will not touch service
# configuration.
timesyncd__enabled: '{{ True
if (ansible_service_mgr == "systemd" and
timesyncd__fact_service_state == "present")
else False }}'
# ]]]
# .. envvar:: timesyncd__deploy_state [[[
#
# This variable controls if the :command:`systemd-timesyncd` main configuration
# file is managed on the host (``present``) or not (``absent``, default). If
# deployment state is disabled, :command:`systemd-timesyncd` will use the
# configuration provided with the OS package.
timesyncd__deploy_state: 'absent'
# ]]]
# ]]]
# APT packages and installation [[[
# ---------------------------------
# .. envvar:: timesyncd__base_packages [[[
#
# List of base APT packages for :command:`systemd-timesyncd` support. The APT
# package is separate from ``systemd`` APT package to allow for conflict
# resolution with other APT packages that provide the ``time-daemon`` virtual
# package.
timesyncd__base_packages: [ 'systemd-timesyncd' ]
# ]]]
# .. envvar:: timesyncd__packages [[[
#
# List of additional APT packages to install for :command:`systemd-timesyncd`
# support.
timesyncd__packages: []
# ]]]
# .. envvar:: timesyncd__skip_packages [[[
#
# List of APT packages which provide the ``time-daemon`` virtual package. When
# the role detects that they are installed on the host, it will turn itself off
# to avoid conflicts.
timesyncd__skip_packages: [ 'openntpd', 'ntpsec', 'ntp', 'chrony' ]
# ]]]
# .. envvar:: timesyncd__version [[[
#
# Specify the version of the :command:`systemd-timesyncd` daemon installed on
# the host. By default this variable is defined using Ansible local facts and
# can be used to alter configuration depending on the version of the service.
timesyncd__version: '{{ ansible_local.timesyncd.version | d("0") }}'
# ]]]
# ]]]
# The :command:`systemd-timesyncd` daemon configuration [[[
# ---------------------------------------------------------
# These variables define the contents of the
# :file:`/etc/systemd/timesyncd.conf` configuration file. Check the
# :man:`timesyncd.conf(5)` manual page for more information about the
# configuration options, and :ref:`timesyncd__ref_configuration` for details
# about the configuration of the role itself.
#
# By default the configuration is not applied on the hosts, you need to set
# :envvar:`timesyncd__deploy_state` variable to ``present`` to deploy the
# configuration.
# .. envvar:: timesyncd__default_configuration [[[
#
# List of the default configuration options defined by the role.
timesyncd__default_configuration:
- name: 'NTP'
value: []
state: 'init'
- name: 'FallbackNTP'
value:
- '0.debian.pool.ntp.org'
- '1.debian.pool.ntp.org'
- '2.debian.pool.ntp.org'
- '3.debian.pool.ntp.org'
state: 'init'
- name: 'RootDistanceMaxSec'
value: 5
state: 'init'
- name: 'PollIntervalMinSec'
value: 32
state: 'init'
- name: 'PollIntervalMaxSec'
value: 2048
state: 'init'
# ]]]
# .. envvar:: timesyncd__configuration [[[
#
# List of the configuration options which should be present on all hosts in the
# Ansible inventory.
timesyncd__configuration: []
# ]]]
# .. envvar:: timesyncd__group_configuration [[[
#
# List of the configuration options which should be present on hosts in
# a specific Ansible inventory group.
timesyncd__group_configuration: []
# ]]]
# .. envvar:: timesyncd__host_configuration [[[
#
# List of the configuration options which should be present on specific hosts
# in the Ansible inventory.
timesyncd__host_configuration: []
# ]]]
# .. envvar:: timesyncd__combined_configuration [[[
#
# Variable which combines all configuration lists and is used in the role tasks
# and templates.
timesyncd__combined_configuration: '{{ timesyncd__default_configuration
+ timesyncd__configuration
+ timesyncd__group_configuration
+ timesyncd__host_configuration }}'
# ]]]
# ]]]
# Configuration for other Ansible roles [[[
# -----------------------------------------
# .. envvar:: timesyncd__dpkg_cleanup__dependent_packages [[[
#
# Configuration for the :ref:`debops.dpkg_cleanup` Ansible role.
timesyncd__dpkg_cleanup__dependent_packages:
- name: 'systemd-timesyncd'
ansible_fact: 'timesyncd'
# ]]]
# ]]]

View file

@ -0,0 +1,32 @@
---
# Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2023 DebOps <http://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# Ensure that custom Ansible plugins and modules included in the main DebOps
# collection are available to roles in other collections.
collections: [ 'debops.debops' ]
dependencies: []
galaxy_info:
author: 'Maciej Delmanowski'
description: 'Manage time synchronization using systemd-timesyncd'
company: 'DebOps'
license: 'GPL-3.0-only'
min_ansible_version: '2.9.0'
platforms:
- name: 'Ubuntu'
versions: [ 'all' ]
- name: 'Debian'
versions: [ 'all' ]
galaxy_tags:
- system
- systemd
- time
- ntp

View file

@ -0,0 +1,90 @@
---
# Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2023 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Import DebOps global handlers
ansible.builtin.import_role:
name: 'global_handlers'
- name: Check if other time daemons are installed
environment:
LC_MESSAGES: 'C'
ansible.builtin.shell: |
set -o nounset -o pipefail -o errexit &&
dpkg --get-selections | grep -w -E '({{ timesyncd__skip_packages | join("|") }})'
| awk '{print $1}' || true
args:
executable: '/bin/bash'
register: timesyncd__register_time_daemons
changed_when: False
failed_when: False
check_mode: False
- name: Set timesyncd deployment state
ansible.builtin.set_fact:
timesyncd__fact_service_state: '{{ "present"
if (not timesyncd__register_time_daemons.stdout | d())
else "absent" }}'
- name: Install required timesyncd packages
ansible.builtin.package:
name: '{{ timesyncd__base_packages + timesyncd__packages }}'
state: 'present'
register: timesyncd__register_packages
until: timesyncd__register_packages is succeeded
when: timesyncd__enabled | bool
- name: Make sure that Ansible local facts directory exists
ansible.builtin.file:
path: '/etc/ansible/facts.d'
state: 'directory'
mode: '0755'
when: timesyncd__enabled | bool
- name: Save timesyncd local facts
ansible.builtin.template:
src: 'etc/ansible/facts.d/timesyncd.fact.j2'
dest: '/etc/ansible/facts.d/timesyncd.fact'
mode: '0755'
notify: [ 'Refresh host facts' ]
when: timesyncd__enabled | bool
tags: [ 'meta::facts' ]
- name: Update Ansible facts if they were modified
ansible.builtin.meta: 'flush_handlers'
- name: Remove systemd-timesyncd configuration if requested
ansible.builtin.file:
path: '/etc/systemd/timesyncd.conf.d/ansible.conf'
state: 'absent'
notify: [ 'Restart systemd-timesyncd service' ]
when: timesyncd__enabled | bool and timesyncd__deploy_state == 'absent'
- name: Create systemd-timesyncd configuration directory
ansible.builtin.file:
path: '/etc/systemd/timesyncd.conf.d'
state: 'directory'
mode: '0755'
when: timesyncd__enabled | bool and timesyncd__deploy_state != 'absent'
- name: Generate systemd-timesyncd configuration
ansible.builtin.template:
src: 'etc/systemd/timesyncd.conf.d/ansible.conf.j2'
dest: '/etc/systemd/timesyncd.conf.d/ansible.conf'
mode: '0644'
notify: [ 'Restart systemd-timesyncd service' ]
when: timesyncd__enabled | bool and timesyncd__deploy_state != 'absent'
- name: Flush handlers when needed
ansible.builtin.meta: 'flush_handlers'
- name: Prepare cleanup during package removal
ansible.builtin.import_role:
name: 'dpkg_cleanup'
vars:
dpkg_cleanup__dependent_packages:
- '{{ timesyncd__dpkg_cleanup__dependent_packages }}'
when: timesyncd__enabled | bool
tags: [ 'role::dpkg_cleanup', 'skip::dpkg_cleanup',
'role::timesyncd:dpkg_cleanup' ]

View file

@ -0,0 +1,39 @@
#!{{ ansible_python['executable'] }}
# -*- coding: utf-8 -*-
# Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2023 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# {{ ansible_managed }}
from __future__ import print_function
from json import loads, dumps
import subprocess
import os
def binary_exists(binary):
if os.path.exists(binary) and os.path.isfile(binary):
return True
else:
return False
output = {'installed': binary_exists('/lib/systemd/systemd-timesyncd'),
'enabled': loads('''{{ timesyncd__enabled
| bool | to_json }}''')}
try:
timesyncd_version_stdout = subprocess.check_output(
["timedatectl", "--version"]
).decode('utf-8').strip()
for line in timesyncd_version_stdout.split('\n'):
if line.lower().startswith('systemd '):
output['version'] = line.split()[1]
except Exception:
pass
print(dumps(output, sort_keys=True, indent=4))

View file

@ -0,0 +1,40 @@
{# Copyright (C) 2023 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2023 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# {{ ansible_managed }}
# See timesyncd.conf(5) for details.
[Time]
{% for element in timesyncd__combined_configuration | debops.debops.parse_kv_config %}
{% if element.name | d() and element.state | d('present') not in [ 'absent', 'ignore' ] %}
{% set element_comment = ('#' if (element.state | d('present') in [ 'init', 'comment' ]) else '') %}
{% if element.value is undefined %}
{% set element_value = '' %}
{% elif element.value is string and not element.value | bool %}
{% set element_value = element.value %}
{% elif element.value | bool and element.value is not iterable %}
{% if element.value | string == '1' %}
{% set element_value = element.value %}
{% else %}
{% set element_value = 'yes' %}
{% endif %}
{% elif not element.value | bool and element.value is not iterable %}
{% if element.value is not none %}
{% if element.value | int %}
{% set element_value = element.value %}
{% else %}
{% if element.value | string == '0' %}
{% set element_value = element.value %}
{% else %}
{% set element_value = 'no' %}
{% endif %}
{% endif %}
{% endif %}
{% else %}
{% set element_value = element.value | selectattr('state', 'equalto', 'present') | map(attribute='name') | list | join(' ') %}
{% endif %}
{{ '{}{}={}'.format(element_comment, element.name, element_value) }}
{% endif %}
{% endfor %}