forked from Tecnativa/docker-duplicity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjobrunner.py
94 lines (81 loc) · 2.58 KB
/
jobrunner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python
"""Run all commands extracted from environment variables when they should."""
from __future__ import unicode_literals
import logging
import re
import smtplib
import sys
from datetime import datetime
from os import environ, path
from socket import gethostname
from string import Template
from subprocess import CalledProcessError, check_output, STDOUT
logging.basicConfig(level=logging.INFO)
logging.root.name = "jobrunner"
# Get expected periodicity from this script's placement
periodicity = path.basename(path.dirname(path.abspath(__file__)))
logging.info("Running %s jobs", periodicity)
# Get email settings
host = environ.get("SMTP_HOST")
port = environ.get("SMTP_PORT")
from_ = environ.get("EMAIL_FROM")
to = environ.get("EMAIL_TO")
subject = environ.get("EMAIL_SUBJECT")
# Get the commands we need to run
to_run = dict()
for key, when in environ.items():
match = re.match(r"^JOB_(\d+)_WHEN$", key)
if match and periodicity in when.split():
njob = int(match.group(1))
to_run[njob] = environ["JOB_{}_WHAT".format(njob)]
if not to_run:
logging.info("Nothing to do")
sys.exit()
# Run commands in order
message = [
"From: {}".format(from_),
"To: {}\r\n".format(to),
]
failed = False
for njob, command in sorted(to_run.items()):
expanded_command = Template(command).safe_substitute(environ)
start = datetime.now()
logging.info("Running job %d: `%s`", njob, expanded_command)
try:
result = check_output(expanded_command, stderr=STDOUT, shell=True)
success = True
except CalledProcessError as error:
failed = True
success = False
result = str(error) + "\n" + error.output
logging.exception("Failed!")
end = datetime.now()
log = [
"",
"===================================",
"Job {}: `{}`".format(njob, expanded_command),
"Started: {!s}".format(start),
"Finished: {!s}".format(end),
"Success: {!s}".format(success),
"",
result,
]
logging.log(logging.INFO if success else logging.ERROR, "\n".join(log))
message += log
# Report results
if all((host, port, from_, to, subject)):
logging.info("Sending email report")
message.insert(0, "Subject: {}".format(subject.format(
hostname=gethostname(),
periodicity=periodicity,
result="ERROR" if failed else "OK",
)))
try:
smtp = smtplib.SMTP(host, port)
smtp.sendmail(from_, to, "\r\n".join(message))
finally:
smtp.quit()
else:
logging.info("Finished")
if failed:
sys.exit("At least one job failed")