diff --git a/tasks/client.yml b/tasks/client.yml index de4fa89..22f6cca 100644 --- a/tasks/client.yml +++ b/tasks/client.yml @@ -89,6 +89,9 @@ vars: _cvmfs_repo_option_key: client +- name: Include partial replica client tasks + ansible.builtin.include_tasks: client_partial_replica.yml + - name: Install cvmfs_wipecache setuid binary ansible.builtin.copy: src: cvmfs_wipecache.{{ _cvmfs_install_setuid_platform }}_{{ ansible_distribution_major_version }} diff --git a/tasks/client_partial_replica.yml b/tasks/client_partial_replica.yml new file mode 100644 index 0000000..b370446 --- /dev/null +++ b/tasks/client_partial_replica.yml @@ -0,0 +1,63 @@ +--- +# Client-side opt-in for using a partial Stratum 1 replica, driven by an +# optional per-repo dict: +# +# cvmfs_repositories[*].partial_replica_client: +# enabled: true +# mode: failover # or: fail +# # Optional per-repo override of CVMFS_SERVER_URL pointing the client +# # at the partial replica (a ';'-separated list is allowed, the +# # regular server list failover semantics apply). Without it, the +# # domain-level CVMFS_SERVER_URL is used. +# server_url: "http://partial-s1.example.org/cvmfs/repo.example.org" +# # Required for mode 'failover'. Ignored for mode 'fail'. +# full_stratum1_url: "http://full-s1.example.org/cvmfs/repo.example.org" +# +# The config is written to /etc/cvmfs/config.d/.local, the last file +# in the client's config chain, so it overrides domain-level settings. +# That file is considered fully managed here; do not mix other settings in. +# +# Requires CernVM-FS >= 2.14.0 on the client. + +- name: Validate partial replica client configuration + ansible.builtin.assert: + that: + - item.partial_replica_client.mode in ['failover', 'fail'] + - item.partial_replica_client.mode == 'fail' or + item.partial_replica_client.full_stratum1_url is defined + fail_msg: >- + Invalid partial_replica_client for {{ item.repository }}: mode must + be 'failover' or 'fail'; 'failover' requires full_stratum1_url. + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }}: validate partial_replica_client" + when: item.partial_replica_client is defined and item.partial_replica_client.enabled + +- name: Write partial replica client configuration + ansible.builtin.copy: + dest: "/etc/cvmfs/config.d/{{ item.repository }}.local" + content: | + ## This file is maintained by Ansible - CHANGES WILL BE OVERWRITTEN + {% if item.partial_replica_client.server_url is defined %} + CVMFS_SERVER_URL="{{ item.partial_replica_client.server_url }}" + {% endif %} + CVMFS_PARTIAL_REPLICA_MODE={{ item.partial_replica_client.mode }} + {% if item.partial_replica_client.mode == 'failover' %} + CVMFS_FULL_STRATUM1_URL="{{ item.partial_replica_client.full_stratum1_url }}" + {% endif %} + owner: root + group: root + mode: 0444 + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "/etc/cvmfs/config.d/{{ item.repository }}.local" + when: item.partial_replica_client is defined and item.partial_replica_client.enabled + +- name: Remove partial replica client configuration (full-replica fallback) + ansible.builtin.file: + dest: "/etc/cvmfs/config.d/{{ item.repository }}.local" + state: absent + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "/etc/cvmfs/config.d/{{ item.repository }}.local" + when: item.partial_replica_client is not defined or not item.partial_replica_client.enabled diff --git a/tasks/partial_replication.yml b/tasks/partial_replication.yml new file mode 100644 index 0000000..96de32e --- /dev/null +++ b/tasks/partial_replication.yml @@ -0,0 +1,52 @@ +--- +- name: Write partial replication specifications + ansible.builtin.copy: + dest: /etc/cvmfs/repositories.d/{{ item.repository }}/partial-replication.spec + content: "version 1\n{% for path in item.partial_replication.paths %}{{ path }}\n{% endfor %}" + mode: 0644 + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }} partial-replication.spec" + when: item.partial_replication is defined and item.partial_replication.enabled + +- name: Enable partial replication flag in server configuration + ansible.builtin.lineinfile: + path: /etc/cvmfs/repositories.d/{{ item.repository }}/server.conf + regexp: '^CVMFS_PARTIAL_REPLICATION=.*' + line: 'CVMFS_PARTIAL_REPLICATION=true' + mode: 0644 + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }}: CVMFS_PARTIAL_REPLICATION" + when: item.partial_replication is defined and item.partial_replication.enabled + +- name: Set partial replication specification path in server configuration + ansible.builtin.lineinfile: + path: /etc/cvmfs/repositories.d/{{ item.repository }}/server.conf + regexp: '^CVMFS_PARTIAL_REPLICATION_SPEC=.*' + line: 'CVMFS_PARTIAL_REPLICATION_SPEC=/etc/cvmfs/repositories.d/{{ item.repository }}/partial-replication.spec' + mode: 0644 + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }}: CVMFS_PARTIAL_REPLICATION_SPEC" + when: item.partial_replication is defined and item.partial_replication.enabled + +- name: Remove partial replication specification file (full-sync fallback) + ansible.builtin.file: + path: /etc/cvmfs/repositories.d/{{ item.repository }}/partial-replication.spec + state: absent + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }}: remove partial-replication.spec" + when: item.partial_replication is not defined or not item.partial_replication.enabled + +- name: Remove partial replication lines from server configuration (full-sync fallback) + ansible.builtin.lineinfile: + path: /etc/cvmfs/repositories.d/{{ item.repository }}/server.conf + regexp: '^CVMFS_PARTIAL_REPLICATION(_SPEC)?=.*' + state: absent + loop: "{{ cvmfs_repositories }}" + loop_control: + label: "{{ item.repository }}: clear partial replication lines" + when: item.partial_replication is not defined or not item.partial_replication.enabled + diff --git a/tasks/stratum1.yml b/tasks/stratum1.yml index ab866fa..5d59da6 100644 --- a/tasks/stratum1.yml +++ b/tasks/stratum1.yml @@ -102,6 +102,9 @@ vars: _cvmfs_repo_option_key: server +- name: Include partial replication tasks + ansible.builtin.include_tasks: partial_replication.yml + - name: Perform initial snapshot ansible.builtin.command: /usr/bin/cvmfs_server snapshot {{ item.item.repository }} loop: "{{ __cvmfs_add_replica_result.results }}"