From bf31836ae3c3d8e2a147d5678865fc72c3c29c2a Mon Sep 17 00:00:00 2001 From: Juunjus Date: Sun, 26 Apr 2026 02:38:38 +0200 Subject: [PATCH 1/2] WIP --- README.md | 14 +++++++------- defaults/main.yml | 22 +++++++++++++++------- tasks/chrony.yml | 19 +++++++++++++++---- tasks/main.yml | 5 +++++ templates/chrony_source_file.conf.j2 | 4 ++++ vars/Debian-trixie.yml | 4 ++++ 6 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 templates/chrony_source_file.conf.j2 create mode 100644 vars/Debian-trixie.yml diff --git a/README.md b/README.md index 07c1200..7b16263 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,13 @@ Configuration of timezone and ntp settings * Fedora 25 Server ## Configuration -| Name | Default value | Description | -|------|---------------|-------------| -|`timezone_area` | `Europe` | Timezone area | -|`timezone` | `Zurich` | Exact timezone (area needs to match) | -|`ntp_servers` | `["time.ethz.ch", "swisstime.ethz.ch"]` | Timeservers. Note that these are only guaranteed to be accessible from inside ETH's network, so you might need to specify different ones. | -|`ntp_sources_dir` | `/etc/chrony/sources.d` | Directory for optional Chrony source drop-ins. | -|`ntp_sources_files` | `[]` | Optional list of drop-in files and server lists to render as `server ... iburst` lines. | +| Name | Default value | Description | +| ------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `timezone_area` | `Europe` | Timezone area | +| `timezone` | `Zurich` | Exact timezone (area needs to match) | +| `ntp_servers` | `["time.ethz.ch", "swisstime.ethz.ch"]` | Timeservers. Note that these are only guaranteed to be accessible from inside ETH's network, so you might need to specify different ones. | +| `ntp_sources_dir` | `/etc/chrony/sources.d` | Directory for optional Chrony source drop-ins. | +| `ntp_sources_files` | `[]` | Optional list of drop-in files and server lists to render as `server ... iburst` lines. | ### Proxmox 9 / Debian Trixie drop-in example diff --git a/defaults/main.yml b/defaults/main.yml index ac7935e..ea9c88e 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -17,11 +17,19 @@ ntp_servers: # Optional Chrony drop-in source files. # The legacy ntp_servers-based chrony.conf remains managed as before. -ntp_sources_dir: /etc/chrony/sources.d +ntp_sources_dir: + dir: /etc/chrony/sources.d + # List of drop-in source files to manage. + # Example: + # files: + # - name: ethz.sources + # servers: [time.ethz.ch, swisstime.ethz.ch] + files: [] -# List of drop-in source files to manage. -# Example: -# ntp_sources_files: -# - name: ethz.sources -# servers: [time.ethz.ch, time6.ethz.ch] -ntp_sources_files: [] +# Prefer using a chrony conf.d drop-in instead of managing the main +# chrony.conf. Can be overridden in OS/release-specific vars. +# Path for the managed drop-in file when time_chrony_use_dropins=true. +time_chrony_conf_dropin_dir: + use: false + dir: /etc/chrony/conf.d/ + defaultFile: custom.conf diff --git a/tasks/chrony.yml b/tasks/chrony.yml index 708fa10..00e3bb1 100644 --- a/tasks/chrony.yml +++ b/tasks/chrony.yml @@ -21,8 +21,9 @@ mode: "0644" notify: - Restart chronyd + when: not time_chrony_use_dropins -- name: Ensure chrony sources.d exists +- name: Ensure chrony conf.d exists become: true ansible.builtin.file: path: "{{ ntp_sources_dir }}" @@ -30,9 +31,19 @@ owner: root group: root mode: "0755" - when: ntp_sources_files | length > 0 + when: (ntp_sources_files | length > 0) + +- name: Ensure chrony sources.d exists + become: true + ansible.builtin.file: + path: /etc/chrony/sources.d + state: directory + owner: root + group: root + mode: "0755" + when: (ntp_sources_files | length > 0) -- name: Install chronyd source drop-ins +- name: Install chronyd conf.d drop-in become: true ansible.builtin.template: src: chrony_source_file.j2 @@ -43,7 +54,7 @@ loop: "{{ ntp_sources_files }}" notify: - Restart chronyd - when: ntp_sources_files | length > 0 + when: time_chrony_use_dropins - name: Enable chronyd become: true diff --git a/tasks/main.yml b/tasks/main.yml index 36df235..d86bc73 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -2,6 +2,11 @@ - name: Load OS specific variables ansible.builtin.include_vars: "{{ ansible_facts.distribution }}.yml" +- name: Load OS release specific variables + ansible.builtin.include_vars: + file: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_release }}.yml" + failed_when: false + - name: Override default time client variable ansible.builtin.set_fact: time_client: "{{ time_client_override }}" diff --git a/templates/chrony_source_file.conf.j2 b/templates/chrony_source_file.conf.j2 new file mode 100644 index 0000000..513b6ff --- /dev/null +++ b/templates/chrony_source_file.conf.j2 @@ -0,0 +1,4 @@ +# Managed with Ansible +{% for s in ntp_servers %} +server {{ s }} iburst +{% endfor %} diff --git a/vars/Debian-trixie.yml b/vars/Debian-trixie.yml new file mode 100644 index 0000000..808eae5 --- /dev/null +++ b/vars/Debian-trixie.yml @@ -0,0 +1,4 @@ +--- +# Debian 13 / Trixie: keep vendor chrony.conf and manage sources via drop-ins. +time_chrony_use_dropins: true +ntp_sources_dir: /etc/chrony/sources.d From a26d88594f43faf6ea9f38f37342d0c725fe925f Mon Sep 17 00:00:00 2001 From: Juunjus Date: Sun, 26 Apr 2026 09:31:04 +0200 Subject: [PATCH 2/2] feat(time): add optional chrony conf.d drop-ins Keep the existing /etc/chrony/chrony.conf flow unchanged so chrony.conf is still managed as before. Add optional chrony_conf_dropins and chrony_sources_dropins variables to support chrony conf.d and sources.d drop-in files. When chrony_conf_dropins_enable is set, creates the conf dropin directory and renders etc_chrony.conf as dropin. When chrony_sources_dropin_enable is set, creates the sources dropin directory and renders out sources_files Why: Debian-Trixie prefers drop-in Chrony config files, but existing hosts should keep current behavior with no migration required. --- README.md | 41 ++++++++++----- defaults/main.yml | 22 +++----- tasks/chrony.yml | 52 +++++++++++++++---- ...le.conf.j2 => chrony_sources_file.conf.j2} | 2 +- vars/Debian-trixie.yml | 10 ++-- 5 files changed, 87 insertions(+), 40 deletions(-) rename templates/{chrony_source_file.conf.j2 => chrony_sources_file.conf.j2} (67%) diff --git a/README.md b/README.md index 7b16263..d242016 100644 --- a/README.md +++ b/README.md @@ -8,26 +8,41 @@ Configuration of timezone and ntp settings * Fedora 25 Server ## Configuration -| Name | Default value | Description | -| ------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `timezone_area` | `Europe` | Timezone area | -| `timezone` | `Zurich` | Exact timezone (area needs to match) | -| `ntp_servers` | `["time.ethz.ch", "swisstime.ethz.ch"]` | Timeservers. Note that these are only guaranteed to be accessible from inside ETH's network, so you might need to specify different ones. | -| `ntp_sources_dir` | `/etc/chrony/sources.d` | Directory for optional Chrony source drop-ins. | -| `ntp_sources_files` | `[]` | Optional list of drop-in files and server lists to render as `server ... iburst` lines. | +| Name | Default value | Description | +| -------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `timezone_area` | `Europe` | Timezone area | +| `timezone` | `Zurich` | Exact timezone (area needs to match) | +| `ntp_servers` | `["time.ethz.ch", "swisstime.ethz.ch"]` | Timeservers. Note that these are only guaranteed to be accessible from inside ETH's network, so you might need to specify different ones. | +| `chrony_conf_dropin_enabled` | `false` | Enable managed config drop-in mode (keep vendor main config). | +| `chrony_conf_dropin_dir` | `/etc/chrony/conf.d` | Directory for managed Chrony config drop-in file. | +| `chrony_conf_dropin_file` | `custom.conf` | Filename for managed Chrony config drop-in file. | +| `chrony_sources_dropins_enabled` | `false` | Enable Chrony `sources.d` drop-ins management. | +| `chrony_sources_dropins_dir` | `/etc/chrony/sources.d` | Directory for Chrony source drop-in files. | +| `chrony_sources_dropins_files` | `[]` | List of source files with `name` and `servers`. | ### Proxmox 9 / Debian Trixie drop-in example -Keep existing role behavior (`ntp_servers` still drives `chrony.conf`) and add source drop-ins: +Keep vendor `chrony.conf`, manage our config via conf.d drop-in, and optional sources.d files: ```yaml time_client_override: chrony -ntp_sources_files: - - name: ethz.sources - servers: [time.ethz.ch, time6.ethz.ch] - - name: swiss.sources - servers: [0.ch.pool.ntp.org, 1.ch.pool.ntp.org, 2.ch.pool.ntp.org, 3.ch.pool.ntp.org] + +chrony_conf_dropin_enabled: true +chrony_conf_dropin_dir: /etc/chrony/conf.d +chrony_conf_dropin_file: vis.conf + +chrony_sources_dropins_enabled: true +chrony_sources_dropins_dir: /etc/chrony/sources.d +chrony_sources_dropins_files: + - name: ethz.sources + servers: [time.ethz.ch, time6.ethz.ch] + - name: swiss.sources + servers: [0.ch.pool.ntp.org, 1.ch.pool.ntp.org, 2.ch.pool.ntp.org, 3.ch.pool.ntp.org] ``` +When `chrony_conf_dropin_enabled` or `chrony_sources_dropins_enabled` is true, +the role performs independent preflight checks that `{{ time_chrony_conf_path }}` +contains the matching `confdir`/`sourcedir` directives for the configured directories. + ## License GPLv3 diff --git a/defaults/main.yml b/defaults/main.yml index ea9c88e..9aa4c79 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -15,21 +15,15 @@ ntp_servers: - time.ethz.ch - swisstime.ethz.ch +chrony_conf_dropin_enabled: false +chrony_conf_dropin_dir: /etc/chrony/conf.d +chrony_conf_dropin_file: custom.conf + # Optional Chrony drop-in source files. # The legacy ntp_servers-based chrony.conf remains managed as before. -ntp_sources_dir: - dir: /etc/chrony/sources.d - # List of drop-in source files to manage. - # Example: +chrony_sources_dropins_enabled: false +chrony_sources_dropins_dir: /etc/chrony/sources.d +chrony_sources_dropins_files: [] # files: # - name: ethz.sources - # servers: [time.ethz.ch, swisstime.ethz.ch] - files: [] - -# Prefer using a chrony conf.d drop-in instead of managing the main -# chrony.conf. Can be overridden in OS/release-specific vars. -# Path for the managed drop-in file when time_chrony_use_dropins=true. -time_chrony_conf_dropin_dir: - use: false - dir: /etc/chrony/conf.d/ - defaultFile: custom.conf + # servers: [time.ethz.ch, time6.ethz.ch] diff --git a/tasks/chrony.yml b/tasks/chrony.yml index 00e3bb1..029ad27 100644 --- a/tasks/chrony.yml +++ b/tasks/chrony.yml @@ -11,6 +11,28 @@ name: chrony state: present +- name: Ensure chrony sources.d support is configured + become: true + ansible.builtin.lineinfile: + path: "{{ time_chrony_conf_path }}" + regexp: "^\\s*sourcedir\\s+{{ chrony_sources_dropins_dir | regex_escape }}/?\\s*$" + line: "sourcedir {{ chrony_sources_dropins_dir }}" + state: present + create: false + backup: true + when: chrony_sources_dropins_enabled + +- name: Ensure chrony conf.d support is configured + become: true + ansible.builtin.lineinfile: + path: "{{ time_chrony_conf_path }}" + regexp: "^\\s*confdir\\s+{{ chrony_conf_dropin_dir | regex_escape }}/?\\s*$" + line: "confdir {{ chrony_conf_dropin_dir }}" + state: present + create: false + backup: true + when: chrony_conf_dropin_enabled + - name: Install chronyd configuration become: true ansible.builtin.template: @@ -21,40 +43,52 @@ mode: "0644" notify: - Restart chronyd - when: not time_chrony_use_dropins + when: not chrony_conf_dropin_enabled - name: Ensure chrony conf.d exists become: true ansible.builtin.file: - path: "{{ ntp_sources_dir }}" + path: "{{ chrony_conf_dropin_dir }}" state: directory owner: root group: root mode: "0755" - when: (ntp_sources_files | length > 0) + when: chrony_conf_dropin_enabled - name: Ensure chrony sources.d exists become: true ansible.builtin.file: - path: /etc/chrony/sources.d + path: "{{ chrony_sources_dropins_dir }}" state: directory owner: root group: root mode: "0755" - when: (ntp_sources_files | length > 0) + when: chrony_sources_dropins_enabled - name: Install chronyd conf.d drop-in become: true ansible.builtin.template: - src: chrony_source_file.j2 - dest: "{{ ntp_sources_dir }}/{{ item.name }}" + src: etc_chrony.conf.j2 + dest: "{{ chrony_conf_dropin_dir }}/{{ chrony_conf_dropin_file }}" + owner: root + group: root + mode: "0644" + notify: + - Restart chronyd + when: chrony_conf_dropin_enabled + +- name: Install chronyd source drop-ins + become: true + ansible.builtin.template: + src: chrony_sources_file.conf.j2 + dest: "{{ chrony_sources_dropins_dir }}/{{ item.name }}" owner: root group: root mode: "0644" - loop: "{{ ntp_sources_files }}" + loop: "{{ chrony_sources_dropins_files }}" notify: - Restart chronyd - when: time_chrony_use_dropins + when: chrony_sources_dropins_enabled - name: Enable chronyd become: true diff --git a/templates/chrony_source_file.conf.j2 b/templates/chrony_sources_file.conf.j2 similarity index 67% rename from templates/chrony_source_file.conf.j2 rename to templates/chrony_sources_file.conf.j2 index 513b6ff..cbceb81 100644 --- a/templates/chrony_source_file.conf.j2 +++ b/templates/chrony_sources_file.conf.j2 @@ -1,4 +1,4 @@ # Managed with Ansible -{% for s in ntp_servers %} +{% for s in item.servers %} server {{ s }} iburst {% endfor %} diff --git a/vars/Debian-trixie.yml b/vars/Debian-trixie.yml index 808eae5..5342525 100644 --- a/vars/Debian-trixie.yml +++ b/vars/Debian-trixie.yml @@ -1,4 +1,8 @@ --- -# Debian 13 / Trixie: keep vendor chrony.conf and manage sources via drop-ins. -time_chrony_use_dropins: true -ntp_sources_dir: /etc/chrony/sources.d +# Debian 13 / Trixie: keep vendor chrony.conf and manage drop-ins. +chrony_conf_dropin_enabled: true +chrony_conf_dropin_dir: /etc/chrony/conf.d +chrony_conf_dropin_file: vis.conf + +chrony_sources_dropins_enabled: true +chrony_sources_dropins_dir: /etc/chrony/sources.d