many things

This commit is contained in:
Chronial committed 2014-02-14 13:25:39 +00:00
1 parent 0dbf023957
commit bd55a215f3
2 files changed
+106 -92

No files matched your search

+21 -21
View File
@@ -1,3 +1,24 @@
[snapraid]
; path to the snapraid executable
executable =
; path to the snapraid config to be used
config = snapraid.conf
; abort operation if there are more deletes than this, set to -1 to disable
deletethreshold = 40
[logging]
; logfile to write to, leave empty to disable
file = snapraid.log
; maximum logfile size in KiB, leave empty for infinite
maxsize = 5000
[email]
; when to send an email, comma-separated list of [success, error]
sendon = success,error
subject = [SnapRAID] Status Report:
from =
to =
[smtp] [smtp]
host = host =
; leave empty for default port ; leave empty for default port
@@ -7,27 +28,6 @@ ssl = false
user = user =
password = password =
[email]
; when to send an email, comma-separated list of [success, error]
send = success,error
subject = [SnapRAID] Status Report:
from =
to =
[snapraid]
; path to the snapraid executable
executable =
; path to the snapraid config to be used
config = snapraid.conf
; abort operation if there are more deletes than this, leave empty to disable
deletethreshold = 40
[logging]
; logfile to write to, leave empty to disable
file = snapraid.log
; maximum logfile size in KiB, leave empty for infinite
maxsize = 5000
; maybe some smartctrl options ; maybe some smartctrl options
+85 -71
View File
@@ -1,20 +1,16 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
import ConfigParser
import argparse import argparse
import ConfigParser
import logging import logging
import logging.handlers import logging.handlers
import sys import os.path
import subprocess import subprocess
import sys
import threading import threading
import traceback import traceback
from collections import Counter from collections import Counter, defaultdict
from cStringIO import StringIO from cStringIO import StringIO
# TODO: check config validity
# TODO: alles in main und exceptions handlen
# finish() darf keine exceptions werfen!
# Global variables # Global variables
config = None config = None
email_log = None email_log = None
@@ -22,20 +18,20 @@ email_log = None
def tee_log(infile, out_lines, log_level): def tee_log(infile, out_lines, log_level):
def tee_thread(): def tee_thread():
for line in iter(infile.readline, ''): for line in iter(infile.readline, ""):
logging.log(log_level, line.strip()) logging.log(log_level, line.strip())
out_lines.append(line) out_lines.append(line)
infile.close() infile.close()
t = threading.Thread(target=tee_thread) t = threading.Thread(target=tee_thread)
#t.daemon = True t.daemon = True
t.start() t.start()
return t return t
def snapraid_command(command): def snapraid_command(command):
p = subprocess.Popen( p = subprocess.Popen(
[config.get("snapraid", "executable"), command, [config["snapraid"]["executable"], command,
"--conf", config.get("snapraid", "config")], "--conf", config["snapraid"]["config"]],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) stderr=subprocess.PIPE)
out = [] out = []
@@ -56,56 +52,64 @@ def send_email(success):
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email import charset from email import charset
# use quoted-printable instead of the default base64 # use quoted-printable instead of the default base64
charset.add_charset('utf-8', charset.SHORTEST, charset.QP) charset.add_charset("utf-8", charset.SHORTEST, charset.QP)
if success: if success:
body = "SnapRAID job completed successfully:\n\n\n" body = "SnapRAID job completed successfully:\n\n\n"
else: else:
body = "Error during SnapRAID job:\n\n\n" body = "Error during SnapRAID job:\n\n\n"
body += email_log.getvalue() body += email_log.getvalue()
msg = MIMEText(body, "plain", "utf-8") msg = MIMEText(body, "plain", "utf-8")
msg['Subject'] = config.get("email", "subject") + \ msg["Subject"] = config["email"]["subject"] + \
" SUCCESS" if success else " ERROR" (" SUCCESS" if success else " ERROR")
msg['From'] = config.get("email", "from") msg["From"] = config["email"]["from"]
msg['To'] = config.get("email", "to") msg["To"] = config["email"]["to"]
smtp = {"host": config.get("smtp", "host")} smtp = {"host": config["smtp"]["host"]}
if config.get("smtp", "port"): if config["smtp"]["port"]:
smtp["port"] = config.getint("smtp", "port") smtp["port"] = config["smtp"]["port"]
if config.get("smtp", "ssl").lower() == "true": if config["smtp"]["ssl"]:
server = smtplib.SMTP_SSL(**smtp) server = smtplib.SMTP_SSL(**smtp)
else: else:
server = smtplib.SMTP(**smtp) server = smtplib.SMTP(**smtp)
if config.get("smtp", "user"): if config["smtp"]["user"]:
server.login(config.get("smtp", "user"), server.login(config["smtp"]["user"], config["smtp"]["password"])
config.get("smtp", "password"))
server.sendmail( server.sendmail(
config.get("email", "from"), config["email"]["from"],
[config.get("email", "to")], [config["email"]["to"]],
msg.as_string()) msg.as_string())
server.quit server.quit()
def finish(is_success): def finish(is_success):
if ("error", "success")[is_success] in config["email"]["sendon"]:
try:
send_email(is_success)
except:
logging.exception("Failed to send email")
if is_success: if is_success:
logging.info("Run finished successfully") logging.info("Run finished successfully")
else: else:
logging.error("Run failed") logging.error("Run failed")
if ((is_success and "success" in config.get("email", "send")) or
(not is_success and "error" in config.get("email", "send"))):
send_email(is_success)
sys.exit(0 if is_success else 1) sys.exit(0 if is_success else 1)
def load_config(file): def load_config(file):
global config global config
config = ConfigParser.RawConfigParser(allow_no_value=True) parser = ConfigParser.RawConfigParser()
config.add_section("smtp") parser.read(file)
config.add_section("email") sections = ["snapraid", "logging", "email", "smtp"]
config.add_section("snapraid") config = dict((x, defaultdict(lambda: "")) for x in sections)
config.set("snapraid", "delethreshold", 0) for section in parser.sections():
config.add_section("logging") for (k, v) in parser.items(section):
config.set("logging", "file", None) config[section][k] = v.strip()
config.set("logging", "maxsize", 0)
config.read(file) intvals = [("snapraid", "deletethreshold"), ("logging", "maxsize")]
for section, option in intvals:
try:
config[section][option] = int(config[section][option])
except ValueError:
config[section][option] = 0
config["smtp"]["ssl"] = (config["smtp"]["ssl"].lower() == "true")
def setup_logger(): def setup_logger():
@@ -121,16 +125,16 @@ def setup_logger():
console_logger.setFormatter(log_format) console_logger.setFormatter(log_format)
root_logger.addHandler(console_logger) root_logger.addHandler(console_logger)
if config.get("logging", "file"): if config["logging"]["file"]:
max_log_size = min(config.getint("logging", "maxsize"), 0) * 1024 max_log_size = min(config["logging"]["maxsize"], 0) * 1024
file_logger = logging.handlers.RotatingFileHandler( file_logger = logging.handlers.RotatingFileHandler(
config.get("logging", "file"), config["logging"]["file"],
maxBytes=max_log_size, maxBytes=max_log_size,
backupCount=9) backupCount=9)
file_logger.setFormatter(log_format) file_logger.setFormatter(log_format)
root_logger.addHandler(file_logger) root_logger.addHandler(file_logger)
if config.get("email", "send"): if config["email"]["sendon"]:
global email_log global email_log
email_log = StringIO() email_log = StringIO()
email_logger = logging.StreamHandler(email_log) email_logger = logging.StreamHandler(email_log)
@@ -142,17 +146,46 @@ def setup_logger():
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('-c', '--conf', nargs=1, parser.add_argument("-c", "--conf", nargs=1,
default='snapraid-runner.conf', default="snapraid-runner.conf",
help='Configuration file (default %(default)s)') help="Configuration file (default %(default)s)")
args = parser.parse_args() args = parser.parse_args()
load_config(args.conf)
setup_logger()
try:
load_config(args.conf)
except:
print("unexpected exception while loading config")
print traceback.format_exc()
sys.exit(2)
try:
setup_logger()
except:
print("unexpected exception while setting up logging")
print traceback.format_exc()
sys.exit(2)
try:
run()
except Exception:
logging.exception("Run failed due to unexpected exception:")
finish(False)
def run():
logging.info("=" * 60) logging.info("=" * 60)
logging.info("Run started") logging.info("Run started")
logging.info("=" * 60) logging.info("=" * 60)
if not os.path.exists(config["snapraid"]["executable"]):
logging.error("Snapraid executable does not exist at " +
config["snapraid"]["executable"])
finish(False)
if not os.path.exists(config["snapraid"]["config"]):
logging.error("Snapraid config does not exist at " +
config["snapraid"]["config"])
finish(False)
logging.info("Running diff...") logging.info("Running diff...")
try: try:
diff_out = snapraid_command("diff") diff_out = snapraid_command("diff")
@@ -165,12 +198,11 @@ def main():
logging.info(("Diff results: {add} added, {remove} removed, " logging.info(("Diff results: {add} added, {remove} removed, "
+ "{move} moved, {update} modified").format(**diff_results)) + "{move} moved, {update} modified").format(**diff_results))
if (config.getint("snapraid", "deletethreshold") > 0 and if (config["snapraid"]["deletethreshold"] >= 0 and
diff_results["remove"] > diff_results["remove"] > config["snapraid"]["deletethreshold"]):
config.getint("snapraid", "deletethreshold")):
logging.error( logging.error(
"Deleted files exceed delete threshold {}, aborting".format( "Deleted files exceed delete threshold of {}, aborting".format(
config.getint("snapraid", "deletethreshold"))) config["snapraid"]["deletethreshold"]))
finish(False) finish(False)
if (diff_results["remove"] + diff_results["add"] + diff_results["move"] + if (diff_results["remove"] + diff_results["add"] + diff_results["move"] +
@@ -190,22 +222,4 @@ def main():
finish(True) finish(True)
try:
load_config()
except:
print("unexpected exception while loading config")
print traceback.format_exc()
sys.exit(2)
try:
setup_logger()
except:
print("unexpected exception while setting up logging")
print traceback.format_exc()
sys.exit(2)
try:
main() main()
except Exception as e:
logging.exception("Run failed due to unexpected exception:")
finish(False)