summaryrefslogtreecommitdiff
path: root/roles/storage/zfs/syncoid/templates/autosuspend.py.j2
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2021-05-19 16:52:36 +0200
committerChristian Pointner <equinox@spreadspace.org>2021-05-19 16:52:36 +0200
commit26214e3f7c5343fa30d2ff1ae71a6cf7197b6f3e (patch)
tree3782b45b690df45257e4170df86b57a4b4f3575c /roles/storage/zfs/syncoid/templates/autosuspend.py.j2
parentrename apt-repo github-containers to kubic-project (diff)
initial version of syncoid autosuspender
Diffstat (limited to 'roles/storage/zfs/syncoid/templates/autosuspend.py.j2')
-rw-r--r--roles/storage/zfs/syncoid/templates/autosuspend.py.j292
1 files changed, 92 insertions, 0 deletions
diff --git a/roles/storage/zfs/syncoid/templates/autosuspend.py.j2 b/roles/storage/zfs/syncoid/templates/autosuspend.py.j2
new file mode 100644
index 00000000..e54ddd1b
--- /dev/null
+++ b/roles/storage/zfs/syncoid/templates/autosuspend.py.j2
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+
+import sys
+import dbus
+import re
+import datetime
+#import pprint
+
+
+class AutoSuspender(object):
+
+ def __init__(self):
+ self.__bus = dbus.SystemBus()
+ self.__timer_re = re.compile('^syncoid-run-.*\.timer$')
+ #self.__pp = pprint.PrettyPrinter(indent=2)
+
+ def _get_interface(self, dest, object, interface):
+ try:
+ obj = self.__bus.get_object(dest, object)
+ return dbus.Interface(obj, interface)
+ except dbus.exceptions.DBusException as error:
+ print(error)
+ sys.exit(1)
+
+ def _get_logind_manager_interface(self):
+ return self._get_interface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager")
+
+ def _get_systemd_manager_interface(self):
+ return self._get_interface("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager")
+
+ def _get_systemd_timer_properties(self, path):
+ return self._get_interface("org.freedesktop.systemd1", path, "org.freedesktop.DBus.Properties").GetAll("org.freedesktop.systemd1.Timer")
+
+ def _get_users_logged_in(self):
+ manager = self._get_logind_manager_interface()
+ users = []
+ for user in manager.ListUsers():
+ uid = int(user[0])
+ name = str(user[1])
+ users.append((name, uid))
+ return users
+
+ def _get_syncoid_timers(self):
+ manager = self._get_systemd_manager_interface()
+ timers = []
+ for unit in manager.ListUnits():
+ name = str(unit[0])
+ path = str(unit[6])
+ if not self.__timer_re.match(name):
+ continue
+ timers.append((name, path))
+ return timers
+
+ def _get_timer_next_elapse(self, path):
+ props = self._get_systemd_timer_properties(path)
+ try:
+ return datetime.datetime.fromtimestamp(int(props['NextElapseUSecRealtime']) / 1000000)
+ except ValueError:
+ return datetime.datetime.now()
+
+ def check(self):
+ result = True
+
+ users = self._get_users_logged_in()
+ if(len(users) > 0):
+ print("%d users logged in: %s" % (len(users), ", ".join([user[0] for user in users])))
+ result = False
+
+ timers = self._get_syncoid_timers()
+ for timer in timers:
+ next = self._get_timer_next_elapse(timer[1])
+ until = next - datetime.datetime.now()
+ if(until < datetime.timedelta(minutes=10)):
+ print("Timer %s elapses in less then 10 Minutes -> %s (%s)" % (timer[0], next, until))
+ result = False
+
+ return result
+
+ def suspend(self):
+ manager = self._get_logind_manager_interface()
+ if not manager.CanSuspend():
+ print("suspending is not possible!")
+ return
+
+ print("suspending system")
+ manager.Suspend(False)
+
+
+if __name__ == "__main__":
+ s = AutoSuspender()
+ if s.check():
+ s.suspend()