2019-05-03 21:36:44 +02:00
|
|
|
import os
|
|
|
|
import json
|
2020-01-06 13:26:52 +01:00
|
|
|
import logging
|
2020-01-05 13:17:46 +01:00
|
|
|
from datetime import datetime
|
2019-05-03 21:36:44 +02:00
|
|
|
|
|
|
|
|
2020-01-05 13:17:46 +01:00
|
|
|
class Scheduler():
|
|
|
|
__shared_state = dict()
|
|
|
|
__data = dict()
|
2019-05-03 21:36:44 +02:00
|
|
|
def __init__(self):
|
2020-01-05 13:17:46 +01:00
|
|
|
self.__dict__ = self.__shared_state
|
|
|
|
if not self.__data:
|
|
|
|
# who are we?
|
|
|
|
uid = os.getuid()
|
|
|
|
if uid == 0:
|
2020-01-06 13:26:52 +01:00
|
|
|
logging.info("Executing as root.")
|
2020-01-05 13:17:46 +01:00
|
|
|
self._data_file = "/var/lib/backive/data.json"
|
|
|
|
else:
|
2020-01-06 13:26:52 +01:00
|
|
|
logging.info("Executing as user.")
|
2020-01-05 13:17:46 +01:00
|
|
|
self._data_file = os.path.join(
|
2019-05-03 21:36:44 +02:00
|
|
|
os.path.expanduser("~"),
|
|
|
|
".config",
|
|
|
|
"backive",
|
|
|
|
"data.json"
|
|
|
|
)
|
2020-01-05 13:17:46 +01:00
|
|
|
if not os.path.exists(os.path.dirname(self._data_file)):
|
|
|
|
os.makedirs(os.path.dirname(self._data_file))
|
|
|
|
self.save()
|
2020-03-19 21:16:38 +01:00
|
|
|
else:
|
|
|
|
self.load()
|
2019-05-03 21:36:44 +02:00
|
|
|
|
|
|
|
def save(self):
|
2021-05-20 20:24:46 +02:00
|
|
|
logging.debug("Scheduler.save()")
|
2019-05-03 21:36:44 +02:00
|
|
|
with open(self._data_file, "w") as stream:
|
2020-01-05 13:17:46 +01:00
|
|
|
json.dump(self.__data, stream, indent=2)
|
2019-05-03 21:36:44 +02:00
|
|
|
|
|
|
|
def load(self):
|
2021-05-20 20:24:46 +02:00
|
|
|
logging.debug("Scheduler.load()")
|
|
|
|
if not os.path.exists(os.path.dirname(self._data_file)):
|
|
|
|
os.makedirs(os.path.dirname(self._data_file))
|
|
|
|
self.save()
|
2019-05-03 21:36:44 +02:00
|
|
|
with open(self._data_file, "r") as stream:
|
2020-01-05 13:17:46 +01:00
|
|
|
self.__data = json.load(stream)
|
2019-05-03 21:36:44 +02:00
|
|
|
|
|
|
|
def register_backup(self, name, frequency):
|
2020-03-19 21:16:38 +01:00
|
|
|
logging.debug("Registering %s, freq %s in Scheduler", name, frequency)
|
2020-01-05 13:17:46 +01:00
|
|
|
backups = self.__data.get("backups", dict())
|
|
|
|
if not backups:
|
|
|
|
self.__data["backups"] = backups
|
|
|
|
if (
|
|
|
|
name not in backups.keys() or
|
|
|
|
backups[name] != frequency
|
2020-03-19 21:16:38 +01:00
|
|
|
):
|
2020-01-05 13:17:46 +01:00
|
|
|
backups[name] = frequency
|
|
|
|
self.save()
|
2019-05-03 21:36:44 +02:00
|
|
|
|
2020-03-19 21:16:38 +01:00
|
|
|
async def register_run(self, name):
|
|
|
|
logging.info("Registered run of backup '%s'", name)
|
2020-01-05 13:17:46 +01:00
|
|
|
runs = self.__data.get("runs", dict())
|
|
|
|
if not runs:
|
|
|
|
self.__data["runs"] = runs
|
|
|
|
if name not in runs.keys():
|
|
|
|
runs[name] = [datetime.now().isoformat()]
|
|
|
|
else:
|
|
|
|
runs[name].append(datetime.now().isoformat())
|
|
|
|
self.save()
|
2019-05-03 21:36:44 +02:00
|
|
|
|
2020-03-19 21:16:38 +01:00
|
|
|
async def should_run(self, name):
|
|
|
|
logging.debug("Checking if %s may run...", name)
|
2020-01-06 23:01:25 +01:00
|
|
|
runs = self.__data.get("runs", dict())
|
|
|
|
if name not in runs:
|
2020-03-19 21:16:38 +01:00
|
|
|
logging.debug("Not registered, so YES")
|
2020-01-06 23:01:25 +01:00
|
|
|
return True
|
2020-03-19 21:16:38 +01:00
|
|
|
frequency = 0
|
2020-01-06 23:01:25 +01:00
|
|
|
if name in runs:
|
2020-03-19 21:16:38 +01:00
|
|
|
logging.debug("Registered, checking...")
|
2020-01-06 23:01:25 +01:00
|
|
|
backups = self.__data.get("backups", dict())
|
|
|
|
if name in backups:
|
2020-03-19 21:16:38 +01:00
|
|
|
logging.debug("retrieving frequency")
|
2020-01-06 23:01:25 +01:00
|
|
|
frequency = backups[name]
|
|
|
|
last_ts = runs[name][-1]
|
|
|
|
now = datetime.now()
|
|
|
|
last = datetime.fromisoformat(last_ts)
|
|
|
|
diff = now - last
|
|
|
|
days = diff.days
|
2020-03-19 21:16:38 +01:00
|
|
|
if days >= frequency and days >= 1 or frequency == 0:
|
|
|
|
logging.debug("YES, should run.")
|
2020-01-06 23:01:25 +01:00
|
|
|
return True
|
2020-03-19 21:16:38 +01:00
|
|
|
logging.debug("No should not run.")
|
2020-01-06 23:01:25 +01:00
|
|
|
return False
|
2019-05-03 21:36:44 +02:00
|
|
|
|
|
|
|
def get_overtimed(self):
|
2020-03-19 21:16:38 +01:00
|
|
|
overtime = list()
|
|
|
|
now = datetime.now()
|
|
|
|
runs = self.__data.get("runs", dict())
|
|
|
|
for bkp_name, freq in self.__data.get("backups").items():
|
|
|
|
if bkp_name not in runs.keys():
|
|
|
|
overtime.append(bkp_name)
|
|
|
|
else:
|
|
|
|
last_ts = runs[bkp_name][-1]
|
|
|
|
last = datetime.fromisoformat(last_ts)
|
|
|
|
diff = now - last
|
|
|
|
days = diff.days
|
|
|
|
if days > freq and freq != 0:
|
|
|
|
overtime.append(bkp_name)
|
|
|
|
return overtime
|