ZFS_Snapshot_Manager/zfssmd.py

84 lines
2.6 KiB
Python

#!/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()