automatic backup disk on/off

This commit is contained in:
2025-11-19 16:27:06 +01:00
parent 2e245eeefa
commit 153c774692
6 changed files with 135 additions and 27 deletions

View File

@@ -0,0 +1,12 @@
- name: reload systemd
command: systemctl daemon-reload
- name: Restart NGINX
service:
name: nginx
state: restarted
- name: Run APT update
command: apt update -y

View File

@@ -0,0 +1,9 @@
[Unit]
Description="Check Backup mounts and turn Disk off if apropriate"
[Timer]
OnCalendar=*:0/15
Unit=backup-disk-onoff@off.service
[Install]
WantedBy=network.target

View File

@@ -1,5 +1,24 @@
#!/usr/bin/env python3
import subprocess import subprocess
import json import json
import sys
import paho.mqtt.client as mqtt
import time
def send_mqtt_message(topic, payload):
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) # Use the latest API version
client.connect("mqtt.chaos", 1883, 60)
client.publish(topic, payload)
client.disconnect()
def get_args(name='default', first='on'):
return first
mode = get_args(*sys.argv)
print(f"Mode is: {mode}")
if mode not in ["on", "off"]:
print("Error: mode must be either 'on' or 'off'")
sys.exit(1)
# Run the systemctl command and capture the output # Run the systemctl command and capture the output
try: try:
@@ -21,7 +40,7 @@ except json.JSONDecodeError as e:
print(f"Error parsing JSON: {e}") print(f"Error parsing JSON: {e}")
exit(1) exit(1)
# Filter units that are loaded, active, and sub: running # Filter units that are loaded, active, and sub: running, and start with 'backup-'
running_units = [] running_units = []
for unit in units: for unit in units:
if ( if (
@@ -36,3 +55,46 @@ for unit in units:
print("Units with load: loaded, active: active, sub: running:") print("Units with load: loaded, active: active, sub: running:")
for unit in running_units: for unit in running_units:
print(f" - {unit['unit']}: {unit['description']}") print(f" - {unit['unit']}: {unit['description']}")
# Send MQTT message based on mode
if mode == "on" or (mode == "off" and running_units):
# Send ON MQTT message
print(f"Turning backup Disk ON")
send_mqtt_message("switch_backup/switch/switch_backup_power/command", "on")
time.sleep(15)
# ON case: Send ON message after waiting 5 seconds and running vgchange -ay backup if needed
if mode == "on":
# Check if 'backup' VG is active
try:
result = subprocess.run(
["vgdisplay", "-cA"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=True
)
vgdisplay_output = result.stdout.strip().split("\n")
print(f"vgdisplay: {vgdisplay_output}")
backup_present = any(line.split(":")[0].strip() == "backup" for line in vgdisplay_output)
print(f"backup VG active? {backup_present}")
if not backup_present:
try:
print(f"Activating VG backup")
subprocess.run(["vgchange", "-ay", "backup"], check=True)
except subprocess.CalledProcessError as e:
print(f"Error executing vgchange: {e.stderr}")
exit(1)
except subprocess.CalledProcessError as e:
print(f"Error executing vgdisplay: {e.stderr}")
exit(1)
else:
# OFF case: Only execute if nothing is mounted
if not running_units:
print(f"Turning backup Disk OFF")
subprocess.run(["sync"], check=True)
try:
subprocess.run(["vgchange", "-an", "backup"], check=True)
except subprocess.CalledProcessError as e:
print(f"Error executing vgchange: {e.stderr}")
exit(1)
send_mqtt_message("switch_backup/switch/switch_backup_power/command", "off")

View File

@@ -0,0 +1,11 @@
[Unit]
Description=Backup Disk %I
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-disk-onoff.py %I
RemainAfterExit=yes
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,2 @@
dependencies:
- _handlers

View File

@@ -1,3 +1,9 @@
- name: Additional packages
apt:
state: present
name:
- python3-paho-mqtt
- name: Generate Automounts - name: Generate Automounts
include_role: include_role:
@@ -12,7 +18,8 @@
Type: btrfs Type: btrfs
Options: defaults,compress=lzo,space_cache=v2 Options: defaults,compress=lzo,space_cache=v2
Unit: Unit:
After: network.target After: network.target backup-disk-onoff@on.service
Requires: backup-disk-onoff@on.service
Install: Install:
WantedBy: network.target WantedBy: network.target
catena_automount: catena_automount:
@@ -35,28 +42,33 @@
loop_var: mount_point loop_var: mount_point
- name: BackupDisk On/Off service
# [Unit] block:
# Description=Automount /backup/yori - name: Copy Script
# After=network.target copy:
src: backup-disk-onoff.py
# [Automount] dest: /usr/local/bin/backup-disk-onoff.py
# Where=/backup/yori mode: 0755
# TimeoutIdleSec=30 owner: root
group: root
# [Install] - name: Install Unit file
# WantedBy=network.target notify: reload systemd
# [Unit] copy:
# Description=Mount /backup/yori src: backup-disk-onoff@.service
# After=network.target dest: /etc/systemd/system/backup-disk-onoff@.service
# #Requires=backup-yori.automount owner: root
# #After=backup-yori.automount group: root
- name: Create a timer to turn OFF the Disk
# [Mount] notify: reload systemd
# What=/dev/backup/yori copy:
# Where=/backup/yori src: backup-disk-off.timer
# Type=btrfs dest: /etc/systemd/system/backup-disk-off.timer
# Options=defaults,compress=lzo,space_cache=v2 owner: root
group: root
# [Install] - name: Enable timer and start it
# WantedBy=network.target ansible.builtin.systemd_service:
name: backup-disk-off.timer
enabled: true
state: started