testing new proxmox logic
This commit is contained in:
17
roles/proxmox_restore/defaults/main.yml
Normal file
17
roles/proxmox_restore/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# proxmox_restore — defaults
|
||||
# =============================================================================
|
||||
|
||||
# State file directory (must match drain_state_dir)
|
||||
restore_state_dir: "/tmp/proxmox_drain_state"
|
||||
|
||||
# If true, delete the state file after successful restore
|
||||
restore_cleanup_state_file: true
|
||||
|
||||
# Timeout waiting for VM to start on restored node
|
||||
restore_vm_start_timeout: 120
|
||||
|
||||
# API connection (inherited from inventory)
|
||||
api_port: 8006
|
||||
validate_certs: false
|
||||
11
roles/proxmox_restore/meta/main.yml
Normal file
11
roles/proxmox_restore/meta/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: proxmox_restore
|
||||
author: ansible-msp
|
||||
description: "MSP Proxmox automation — proxmox_restore"
|
||||
min_ansible_version: "2.15"
|
||||
platforms:
|
||||
- name: Debian
|
||||
versions:
|
||||
- bookworm
|
||||
dependencies: []
|
||||
112
roles/proxmox_restore/tasks/main.yml
Normal file
112
roles/proxmox_restore/tasks/main.yml
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# proxmox_restore — tasks
|
||||
# Returns VMs to their origin nodes using state written by proxmox_drain.
|
||||
#
|
||||
# Required vars:
|
||||
# current_node — the node whose VMs should be restored
|
||||
# restore_state_file — path to the JSON state file (set by caller or discovered)
|
||||
# =============================================================================
|
||||
|
||||
# ── Find state file ───────────────────────────────────────────────────────────
|
||||
- name: "Restore | {{ current_node }} | Find state files"
|
||||
ansible.builtin.find:
|
||||
paths: "{{ restore_state_dir }}"
|
||||
patterns: "{{ current_node }}_*.json"
|
||||
file_type: file
|
||||
register: restore_found_files
|
||||
delegate_to: localhost
|
||||
|
||||
- name: "Restore | {{ current_node }} | No state files found — skipping"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
No drain state files found for {{ current_node }} in {{ restore_state_dir }}.
|
||||
Skipping restore.
|
||||
when: restore_found_files.files | length == 0
|
||||
|
||||
- name: "Restore | {{ current_node }} | End if no state files"
|
||||
ansible.builtin.meta: end_play
|
||||
when: restore_found_files.files | length == 0
|
||||
|
||||
- name: "Restore | {{ current_node }} | Use most recent state file"
|
||||
ansible.builtin.set_fact:
|
||||
restore_state_file: >-
|
||||
{{ (restore_found_files.files | sort(attribute='mtime') | last).path }}
|
||||
delegate_to: localhost
|
||||
|
||||
- name: "Restore | {{ current_node }} | Load state file"
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ restore_state_file }}"
|
||||
register: restore_state_raw
|
||||
delegate_to: localhost
|
||||
|
||||
- name: "Restore | {{ current_node }} | Parse VM origin list"
|
||||
ansible.builtin.set_fact:
|
||||
restore_vm_list: "{{ restore_state_raw.content | b64decode | from_json }}"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: "Restore | {{ current_node }} | Log restore plan"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Restoring {{ restore_vm_list | length }} guest(s) to {{ current_node }}:
|
||||
{{ restore_vm_list | map(attribute='vmid') | list }}
|
||||
|
||||
# ── Get current VM locations ──────────────────────────────────────────────────
|
||||
- name: "Restore | {{ current_node }} | Get current VM locations"
|
||||
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 }}"
|
||||
validate_certs: "{{ validate_certs }}"
|
||||
register: restore_all_vms
|
||||
delegate_to: localhost
|
||||
|
||||
# ── Migrate KVM guests back ───────────────────────────────────────────────────
|
||||
- name: "Restore | {{ current_node }} | KVM | Migrate back"
|
||||
ansible.builtin.command: >
|
||||
qm migrate {{ item.vmid }} {{ current_node }}
|
||||
{% if item.status == 'running' %}--online{% endif %}
|
||||
--with-local-disks 0
|
||||
loop: "{{ restore_vm_list | selectattr('type', 'equalto', 'qemu') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} (VMID {{ item.vmid }})"
|
||||
changed_when: true
|
||||
vars:
|
||||
current_location: >-
|
||||
{{ restore_all_vms.proxmox_vms
|
||||
| selectattr('vmid', 'equalto', item.vmid)
|
||||
| map(attribute='node')
|
||||
| first
|
||||
| default('unknown') }}
|
||||
when: current_location != current_node
|
||||
|
||||
# ── Migrate LXC guests back ───────────────────────────────────────────────────
|
||||
- name: "Restore | {{ current_node }} | LXC | Migrate back"
|
||||
ansible.builtin.command: >
|
||||
pct migrate {{ item.vmid }} {{ current_node }} --restart --timeout 120
|
||||
loop: "{{ restore_vm_list | selectattr('type', 'equalto', 'lxc') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name | default(item.vmid) }} (VMID {{ item.vmid }})"
|
||||
changed_when: true
|
||||
vars:
|
||||
current_location: >-
|
||||
{{ restore_all_vms.proxmox_vms
|
||||
| selectattr('vmid', 'equalto', item.vmid)
|
||||
| map(attribute='node')
|
||||
| first
|
||||
| default('unknown') }}
|
||||
when: current_location != current_node
|
||||
|
||||
# ── Cleanup ───────────────────────────────────────────────────────────────────
|
||||
- name: "Restore | {{ current_node }} | Remove state file"
|
||||
ansible.builtin.file:
|
||||
path: "{{ restore_state_file }}"
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
when: restore_cleanup_state_file
|
||||
|
||||
- name: "Restore | {{ current_node }} | Complete"
|
||||
ansible.builtin.debug:
|
||||
msg: "✓ Restore complete — {{ restore_vm_list | length }} guest(s) returned to {{ current_node }}."
|
||||
Reference in New Issue
Block a user