Files
cluster-knaster/platform/proxmox/ansible/roles/pve-host/tasks/main.yml
T
2026-10-12 19:41:17 +02:00

162 lines
5.6 KiB
YAML

- name: Site-Datei laden
ansible.builtin.set_fact:
knaster_pve: "{{ lookup('ansible.builtin.file', pve_site_file) | from_yaml }}"
run_once: true
delegate_to: localhost
- name: Bootloader erkennen (systemd-boot bei ZFS-Root, sonst GRUB)
ansible.builtin.stat:
path: /etc/kernel/cmdline
register: kernel_cmdline
- name: IOMMU aktivieren (systemd-boot)
ansible.builtin.replace:
path: /etc/kernel/cmdline
regexp: '^((?!.*intel_iommu=on).*)$'
replace: '\1 {{ pve_iommu_cmdline }}'
when: kernel_cmdline.stat.exists
notify: refresh boot
- name: IOMMU aktivieren (GRUB)
ansible.builtin.lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((?!.*intel_iommu=on).*)"$'
line: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 {{ pve_iommu_cmdline }}"'
backrefs: true
when: not kernel_cmdline.stat.exists
notify: refresh boot
- name: VFIO-Module laden
ansible.builtin.copy:
dest: /etc/modules-load.d/vfio.conf
content: "{{ pve_vfio_modules | join('\n') }}\n"
mode: "0644"
notify: update initramfs
# IDs auf dem Knoten lesen, nicht aus dem Gedächtnis: Grafik- und Audio-Funktion jeder Karte
- name: NVIDIA-Funktionen des Knotens lesen
ansible.builtin.shell: |
set -o pipefail
lspci -n -d 10de: | awk '{print $3}' | sort -u | paste -sd,
args:
executable: /bin/bash
register: nvidia_ids
check_mode: false
changed_when: false
failed_when: nvidia_ids.rc != 0 or nvidia_ids.stdout == ''
- name: Karten an vfio-pci binden, bevor ein Grafik- oder Audiotreiber zugreift
ansible.builtin.copy:
dest: /etc/modprobe.d/vfio.conf
content: |
options vfio-pci ids={{ nvidia_ids.stdout }}
softdep nouveau pre: vfio-pci
softdep nvidia pre: vfio-pci
softdep nvidiafb pre: vfio-pci
softdep snd_hda_intel pre: vfio-pci
mode: "0644"
notify: update initramfs
- name: NVIDIA-Treiber auf dem Host sperren (GPU gehört der VM)
ansible.builtin.copy:
dest: /etc/modprobe.d/blacklist-nvidia.conf
content: |
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
mode: "0644"
notify: update initramfs
- name: Speicher local darf Snippets enthalten (clusterweite Einstellung, einmal)
ansible.builtin.shell: |
set -euo pipefail
c=$(pvesh get /storage/local --output-format json | python3 -c 'import json,sys; print(json.load(sys.stdin)["content"])')
case ",$c," in
*,snippets,*) echo unverändert ;;
*) pvesm set local --content "$c,snippets"; echo geändert ;;
esac
args:
executable: /bin/bash
register: snippets
changed_when: "'geändert' in snippets.stdout"
run_once: true
- name: Snippet-Verzeichnis
ansible.builtin.file:
path: "{{ pve_vendor_snippet | dirname }}"
state: directory
mode: "0755"
- name: cloud-init-Vendor-Daten für GPU-VMs (qemu-guest-agent meldet tofu die DHCP-Adresse)
ansible.builtin.copy:
dest: "{{ pve_vendor_snippet }}"
content: |
#cloud-config
packages: [qemu-guest-agent]
runcmd:
- [systemctl, enable, --now, qemu-guest-agent]
mode: "0644"
- name: Container auf diesem Knoten lesen
ansible.builtin.command: ls /etc/pve/lxc/
register: local_cts
check_mode: false
changed_when: false
- name: Bestehende Replikationsjobs lesen
ansible.builtin.command: pvesr list
register: pvesr_jobs
check_mode: false
changed_when: false
- name: ZFS-Replikation für Infra-Gäste (erst wenn der Container auf diesem Knoten existiert)
ansible.builtin.command: >
pvesr create-local-job {{ item.0.value.vmid }}-{{ idx }} {{ item.1 }}
--schedule '{{ knaster_pve.replication_schedule }}' --comment 'knaster {{ item.0.key }}'
loop: "{{ knaster_pve.containers | dict2items | subelements('value.replicate_to', skip_missing=True) }}"
vars:
idx: "{{ item.0.value.replicate_to.index(item.1) }}"
when:
- item.0.value.node == inventory_hostname
- (item.0.value.vmid | string) + '.conf' in local_cts.stdout_lines
- (item.0.value.vmid | string) + '-' + (idx | string) not in pvesr_jobs.stdout
changed_when: true
- name: HA-Konfiguration lesen
ansible.builtin.command: ha-manager config
register: ha_config
check_mode: false
changed_when: false
- name: Infra-Gäste unter HA stellen (erst wenn der Container auf diesem Knoten existiert)
ansible.builtin.command: >
ha-manager add ct:{{ item.value.vmid }} --state started --max_restart 1 --max_relocate 1
--comment 'knaster {{ item.key }}'
loop: "{{ knaster_pve.containers | dict2items }}"
when:
- item.value.ha | default(false)
- item.value.node == inventory_hostname
- (item.value.vmid | string) + '.conf' in local_cts.stdout_lines
- ('ct:' + (item.value.vmid | string)) not in ha_config.stdout
changed_when: true
- name: HA-Regeln lesen
ansible.builtin.command: ha-manager rules config
register: ha_rules
check_mode: false
changed_when: false
# Strikt: Die Gäste liegen auf tank, den gibt es nur auf dem Heimatknoten und den Replikationszielen
- name: Node-Affinity für Infra-Gäste (Heimatknoten bevorzugt, sonst Replikationsziele)
ansible.builtin.command: >
ha-manager rules add node-affinity knaster-{{ item.key }} --resources ct:{{ item.value.vmid }}
--nodes {{ ([item.value.node ~ ':2'] + (item.value.replicate_to | map('regex_replace', '$', ':1') | list)) | join(',') }}
--strict 1 --comment 'knaster {{ item.key }}'
loop: "{{ knaster_pve.containers | dict2items }}"
when:
- item.value.ha | default(false)
- item.value.node == inventory_hostname
- (item.value.vmid | string) + '.conf' in local_cts.stdout_lines
- ('knaster-' + item.key) not in ha_rules.stdout
changed_when: true