diff --git a/roles/_handlers/handlers/main.yaml b/roles/_handlers/handlers/main.yaml new file mode 100644 index 0000000..0295242 --- /dev/null +++ b/roles/_handlers/handlers/main.yaml @@ -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 \ No newline at end of file diff --git a/roles/backup_server/files/backup-disk-off.timer b/roles/backup_server/files/backup-disk-off.timer new file mode 100644 index 0000000..207b23b --- /dev/null +++ b/roles/backup_server/files/backup-disk-off.timer @@ -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 \ No newline at end of file diff --git a/roles/backup_server/files/backup-disk-onoff.py b/roles/backup_server/files/backup-disk-onoff.py index 321c2f9..9c8cef8 100644 --- a/roles/backup_server/files/backup-disk-onoff.py +++ b/roles/backup_server/files/backup-disk-onoff.py @@ -1,5 +1,24 @@ +#!/usr/bin/env python3 import subprocess 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 try: @@ -21,7 +40,7 @@ except json.JSONDecodeError as e: print(f"Error parsing JSON: {e}") 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 = [] for unit in units: if ( @@ -36,3 +55,46 @@ for unit in units: print("Units with load: loaded, active: active, sub: running:") for unit in running_units: 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") \ No newline at end of file diff --git a/roles/backup_server/files/backup-disk-onoff@.service b/roles/backup_server/files/backup-disk-onoff@.service new file mode 100644 index 0000000..f1d404f --- /dev/null +++ b/roles/backup_server/files/backup-disk-onoff@.service @@ -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 \ No newline at end of file diff --git a/roles/backup_server/meta/main.yaml b/roles/backup_server/meta/main.yaml new file mode 100644 index 0000000..411c464 --- /dev/null +++ b/roles/backup_server/meta/main.yaml @@ -0,0 +1,2 @@ +dependencies: + - _handlers \ No newline at end of file diff --git a/roles/backup_server/tasks/main.yaml b/roles/backup_server/tasks/main.yaml index 1462f5a..c874678 100644 --- a/roles/backup_server/tasks/main.yaml +++ b/roles/backup_server/tasks/main.yaml @@ -1,3 +1,9 @@ +- name: Additional packages + apt: + state: present + name: + - python3-paho-mqtt + - name: Generate Automounts include_role: @@ -12,7 +18,8 @@ Type: btrfs Options: defaults,compress=lzo,space_cache=v2 Unit: - After: network.target + After: network.target backup-disk-onoff@on.service + Requires: backup-disk-onoff@on.service Install: WantedBy: network.target catena_automount: @@ -35,28 +42,33 @@ loop_var: mount_point - -# [Unit] -# Description=Automount /backup/yori -# After=network.target - -# [Automount] -# Where=/backup/yori -# TimeoutIdleSec=30 - -# [Install] -# WantedBy=network.target -# [Unit] -# Description=Mount /backup/yori -# After=network.target -# #Requires=backup-yori.automount -# #After=backup-yori.automount - -# [Mount] -# What=/dev/backup/yori -# Where=/backup/yori -# Type=btrfs -# Options=defaults,compress=lzo,space_cache=v2 - -# [Install] -# WantedBy=network.target \ No newline at end of file +- name: BackupDisk On/Off service + block: + - name: Copy Script + copy: + src: backup-disk-onoff.py + dest: /usr/local/bin/backup-disk-onoff.py + mode: 0755 + owner: root + group: root + - name: Install Unit file + notify: reload systemd + copy: + src: backup-disk-onoff@.service + dest: /etc/systemd/system/backup-disk-onoff@.service + owner: root + group: root + - name: Create a timer to turn OFF the Disk + notify: reload systemd + copy: + src: backup-disk-off.timer + dest: /etc/systemd/system/backup-disk-off.timer + owner: root + group: root + - name: Enable timer and start it + ansible.builtin.systemd_service: + name: backup-disk-off.timer + enabled: true + state: started + + \ No newline at end of file