#!/usr/bin/python3 import subprocess import Pyro4 from pathlib import Path import logging as log import signal import time from os import getpid from zfssmd_worker import ZFSSMDaemonRefresh ENCODING = 'utf-8' UNIX_SOCK=Path('/run/zfssmd.sock') UNIX_PID=Path('/run/zfssmd.pid') CONN_ID='058b7dde9ec53de9235cfc57a07ce17a9eabfce3' class ZfsSnapshotManagerDaemon(object): # TODO docstrings class and methods snapshots = list() last_refreshed=0 def __init__(self): self.last_refreshed = self.call_zfs_list_snapshots() @Pyro4.expose def call_zfs_list_snapshots(self): command = 'zfs list -Hp -t snapshot -o name,creation,used,referenced -s name' try: p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception as e: log.error("Couldn't run ZFS list command. " + e) snapshot_list = [snapshot.decode(ENCODING) for snapshot in p.stdout] last_refreshed = time.time() self.snapshots = snapshot_list self.last_refreshed = last_refreshed return last_refreshed @Pyro4.expose def get_current_list(self): return {self.last_refreshed:self.snapshots} def check_start_conditions(): if UNIX_PID.is_file(): log.warning("Daemon already running or didn't exit gracefully. Trying to clean up.") try: UNIX_PID.unlink() except Exception as e: log.error("Couldn't delete PID file" + str(UNIX_PID)) log.error(e) raise SystemExit(1) try: UNIX_PID.touch() except Exception as e: log.error("Couldn't create PID file. " + UNIX_PID + " Check Permissions") log.error(e) raise SystemExit(1) if UNIX_SOCK.is_socket() or UNIX_SOCK.is_file(): log.warning("Daemon already running or didn't exit gracefully. Trying to clean up.") try: UNIX_SOCK.unlink() except Exception as e: log.error("Couldn't delete sock file" + str(UNIX_SOCK)) log.error(e) raise SystemExit(1) else: log.debug("Socket not set. Continuing.") def sigterm_handler(_signo, _stack_frame): log.warning("Received Termination signal. Cleaning up.") UNIX_SOCK.unlink() UNIX_PID.unlink() raise SystemExit(0) def start_daemon(): signal.signal(signal.SIGTERM, sigterm_handler) signal.signal(signal.SIGINT, sigterm_handler) check_start_conditions() daemon = Pyro4.Daemon(port=None,unixsocket=str(UNIX_SOCK)) uri = daemon.register(ZfsSnapshotManagerDaemon(), CONN_ID) log.info(uri) ZFSSMDaemonRefresh() daemon.requestLoop() start_daemon()