--- # Idempotently registers dedicated disks on Longhorn worker nodes and removes # the auto-created default disk at /var/lib/longhorn. # Runs after helm.yml — Longhorn must already be installed. # ── Step 1: wait for Longhorn to discover all worker nodes ──────────────────── - name: Disks | Wait for worker nodes to appear in Longhorn ansible.builtin.command: argv: [kubectl, get, node.longhorn.io, "{{ item }}", -n, "{{ longhorn_namespace }}"] loop: "{{ groups['workers'] }}" register: _lh_node_wait until: _lh_node_wait.rc == 0 retries: 24 delay: 5 changed_when: false failed_when: _lh_node_wait.rc != 0 and _lh_node_wait.attempts | default(0) >= 24 environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin # ── Step 2: register dedicated disks via k8s_json_patch ── # - name: Disks | Install python kubernetes library for kubernetes.core modules # ansible.builtin.pip: # name: # - kubernetes # # Rocky Linux's rpm-packaged python3-oauthlib (3.1.1) strips SIGNATURE_RSA # # (crypto hardening), which breaks requests-oauthlib's import used by the # # kubernetes library. A bare "oauthlib" pip requirement is satisfied by # # that already-installed 3.1.1 and no-ops, so the version floor is # # required to force pip to actually install a newer, unpatched build. # - "oauthlib>=3.2.0" # executable: pip3 - name: Disks | Build flat worker-disk list ansible.builtin.set_fact: _lh_worker_disks: "{{ _lh_worker_disks | default([]) + [hostvars[item].longhorn_disks | default([]) | map('combine', {'node': item}) | list] | flatten }}" loop: "{{ groups['workers'] }}" - name: Disks | Register dedicated disk on Longhorn node kubernetes.core.k8s_json_patch: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item.node }}" patch: - op: add path: "/spec/disks/{{ item.mountpoint | basename | replace('/', '~1') }}" value: path: "{{ item.mountpoint }}" allowScheduling: "{{ item.allowScheduling | default(true) }}" diskType: "{{ item.diskType | default('filesystem') }}" storageReserved: "{{ item.storageReserved | default(0) }}" loop: "{{ _lh_worker_disks | default([]) }}" loop_control: label: "{{ item.node }}/{{ item.mountpoint | basename }}" register: _disk_patch changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin # ── Step 3: remove auto-created default disk at /var/lib/longhorn ───────────── - name: Disks | Get current disk spec for each worker node kubernetes.core.k8s_info: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item }}" loop: "{{ groups['workers'] }}" register: _lh_node_info changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin - name: Disks | Disable auto-created default disk (required before removal) kubernetes.core.k8s_json_patch: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item.item }}" patch: - op: add path: "/spec/disks/{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | first | default({key: ''}) | key | replace('/', '~1') }}" value: path: "{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | first | default({value: {value: {}}}) | value | path | default('/var/lib/longhorn/') }}" allowScheduling: false diskType: "filesystem" loop: "{{ _lh_node_info.results }}" when: - item.resources | length > 0 - item.resources[0].spec.disks | default({}) | dict2items | selectattr('key', 'match', 'default-disk-.*') | selectattr('value.allowScheduling', 'equalto', true) | list | length > 0 register: _disable_default changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin - name: Disks | Remove auto-created default disk kubernetes.core.k8s_json_patch: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item.item }}" patch: - op: remove path: "/spec/disks/{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | map(attribute='key') | first | default('') | replace('/', '~1') }}" loop: "{{ _lh_node_info.results }}" when: - item.resources | length > 0 - item.resources[0].spec.disks | default({}) | dict2items | selectattr('key', 'match', 'default-disk-.*') | list | length > 0 register: _remove_default changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin # ── Step 4: remove auto-created default disk from control_plane nodes ───────── # Control plane nodes have no dedicated storage disks; Longhorn must not # schedule replicas on the small OS disk (/var/lib/longhorn/). - name: Disks | Get current disk spec for control_plane nodes kubernetes.core.k8s_info: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item }}" loop: "{{ groups['control_plane'] }}" register: _lh_cp_node_info changed_when: false failed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin - name: Disks | Disable auto-created default disk on control_plane nodes kubernetes.core.k8s_json_patch: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item.item }}" patch: - op: add path: "/spec/disks/{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | first | default({key: ''}) | key | replace('/', '~1') }}" value: path: "{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | first | default({value: {}}) | value | path | default('/var/lib/longhorn/') }}" allowScheduling: false diskType: "filesystem" loop: "{{ _lh_cp_node_info.results }}" when: - item.resources | length > 0 - item.resources[0].spec.disks | default({}) | dict2items | selectattr('key', 'match', 'default-disk-.*') | selectattr('value.allowScheduling', 'equalto', true) | list | length > 0 register: _disable_cp_default changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin - name: Disks | Remove auto-created default disk from control_plane nodes kubernetes.core.k8s_json_patch: api_version: longhorn.io/v1beta2 kind: Node namespace: "{{ longhorn_namespace }}" name: "{{ item.item }}" patch: - op: remove path: "/spec/disks/{{ item.resources[0].spec.disks | dict2items | selectattr('key', 'match', 'default-disk-.*') | map(attribute='key') | first | default('') | replace('/', '~1') }}" loop: "{{ _lh_cp_node_info.results }}" when: - item.resources | length > 0 - item.resources[0].spec.disks | default({}) | dict2items | selectattr('key', 'match', 'default-disk-.*') | list | length > 0 register: _remove_cp_default changed_when: false environment: KUBECONFIG: "{{ longhorn_kubeconfig }}" PATH: /usr/local/bin:/usr/bin:/bin