prole/infrastructure/roles/k3s/tasks/cnpg.yml
chrisfu 57a7f12e7d k3s: Fix CloudNative-PG installation and improve Retropie networking
- Fixed YAML syntax and Python version parsing in CNPG operator tasks.
- Added automated detection of active network interface (eth0 vs wlan0) for Retropie and Pi nodes to ensure correct K3s configuration.
- Implemented persistent node taints for retropie.prole.org to exclude CloudNative-PG workloads.
- Added a rollout restart mechanism for cnpg-controller-manager to recover from scheduling on tainted or unstable nodes.
- Removed redundant kubectl-cnpg dependency from the Python installer as it is now managed by Ansible.
- Improved prole.sh to force color output for Ansible playbooks.
- Updated prole.cfg with active K3s token and CNPG version information.
2026-02-17 17:32:47 -08:00

248 lines
8.1 KiB
YAML

---
- name: Load CNPG release series from prole.cfg
ansible.builtin.set_fact:
cnpg_release_series_raw: "{{ lookup('ansible.builtin.ini', 'CNPG_RELEASE_SERIES section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='1.28') }}"
- name: Normalize CNPG release series
ansible.builtin.set_fact:
cnpg_release_series: "{{ cnpg_release_series_raw | trim | regex_replace('^v', '') }}"
- name: Resolve latest CNPG release for series
ansible.builtin.shell: |
python3 - <<'PY'
import json
import sys
import urllib.request
series = "{{ cnpg_release_series }}"
url = "https://api.github.com/repos/cloudnative-pg/cloudnative-pg/releases?per_page=100"
try:
with urllib.request.urlopen(url, timeout=10) as resp:
data = json.load(resp)
except Exception:
print("")
sys.exit(0)
versions = []
for rel in data:
tag = (rel.get("tag_name") or "").lstrip("v")
if tag.startswith(series + "."):
try:
tuple(int(x) for x in tag.split("."))
versions.append(tag)
except ValueError:
continue
if not versions:
print("")
sys.exit(0)
def parse(v):
return tuple(int(x) for x in v.split("."))
versions.sort(key=parse)
print(versions[-1])
PY
register: cnpg_latest_version_cmd
changed_when: false
run_once: true
delegate_to: localhost
become: false
- name: Cache CNPG latest version
ansible.builtin.set_fact:
cnpg_latest_version: "{{ (cnpg_latest_version_cmd.stdout | trim) if (cnpg_latest_version_cmd.stdout | trim) else (cnpg_release_series ~ '.0') }}"
run_once: true
delegate_to: localhost
delegate_facts: true
become: false
- name: Share CNPG latest version
ansible.builtin.set_fact:
cnpg_latest_version: "{{ hostvars['localhost'].cnpg_latest_version }}"
- name: Build CNPG manifest URL
ansible.builtin.set_fact:
cnpg_manifest_url: "https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-{{ cnpg_release_series }}/releases/cnpg-{{ cnpg_latest_version }}.yaml"
- name: Check prole.cfg on controller
ansible.builtin.stat:
path: "{{ playbook_dir }}/../../conf/prole.cfg"
register: cnpg_prole_cfg
run_once: true
delegate_to: localhost
become: false
- name: Save CNPG release series to prole.cfg
ansible.builtin.lineinfile:
path: "{{ playbook_dir }}/../../conf/prole.cfg"
regexp: '^CNPG_RELEASE_SERIES\s*='
line: "CNPG_RELEASE_SERIES = {{ cnpg_release_series }}"
insertafter: '^\[Global\]'
run_once: true
delegate_to: localhost
become: false
when: cnpg_prole_cfg.stat.exists
- name: Save CNPG version to prole.cfg
ansible.builtin.lineinfile:
path: "{{ playbook_dir }}/../../conf/prole.cfg"
regexp: '^CNPG_VERSION\s*='
line: "CNPG_VERSION = {{ cnpg_latest_version }}"
insertafter: '^\[Global\]'
run_once: true
delegate_to: localhost
become: false
when: cnpg_prole_cfg.stat.exists
- name: Load k3s server URL from prole.cfg
ansible.builtin.set_fact:
cnpg_prole_k3s_server_cfg: "{{ lookup('ansible.builtin.ini', 'PROLE_K3S_SERVER section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='') }}"
- name: Resolve k3s API URL for kubectl
ansible.builtin.set_fact:
cnpg_k3s_server_url_raw: >-
{{ (k3s_server_url | default('')) if (k3s_server_url | default('') | length > 0)
else (cnpg_prole_k3s_server_cfg | default('')) if (cnpg_prole_k3s_server_cfg | default('') | length > 0)
else 'https://' + inventory_hostname + ':6443' }}
- name: Normalize k3s API URL for kubectl
ansible.builtin.set_fact:
cnpg_k3s_server_url: "{{ cnpg_k3s_server_url_raw if cnpg_k3s_server_url_raw.startswith('http') else 'https://' + cnpg_k3s_server_url_raw }}"
- name: Check for local k3s kubeconfig
ansible.builtin.stat:
path: /etc/rancher/k3s/k3s.yaml
register: cnpg_kubeconfig_stat
- name: Ensure k3s kubeconfig for kubectl on hosts
ansible.builtin.copy:
dest: /etc/rancher/k3s/k3s.yaml
owner: root
group: "{{ k3s_kubeconfig_group | default('root') }}"
mode: "{{ k3s_write_kubeconfig_mode | default('0640') }}"
content: |
apiVersion: v1
kind: Config
clusters:
- cluster:
server: {{ cnpg_k3s_server_url }}
insecure-skip-tls-verify: true
name: prole-k3s
contexts:
- context:
cluster: prole-k3s
user: prole-k3s
name: prole-k3s
current-context: prole-k3s
users:
- name: prole-k3s
user:
token: {{ k3s_token }}
when:
- not cnpg_kubeconfig_stat.stat.exists
- cnpg_k3s_server_url | length > 0
- k3s_token | default('') | length > 0
- name: Check k3s API availability for CNPG
ansible.builtin.command: kubectl get nodes
environment:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
register: cnpg_k3s_api_check
changed_when: false
failed_when: false
- name: Map kubectl-cnpg architecture
ansible.builtin.set_fact:
cnpg_arch_map:
x86_64: x86_64
amd64: x86_64
aarch64: arm64
arm64: arm64
ppc64le: ppc64le
s390x: s390x
- name: Set cnpg architecture and supported arches
ansible.builtin.set_fact:
cnpg_arch: "{{ cnpg_arch_map.get(ansible_architecture, ansible_architecture) }}"
cnpg_supported_arches:
- x86_64
- arm64
- ppc64le
- s390x
- name: Check kubectl-cnpg version
ansible.builtin.command: kubectl cnpg version
register: cnpg_plugin_version_check
changed_when: false
failed_when: false
- name: Parse installed kubectl-cnpg version
ansible.builtin.set_fact:
cnpg_plugin_installed_version: "{{ (cnpg_plugin_version_check.stdout ~ ' ' ~ cnpg_plugin_version_check.stderr) | regex_search('Version:([0-9]+\\.[0-9]+\\.[0-9]+)', '\\1') | default('') }}"
- name: Build kubectl-cnpg download URL
ansible.builtin.set_fact:
cnpg_plugin_asset: "kubectl-cnpg_{{ cnpg_latest_version }}_linux_{{ cnpg_arch }}.tar.gz"
cnpg_plugin_url: "https://github.com/cloudnative-pg/cloudnative-pg/releases/download/v{{ cnpg_latest_version }}/kubectl-cnpg_{{ cnpg_latest_version }}_linux_{{ cnpg_arch }}.tar.gz"
when: cnpg_arch in cnpg_supported_arches
- name: Download kubectl-cnpg
ansible.builtin.get_url:
url: "{{ cnpg_plugin_url }}"
dest: "/tmp/{{ cnpg_plugin_asset }}"
mode: "0644"
when:
- cnpg_arch in cnpg_supported_arches
- cnpg_plugin_installed_version != cnpg_latest_version
- name: Install kubectl-cnpg
ansible.builtin.unarchive:
src: "/tmp/{{ cnpg_plugin_asset }}"
dest: /usr/local/bin
remote_src: true
when:
- cnpg_arch in cnpg_supported_arches
- cnpg_plugin_installed_version != cnpg_latest_version
- name: Ensure kubectl-cnpg is executable
ansible.builtin.file:
path: /usr/local/bin/kubectl-cnpg
mode: "0755"
when:
- cnpg_arch in cnpg_supported_arches
- cnpg_plugin_installed_version != cnpg_latest_version
- name: Apply CNPG operator manifest
ansible.builtin.command: kubectl apply --server-side -f {{ cnpg_manifest_url }}
environment:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
register: cnpg_apply
changed_when: "'created' in cnpg_apply.stdout or 'configured' in cnpg_apply.stdout"
when: cnpg_k3s_api_check.rc == 0
- name: Verify CNPG controller rollout
ansible.builtin.command: kubectl rollout status deployment -n cnpg-system cnpg-controller-manager --timeout=60s
environment:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
register: cnpg_rollout_check
changed_when: false
failed_when: false
when: cnpg_k3s_api_check.rc == 0
- name: Restart CNPG controller if rollout failed (possibly stuck on tainted node)
ansible.builtin.command: kubectl rollout restart deployment -n cnpg-system cnpg-controller-manager
environment:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
when:
- cnpg_k3s_api_check.rc == 0
- cnpg_rollout_check.rc != 0
changed_when: true
- name: Final CNPG controller rollout check
ansible.builtin.command: kubectl rollout status deployment -n cnpg-system cnpg-controller-manager --timeout=300s
environment:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
changed_when: false
when: cnpg_k3s_api_check.rc == 0