commit 6618ab5a105a78395ddf24142b95e6c197e75a5e Author: George Butskivsky Date: Mon Jun 2 11:23:28 2025 +0300 initial version diff --git a/README.md b/README.md new file mode 100644 index 0000000..42f8179 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +Простой монитор доступности виртуальных машин. + +Следит по IP и перезапускает если недостуна + +- запускать на хосте proxmox, по крону, раз в минуту (например: crontab -e; */1 * * * * /usr/bin/python3 /root/svs-proxmox-watchdog.py 1>/dev/null 2>/dev/null) + +- необходим первичный json со списком виртуалок для мониторинга, вида: + +List of dicts: [ {}, {}, ... ] + +Dict: { "name" : "", "id" : proxmox_vm_id, "ip" : "x.x.x.x", "down" : 0 } diff --git a/svs-proxmox-watchdog.py b/svs-proxmox-watchdog.py new file mode 100644 index 0000000..36f882c --- /dev/null +++ b/svs-proxmox-watchdog.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +import subprocess as sp +import json +import time, re + +# Read DB from file +def read_json_from_file(filepath): + with open(filepath, 'r') as file: + data = json.load(file) + return data + +# Alive check for host +def ping(ip): + status,result = sp.getstatusoutput("ping -c1 -w2 " + ip) + return status + +def vmstat(id): + vm_status = "dnd" + status,result = sp.getstatusoutput("qm status 114") + match = re.search(r"status: (.+)", result) + if match: + vm_status = match.group(1) + return vm_status + +# timeout +shutdown_timeout = 5 + +# DB file +file_path = '/root/svs-watchdog.json' + +# Read DB to mem +vms = read_json_from_file(file_path) + +# Monitor VMs +for vm in vms: + ip = vm['ip'] + down = vm['down'] + + if ping(ip) == 0: + vm['down'] = 0 + else: + vm['down'] = down + 1 + if vmstat(vm['id']) == 'runnnig' and vm['down'] >= shutdown_timeout: + status,result = sp.getstatusoutput("qm stop " + str(vm['id']) + " --overrule-shutdown 1") + else: + if vmstat(vm['id']) == 'stopped' and vm['down'] >= shutdown_timeout: + status,result = sp.getstatusoutput("qm start " + str(vm['id'])) + vm['down'] = 0 + +# Update the status +with open(file_path, "w") as file: + json.dump(vms, file)