172 lines
6.6 KiB
YAML
172 lines
6.6 KiB
YAML
---
|
|
# =============================================================================
|
|
# proxmox_upgrade — drain.yml
|
|
# Migrate all VMs/LXCs off current_node before upgrading
|
|
# KVM: community.proxmox.proxmox_kvm (API, delegate_to: localhost)
|
|
# LXC: pct migrate (SSH on source node)
|
|
# =============================================================================
|
|
|
|
# ── Discover guests on this node ──────────────────────────────────────────────
|
|
- name: "Drain | Get all guests on {{ current_node }}"
|
|
community.proxmox.proxmox_vm_info:
|
|
api_host: "{{ api_host }}"
|
|
api_user: "{{ api_user }}"
|
|
api_token_id: "{{ api_token_id }}"
|
|
api_token_secret: "{{ api_token_secret }}"
|
|
api_port: "{{ api_port }}"
|
|
node: "{{ current_node }}"
|
|
register: node_guests
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Get available target nodes"
|
|
community.proxmox.proxmox_node_info:
|
|
api_host: "{{ api_host }}"
|
|
api_user: "{{ api_user }}"
|
|
api_token_id: "{{ api_token_id }}"
|
|
api_token_secret: "{{ api_token_secret }}"
|
|
api_port: "{{ api_port }}"
|
|
register: all_nodes_info
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Set migration target"
|
|
ansible.builtin.set_fact:
|
|
migration_target: >-
|
|
{{ all_nodes_info.proxmox_nodes
|
|
| selectattr('status', 'equalto', 'online')
|
|
| rejectattr('node', 'equalto', current_node)
|
|
| map(attribute='node')
|
|
| list
|
|
| first }}
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Fail if no migration target available"
|
|
ansible.builtin.fail:
|
|
msg: "No online nodes available to migrate guests to. Cannot drain {{ current_node }}."
|
|
when: migration_target is not defined or migration_target == ''
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Log raw guest data (for debugging)"
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Guests on {{ current_node }}:
|
|
vmids={{ node_guests.proxmox_vms | map(attribute='vmid') | list }}
|
|
first_vm_keys={{ node_guests.proxmox_vms | first | list }}
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Build KVM migration list"
|
|
ansible.builtin.set_fact:
|
|
kvm_guests: >-
|
|
{{ node_guests.proxmox_vms
|
|
| selectattr('type', 'equalto', 'qemu')
|
|
| list }}
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Build LXC migration list"
|
|
ansible.builtin.set_fact:
|
|
lxc_guests: >-
|
|
{{ node_guests.proxmox_vms
|
|
| selectattr('type', 'equalto', 'lxc')
|
|
| list }}
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | Log migration plan"
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Drain plan for {{ current_node }} → {{ migration_target }}:
|
|
KVM ({{ kvm_guests | length }}): {{ kvm_guests | map(attribute='vmid') | list }}
|
|
LXC ({{ lxc_guests | length }}): {{ lxc_guests | map(attribute='vmid') | list }}
|
|
delegate_to: localhost
|
|
|
|
# ── KVM migrations ────────────────────────────────────────────────────────────
|
|
- name: "Drain | Migrate KVM guests"
|
|
when: kvm_guests | length > 0
|
|
block:
|
|
- name: "Drain | KVM | Live migrate (sequential)"
|
|
community.proxmox.proxmox_kvm:
|
|
api_host: "{{ api_host }}"
|
|
api_user: "{{ api_user }}"
|
|
api_token_id: "{{ api_token_id }}"
|
|
api_token_secret: "{{ api_token_secret }}"
|
|
api_port: "{{ api_port }}"
|
|
node: "{{ current_node }}"
|
|
vmid: "{{ item.vmid }}"
|
|
migrate: true
|
|
target: "{{ migration_target }}"
|
|
timeout: "{{ vm_shutdown_timeout }}"
|
|
loop: "{{ kvm_guests }}"
|
|
delegate_to: localhost
|
|
when: not migration_bulk | bool
|
|
|
|
- name: "Drain | KVM | Bulk migrate (fire all simultaneously)"
|
|
community.proxmox.proxmox_kvm:
|
|
api_host: "{{ api_host }}"
|
|
api_user: "{{ api_user }}"
|
|
api_token_id: "{{ api_token_id }}"
|
|
api_token_secret: "{{ api_token_secret }}"
|
|
api_port: "{{ api_port }}"
|
|
node: "{{ current_node }}"
|
|
vmid: "{{ item.vmid }}"
|
|
migrate: true
|
|
target: "{{ migration_target }}"
|
|
timeout: "{{ vm_shutdown_timeout }}"
|
|
loop: "{{ kvm_guests }}"
|
|
delegate_to: localhost
|
|
async: "{{ vm_shutdown_timeout * 2 }}"
|
|
poll: 0
|
|
register: kvm_bulk_jobs
|
|
when: migration_bulk | bool
|
|
|
|
- name: "Drain | KVM | Wait for bulk migrations to complete"
|
|
ansible.builtin.async_status:
|
|
jid: "{{ item.ansible_job_id }}"
|
|
register: kvm_job_result
|
|
until: kvm_job_result.finished
|
|
retries: 60
|
|
delay: 10
|
|
loop: "{{ kvm_bulk_jobs.results }}"
|
|
delegate_to: localhost
|
|
when: migration_bulk | bool
|
|
|
|
# ── LXC migrations ────────────────────────────────────────────────────────────
|
|
- name: "Drain | Migrate LXC guests"
|
|
when: lxc_guests | length > 0
|
|
block:
|
|
- name: "Drain | LXC | Warn about restart requirement"
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
LXC {{ item.vmid }} ({{ item.name | default('unknown') }}) will be
|
|
stopped, migrated to {{ migration_target }}, and restarted.
|
|
(LXC live migration is not supported by Proxmox)
|
|
loop: "{{ lxc_guests | selectattr('status', 'equalto', 'running') | list }}"
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | LXC | Skip warning"
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
WARNING — LXC {{ item.vmid }} ({{ item.name | default('unknown') }})
|
|
live_migrate_fallback=skip — THIS CONTAINER WILL GO DOWN during node reboot.
|
|
loop: "{{ lxc_guests | selectattr('status', 'equalto', 'running') | list }}"
|
|
when: live_migrate_fallback == 'skip'
|
|
delegate_to: localhost
|
|
|
|
- name: "Drain | LXC | Migrate via pct migrate"
|
|
ansible.builtin.command: >
|
|
pct migrate {{ item.vmid }} {{ migration_target }}
|
|
{% if item.status == 'running' %}--restart{% endif %}
|
|
--timeout {{ lxc_migrate_timeout }}
|
|
loop: "{{ lxc_guests }}"
|
|
when: live_migrate_fallback != 'skip'
|
|
changed_when: true
|
|
|
|
- name: "Drain | LXC | Log migration results"
|
|
ansible.builtin.debug:
|
|
msg: "LXC {{ item.item.vmid }} migrated to {{ migration_target }}"
|
|
loop: "{{ lxc_migrate_result.results | default([]) }}"
|
|
when: item.rc is defined and item.rc == 0
|
|
|
|
- name: "Drain | {{ current_node }} drained successfully"
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Node {{ current_node }} drained —
|
|
{{ kvm_guests | length }} KVM + {{ lxc_guests | length }} LXC guests
|
|
migrated to {{ migration_target }} |